00001
00002
00003
00004
00005
00006
00007 #include "pkt.h"
00008
00009
00010
00011
00012
00013
00014
00015 static Pkt_EthernetHdr_t *createPacketFromAttribValArray (array_t *
00016 attribValueArray);
00017 static util_byte_array_t *createIpPktFromAttribValueArray (array_t *
00018 attribValueArray,
00019 util_byte_array_t *
00020 l4Packet,
00021 int l4Protocol);
00022 static util_byte_array_t *createIcmpPktFromAttribValueArray (array_t *
00023 attribValueArray);
00024 static util_byte_array_t *createUdpPktFromAttribValueArray (array_t *
00025 attribValueArray);
00026 static util_byte_array_t *createTcpPktFromAttribValueArray (array_t *
00027 attribValueArray);
00028 static Pkt_L4ProtType_t getL4Prot (array_t * attribValueArray);
00029 static Pkt_L3ProtType_t getL3Prot (array_t * attribValueArray);
00030 static st_table *parseIpOptions (char *value);
00031
00032
00033
00034
00035
00036
00037
00038
00039
00040
00041
00042
00043
00044
00045
00046
00047
00048
00049
00050
00051
00052
00053
00054
00055 int
00056 Pkt_EthPacketWriteToFile (int fd,
00057 Pkt_EthernetHdr_t * anEthPkt, unsigned int length)
00058 {
00059
00060 char *lengthPtr = (char *) &length;
00061
00062 if ((sizeof (char *) != write (fd, lengthPtr, sizeof (char *))) ||
00063 (length != (unsigned int) write (fd, anEthPkt, length)))
00064 {
00065 printf ("Write failed in Pkt_EthPacketWriteToFile\n");
00066 return -1;
00067 }
00068 return 0;
00069
00070 }
00071
00072
00073
00074
00075
00076
00077
00078
00079
00080 int
00081 Pkt_EthPacketReadFromFile (int fd, Pkt_EthernetHdr_t ** anEthPktPtr)
00082 {
00083 int length;
00084 char *packet;
00085
00086 if (sizeof (int) != read (fd, &length, sizeof (int)))
00087 {
00088 return 0;
00089 }
00090
00091 if (length < (int) sizeof (Pkt_EthernetHdr_t))
00092 {
00093
00094 printf ("Corrupt file in Pkt_EthPacketReadFromFile, bailing\n");
00095 assert (0);
00096 }
00097
00098 packet = (char *) malloc (length);
00099 if (length != read (fd, packet, length))
00100 {
00101 printf ("Corrupt file in Pkt_EthPacketReadFromFile, bailing\n");
00102 assert (0);
00103 }
00104 *anEthPktPtr = (Pkt_EthernetHdr_t *) packet;
00105
00106 return length;
00107 }
00108
00109
00110
00111
00112
00113
00114
00115
00116
00117
00118
00119
00120
00121
00122
00123
00124
00125
00126
00127
00128
00129
00130
00131
00132
00133 array_t *
00134 Pkt_CreatePktsFromString (char *pktFile)
00135 {
00136 array_t *result = array_alloc (Pkt_EthernetHdr_t *, 0);
00137 array_t *rawPktsAndMacrosArray = util_process_file (pktFile);
00138 st_table *defineTable = Hash_InitTable ( ( int(*)() ) strcmp, ( int(*)() ) st_strhash);
00139 int i;
00140
00141 for (i = 0; i < array_n (rawPktsAndMacrosArray); i++)
00142 {
00143 char *anEntry = array_fetch (char *, rawPktsAndMacrosArray, i);
00144 if (util_strequalN (anEntry, "var", 3))
00145 {
00146 Rlp_UpdateDefineTable (defineTable, anEntry);
00147 }
00148 else
00149 {
00150 array_t *attribValueArray = Rlp_L7StringParse (anEntry);
00151
00152
00153
00154
00155
00156
00157
00158 Pkt_EthernetHdr_t *pkt =
00159 createPacketFromAttribValArray (attribValueArray);
00160 array_insert_last (Pkt_EthernetHdr_t *, result, pkt);
00161 }
00162 }
00163 return result;
00164 }
00165
00166
00167
00168
00169
00170
00171
00172
00173
00174 Pkt_EthernetHdr_t *
00175 Pkt_CreatePktFromString (char *pktString)
00176 {
00177 array_t *pkts = Pkt_CreatePktsFromString (pktString);
00178 if (array_n (pkts) != 1)
00179 {
00180 fprintf (stderr, "Error, called Pkt_CreatePktFromString "
00181 "on a string that resulted in %d pkts", array_n (pkts));
00182 assert (0);
00183 }
00184 Pkt_EthernetHdr_t *result = array_fetch (Pkt_EthernetHdr_t *, pkts, 0);
00185 array_free (pkts);
00186 return result;
00187 }
00188
00189
00190
00191
00192
00193
00194
00195
00196 static Pkt_EthernetHdr_t *
00197 createPacketFromAttribValArray (array_t * attribValueArray)
00198 {
00199 Pkt_L4ProtType_t l4Prot = getL4Prot (attribValueArray);
00200 util_byte_array_t *l4Packet;
00201 switch (l4Prot)
00202 {
00203 case Pkt_L4ProtTcp_c:
00204 l4Packet = createTcpPktFromAttribValueArray (attribValueArray);
00205 break;
00206 case Pkt_L4ProtUdp_c:
00207 l4Packet = createUdpPktFromAttribValueArray (attribValueArray);
00208 break;
00209 case Pkt_L4ProtIcmp_c:
00210 l4Packet = createIcmpPktFromAttribValueArray (attribValueArray);
00211 break;
00212 default:
00213 printf ("Error: no l4 protocol specified\n");
00214 assert (0);
00215 }
00216
00217 Pkt_L3ProtType_t l3Prot = getL3Prot (attribValueArray);
00218 util_byte_array_t *l3Packet;
00219 switch (l3Prot)
00220 {
00221 case Pkt_L3ProtIp_c:
00222 l3Packet =
00223 createIpPktFromAttribValueArray (attribValueArray, l4Packet, l4Prot);
00224 break;
00225 case Pkt_L3ProtArp_c:
00226
00227
00228 break;
00229 default:
00230 printf ("Error: no l3 protocol specified\n");
00231 assert (0);
00232 }
00233 Pkt_EthernetHdr_t *result =
00234 Pkt_CreateEthPkt ("000000", "111111", l3Packet, Pkt_L3ProtIp_c);
00235
00236 return result;
00237 }
00238
00239
00240
00241
00242
00243
00244 static util_byte_array_t *
00245 createIpPktFromAttribValueArray (array_t * attribValueArray,
00246 util_byte_array_t * l4Packet, int l4Protocol)
00247 {
00248 array_t *srcIps = array_alloc (u_int32_t, 0);
00249 array_t *destIps = array_alloc (u_int32_t, 0);
00250
00251 array_t *offsets = array_alloc (u_int16_t, 0);
00252 array_t *ids = array_alloc (u_int16_t, 0);
00253 array_t *ttls = array_alloc (u_int8_t, 0);
00254
00255 st_table *ipFlags = Hash_InitTable ( ( int(*)() ) strcmp, ( int(*)() ) st_strhash);
00256 st_table *ipOptions = Hash_InitTable ( ( int(*)() ) strcmp, ( int(*)() ) st_strhash);
00257
00258 int i;
00259 for (i = 0; i < array_n (attribValueArray); i++)
00260 {
00261 util_attrib_val_t *avPair =
00262 array_fetch (util_attrib_val_t *, attribValueArray, i);
00263 char *attribute = avPair->rawAttribute;
00264 char *value = avPair->rawValue;
00265 if (util_strequal (attribute, "srcip"))
00266 {
00267 u_int32_t srcip = (u_int32_t) Rlp_DotToInt (value);
00268 array_insert_last (u_int32_t, srcIps, srcip);
00269 }
00270 else if (util_strequal (attribute, "destip"))
00271 {
00272 u_int32_t destip = Rlp_DotToInt (value);
00273 array_insert_last (u_int32_t, destIps, destip);
00274 }
00275 else if (util_strequal (attribute, "ttl"))
00276 {
00277 u_int32_t ttlDummy;
00278 sscanf (value, "%u", &ttlDummy);
00279 u_int8_t ttl = (u_int8_t) ttlDummy;
00280 array_insert_last (u_int8_t, ttls, ttl);
00281 }
00282 else if (util_strequal (attribute, "offset"))
00283 {
00284 u_int16_t offset;
00285 sscanf (value, "%hu", &offset);
00286 assert (offset < (2 << 13));
00287 array_insert_last (u_int16_t, offsets, offset);
00288 }
00289 else if (util_strequal (attribute, "id"))
00290 {
00291 u_int16_t id;
00292 sscanf (value, "%hu", &id);
00293 array_insert_last (u_int16_t, ids, id);
00294 }
00295 else if (util_strequal (attribute, "ipflags"))
00296 {
00297 assert (util_strequal (value, "DF") ||
00298 util_strequal (value, "RB") ||
00299 util_strequal (value, "MF") ||
00300 util_strequal (value, "!DF") ||
00301 util_strequal (value, "!RB") ||
00302 util_strequal (value, "!MF"));
00303 if (value[0] != '!')
00304 {
00305 Hash_Insert (ipFlags, strdup (value), (char *) 1);
00306 }
00307 else
00308 {
00309 Hash_Insert (ipFlags, strdup (value + 1), 0);
00310 }
00311 }
00312 else if (util_strequal (attribute, "ipopts"))
00313 {
00314 ipOptions = parseIpOptions (value);
00315 }
00316 }
00317 util_byte_array_t *l3Packet =
00318 Pkt_CreateIpPkt (srcIps, destIps, ipFlags, offsets, ids, ipOptions, ttls,
00319 l4Packet, l4Protocol);
00320
00321 return l3Packet;
00322 }
00323
00324
00325
00326
00327 static util_byte_array_t *
00328 createIcmpPktFromAttribValueArray (array_t * attribValueArray)
00329 {
00330 array_t *typeArray = array_alloc (u_int8_t, 0);
00331 array_t *codeArray = array_alloc (u_int8_t, 0);
00332
00333 array_t *idArray = array_alloc (u_int16_t, 0);
00334 array_t *seqArray = array_alloc (u_int16_t, 0);
00335
00336 int i;
00337 for (i = 0; i < array_n (attribValueArray); i++)
00338 {
00339 util_attrib_val_t *avPair =
00340 array_fetch (util_attrib_val_t *, attribValueArray, i);
00341 char *attribute = avPair->rawAttribute;
00342 char *value = avPair->rawValue;
00343 if (util_strequal (attribute, "itype"))
00344 {
00345 u_int32_t itypeDummy;
00346 u_int8_t itype;
00347 sscanf (value, "%u", &itypeDummy);
00348 itype = (u_int8_t) itypeDummy;
00349 array_insert_last (u_int8_t, typeArray, itype);
00350 }
00351 else if (util_strequal (attribute, "icmp_id"))
00352 {
00353 int icmpid;
00354 sscanf (value, "%u", &icmpid);
00355 array_insert_last (u_int16_t, idArray, icmpid);
00356 }
00357 else if (util_strequal (attribute, "icmp_seq"))
00358 {
00359 u_int16_t icmpseq;
00360 sscanf (value, "%hu", &icmpseq);
00361 array_insert_last (u_int16_t, seqArray, icmpseq);
00362 }
00363 else if (util_strequal (attribute, "icode"))
00364 {
00365 u_int8_t icodeDummy;
00366 u_int8_t icode;
00367 sscanf (value, "%u", &icodeDummy);
00368 icode = (u_int8_t) icodeDummy;
00369 array_insert_last (u_int8_t, codeArray, icode);
00370 }
00371 }
00372 util_byte_array_t *l4Packet =
00373 Pkt_CreateIcmpPkt (typeArray, codeArray, idArray, seqArray);
00374
00375 return l4Packet;
00376 }
00377
00378
00379
00380
00381 static util_byte_array_t *
00382 createUdpPktFromAttribValueArray (array_t * attribValueArray)
00383 {
00384 array_t *srcPorts = array_alloc (u_int16_t, 0);
00385 array_t *destPorts = array_alloc (u_int16_t, 0);
00386
00387 array_t *sizes = array_alloc (u_int16_t, 0);
00388 array_t *byteStrings = array_alloc (util_byte_array_t *, 0);
00389
00390 int i;
00391 for (i = 0; i < array_n (attribValueArray); i++)
00392 {
00393 util_attrib_val_t *avPair =
00394 array_fetch (util_attrib_val_t *, attribValueArray, i);
00395 char *attribute = avPair->rawAttribute;
00396 char *value = avPair->rawValue;
00397 if (util_strequal (attribute, "srcport"))
00398 {
00399 u_int16_t srcport;
00400 sscanf (value, "%hu", &srcport);
00401 array_insert_last (u_int16_t, srcPorts, srcport);
00402 }
00403 else if (util_strequal (attribute, "destport"))
00404 {
00405 u_int16_t destport;
00406 sscanf (value, "%hu", &destport);
00407 array_insert_last (u_int16_t, destPorts, destport);
00408 }
00409 else if (util_strequal (attribute, "size"))
00410 {
00411 u_int16_t size;
00412 sscanf (value, "%hu", &size);
00413 array_insert_last (u_int16_t, sizes, size);
00414 }
00415 else if (util_strequal (attribute, "content"))
00416 {
00417 array_insert_last (util_byte_array_t *, byteStrings,
00418 util_byte_array_create (strdup (value),
00419 strlen (value)));
00420 }
00421 }
00422 util_byte_array_t *l4Packet =
00423 Pkt_CreateUdpPkt (srcPorts, destPorts, sizes, byteStrings);
00424
00425 return l4Packet;
00426 }
00427
00428
00429
00430
00431 static util_byte_array_t *
00432 createTcpPktFromAttribValueArray (array_t * attribValueArray)
00433 {
00434 array_t *srcPorts = array_alloc (u_int16_t, 0);
00435 array_t *destPorts = array_alloc (u_int16_t, 0);
00436
00437 array_t *seqNums = array_alloc (u_int32_t, 0);
00438 array_t *ackNums = array_alloc (u_int32_t, 0);
00439
00440 st_table *tcpFlags = Hash_InitTable ( ( int(*)() ) strcmp, ( int(*)() ) st_strhash);
00441
00442 array_t *sizes = array_alloc (u_int16_t, 0);
00443 array_t *byteStrings = array_alloc (util_byte_array_t *, 0);
00444
00445 int i;
00446 for (i = 0; i < array_n (attribValueArray); i++)
00447 {
00448 util_attrib_val_t *avPair =
00449 array_fetch (util_attrib_val_t *, attribValueArray, i);
00450 char *attribute = avPair->rawAttribute;
00451 char *value = avPair->rawValue;
00452 if (util_strequal (attribute, "srcport"))
00453 {
00454 u_int16_t srcport;
00455 sscanf (value, "%hu", &srcport);
00456 array_insert_last (u_int16_t, srcPorts, srcport);
00457 }
00458 else if (util_strequal (attribute, "destport"))
00459 {
00460 u_int16_t destport;
00461 sscanf (value, "%hu", &destport);
00462 array_insert_last (u_int16_t, destPorts, destport);
00463 }
00464 else if (util_strequal (attribute, "seq"))
00465 {
00466 u_int32_t seqnum;
00467 sscanf (value, "%u", &seqnum);
00468 array_insert_last (u_int32_t, seqNums, seqnum);
00469 }
00470 else if (util_strequal (attribute, "ack"))
00471 {
00472 u_int32_t acknum;
00473 sscanf (value, "%u", &acknum);
00474 array_insert_last (u_int32_t, ackNums, acknum);
00475 }
00476 else if (util_strequal (attribute, "size"))
00477 {
00478 u_int16_t size;
00479 sscanf (value, "%hu", &size);
00480 array_insert_last (u_int16_t, sizes, size);
00481 }
00482 else if (util_strequal (attribute, "tcpflags"))
00483 {
00484 assert (util_strequal (value, "F") ||
00485 util_strequal (value, "S") ||
00486 util_strequal (value, "R") ||
00487 util_strequal (value, "P") ||
00488 util_strequal (value, "A") ||
00489 util_strequal (value, "U") ||
00490 util_strequal (value, "E") ||
00491 util_strequal (value, "C") ||
00492 util_strequal (value, "!F") ||
00493 util_strequal (value, "!S") ||
00494 util_strequal (value, "!R") ||
00495 util_strequal (value, "!P") ||
00496 util_strequal (value, "!A") ||
00497 util_strequal (value, "!U") ||
00498 util_strequal (value, "!E") || util_strequal (value, "!C"));
00499 if (value[0] == '!')
00500 {
00501 Hash_Insert (tcpFlags, strdup (value + 1), 0);
00502 }
00503 else
00504 {
00505 Hash_Insert (tcpFlags, strdup (value), (char *) 1);
00506 }
00507 }
00508 else if (util_strequal (attribute, "content"))
00509 {
00510 array_insert_last (util_byte_array_t *, byteStrings,
00511 util_byte_array_create (strdup (value),
00512 strlen (value)));
00513 }
00514 }
00515 util_byte_array_t *l4Packet =
00516 Pkt_CreateTcpPkt (srcPorts, destPorts, seqNums, ackNums, tcpFlags, sizes,
00517 byteStrings);
00518
00519 return l4Packet;
00520 }
00521
00522
00523
00524
00525 static Pkt_L4ProtType_t
00526 getL4Prot (array_t * attribValueArray)
00527 {
00528 int i;
00529 for (i = 0; i < array_n (attribValueArray); i++)
00530 {
00531 util_attrib_val_t *avPair =
00532 array_fetch (util_attrib_val_t *, attribValueArray, i);
00533 char *attribute = avPair->rawAttribute;
00534 if (util_strequal (attribute, "protocol"))
00535 {
00536 char *value = avPair->rawValue;
00537 if (util_strequal (value, "tcp"))
00538 {
00539 return Pkt_L4ProtTcp_c;
00540 }
00541 else if (util_strequal (value, "icmp"))
00542 {
00543 return Pkt_L4ProtIcmp_c;
00544 }
00545 else if (util_strequal (value, "udp"))
00546 {
00547 return Pkt_L4ProtUdp_c;
00548 }
00549 }
00550 }
00551 return Pkt_L4ProtUndef_c;
00552 }
00553
00554
00555
00556
00557 static Pkt_L3ProtType_t
00558 getL3Prot (array_t * attribValueArray)
00559 {
00560 int i;
00561 for (i = 0; i < array_n (attribValueArray); i++)
00562 {
00563 util_attrib_val_t *avPair =
00564 array_fetch (util_attrib_val_t *, attribValueArray, i);
00565 char *attribute = avPair->rawAttribute;
00566 if (util_strequal (attribute, "protocol"))
00567 {
00568 char *value = avPair->rawValue;
00569 if (util_strequal (value, "tcp") ||
00570 util_strequal (value, "udp") ||
00571 util_strequal (value, "icmp") || util_strequal (value, "ip"))
00572 {
00573 return Pkt_L3ProtIp_c;
00574 }
00575 else if (util_strequal (value, "arp"))
00576 {
00577 return Pkt_L3ProtArp_c;
00578 }
00579 }
00580 }
00581 return Pkt_L3ProtUndef_c;
00582 }
00583
00584
00585
00586
00587
00588
00589
00590
00591 static st_table *
00592 parseIpOptions (char *value)
00593 {
00594 st_table *result = Hash_InitTable ( ( int(*)() ) strcmp, ( int(*)() ) st_strhash);
00595
00596 char *comma;
00597 char *string = strdup (value);
00598 char *origstring = string;
00599 while (NIL (char) != (comma = strchr (string, ',')))
00600 {
00601 *comma = '\0';
00602 char *entry = strdup (string);
00603 Hash_Insert (result, entry, NIL (char));
00604 string = comma + 1;
00605 }
00606 char *lastentry = strdup (string);
00607 Hash_Insert (result, lastentry, NIL (char));
00608 free (origstring);
00609
00610 return result;
00611 }