00001
00002
00003
00004
00005
00006
00007
00008 #include "rlp.h"
00009
00010
00011
00012
00013 static int L4CheckStructPopulateComponentStrings (Rlp_L4Check_t * result,
00014 char *rawFormula);
00015 static char *computeComponentN (char *aString, int N);
00016 static Rlp_OperatorEnum_t computeTypeFromString (char *aString);
00017 static Rlp_Formula_t *createIpFormulaFromList (char *aString);
00018 static Rlp_Formula_t *processLeafIpFormula (char *leafString);
00019 static char *clearBrackets (char *text);
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032 Rlp_L4Check_t *
00033 Rlp_AllocL4CheckStruct ()
00034 {
00035 Rlp_L4Check_t *result = (Rlp_L4Check_t *) malloc (sizeof (Rlp_L4Check_t));
00036 result->type = Rlp_Undef_c;
00037
00038 result->srcIp = NIL (Rlp_Formula_t);
00039 result->srcPort = NIL (Rlp_Formula_t);
00040 result->destIp = NIL (Rlp_Formula_t);
00041 result->destPort = NIL (Rlp_Formula_t);
00042
00043 return result;
00044 }
00045
00046
00047
00048
00049
00050
00051 Rlp_L4Check_t *
00052 Rlp_CreateL4CheckFromRawFormula (char *rawFormula)
00053 {
00054 Rlp_L4Check_t *result = Rlp_AllocL4CheckStruct ();
00055 L4CheckStructPopulateComponentStrings (result, rawFormula);
00056
00057 result->type = computeTypeFromString (result->typeString);
00058
00059 result->srcIpString = clearBrackets (result->srcIpString);
00060 result->srcIp = Rlp_ComputeIpFormulaFromString (result->srcIpString);
00061 result->srcPort = Rlp_ComputePortFormulaFromString (result->srcPortString);
00062
00063 result->destIpString = clearBrackets (result->destIpString);
00064 result->destIp = Rlp_ComputeIpFormulaFromString (result->destIpString);
00065 result->destPort =
00066 Rlp_ComputePortFormulaFromString (result->destPortString);
00067
00068 return result;
00069 }
00070
00071
00072
00073
00074
00075
00076 static int
00077 L4CheckStructPopulateComponentStrings (Rlp_L4Check_t * result,
00078 char *rawFormula)
00079 {
00080 char tmpBuf[1000];
00081 char *tmpPtr;
00082
00083
00084
00085 while (isspace (*rawFormula))
00086 rawFormula++;
00087 tmpPtr = tmpBuf;
00088 while (*rawFormula != '\0')
00089 {
00090 if (!isspace (*rawFormula))
00091 {
00092 *tmpPtr = *rawFormula;
00093 tmpPtr++;
00094 rawFormula++;
00095 }
00096 else
00097 {
00098 *tmpPtr = ' ';
00099 tmpPtr++;
00100 while (isspace (*rawFormula))
00101 rawFormula++;
00102 }
00103 }
00104
00105
00106 result->typeString = computeComponentN (tmpBuf, 0);
00107 result->srcIpString = computeComponentN (tmpBuf, 1);
00108 result->srcPortString = computeComponentN (tmpBuf, 2);
00109 result->destIpString = computeComponentN (tmpBuf, 4);
00110 result->destPortString = computeComponentN (tmpBuf, 5);
00111
00112 return 0;
00113
00114 }
00115
00116
00117
00118
00119
00120
00121
00122
00123
00124
00125
00126 static char *
00127 computeComponentN (char *aString, int N)
00128 {
00129 char *result;
00130
00131 char *tmp1Ptr;
00132 char *tmp2Ptr = util_strchr_N (aString, ' ', N + 1);
00133 *tmp2Ptr = '\0';
00134
00135 if (N > 0)
00136 {
00137 tmp1Ptr = util_strchr_N (aString, ' ', N);
00138 }
00139 else
00140 {
00141 tmp1Ptr = aString;
00142 }
00143
00144 while (isspace (*tmp1Ptr))
00145 tmp1Ptr++;
00146 result = strdup (tmp1Ptr);
00147 *tmp2Ptr = ' ';
00148
00149 return result;
00150 }
00151
00152
00153
00154
00155 static Rlp_OperatorEnum_t
00156 computeTypeFromString (char *aString)
00157 {
00158 assert (util_strequal (aString, "icmp") ||
00159 util_strequal (aString, "ip") ||
00160 util_strequal (aString, "tcp") ||
00161 util_strequal (aString, "udp") ||
00162 util_strequal (aString, "generic") ||
00163 util_strequal (aString, "any"));
00164
00165 if (util_strequal (aString, "icmp"))
00166 {
00167 return Rlp_Icmp_c;
00168 }
00169 if (util_strequal (aString, "ip"))
00170 {
00171 return Rlp_Ip_c;
00172 }
00173 if (util_strequal (aString, "tcp"))
00174 {
00175 return Rlp_Tcp_c;
00176 }
00177 if (util_strequal (aString, "udp"))
00178 {
00179 return Rlp_Udp_c;
00180 }
00181 if (util_strequal (aString, "any"))
00182 {
00183 return Rlp_Any_c;
00184 }
00185 if (util_strequal (aString, "generic"))
00186 {
00187 return Rlp_Generic_c;
00188 }
00189
00190 return Rlp_Undef_c;
00191 }
00192
00193
00194
00195
00196
00197
00198
00199
00200
00201
00202
00203
00204
00205
00206
00207
00208
00209
00210
00211
00212
00213
00214
00215 Rlp_Formula_t *
00216 Rlp_ComputeIpFormulaFromString (char *ipString)
00217 {
00218
00219 char *tmpString = ipString;
00220 char *checkString;
00221 int length;
00222
00223 if (util_strequal (ipString, "any"))
00224 {
00225 return new_node (Rlp_Any_c, NIL (Rlp_Formula_t), NIL (Rlp_Formula_t));
00226 }
00227
00228 Rlp_Formula_t *result;
00229 Rlp_Formula_t *nextFormula;
00230 Rlp_Formula_t *subFormula;
00231
00232 char tmpBuf[1000];
00233 int leftParensCount;
00234
00235 tmpString = ipString;
00236 if (*tmpString == '!')
00237 {
00238 if (*(tmpString + 1) == '(')
00239 {
00240 leftParensCount = 1;
00241 checkString = tmpString + 2;
00242 leftParensCount = 1;
00243 while (1)
00244 {
00245 if (*checkString == ')')
00246 {
00247 leftParensCount--;
00248 }
00249 if (*checkString == '(')
00250 {
00251 leftParensCount++;
00252 }
00253 if (leftParensCount == 0)
00254 {
00255 break;
00256 }
00257 checkString++;
00258 }
00259 length = checkString - (tmpString + 2);
00260 strncpy (tmpBuf, tmpString + 2, length);
00261 tmpBuf[length] = '\0';
00262 }
00263 else
00264 {
00265 checkString = strchr (tmpString, ',');
00266 if (checkString == NIL (char))
00267 {
00268 checkString = strchr (tmpString, '\0');
00269 }
00270 length = checkString - tmpString;
00271 strncpy (tmpBuf, tmpString + 1, length);
00272 }
00273 subFormula = Rlp_ComputeIpFormulaFromString (tmpBuf);
00274 result = new_node (Rlp_Negation_c, subFormula, NIL (Rlp_Formula_t));
00275 if (*checkString == '\0')
00276 {
00277 return result;
00278 }
00279 else
00280 {
00281 nextFormula = Rlp_ComputeIpFormulaFromString (checkString);
00282 Rlp_Formula_t *list =
00283 new_node (Rlp_List_c, result, NIL (Rlp_Formula_t));
00284 list->rchild =
00285 new_node (Rlp_List_c, nextFormula, NIL (Rlp_Formula_t));
00286 return list;
00287 }
00288 }
00289 else
00290 {
00291
00292 if (!strchr (tmpString, ','))
00293 {
00294
00295 return processLeafIpFormula (tmpString);
00296 }
00297 else
00298 {
00299
00300
00301 return createIpFormulaFromList (tmpString);
00302
00303
00304
00305
00306
00307
00308
00309
00310
00311
00312
00313 }
00314 }
00315 }
00316
00317
00318
00319
00320
00321
00322
00323 static Rlp_Formula_t *
00324 createIpFormulaFromList (char *aString)
00325 {
00326 char *iterString = aString;
00327 Rlp_Formula_t *result =
00328 new_node (Rlp_List_c, NIL (Rlp_Formula_t), NIL (Rlp_Formula_t));
00329 Rlp_Formula_t *lastNode = result;
00330 char tmpBuf[1000];
00331 while (1)
00332 {
00333
00334 char *commaString = strchr (iterString, ',');
00335 if (commaString == NIL (char))
00336 {
00337 lastNode->lchild = Rlp_ComputeIpFormulaFromString (iterString);
00338 return result;
00339 }
00340 int length = commaString - iterString;
00341 strncpy (tmpBuf, iterString, length);
00342 tmpBuf[length] = '\0';
00343
00344 lastNode->lchild = Rlp_ComputeIpFormulaFromString (tmpBuf);
00345 lastNode->rchild =
00346 new_node (Rlp_List_c, NIL (Rlp_Formula_t), NIL (Rlp_Formula_t));
00347 lastNode = lastNode->rchild;
00348 iterString = commaString + 1;
00349 }
00350 }
00351
00352
00353
00354
00355
00356
00357
00358
00359 static Rlp_Formula_t *
00360 processLeafIpFormula (char *leafString)
00361 {
00362 char tmpBuf[1000];
00363 int length;
00364 u_int32_t ip;
00365 u_int32_t mask;
00366 int maskAmount;
00367
00368 if (strchr (leafString, '.') && strchr (leafString, '/'))
00369 {
00370
00371 char *endOfIp = strchr (leafString, '/');
00372 length = endOfIp - leafString;
00373 strncpy (tmpBuf, leafString, length);
00374 tmpBuf[length] = '\0';
00375 ip = Rlp_DotToInt (tmpBuf);
00376 char *beginningOfMask = endOfIp + 1;
00377 if (!strchr (beginningOfMask, '.'))
00378 {
00379
00380 sscanf (beginningOfMask, "%u", &maskAmount);
00381 assert (maskAmount < 33);
00382
00383
00384 mask = (~0x0) << (32 - maskAmount);
00385 }
00386 else
00387 {
00388 mask = Rlp_DotToInt (beginningOfMask);
00389 }
00390 return new_node (Rlp_IpEntry_c, (Rlp_Formula_t *) ip,
00391 (Rlp_Formula_t *) mask);
00392 }
00393 if (strchr (leafString, '.'))
00394 {
00395
00396 ip = Rlp_DotToInt (leafString);
00397 mask = (~0x0);
00398 return new_node (Rlp_IpEntry_c, (Rlp_Formula_t *) ip,
00399 (Rlp_Formula_t *) mask);
00400 }
00401
00402 return new_node (Rlp_Define_c, (Rlp_Formula_t *) strdup (leafString),
00403 NIL (Rlp_Formula_t));
00404
00405 }
00406
00407
00408
00409
00410
00411
00412
00413 u_int32_t
00414 Rlp_DotToInt (char *dotString)
00415 {
00416
00417 int i;
00418 unsigned int ipAddress = 0;
00419
00420 char *dupDotString = strdup (dotString);
00421 char *tmpString = dupDotString;
00422 char *freeString = dupDotString;
00423
00424 for (i = 0; i < 4; i++)
00425 {
00426 while ((*tmpString != '.') && (*tmpString != '\0'))
00427 {
00428 tmpString++;
00429 }
00430 *tmpString = '\0';
00431 unsigned int tmpInt = atoi (dupDotString);
00432 dupDotString = &(tmpString[1]);
00433 tmpString = dupDotString;
00434 ipAddress = ipAddress * 256 + tmpInt;
00435 }
00436 free (freeString);
00437 return ipAddress;
00438 }
00439
00440
00441
00442
00443
00444
00445
00446
00447
00448
00449
00450
00451
00452
00453
00454
00455
00456
00457 Rlp_Formula_t *
00458 Rlp_ComputePortFormulaFromString (char *portString)
00459 {
00460 Rlp_Formula_t *result;
00461 int highPort;
00462 int lowPort;
00463
00464 if (util_strequal ("any", portString))
00465 {
00466 return new_node (Rlp_Any_c, NIL (Rlp_Formula_t), NIL (Rlp_Formula_t));
00467 }
00468
00469 char *tmpString = portString;
00470 while (*tmpString != '\0')
00471 {
00472 if (isspace (*tmpString))
00473 {
00474 assert (0);
00475 }
00476 tmpString++;
00477 }
00478
00479 bool negFlag = false;
00480 tmpString = portString;
00481 if (*tmpString == '!')
00482 {
00483 negFlag = true;
00484 tmpString++;
00485 while (isspace (*tmpString))
00486 {
00487 tmpString++;
00488 }
00489 }
00490
00491 bool isSinglePort = true;
00492 int i;
00493 for (i = 0; i < (int) strlen (tmpString); i++)
00494 {
00495 if (!isdigit (tmpString[i]))
00496 {
00497
00498 isSinglePort = false;
00499 break;
00500 }
00501 }
00502
00503 if (isSinglePort == true)
00504 {
00505 sscanf (tmpString, "%d", &lowPort);
00506 highPort = lowPort;
00507 Rlp_Formula_t *singlePort =
00508 new_node (Rlp_PortRange_c, (Rlp_Formula_t *) lowPort,
00509 (Rlp_Formula_t *) highPort);
00510 if (negFlag)
00511 {
00512 result = new_node (Rlp_Negation_c, singlePort, NIL (Rlp_Formula_t));
00513 }
00514 else
00515 {
00516 result = singlePort;
00517 }
00518 return result;
00519 }
00520
00521 int length = strlen (tmpString);
00522 if (strchr (tmpString, ':'))
00523 {
00524
00525 if (tmpString[0] == ':')
00526 {
00527
00528 lowPort = 0;
00529 sscanf (tmpString + 1, "%d", &highPort);
00530 }
00531 else if (tmpString[length - 1] == ':')
00532 {
00533
00534 highPort = 65535;
00535 sscanf (tmpString, "%d", &lowPort);
00536 }
00537 else
00538 {
00539
00540 sscanf (tmpString, "%d", &lowPort);
00541 tmpString = strchr (tmpString, ':');
00542 tmpString++;
00543 sscanf (tmpString, "%d", &highPort);
00544 }
00545 Rlp_Formula_t *rangeFormula =
00546 new_node (Rlp_PortRange_c, (Rlp_Formula_t *) lowPort,
00547 (Rlp_Formula_t *) highPort);
00548 if (negFlag)
00549 {
00550 result =
00551 new_node (Rlp_Negation_c, rangeFormula, NIL (Rlp_Formula_t));
00552 }
00553 else
00554 {
00555 result = rangeFormula;
00556 }
00557 }
00558 else
00559 {
00560
00561 result =
00562 new_node (Rlp_Define_c, (Rlp_Formula_t *) strdup (tmpString),
00563 NIL (Rlp_Formula_t));
00564 if (negFlag)
00565 {
00566 result = new_node (Rlp_Negation_c, result, NIL (Rlp_Formula_t));
00567 }
00568 }
00569 return result;
00570 }
00571
00572
00573
00574
00575
00576
00577 static char *
00578 clearBrackets (char *text)
00579 {
00580 char *firstBracket = strchr (text, '[');
00581 if (firstBracket == NIL (char))
00582 {
00583 assert (strchr (text, ']') == NIL (char));
00584 return text;
00585 }
00586
00587 char *lastBracket = strchr (text, ']');
00588 assert (lastBracket != NIL (char));
00589
00590
00591
00592 int bytesNeeded = lastBracket - firstBracket;
00593 char *result = (char *) malloc ((sizeof (char) * bytesNeeded));
00594 strncpy (result, (firstBracket + 1), (bytesNeeded - 1));
00595 result[bytesNeeded - 1] = '\0';
00596
00597 free (text);
00598
00599 return result;
00600 }