1 /* $Id: ssp_ipfw2.c,v 2.4 2008/04/26 19:53:21 fknobbe Exp $
2 *
3 *
4 * Copyright (c) 2005-2008 Robert Rolfe <rob@wehostwebpages.com>, Frank Knobbe <frank@knobbe.us>
5 * All rights reserved.
6 *
7 * Redistribution and use in source and binary forms, with or without
8 * modification, are permitted provided that the following conditions
9 * are met:
10 * 1. Redistributions of source code must retain the above copyright
11 * notice, this list of conditions and the following disclaimer.
12 * 2. Redistributions in binary form must reproduce the above copyright
13 * notice, this list of conditions and the following disclaimer in the
14 * documentation and/or other materials provided with the distribution.
15 *
16 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
17 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
18 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
19 * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
20 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
21 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
22 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
23 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
24 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
25 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
26 * SUCH DAMAGE.
27 *
28 *
29 * ssp_ipfw2.c
30 *
31 * Purpose:
32 *
33 * This SnortSam plugin is meant for dynamic blocking on IPFW2 firewalls.
34 * SnortSam will expire the blocks itself since IPFW2 does not have
35 * automatic time-out functionality.
36 *
37 */
38
39
40 #if defined(FreeBSD)
41
42 #ifndef __SSP_IPFW2_C__
43 #define __SSP_IPFW2_C__
44
45 #include "snortsam.h"
46 #include "ssp_ipfw2.h"
47
48
49 #include <sys/types.h>
50 #include <stdio.h>
51 #include <string.h>
52 #include <time.h>
53 #include <netinet/in.h>
54 #include <arpa/inet.h>
55
56
57 /* This routine parses the ipf statements in the config file.
58 */
IPFW2Parse(char * val,char * file,unsigned long line,DATALIST * plugindatalist)59 void IPFW2Parse(char *val,char *file,unsigned long line,DATALIST *plugindatalist)
60 { IPFW2DATA *ipfw2p=NULL;
61 char *p2,msg[STRBUFSIZE+2],chk[STRBUFSIZE+2];
62
63 #ifdef FWSAMDEBUG
64 printf("Debug: [ipfw2] Plugin Parsing...\n");
65 #endif
66
67 if(*val)
68 { p2=val;
69 while(*p2 && !myisspace(*p2)) p2++;
70 if(*p2) *p2++ =0;
71 ipfw2p=safemalloc(sizeof(IPFW2DATA),"IPFW2Parse","ipfw2p");
72 plugindatalist->data=ipfw2p;
73 safecopy(ipfw2p->interface,val); /* save interface */
74 ipfw2p->in_table=1; /* Setting defaults for the tables */
75 ipfw2p->out_table=2;
76 if(*p2)
77 { while(*p2 && myisspace(*p2)) p2++;
78 if(*p2)
79 { val=p2;
80 while(*p2 && !myisspace(*p2)) p2++;
81 if(*p2) *p2++ =0;
82 ipfw2p->in_table=(unsigned short)atoi(val);
83 if(*p2)
84 { while(*p2 && myisspace(*p2)) p2++;
85 if(*p2)
86 { val=p2;
87 while(*p2 && !myisspace(*p2)) p2++;
88 if(*p2) *p2++ =0;
89 ipfw2p->out_table=(unsigned short)atoi(val);
90 }
91 }
92 }
93 }
94 /* Check if inbound table exists */
95 snprintf(chk,sizeof(chk)-1,"/sbin/ipfw show | grep -q \"deny ip from any to table(%u) via %s\"",ipfw2p->in_table,ipfw2p->interface);
96 if(system(chk))
97 { /* We just exist with an error for now. In the future, we'll set up the table automatically */
98 snprintf(msg,sizeof(msg)-1,"Error: [%s: %lu] Inbound block table (%u) not defined!",file,line,ipfw2p->in_table);
99 logmessage(1,msg,"ipfw2",0);
100 free(ipfw2p);
101 plugindatalist->data=NULL;
102 }
103 else /* Check if oubound table exists */
104 { snprintf(chk,sizeof(chk)-1,"/sbin/ipfw show | grep -q \"deny ip from table(%u) to any via %s\"",ipfw2p->out_table,ipfw2p->interface);
105 if(system(chk))
106 { snprintf(msg,sizeof(msg)-1,"Error: [%s: %lu] Outbound block table (%u) not defined!",file,line,ipfw2p->out_table);
107 logmessage(1,msg,"ipfw2",0);
108 free(ipfw2p);
109 plugindatalist->data=NULL;
110 }
111 }
112
113 #ifdef FWSAMDEBUG
114 if(plugindatalist->data)
115 printf("Debug: [ipfw2] Adding IPFW2: i/f '%s', tables %u (in) and %u (out)\n", ipfw2p->interface, ipfw2p->in_table,ipfw2p->out_table);
116 #endif
117 }
118 else
119 { snprintf(msg,sizeof(msg)-1,"Error: [%s: %lu] IPFW2 defined without parameters!",file,line);
120 logmessage(1,msg,"ipfw2",0);
121 }
122 }
123
124
125 /* This routine initiates the block.
126 */
IPFW2Block(BLOCKINFO * bd,void * data,unsigned long qp)127 void IPFW2Block(BLOCKINFO *bd,void *data,unsigned long qp)
128 { IPFW2DATA *ipfw2p;
129 int ret;
130 char ipfw2cmd[STRBUFSIZE+2],msg[STRBUFSIZE+2];
131
132 #ifdef FWSAMDEBUG
133 pthread_t threadid=pthread_self();
134 #endif
135
136 if(!data) return;
137 ipfw2p=(IPFW2DATA *)data;
138
139 #ifdef FWSAMDEBUG
140 printf("Debug: [ipfw2][%lx] Plugin Blocking...\n",(unsigned long)threadid);
141 #endif
142
143 switch(bd->mode&FWSAM_HOW)
144 { case FWSAM_HOW_IN: ret=snprintf(ipfw2cmd,sizeof(ipfw2cmd)-1,
145 "/sbin/ipfw table %u %s %s/32",
146 ipfw2p->in_table, bd->block?"add":"delete",inettoa(bd->blockip));
147 break;
148 case FWSAM_HOW_OUT: ret=snprintf(ipfw2cmd,sizeof(ipfw2cmd)-1,
149 "/sbin/ipfw table %u %s %s/32",
150 ipfw2p->out_table, bd->block?"add":"delete",inettoa(bd->blockip));
151 break;
152 case FWSAM_HOW_INOUT:;
153 default: ret=snprintf(ipfw2cmd,sizeof(ipfw2cmd)-1,
154 "/sbin/ipfw table %u %s %s/32;/sbin/ipfw table %u %s %s/32",
155 ipfw2p->in_table, bd->block?"add":"delete",inettoa(bd->blockip),
156 ipfw2p->out_table, bd->block?"add":"delete",inettoa(bd->blockip));
157 break;
158 }
159 if(ret >= sizeof(ipfw2cmd)-1)
160 { snprintf(msg,sizeof(msg)-1,"Error: Command %s is too long", ipfw2cmd);
161 logmessage(1,msg,"ipfw2",0);
162 }
163 else
164 {
165 #ifdef FWSAMDEBUG
166 printf("Debug: [ipfw2][%lx] command \"%s\"\n", (unsigned long)threadid, ipfw2cmd);
167 #endif
168 /* Run the command */
169 if ((system(ipfw2cmd) && 0xff) )
170 { snprintf(msg,sizeof(msg)-1,"Error: Command \"%s\" Failed", ipfw2cmd);
171 logmessage(1,msg,"ipfw2",0);
172 }
173 else
174 { snprintf(msg,sizeof(msg)-1,"Info: Command \"%s\" Executed Successfully", ipfw2cmd);
175 logmessage(3,msg,"ipfw2",0);
176 }
177 }
178 }
179
180 #endif /* __SSP_IPFW2_C__ */
181 #endif /* FreeBSD */
182