00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026 #ifdef HAVE_CONFIG_H
00027 #include "config.h"
00028 #endif
00029
00030 #include <errno.h>
00031 #include <stdio.h>
00032 #include <string.h>
00033 #include <stdlib.h>
00034 #ifndef WIN32
00035 #include <netdb.h>
00036 #include <ctype.h>
00037 #include <sys/types.h>
00038 #include <sys/socket.h>
00039 #include <netinet/in.h>
00040 #include <arpa/inet.h>
00041 #endif
00042
00043 #ifdef HAVE_STRINGS_H
00044 #include <strings.h>
00045 #endif
00046
00047 #include "util.h"
00048 #include "mstring.h"
00049 #include "parser.h"
00050 #include "debug.h"
00051
00052 #include "IpAddrSet.h"
00053
00054 IpAddrSet *IpAddrSetCreate()
00055 {
00056 IpAddrSet *tmp;
00057
00058 tmp = (IpAddrSet *) SnortAlloc(sizeof(IpAddrSet));
00059
00060 return tmp;
00061 }
00062
00063
00064 void IpAddrSetDestroy(IpAddrSet *ipAddrSet)
00065 {
00066 IpAddrSet *next;
00067
00068 while(ipAddrSet)
00069 {
00070 next = ipAddrSet->next;
00071 free(ipAddrSet);
00072 ipAddrSet = next;
00073 }
00074 }
00075
00076 static char buffer[1024];
00077
00078 void IpAddrSetPrint(char *prefix, IpAddrSet *ipAddrSet)
00079 {
00080 struct in_addr in;
00081 size_t offset = 0;
00082 while(ipAddrSet)
00083 {
00084 offset = 0;
00085 if(ipAddrSet->addr_flags & EXCEPT_IP)
00086 offset += snprintf(buffer, 1024 - offset, "NOT ");
00087 in.s_addr = ipAddrSet->ip_addr;
00088 offset += snprintf(buffer + offset, 1024 - offset, "%s/",
00089 inet_ntoa(in));
00090 in.s_addr = ipAddrSet->netmask;
00091 offset += snprintf(buffer + offset, 1024 - offset, "%s", inet_ntoa(in));
00092 buffer[offset] = '\0';
00093 if (prefix)
00094 LogMessage("%s%s\n", prefix, buffer);
00095 else
00096 LogMessage("%s%s\n", buffer);
00097 ipAddrSet = ipAddrSet->next;
00098 }
00099 }
00100
00101 IpAddrSet *IpAddrSetCopy(IpAddrSet *ipAddrSet)
00102 {
00103 IpAddrSet *newIpAddrSet = NULL;
00104 IpAddrSet *current = NULL;
00105 IpAddrSet *prev = NULL;
00106
00107 while(ipAddrSet)
00108 {
00109 if(!(current = (IpAddrSet *)malloc(sizeof(IpAddrSet))))
00110 {
00111
00112 goto failed;
00113 }
00114
00115 current->ip_addr = ipAddrSet->ip_addr;
00116 current->netmask = ipAddrSet->netmask;
00117 current->addr_flags = ipAddrSet->addr_flags;
00118 current->next = NULL;
00119
00120 if(!prev)
00121 newIpAddrSet = current;
00122 else
00123 prev->next = current;
00124
00125 ipAddrSet = ipAddrSet->next;
00126 prev = current;
00127 }
00128
00129 return newIpAddrSet;
00130
00131 failed:
00132 if(newIpAddrSet)
00133 IpAddrSetDestroy(newIpAddrSet);
00134 return NULL;
00135 }
00136
00137
00138
00139
00140
00141
00142
00143
00144
00145
00146
00147
00148
00149
00150
00151
00152 int ParseIP(char *paddr, IpAddrSet *address_data)
00153 {
00154 char **toks;
00155 int num_toks;
00156 int cidr = 1;
00157 int nmask = -1;
00158 char *addr;
00159
00160 struct hostent *host_info;
00161 struct sockaddr_in sin;
00162 char broadcast_addr_set = 0;
00163
00164 addr = paddr;
00165
00166 if(*addr == '!')
00167 {
00168 address_data->addr_flags |= EXCEPT_IP;
00169
00170 addr++;
00171 }
00172
00173
00174 if(!strcasecmp(addr, "any"))
00175 {
00176 address_data->ip_addr = 0;
00177 address_data->netmask = 0;
00178 return 1;
00179 }
00180
00181 toks = mSplit(addr, "/", 2, &num_toks, 0);
00182
00183
00184 if(num_toks == 1)
00185 {
00186 mSplitFree(&toks, num_toks);
00187 toks = mSplit(addr, ":", 2, &num_toks, 0);
00188 }
00189
00190
00191
00192
00193
00194 if((num_toks > 1) && strlen(toks[1]) > 2)
00195 {
00196 cidr = 0;
00197 }
00198
00199 switch(num_toks)
00200 {
00201 case 1:
00202 address_data->netmask = netmasks[32];
00203 break;
00204
00205 case 2:
00206 if(cidr)
00207 {
00208
00209 nmask = atoi(toks[1]);
00210
00211
00212
00213
00214 if(!isdigit((int) toks[1][0]))
00215 nmask = -1;
00216
00217
00218
00219
00220 if((toks[1][1] != '\0')&&(!isdigit((int) toks[1][1]) ))
00221 nmask = -1;
00222
00223 if((nmask > -1) && (nmask < 33))
00224 {
00225 address_data->netmask = netmasks[nmask];
00226 }
00227 else
00228 {
00229 FatalError("ERROR %s(%d): Invalid CIDR block for IP addr "
00230 "%s\n", file_name, file_line, addr);
00231
00232 }
00233 }
00234 else
00235 {
00236
00237
00238
00239
00240
00241
00242
00243
00244
00245
00246
00247
00248 if(!strncmp(toks[1], "255.255.255.255", 15))
00249 {
00250 address_data->netmask = INADDR_BROADCAST;
00251 }
00252 else if((address_data->netmask = inet_addr(toks[1])) == -1)
00253 {
00254 FatalError("ERROR %s(%d): Unable to parse rule netmask "
00255 "(%s)\n", file_name, file_line, toks[1]);
00256 }
00257
00258
00259 nmask = 0;
00260 }
00261 break;
00262
00263 default:
00264 FatalError("ERROR %s(%d) => Unrecognized IP address/netmask %s\n",
00265 file_name, file_line, addr);
00266 break;
00267 }
00268 sin.sin_addr.s_addr = inet_addr(toks[0]);
00269
00270 #ifndef WORDS_BIGENDIAN
00271
00272
00273
00274
00275 if(cidr)
00276 {
00277 address_data->netmask = htonl(address_data->netmask);
00278 }
00279 #endif
00280
00281
00282 if(!strncmp(toks[0], "255.255.255.255", 15))
00283 {
00284 address_data->ip_addr = INADDR_BROADCAST;
00285 broadcast_addr_set = 1;
00286 }
00287 else if (nmask == -1)
00288 {
00289
00290
00291
00292 if(sin.sin_addr.s_addr == INADDR_NONE)
00293 {
00294
00295 if((host_info = gethostbyname(toks[0])))
00296 {
00297
00298 if(host_info->h_length <= sizeof(sin.sin_addr))
00299 {
00300 bcopy(host_info->h_addr, (char *) &sin.sin_addr, host_info->h_length);
00301 }
00302 else
00303 {
00304 bcopy(host_info->h_addr, (char *) &sin.sin_addr, sizeof(sin.sin_addr));
00305 }
00306 }
00307
00308 else if(h_errno == HOST_NOT_FOUND)
00309
00310 {
00311 FatalError("ERROR %s(%d): Couldn't resolve hostname %s\n",
00312 file_name, file_line, toks[0]);
00313 }
00314 }
00315 else
00316 {
00317
00318
00319 }
00320 }
00321 else
00322 {
00323 if(sin.sin_addr.s_addr == INADDR_NONE)
00324 {
00325
00326 FatalError("ERROR %s(%d): Rule IP addr (%s) didn't translate\n",
00327 file_name, file_line, toks[0]);
00328 }
00329 }
00330
00331
00332 if (!broadcast_addr_set)
00333 {
00334 address_data->ip_addr = ((u_long) (sin.sin_addr.s_addr) &
00335 (address_data->netmask));
00336 }
00337 mSplitFree(&toks, num_toks);
00338 return 0;
00339 }
00340
00341
00342 IpAddrSet *IpAddrSetParse(char *addr)
00343 {
00344 IpAddrSet *ias = NULL;
00345 IpAddrSet *tmp_ias = NULL;
00346 char **toks;
00347 int num_toks;
00348 int i;
00349 char *tmp;
00350 char *enbracket;
00351 char *index;
00352 int flags = 0;
00353
00354 index = addr;
00355
00356 while(isspace((int)*index)) index++;
00357
00358 if(*index == '!')
00359 {
00360 flags = EXCEPT_IP;
00361 }
00362
00363 if(*index == '$')
00364 {
00365 if((tmp = VarGet(index+1)) == NULL)
00366 {
00367 FatalError("%s(%d) => Undefined variable %s\n", file_name, file_line,
00368 index);
00369 }
00370 }
00371 else
00372 {
00373 tmp = index;
00374 }
00375
00376 if(*tmp == '[')
00377 {
00378 DEBUG_WRAP(DebugMessage(DEBUG_CONFIGRULES,"Found IP list!\n"););
00379
00380 enbracket = strrchr(tmp, (int)']');
00381
00382 if(enbracket)
00383 *enbracket = '\x0';
00384 else
00385 FatalError("%s(%d) => Unterminated IP List\n", file_name, file_line);
00386
00387 toks = mSplit(tmp+1, ",", 128, &num_toks, 0);
00388
00389 DEBUG_WRAP(DebugMessage(DEBUG_CONFIGRULES,"mSplit got %d tokens...\n",
00390 num_toks););
00391
00392 for(i=0; i< num_toks; i++)
00393 {
00394 DEBUG_WRAP(DebugMessage(DEBUG_CONFIGRULES,"adding %s to IP "
00395 "address list\n", toks[i]););
00396 tmp = toks[i];
00397
00398 while (isspace((int)*tmp)||*tmp=='[') tmp++;
00399
00400 enbracket = strrchr(tmp, (int)']');
00401
00402 if(enbracket)
00403 *enbracket = '\x0';
00404
00405 if (!strlen(tmp))
00406 continue;
00407
00408 if(!ias)
00409 {
00410 ias = (IpAddrSet *) SnortAlloc(sizeof(IpAddrSet));
00411 tmp_ias = ias;
00412 }
00413 else
00414 {
00415 tmp_ias->next = (IpAddrSet *) SnortAlloc(sizeof(IpAddrSet));
00416 tmp_ias = tmp_ias->next;
00417 }
00418
00419 ParseIP(tmp, tmp_ias);
00420 }
00421
00422 mSplitFree(&toks, num_toks);
00423 }
00424 else
00425 {
00426 DEBUG_WRAP(DebugMessage(DEBUG_CONFIGRULES,
00427 "regular IP address, processing...\n"););
00428
00429 ias = (IpAddrSet *) SnortAlloc(sizeof(IpAddrSet));
00430
00431 ParseIP(tmp, ias);
00432 }
00433
00434 return ias;
00435 }
00436
00437
00438 int IpAddrSetContains(IpAddrSet *ias, struct in_addr test_addr)
00439 {
00440 IpAddrSet *index;
00441 u_int32_t raw_addr;
00442 int exception_flag = 0;
00443
00444
00445 raw_addr = test_addr.s_addr;
00446
00447 for(index = ias; index != NULL; index = index->next)
00448 {
00449 if(index->addr_flags & EXCEPT_IP) exception_flag = 1;
00450
00451 if(((index->ip_addr == (raw_addr & index->netmask)) ^ exception_flag))
00452 {
00453 return 1;
00454 }
00455 }
00456
00457 return 0;
00458 }