Azinix

pkt.c

Go to the documentation of this file.
00001 /** \file pkt.c
00002 
00003   \brief Packet code
00004 */
00005 
00006 #include "pkt.h"
00007 
00008 /**AutomaticStart*************************************************************/
00009 
00010 /*---------------------------------------------------------------------------*/
00011 /* Static function prototypes                                                */
00012 /*---------------------------------------------------------------------------*/
00013 
00014 
00015 /**AutomaticEnd***************************************************************/
00016 
00017 
00018 /**
00019   * \brief  Extract the Ip component from an Ethernet packet
00020   * 
00021   * No new memory is allocated, simply returning a pointer. Note that we're 
00022   * being careless with the difference between an actual packet,
00023   * and just the header.
00024   */
00025 
00026 Pkt_IpHdr_t *
00027 Pkt_EthernetExtractIp (Pkt_EthernetHdr_t * ethPkt)
00028 {
00029   assert (ethPkt->type == Pkt_L3ProtIp_c);
00030   return (Pkt_IpHdr_t *) (((char *) ethPkt) + sizeof (Pkt_EthernetHdr_t));
00031 }
00032 
00033 
00034 /**
00035   * \brief  Return the length of the Ethernet packet, including header.
00036   *
00037   * Only IP suppored for now. Packet is assumed to be in network order.
00038   */
00039 
00040 int
00041 Pkt_EthernetPktHdrReadLengthNetworkOrder (Pkt_EthernetHdr_t * pkt)
00042 {
00043   if (pkt->type != Pkt_L3ProtIp_c)
00044     {
00045       fprintf (stderr, "Trying to get the length of a frame that's not IP\n");
00046       assert (0);
00047     }
00048 
00049   Pkt_IpHdr_t *ipPkt = Pkt_EthernetExtractIp (pkt);
00050   u_int16_t length = ipPkt->length;
00051   u_int16_t trueLength = ntohs (length);
00052   return sizeof (Pkt_EthernetHdr_t) + trueLength;
00053 }
00054 
00055 
00056 /** \brief  Return the length of the Ethernet packet, including header.
00057 
00058 Only IP suppored for now 
00059 */
00060 
00061 int
00062 Pkt_EthernetPktHdrReadLength (Pkt_EthernetHdr_t * pkt)
00063 {
00064   if (pkt->type != Pkt_L3ProtIp_c)
00065     {
00066       fprintf (stderr, "Trying to get the length of a frame that's not IP\n");
00067       assert (0);
00068     }
00069 
00070   Pkt_IpHdr_t *ipPkt = Pkt_EthernetExtractIp (pkt);
00071   return sizeof (Pkt_EthernetHdr_t) + ipPkt->length;
00072 }
00073 
00074 
00075 /**
00076   * \brief  Free an Ethernet packet
00077   * 
00078   * Assumes packet was allocated by malloc
00079   */
00080 
00081 int
00082 Pkt_EthernetHdrFree (Pkt_EthernetHdr_t * pkt)
00083 {
00084   free (pkt);
00085   return 0;
00086 }
00087 
00088 
00089 /**
00090   * \brief  Free an ProcessPkt structure. 
00091   * 
00092   *     Does not free the packet, but does free applicable rules.
00093   */
00094 
00095 int
00096 Pkt_ProcessPktFree (Pkt_ProcessPkt_t * pp)
00097 {
00098   array_free (pp->applicableRules);
00099   free (pp);
00100   return 0;
00101 }
00102 
00103 
00104 /**
00105   * \brief  Extract the Icmp component from an Ip packet
00106   * 
00107   * No new memory is allocated, simply returning a pointer. Note that we're 
00108   * being careless with the difference between an actual packet,
00109   * and just the header. If the encapsulated packet is not ip
00110   * encapsualting icmp we return NIL.
00111   */
00112 
00113 Pkt_IcmpHdr_t *
00114 Pkt_IpExtractIcmp (Pkt_IpHdr_t * anIpPkt)
00115 {
00116   if (anIpPkt->protocol != Pkt_L4ProtIcmp_c)
00117     {
00118       return NIL (Pkt_IcmpHdr_t);
00119     }
00120   else
00121     {
00122       return (Pkt_IcmpHdr_t *) Pkt_IpExtractPayload (anIpPkt);
00123     }
00124 }
00125 
00126 
00127 /**
00128   * \brief  Extract the Udp component from an Ip packet
00129   * 
00130   * No new memory is allocated, simply returning a pointer.
00131   */
00132 
00133 Pkt_UdpHdr_t *
00134 Pkt_IpExtractUdp (Pkt_IpHdr_t * anIpPkt)
00135 {
00136   if (anIpPkt->protocol != Pkt_L4ProtUdp_c)
00137     {
00138       return NIL (Pkt_UdpHdr_t);
00139     }
00140   else
00141     {
00142       return (Pkt_UdpHdr_t *) Pkt_IpExtractPayload (anIpPkt);
00143     }
00144 }
00145 
00146 
00147 /**
00148   * \brief  Extract the Tcp component from an Ip packet
00149   * 
00150   * No new memory is allocated, simply returning a pointer.
00151   */
00152 
00153 Pkt_TcpHdr_t *
00154 Pkt_IpExtractTcp (Pkt_IpHdr_t * anIpPkt)
00155 {
00156   assert (anIpPkt->protocol == Pkt_L4ProtTcp_c);
00157 
00158   return (Pkt_TcpHdr_t *) Pkt_IpExtractPayload (anIpPkt);
00159 }
00160 
00161 
00162 /**
00163   * \brief  Extract the payload component from an Ip packet
00164   * 
00165   * No new memory is allocated, simply returning a pointer.
00166   */
00167 
00168 char *
00169 Pkt_IpExtractPayload (Pkt_IpHdr_t * anIpPkt)
00170 {
00171   // the header length is in multiples of 4 bytes
00172   int headerLength = anIpPkt->ihl * 4;
00173 
00174   return (char *) (((char *) anIpPkt) + headerLength);
00175 }
00176 
00177 
00178 /**
00179   * \brief  Extract the Tcp component from an Ethernet packet
00180   * 
00181   * No new memory is allocated, simply returning a pointer.
00182   */
00183 
00184 Pkt_UdpHdr_t *
00185 Pkt_EthernetExtractUdp (Pkt_EthernetHdr_t * aEthernetPkt)
00186 {
00187   assert (aEthernetPkt->type == Pkt_L4ProtUdp_c);
00188   Pkt_IpHdr_t *anIpPkt = Pkt_EthernetExtractIp (aEthernetPkt);
00189   return Pkt_IpExtractUdp (anIpPkt);
00190 }
00191 
00192 
00193 /**
00194   * \brief  Extract the Tcp component from an Ethernet packet
00195   * 
00196   * No new memory is allocated, simply returning a pointer.
00197   */
00198 
00199 Pkt_TcpHdr_t *
00200 Pkt_EthernetExtractTcp (Pkt_EthernetHdr_t * aEthernetPkt)
00201 {
00202   assert (aEthernetPkt->type == Pkt_L3ProtIp_c);
00203   Pkt_IpHdr_t *anIpPkt = Pkt_EthernetExtractIp (aEthernetPkt);
00204   return Pkt_IpExtractTcp (anIpPkt);
00205 }
00206 
00207 
00208 /**
00209   * \brief  Extract the Icmp component from an Ethernet packet
00210   * 
00211   * No new memory is allocated, simply returning a pointer.
00212   */
00213 
00214 Pkt_IcmpHdr_t *
00215 Pkt_EthernetExtractIcmp (Pkt_EthernetHdr_t * aEthernetPkt)
00216 {
00217   assert (aEthernetPkt->type == Pkt_L3ProtIp_c);
00218   Pkt_IpHdr_t *anIpPkt = Pkt_EthernetExtractIp (aEthernetPkt);
00219   return Pkt_IpExtractIcmp (anIpPkt);
00220 }
00221 
00222 
00223 /**
00224   * \brief  Returns a pointer to the payload of a UDP packet.
00225   */
00226 
00227 
00228 char *
00229 Pkt_UdpHdrReadPayload (Pkt_UdpHdr_t * aUdpPkt)
00230 {
00231   char *result = ((char *) aUdpPkt) + sizeof (Pkt_UdpHdr_t);
00232   return result;
00233 }
00234 
00235 
00236 /**
00237   * \brief  Returns a pointer to the payload of a TCP packet.
00238   */
00239 
00240 char *
00241 Pkt_TcpHdrReadPayload (Pkt_TcpHdr_t * aTcpPkt)
00242 {
00243   char *result = ((char *) aTcpPkt) + (aTcpPkt->doff * 4);
00244   return result;
00245 }
00246 
00247 
00248 /**
00249   * \brief  Compare two src ip flows
00250   * Returns -1, 0, 1 a la strcmp
00251   *
00252   *     \sa st_init_table
00253   */
00254 
00255 int
00256 Pkt_SrcIpFlowCmp (Pkt_EthernetHdr_t * pkt1, Pkt_EthernetHdr_t * pkt2)
00257 {
00258   Pkt_IpHdr_t *ipPkt1 = Pkt_EthernetExtractIp (pkt1);
00259   Pkt_IpHdr_t *ipPkt2 = Pkt_EthernetExtractIp (pkt2);
00260 
00261   if (ipPkt1->sourceIp < ipPkt2->sourceIp)
00262     {
00263       return -1;
00264     }
00265   else if (ipPkt1->sourceIp > ipPkt2->sourceIp)
00266     {
00267       return 1;
00268     }
00269 
00270   return 0;
00271 }
00272 
00273 
00274 /**
00275   * \brief  Compare two dest ip flows
00276   * Returns -1, 0 , 1
00277   */
00278 
00279 int
00280 Pkt_DestIpFlowCmp (Pkt_EthernetHdr_t * pkt1, Pkt_EthernetHdr_t * pkt2)
00281 {
00282   Pkt_IpHdr_t *ipPkt1 = Pkt_EthernetExtractIp (pkt1);
00283   Pkt_IpHdr_t *ipPkt2 = Pkt_EthernetExtractIp (pkt2);
00284 
00285   if (ipPkt1->destIp < ipPkt2->destIp)
00286     {
00287       return -1;
00288     }
00289   else if (ipPkt1->destIp > ipPkt2->destIp)
00290     {
00291       return 1;
00292     }
00293   return 0;
00294 }
00295 
00296 
00297 /**
00298   * \brief  Compare two src-dest ip flows
00299   * Returns -1,0,1 a la strcmp
00300   */
00301 
00302 int
00303 Pkt_SrcDestIpFlowCmp (Pkt_EthernetHdr_t * pkt1, Pkt_EthernetHdr_t * pkt2)
00304 {
00305 
00306   Pkt_IpHdr_t *ipPkt1 = Pkt_EthernetExtractIp (pkt1);
00307   Pkt_IpHdr_t *ipPkt2 = Pkt_EthernetExtractIp (pkt2);
00308 
00309   if (ipPkt1->sourceIp < ipPkt2->sourceIp)
00310     {
00311       return -1;
00312     }
00313   else if (ipPkt1->sourceIp > ipPkt2->sourceIp)
00314     {
00315       return 1;
00316     }
00317   else if (ipPkt1->destIp < ipPkt2->destIp)
00318     {
00319       return -1;
00320     }
00321   else if (ipPkt1->destIp > ipPkt2->destIp)
00322     {
00323       return 1;
00324     }
00325   return 0;
00326 }
00327 
00328 
00329 /**
00330   * \brief  Compare two dest tcp-Ip flows.
00331   * Returns -1, 0, 1 a la strcmp
00332   */
00333 
00334 int
00335 Pkt_DestTcpIpFlowCmp (Pkt_EthernetHdr_t * pkt1, Pkt_EthernetHdr_t * pkt2)
00336 {
00337 
00338   Pkt_IpHdr_t *ipPkt1 = Pkt_EthernetExtractIp (pkt1);
00339   Pkt_IpHdr_t *ipPkt2 = Pkt_EthernetExtractIp (pkt2);
00340 
00341   Pkt_TcpHdr_t *tcpPkt1 = Pkt_IpExtractTcp (ipPkt1);
00342   Pkt_TcpHdr_t *tcpPkt2 = Pkt_IpExtractTcp (ipPkt2);
00343 
00344   if (ipPkt1->destIp < ipPkt2->destIp)
00345     {
00346       return -1;
00347     }
00348   else if (ipPkt1->destIp > ipPkt2->destIp)
00349     {
00350       return 1;
00351     }
00352   else if (tcpPkt1->destPort < tcpPkt2->destPort)
00353     {
00354       return -1;
00355     }
00356   else if (tcpPkt1->destPort > tcpPkt2->destPort)
00357     {
00358       return 1;
00359     }
00360   return 0;
00361 }
00362 
00363 
00364 /**
00365   * \brief  Hash a src-ip flow
00366   *
00367   * \arg modulus - the number of buckets in the hashtable
00368   * 
00369   */
00370 
00371 int
00372 Pkt_SrcIpFlowHash (Pkt_EthernetHdr_t * pkt1, int modulus)
00373 {
00374   Pkt_IpHdr_t *ipPkt1 = Pkt_EthernetExtractIp (pkt1);
00375 
00376   u_int32_t sourceIp = ipPkt1->sourceIp;
00377 
00378   u_int32_t hashcode = 8191 * sourceIp;
00379 
00380   return (hashcode % modulus);
00381 
00382 }
00383 
00384 
00385 /**
00386   * \brief  Hash a dest-ip
00387   * 
00388   * \arg modulus - the number of buckets in the hashtable
00389   */
00390 
00391 int
00392 Pkt_DestIpFlowHash (Pkt_EthernetHdr_t * pkt1, int modulus)
00393 {
00394   Pkt_IpHdr_t *ipPkt1 = Pkt_EthernetExtractIp (pkt1);
00395 
00396   u_int32_t destIp = ipPkt1->destIp;
00397 
00398   u_int32_t hashcode = 65521 * destIp;
00399 
00400   return (hashcode % modulus);
00401 }
00402 
00403 
00404 /**
00405   * \brief  Hash a src-dest ip flow
00406   * 
00407   * \arg modulus - the number of buckets in the hashtable
00408   */
00409 
00410 int
00411 Pkt_SrcDestIpFlowHash (Pkt_EthernetHdr_t * pkt1, int modulus)
00412 {
00413   Pkt_IpHdr_t *ipPkt1 = Pkt_EthernetExtractIp (pkt1);
00414 
00415   u_int32_t sourceIp = ipPkt1->sourceIp;
00416   u_int32_t destIp = ipPkt1->destIp;
00417 
00418   u_int32_t hashcode = 8191 * sourceIp + 65521 * destIp;
00419 
00420   return (hashcode % modulus);
00421 }
00422 
00423 
00424 /**
00425   * \brief  Hash a dest tcp-Ip flow
00426   * 
00427   * \arg modulus - the number of buckets in the hashtable
00428   */
00429 
00430 int
00431 Pkt_DestTcpIpFlowHash (Pkt_EthernetHdr_t * pkt1, int modulus)
00432 {
00433   Pkt_IpHdr_t *ipPkt1 = Pkt_EthernetExtractIp (pkt1);
00434   Pkt_TcpHdr_t *tcpPkt1 = Pkt_IpExtractTcp (ipPkt1);
00435 
00436   u_int32_t destIp = ipPkt1->destIp;
00437 
00438   u_int16_t destPort = tcpPkt1->destPort;
00439 
00440   u_int32_t hashcode = 65521 * destIp + 4093 * destPort;
00441 
00442   return (hashcode % modulus);
00443 }
00444 
00445 
00446 /**
00447   * \brief  Hash a tcp-Ip flow
00448   * 
00449   * \arg modulus - the number of buckets in the hashtable
00450   */
00451 
00452 int
00453 Pkt_SrcDestTcpIpFlowHash (Pkt_EthernetHdr_t * pkt1, int modulus)
00454 {
00455   Pkt_IpHdr_t *ipPkt1 = Pkt_EthernetExtractIp (pkt1);
00456   Pkt_TcpHdr_t *tcpPkt1 = Pkt_IpExtractTcp (ipPkt1);
00457 
00458   u_int32_t sourceIp = ipPkt1->sourceIp;
00459   u_int32_t destIp = ipPkt1->destIp;
00460 
00461   u_int16_t srcPort = tcpPkt1->srcPort;
00462   u_int16_t destPort = tcpPkt1->destPort;
00463 
00464   u_int32_t hashcode =
00465     8191 * sourceIp + 65521 * (destIp + 1021 * (srcPort + 4093 * destPort));
00466 
00467   return (hashcode % modulus);
00468 }
00469 
00470 
00471 /**
00472   * \brief  Compare two Tcp-Ip flows.
00473   * Returns -1, 0, 1 a la strcmp
00474   * 
00475   */
00476 
00477 int
00478 Pkt_SrcDestTcpIpFlowCmp (Pkt_EthernetHdr_t * pkt1, Pkt_EthernetHdr_t * pkt2)
00479 {
00480 
00481   Pkt_IpHdr_t *ipPkt1 = Pkt_EthernetExtractIp (pkt1);
00482   Pkt_IpHdr_t *ipPkt2 = Pkt_EthernetExtractIp (pkt2);
00483 
00484   Pkt_TcpHdr_t *tcpPkt1 = Pkt_IpExtractTcp (ipPkt1);
00485   Pkt_TcpHdr_t *tcpPkt2 = Pkt_IpExtractTcp (ipPkt2);
00486 
00487   if (ipPkt1->sourceIp < ipPkt2->sourceIp)
00488     {
00489       return -1;
00490     }
00491   else if (ipPkt1->sourceIp > ipPkt2->sourceIp)
00492     {
00493       return 1;
00494     }
00495   else if (ipPkt1->destIp < ipPkt2->destIp)
00496     {
00497       return -1;
00498     }
00499   else if (ipPkt1->destIp > ipPkt2->destIp)
00500     {
00501       return 1;
00502     }
00503   else if (tcpPkt1->srcPort < tcpPkt2->srcPort)
00504     {
00505       return -1;
00506     }
00507   else if (tcpPkt1->srcPort > tcpPkt2->srcPort)
00508     {
00509       return 1;
00510     }
00511   else if (tcpPkt1->destPort < tcpPkt2->destPort)
00512     {
00513       return -1;
00514     }
00515   else if (tcpPkt1->destPort > tcpPkt2->destPort)
00516     {
00517       return 1;
00518     }
00519   return 0;
00520 }
00521 
00522 
00523 /**
00524   * \brief  Compare function for an L4 flow struct for the st package,
00525   * returns 0 for equal, 1 for unequal
00526   */
00527 
00528 int
00529 Pkt_L4FlowCompareForSt (Pkt_L4Flow_t * foo, Pkt_L4Flow_t * bar)
00530 {
00531   int result = (foo->srcIp == bar->srcIp) &&
00532     (foo->destIp == bar->destIp) &&
00533     (foo->srcPort == bar->srcPort) &&
00534     (foo->destPort == bar->destPort) ? 0 : 1;
00535 
00536   return result;
00537 }
00538 
00539 
00540 /**
00541   * \brief  Compare function for an L4 flow struct - 1 for equal, 0 for unequal
00542   */
00543 
00544 int
00545 Pkt_L4FlowCompare (Pkt_L4Flow_t * foo, Pkt_L4Flow_t * bar)
00546 {
00547   int result = (foo->srcIp == bar->srcIp) &&
00548     (foo->destIp == bar->destIp) &&
00549     (foo->srcPort == bar->srcPort) &&
00550     (foo->destPort == bar->destPort) ? 1 : 0;
00551 
00552   return result;
00553 }
00554 
00555 
00556 /**
00557   * \brief  Hash function for an L4 flow struct with modulus argument
00558   */
00559 
00560 int
00561 Pkt_L4FlowHashForSt (Pkt_L4Flow_t * anL4FlowStruct, int modulus)
00562 {
00563   int hashValue;
00564   unsigned int result;
00565 
00566   hashValue = Pkt_L4FlowHash (anL4FlowStruct);
00567 
00568   result = hashValue % modulus;
00569 
00570   return (int) result;
00571 }
00572 
00573 
00574 /**
00575   * \brief  Hash function for an L4 flow struct
00576   * \sa st_strhash
00577   */
00578 
00579 unsigned int
00580 Pkt_L4FlowHash (Pkt_L4Flow_t * anL4FlowStruct)
00581 {
00582   unsigned int result;
00583 
00584   result =
00585     997 + 997 * (anL4FlowStruct->srcIp +
00586          997 * (anL4FlowStruct->destIp * +997 *
00587             (anL4FlowStruct->srcPort +
00588              997 * anL4FlowStruct->destPort)));
00589 
00590   return result;
00591 }
00592 
00593 
00594 /**
00595   * \brief  Create a L4 flow structure from an Ethernet packet.
00596   */
00597 
00598 Pkt_L4Flow_t *
00599 Pkt_EthPktToL4Flow (Pkt_EthernetHdr_t * anEthPkt)
00600 {
00601   Pkt_IpHdr_t *anIpPkt = Pkt_EthernetExtractIp (anEthPkt);
00602   Pkt_L4Flow_t *result = Pkt_IpPktToL4Flow (anIpPkt);
00603 
00604   return result;
00605 }
00606 
00607 
00608 /**
00609   * \brief  Create a L4 flow structure from an Ip packet.
00610   */
00611 
00612 Pkt_L4Flow_t *
00613 Pkt_IpPktToL4Flow (Pkt_IpHdr_t * anIpPkt)
00614 {
00615 
00616   Pkt_TcpHdr_t *aTcpPkt = Pkt_IpExtractTcp (anIpPkt);
00617 
00618   Pkt_L4Flow_t *result = (Pkt_L4Flow_t *) malloc (sizeof (Pkt_L4Flow_t));
00619 
00620   result->srcIp = anIpPkt->sourceIp;
00621   result->destIp = anIpPkt->destIp;
00622 
00623   result->srcPort = aTcpPkt->srcPort;
00624   result->destPort = aTcpPkt->destPort;
00625 
00626   return result;
00627 }
00628 
00629 
00630 /**
00631   * \brief  Return the L3 type of an ethernet packet
00632   *
00633   *     Promotes a short to an int in the process.
00634   */
00635 
00636 int
00637 Pkt_EthernetReadL3Type (Pkt_EthernetHdr_t * anEth)
00638 {
00639   return anEth->type;
00640 }
00641 
00642 
00643 /**
00644   * \brief  Print an Ethernet packet
00645   *
00646   *  Packet is assumed to be in network format.
00647   */
00648 
00649 int
00650 Pkt_PrintEthernet (Pkt_EthernetHdr_t * anEthPkt, int length)
00651 {
00652   char *packet = (char *) anEthPkt;
00653 
00654   printf ("dest mac = %x%x%x%x%x%x ; src mac = %x%x%x%x%x%x \n",
00655       anEthPkt->dhost[0],
00656       anEthPkt->dhost[1],
00657       anEthPkt->dhost[2],
00658       anEthPkt->dhost[3],
00659       anEthPkt->dhost[4],
00660       anEthPkt->dhost[5],
00661       anEthPkt->shost[0],
00662       anEthPkt->shost[1],
00663       anEthPkt->shost[2],
00664       anEthPkt->shost[3], anEthPkt->shost[4], anEthPkt->shost[5]);
00665   printf ("type = Ox%x (decimal = %d)\n", ntohs (anEthPkt->type),
00666       ntohs (anEthPkt->type));
00667 
00668   if (ntohs (anEthPkt->type) == Pkt_L3ProtIp_c)
00669     {
00670       printf ("Encapsulated Ethernet packet is IP, printing IP\n");
00671       Pkt_IpHdr_t *anIpPkt = Pkt_EthernetExtractIp (anEthPkt);
00672       Pkt_PrintIp (anIpPkt);
00673     }
00674 
00675   printf ("Raw bytes in eth payload:\n");
00676   int i;
00677   for (i = sizeof (Pkt_EthernetHdr_t) + 1; i < length; i++)
00678     {
00679       printf ("%c",
00680           (isalnum (packet[i]) || isgraph (packet[i])
00681            || isspace (packet[i])) ? packet[i] : ',');
00682     }
00683   printf ("\nend raw bytes\n\n");
00684 
00685   return 0;
00686 }
00687 
00688 
00689 /**
00690   * \brief  Print a Wifi packet
00691   */
00692 
00693 int
00694 Pkt_PrintWifi (Pkt_WifiHdr_t * aWifiPkt)
00695 {
00696   printf ("frame control = %x\n", aWifiPkt->frame_control);
00697   printf ("duration_id = %d\n", aWifiPkt->duration_id);
00698   printf ("seq_control = %d\n", aWifiPkt->seq_control);
00699 
00700   printf ("addr1 = %x:%x:%x:%x:%x:%x\n",
00701       aWifiPkt->addr1[0], aWifiPkt->addr1[1], aWifiPkt->addr1[2],
00702       aWifiPkt->addr1[3], aWifiPkt->addr1[4], aWifiPkt->addr1[5]);
00703   printf ("addr2 = %x:%x:%x:%x:%x:%x\n",
00704       aWifiPkt->addr2[0], aWifiPkt->addr2[1], aWifiPkt->addr2[2],
00705       aWifiPkt->addr2[3], aWifiPkt->addr2[4], aWifiPkt->addr2[5]);
00706   printf ("addr3 = %x:%x:%x:%x:%x:%x\n",
00707       aWifiPkt->addr2[0], aWifiPkt->addr2[1], aWifiPkt->addr2[2],
00708       aWifiPkt->addr2[3], aWifiPkt->addr2[4], aWifiPkt->addr2[5]);
00709   printf ("addr4 = %x:%x:%x:%x:%x:%x\n",
00710       aWifiPkt->addr3[0], aWifiPkt->addr3[1], aWifiPkt->addr3[2],
00711       aWifiPkt->addr3[3], aWifiPkt->addr3[4], aWifiPkt->addr3[5]);
00712 
00713   printf ("Treating encapsulated packet as IP, printing IP\n");
00714   Pkt_IpHdr_t *anIpPkt =
00715     (Pkt_IpHdr_t *) ((char *) aWifiPkt) + sizeof (Pkt_WifiHdr_t);
00716   Pkt_PrintIp (anIpPkt);
00717 
00718   return 0;
00719 }
00720 
00721 
00722 /**
00723   * \brief  Print an Ip Pkt, given in network order
00724   */
00725 
00726 int
00727 Pkt_PrintIp (Pkt_IpHdr_t * anIpPkt)
00728 {
00729   printf ("Version = %x\t", anIpPkt->version);
00730   printf ("Header length = %x\t", anIpPkt->ihl);
00731   printf ("TOS = %d\n", anIpPkt->TOS);
00732   printf ("Length = %d\t", ntohs (anIpPkt->length));
00733   printf ("Ident = %x\t", ntohs (anIpPkt->id));
00734   printf ("Flags MF= %x DF= %x RB= %x\n",
00735       anIpPkt->MF, anIpPkt->DF, anIpPkt->RB);
00736   printf ("Offset= %x\t", anIpPkt->offset);
00737   printf ("TTL = %d\t", anIpPkt->TTL);
00738   printf ("protocol = %d\t", anIpPkt->protocol);
00739   printf ("checksum = %d\n", ntohs (anIpPkt->checksum));
00740   printf ("srcIp = %x ", ntohl (anIpPkt->sourceIp));
00741   Pkt_PrintIpAddressDotted (ntohl (anIpPkt->sourceIp));
00742   printf ("destIp = %x ", ntohl (anIpPkt->destIp));
00743   Pkt_PrintIpAddressDotted (ntohl (anIpPkt->destIp));
00744 
00745   return 0;
00746 }
00747 
00748 
00749 /**
00750   * \brief  Print an Ip address in 1.2.3.4 format
00751   */
00752 
00753 void
00754 Pkt_PrintIpAddressDotted( u_int32_t aNumIp)
00755 {
00756   Pkt_PrintIpAddressDottedGeneral ( NIL(char), aNumIp); 
00757 }
00758 
00759 /**
00760   * \brief  Print an Ip address in 1.2.3.4 format
00761   */
00762 
00763 void
00764 Pkt_PrintIpAddressDottedGeneral ( char * buf, u_int32_t aNumIp)
00765 {
00766   u_int32_t mask = 0377;    // start with 0 means octal
00767 
00768   int a1, a2, a3, a4;
00769 
00770   a1 = aNumIp & mask;
00771   a2 = (aNumIp >> 8) & mask;
00772   a3 = (aNumIp >> 16) & mask;
00773   a4 = (aNumIp >> 24) & mask;
00774 
00775   if ( buf == NIL( char ) ) {
00776     printf ("%u.%u.%u.%u\n", a4, a3, a2, a1);
00777   }
00778   else {
00779     sprintf ( buf, "%u.%u.%u.%u", a4, a3, a2, a1);
00780   }
00781 }
00782 
00783 
00784 /**
00785   * \brief  Allocate a process-packet structure
00786   * 
00787   */
00788 
00789 Pkt_ProcessPkt_t *
00790 Pkt_AllocateProcessPacket (Pkt_EthernetHdr_t * pkt, array_t * applicableRules)
00791 {
00792   Pkt_ProcessPkt_t *result =
00793     (Pkt_ProcessPkt_t *) malloc (sizeof (Pkt_ProcessPkt_t));
00794 
00795   result->pkt = pkt;
00796   result->applicableRules = applicableRules;
00797   result->currentRule = 0;
00798   return result;
00799 }