Main Page | Modules | Class List | Directories | File List | Class Members | File Members | Related Pages

decode.c

Go to the documentation of this file.
00001 /* $Id$ */
00002 
00003 /*
00004 ** Copyright (C) 1998-2002 Martin Roesch <roesch@sourcefire.com>
00005 **
00006 ** This program is free software; you can redistribute it and/or modify
00007 ** it under the terms of the GNU General Public License as published by
00008 ** the Free Software Foundation; either version 2 of the License, or
00009 ** (at your option) any later version.
00010 **
00011 ** This program is distributed in the hope that it will be useful,
00012 ** but WITHOUT ANY WARRANTY; without even the implied warranty of
00013 ** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00014 ** GNU General Public License for more details.
00015 **
00016 ** You should have received a copy of the GNU General Public License
00017 ** along with this program; if not, write to the Free Software
00018 ** Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
00019 */
00020 
00021 #ifdef HAVE_CONFIG_H
00022 #include "config.h"
00023 #endif
00024 
00025 #ifdef HAVE_STRINGS_H
00026 #include <strings.h>
00027 #endif
00028 
00029 #include <string.h>
00030 #include <stdlib.h>
00031 
00032 #include "decode.h"
00033 #include "snort.h"
00034 #include "debug.h"
00035 #include "util.h"
00036 #include "detect.h"
00037 #include "checksum.h"
00038 #include "log.h"
00039 #include "generators.h"
00040 #include "event_queue.h"
00041 #include "inline.h"
00042 
00043 /* No great place to put this right now */
00044 HttpUri UriBufs[URI_COUNT];
00045 u_int8_t DecodeBuffer[DECODE_BLEN];
00046 
00047 
00048 /*
00049  * Function: DecodeEthPkt(Packet *, char *, struct pcap_pkthdr*, u_int8_t*)
00050  *
00051  * Purpose: Decode those fun loving ethernet packets, one at a time!
00052  *
00053  * Arguments: p => pointer to the decoded packet struct
00054  *            user => Utility pointer (unused)
00055  *            pkthdr => ptr to the packet header
00056  *            pkt => pointer to the real live packet data
00057  *
00058  * Returns: void function
00059  */
00060 void DecodeEthPkt(Packet * p, struct pcap_pkthdr * pkthdr, u_int8_t * pkt)
00061 {
00062     u_int32_t pkt_len;      /* suprisingly, the length of the packet */
00063     u_int32_t cap_len;      /* caplen value */
00064 
00065     bzero((char *) p, sizeof(Packet));
00066 
00067     p->pkth = pkthdr;
00068     p->pkt = pkt;
00069 
00070     /* set the lengths we need */
00071     pkt_len = pkthdr->len;  /* total packet length */
00072     cap_len = pkthdr->caplen;   /* captured packet length */
00073 
00074     if(snaplen < pkt_len)
00075         pkt_len = cap_len;
00076 
00077     DEBUG_WRAP(DebugMessage(DEBUG_DECODE, "Packet!\n");
00078             DebugMessage(DEBUG_DECODE, "caplen: %lu    pktlen: %lu\n", 
00079                 (unsigned long)cap_len, (unsigned long)pkt_len);
00080             );
00081 
00082     /* do a little validation */
00083     if(cap_len < ETHERNET_HEADER_LEN)
00084     {
00085         if(pv.verbose_flag)
00086         {
00087             ErrorMessage("Captured data length < Ethernet header length!"
00088                          " (%d bytes)\n", p->pkth->caplen);
00089         }
00090         return;
00091     }
00092 
00093     /* lay the ethernet structure over the packet data */
00094     p->eh = (EtherHdr *) pkt;
00095 
00096     DEBUG_WRAP(
00097             DebugMessage(DEBUG_DECODE, "%X   %X\n", 
00098                 *p->eh->ether_src, *p->eh->ether_dst);
00099             );
00100 
00101     /* grab out the network type */
00102     switch(ntohs(p->eh->ether_type))
00103     {
00104         case ETHERNET_TYPE_PPPoE_DISC:
00105         case ETHERNET_TYPE_PPPoE_SESS:
00106             DecodePPPoEPkt(p, pkthdr, pkt);
00107             return;
00108 
00109         case ETHERNET_TYPE_IP:
00110             DEBUG_WRAP(
00111                     DebugMessage(DEBUG_DECODE, 
00112                         "IP datagram size calculated to be %lu bytes\n",
00113                         (unsigned long)(cap_len - ETHERNET_HEADER_LEN));
00114                     );
00115 
00116             DecodeIP(p->pkt + ETHERNET_HEADER_LEN, 
00117                     cap_len - ETHERNET_HEADER_LEN, p);
00118 
00119             return;
00120 
00121         case ETHERNET_TYPE_ARP:
00122         case ETHERNET_TYPE_REVARP:
00123             DecodeARP(p->pkt + ETHERNET_HEADER_LEN, 
00124                     cap_len - ETHERNET_HEADER_LEN, p);
00125             return;
00126 
00127         case ETHERNET_TYPE_IPV6:
00128             DecodeIPV6(p->pkt + ETHERNET_HEADER_LEN, 
00129                     (cap_len - ETHERNET_HEADER_LEN));
00130             return;
00131 
00132         case ETHERNET_TYPE_IPX:
00133             DecodeIPX(p->pkt + ETHERNET_HEADER_LEN, 
00134                     (cap_len - ETHERNET_HEADER_LEN));
00135             return;
00136 
00137         case ETHERNET_TYPE_LOOP:
00138             DecodeEthLoopback(p->pkt + ETHERNET_HEADER_LEN, 
00139                     (cap_len - ETHERNET_HEADER_LEN));
00140             return; 
00141 
00142         case ETHERNET_TYPE_8021Q:
00143             DecodeVlan(p->pkt + ETHERNET_HEADER_LEN, 
00144                     cap_len - ETHERNET_HEADER_LEN, p);
00145             return; 
00146 
00147         default:
00148             pc.other++;
00149             return;
00150     }
00151 
00152     return;
00153 }
00154 
00155 
00156 /*
00157  * Function: DecodeIEEE80211Pkt(Packet *, char *, struct pcap_pkthdr*, 
00158  *                               u_int8_t*)
00159  *
00160  * Purpose: Decode those fun loving wireless LAN packets, one at a time!
00161  *
00162  * Arguments: p => pointer to the decoded packet struct
00163  *            user => Utility pointer (unused)
00164  *            pkthdr => ptr to the packet header
00165  *            pkt => pointer to the real live packet data
00166  *
00167  * Returns: void function
00168  */
00169 void DecodeIEEE80211Pkt(Packet * p, struct pcap_pkthdr * pkthdr, 
00170                         u_int8_t * pkt)
00171 {
00172     u_int32_t pkt_len;      /* suprisingly, the length of the packet */
00173     u_int32_t cap_len;      /* caplen value */
00174 
00175     bzero((char *) p, sizeof(Packet));
00176 
00177     p->pkth = pkthdr;
00178     p->pkt = pkt;
00179 
00180     /* set the lengths we need */
00181     pkt_len = pkthdr->len;  /* total packet length */
00182     cap_len = pkthdr->caplen;   /* captured packet length */
00183 
00184     if(snaplen < pkt_len)
00185         pkt_len = cap_len;
00186 
00187     DEBUG_WRAP(DebugMessage(DEBUG_DECODE, "Packet!\n"););
00188     DEBUG_WRAP(DebugMessage(DEBUG_DECODE, "caplen: %lu    pktlen: %lu\n", 
00189                 (unsigned long)cap_len, (unsigned long)pkt_len););
00190 
00191     /* do a little validation */
00192     if(p->pkth->caplen < MINIMAL_IEEE80211_HEADER_LEN)
00193     {
00194         if(pv.verbose_flag)
00195         {
00196             ErrorMessage("Captured data length < IEEE 802.11 header length! (%d bytes)\n", p->pkth->caplen);
00197         }
00198         return;
00199     }
00200     /* lay the wireless structure over the packet data */
00201     p->wifih = (WifiHdr *) pkt;
00202 
00203     DEBUG_WRAP(DebugMessage(DEBUG_DECODE, "%X   %X\n", *p->wifih->addr1, 
00204                 *p->wifih->addr2););
00205 
00206     /* determine frame type */
00207     switch(p->wifih->frame_control & 0x00ff)
00208     {
00209         /* management frames */
00210         case WLAN_TYPE_MGMT_ASREQ:
00211         case WLAN_TYPE_MGMT_ASRES:
00212         case WLAN_TYPE_MGMT_REREQ:
00213         case WLAN_TYPE_MGMT_RERES:
00214         case WLAN_TYPE_MGMT_PRREQ:
00215         case WLAN_TYPE_MGMT_PRRES:
00216         case WLAN_TYPE_MGMT_BEACON:
00217         case WLAN_TYPE_MGMT_ATIM:
00218         case WLAN_TYPE_MGMT_DIS:
00219         case WLAN_TYPE_MGMT_AUTH:
00220         case WLAN_TYPE_MGMT_DEAUTH:
00221             pc.wifi_mgmt++;
00222             break;
00223 
00224             /* Control frames */
00225         case WLAN_TYPE_CONT_PS:
00226         case WLAN_TYPE_CONT_RTS:
00227         case WLAN_TYPE_CONT_CTS:
00228         case WLAN_TYPE_CONT_ACK:
00229         case WLAN_TYPE_CONT_CFE:
00230         case WLAN_TYPE_CONT_CFACK:
00231             pc.wifi_control++;
00232             break;
00233             /* Data packets without data */
00234         case WLAN_TYPE_DATA_NULL:
00235         case WLAN_TYPE_DATA_CFACK:
00236         case WLAN_TYPE_DATA_CFPL:
00237         case WLAN_TYPE_DATA_ACKPL:
00238 
00239             pc.wifi_data++;
00240             break;
00241         case WLAN_TYPE_DATA_DTCFACK:
00242         case WLAN_TYPE_DATA_DTCFPL:
00243         case WLAN_TYPE_DATA_DTACKPL:
00244         case WLAN_TYPE_DATA_DATA:
00245             pc.wifi_data++;
00246 
00247             if(cap_len < IEEE802_11_DATA_HDR_LEN + sizeof(EthLlc))
00248             {
00249                 if(pv.verbose_flag)
00250                 {
00251                     ErrorMessage("Not enough data for EthLlc header\n");
00252                 }
00253                 
00254                 if((runMode == MODE_IDS) && pv.decoder_flags.decode_alerts)
00255                 {
00256                     SnortEventqAdd(GENERATOR_SNORT_DECODE, 
00257                             DECODE_BAD_80211_ETHLLC, 1, DECODE_CLASS, 3, 
00258                             DECODE_BAD_80211_ETHLLC_STR, 0);
00259 
00260                     if ((InlineMode()) && pv.decoder_flags.drop_alerts)
00261                     {
00262                        DEBUG_WRAP(DebugMessage(DEBUG_DECODE, "Dropping bad packet\n"););
00263                        InlineDrop();
00264                     }
00265                 }
00266                 
00267                 return;
00268             }
00269 
00270             p->ehllc = (EthLlc *) (pkt + IEEE802_11_DATA_HDR_LEN);
00271 
00272 #ifdef DEBUG
00273             PrintNetData(stdout,(u_int8_t *)  p->ehllc, sizeof(EthLlc));
00274             ClearDumpBuf();
00275 
00276             printf("LLC Header:\n");
00277             printf("   DSAP: 0x%X\n", p->ehllc->dsap);
00278             printf("   SSAP: 0x%X\n", p->ehllc->ssap);
00279 #endif
00280 
00281             if(p->ehllc->dsap == ETH_DSAP_IP && p->ehllc->ssap == ETH_SSAP_IP)
00282             {
00283                 if(cap_len < IEEE802_11_DATA_HDR_LEN +
00284                    sizeof(EthLlc) + sizeof(EthLlcOther))
00285                 {
00286                     if(pv.verbose_flag)
00287                     {
00288                         ErrorMessage("Not enough data for EthLlcOther header\n");
00289                     }
00290 
00291                     if((runMode == MODE_IDS) && pv.decoder_flags.decode_alerts)
00292                     {
00293                         SnortEventqAdd(GENERATOR_SNORT_DECODE, 
00294                                 DECODE_BAD_80211_ETHLLC, 1, DECODE_CLASS, 3, 
00295                                 DECODE_BAD_80211_ETHLLC_STR, 0);
00296                         if ((InlineMode()) && pv.decoder_flags.drop_alerts)
00297                         {
00298                            DEBUG_WRAP(DebugMessage(DEBUG_DECODE, "Dropping bad packet\n");); 
00299                            InlineDrop();
00300                         }
00301                     }
00302                     
00303                     return;
00304                 }
00305 
00306                 p->ehllcother = (EthLlcOther *) (pkt + IEEE802_11_DATA_HDR_LEN + sizeof(EthLlc));
00307 #ifdef DEBUG
00308                 PrintNetData(stdout,(u_int8_t *) p->ehllcother, sizeof(EthLlcOther));
00309                 ClearDumpBuf();
00310                 printf("LLC Other Header:\n");
00311                 printf("   CTRL: 0x%X\n", p->ehllcother->ctrl);
00312                 printf("   ORG: 0x%02X%02X%02X\n", p->ehllcother->org_code[0], 
00313                         p->ehllcother->org_code[1], p->ehllcother->org_code[2]);
00314                 printf("   PROTO: 0x%04X\n", ntohs(p->ehllcother->proto_id));
00315 #endif
00316 
00317                 switch(ntohs(p->ehllcother->proto_id))
00318                 {
00319                     case ETHERNET_TYPE_IP:
00320                         DecodeIP(p->pkt + IEEE802_11_DATA_HDR_LEN + sizeof(EthLlc) +
00321                                 sizeof(EthLlcOther), 
00322                                 pkt_len - IEEE802_11_DATA_HDR_LEN - sizeof(EthLlc) - 
00323                                 sizeof(EthLlcOther), p);
00324                         return;
00325 
00326                     case ETHERNET_TYPE_ARP:
00327                     case ETHERNET_TYPE_REVARP:
00328                         DecodeARP(p->pkt + IEEE802_11_DATA_HDR_LEN + sizeof(EthLlc) +
00329                                 sizeof(EthLlcOther), 
00330                                 pkt_len - IEEE802_11_DATA_HDR_LEN - sizeof(EthLlc) -
00331                                 sizeof(EthLlcOther), p);
00332                         return;
00333                     case ETHERNET_TYPE_EAPOL:
00334                         DecodeEapol(p->pkt + IEEE802_11_DATA_HDR_LEN + sizeof(EthLlc) +
00335                                 sizeof(EthLlcOther),
00336                                 pkt_len - IEEE802_11_DATA_HDR_LEN - sizeof(EthLlc) -
00337                                 sizeof(EthLlcOther), p);
00338                         return;
00339                     case ETHERNET_TYPE_8021Q:
00340                         DecodeVlan(p->pkt + IEEE802_11_DATA_HDR_LEN , 
00341                                    cap_len - IEEE802_11_DATA_HDR_LEN , p);
00342                         return; 
00343 
00344                     default:
00345                         pc.other++;
00346                         return;
00347                 }
00348             }
00349             break;
00350         default:
00351             pc.other++;
00352             break;
00353     }
00354 
00355     return;
00356 }
00357 
00358 
00359 void DecodeVlan(u_int8_t * pkt, const u_int32_t len, Packet * p)
00360 {
00361     if(len < sizeof(VlanTagHdr))
00362     {
00363         if(pv.verbose_flag)
00364             ErrorMessage("Not enough data to process a vlan header\n");
00365 
00366         if((runMode == MODE_IDS) && pv.decoder_flags.decode_alerts)
00367         {
00368             SnortEventqAdd(GENERATOR_SNORT_DECODE, DECODE_BAD_VLAN, 1, 
00369                     DECODE_CLASS, 3, DECODE_BAD_VLAN_STR, 0);
00370             if ((InlineMode()) && pv.decoder_flags.drop_alerts)
00371             {
00372                DEBUG_WRAP(DebugMessage(DEBUG_DECODE, "Dropping bad packet\n");); 
00373                InlineDrop();
00374             }
00375  
00376         }
00377         
00378         return;
00379     }
00380 
00381     p->vh = (VlanTagHdr *) pkt;
00382     
00383     DEBUG_WRAP(DebugMessage(DEBUG_DECODE, "Vlan traffic:\n");
00384                DebugMessage(DEBUG_DECODE, "   Priority: %d(0x%X)\n", 
00385                             VTH_PRIORITY(p->vh), VTH_PRIORITY(p->vh));
00386                DebugMessage(DEBUG_DECODE, "   CFI: %d\n", VTH_CFI(p->vh));
00387                DebugMessage(DEBUG_DECODE, "   Vlan ID: %d(0x%04X)\n", 
00388                             VTH_VLAN(p->vh), VTH_VLAN(p->vh));
00389                DebugMessage(DEBUG_DECODE, "   Vlan Proto: 0x%04X\n", 
00390                             ntohs(p->vh->vth_proto));
00391                );
00392 
00393     /* check to see if we've got an encapsulated LLC layer
00394      * http://www.geocities.com/billalexander/ethernet.html
00395      */
00396     if(ntohs(p->vh->vth_proto) <= ETHERNET_MAX_LEN_ENCAP)
00397     {
00398         if(len < sizeof(VlanTagHdr) + sizeof(EthLlc))
00399         {
00400             if(pv.verbose_flag)
00401             {
00402                 ErrorMessage("Not enough data for EthLlc header");
00403             }
00404 
00405             if((runMode == MODE_IDS) && pv.decoder_flags.decode_alerts)
00406             {
00407                 SnortEventqAdd(GENERATOR_SNORT_DECODE, DECODE_BAD_VLAN_ETHLLC,
00408                       1, DECODE_CLASS, 3, DECODE_BAD_VLAN_ETHLLC_STR, 0);
00409                  if ((InlineMode()) && pv.decoder_flags.drop_alerts)
00410                  {
00411                     DEBUG_WRAP(DebugMessage(DEBUG_DECODE, "Dropping bad packet\n"););
00412                     InlineDrop();
00413                  }
00414  
00415             }
00416             return;            
00417         }
00418         
00419         p->ehllc = (EthLlc *) (pkt + sizeof(VlanTagHdr));
00420 
00421         DEBUG_WRAP(
00422                 DebugMessage(DEBUG_DECODE, "LLC Header:\n");
00423                 DebugMessage(DEBUG_DECODE, "   DSAP: 0x%X\n", p->ehllc->dsap);
00424                 DebugMessage(DEBUG_DECODE, "   SSAP: 0x%X\n", p->ehllc->ssap);
00425                 );
00426 
00427         if(p->ehllc->dsap == ETH_DSAP_IP && p->ehllc->ssap == ETH_SSAP_IP)
00428         {
00429             if(len < sizeof(VlanTagHdr) + sizeof(EthLlc) + sizeof(EthLlcOther))
00430             {
00431                 if(pv.verbose_flag)
00432                 {
00433                     ErrorMessage("Not enough data for VLAN header");
00434                 }
00435 
00436                 if((runMode == MODE_IDS) && pv.decoder_flags.decode_alerts)
00437                 {
00438                     SnortEventqAdd(GENERATOR_SNORT_DECODE, 
00439                             DECODE_BAD_VLAN_OTHER, 1, DECODE_CLASS, 3, 
00440                             DECODE_BAD_VLAN_OTHER_STR, 0);
00441                     if ((InlineMode()) && pv.decoder_flags.drop_alerts)
00442                     {
00443                       DEBUG_WRAP(DebugMessage(DEBUG_DECODE, "Dropping bad packet\n"););
00444                       InlineDrop();
00445                     }
00446 
00447                 }
00448                 
00449                 return;            
00450             }
00451 
00452             p->ehllcother = (EthLlcOther *) (pkt + sizeof(VlanTagHdr) + sizeof(EthLlc));
00453 
00454             DEBUG_WRAP(
00455                     DebugMessage(DEBUG_DECODE, "LLC Other Header:\n");
00456                     DebugMessage(DEBUG_DECODE, "   CTRL: 0x%X\n", 
00457                         p->ehllcother->ctrl);
00458                     DebugMessage(DEBUG_DECODE, "   ORG: 0x%02X%02X%02X\n", 
00459                         p->ehllcother->org_code[0], p->ehllcother->org_code[1], 
00460                         p->ehllcother->org_code[2]);
00461                     DebugMessage(DEBUG_DECODE, "   PROTO: 0x%04X\n", 
00462                         ntohs(p->ehllcother->proto_id));
00463                     );
00464 
00465             switch(ntohs(p->ehllcother->proto_id))
00466             {
00467                 case ETHERNET_TYPE_IP:
00468                     DecodeIP(p->pkt + sizeof(VlanTagHdr) + sizeof(EthLlc) +
00469                             sizeof(EthLlcOther), len - sizeof(VlanTagHdr), p);
00470                     return;
00471 
00472                 case ETHERNET_TYPE_ARP:
00473                 case ETHERNET_TYPE_REVARP:
00474                     DecodeARP(p->pkt + sizeof(VlanTagHdr)+ sizeof(EthLlc) +
00475                             sizeof(EthLlcOther), len - sizeof(VlanTagHdr), p);
00476                     return;
00477 
00478                 default:
00479                     pc.other++;
00480                     return;
00481             }
00482         }
00483     }
00484     else
00485     {
00486         switch(ntohs(p->vh->vth_proto))
00487         {
00488             case ETHERNET_TYPE_IP:
00489                 DecodeIP(pkt + sizeof(VlanTagHdr), 
00490                         len - sizeof(VlanTagHdr), p);
00491                 return;
00492 
00493             case ETHERNET_TYPE_ARP:
00494             case ETHERNET_TYPE_REVARP:
00495                 DecodeARP(pkt + sizeof(VlanTagHdr), 
00496                         len - sizeof(VlanTagHdr), p);
00497                 return;
00498 
00499             default:
00500                 pc.other++;
00501                 return;
00502         }
00503     }
00504 }
00505 
00506 #ifdef GIDS
00507 #ifndef IPFW
00508 /*
00509  * Function: DecodeIptablesPkt(Packet *, char *, struct pcap_pkthdr*, u_int8_t*)
00510  *
00511  * Purpose: Decoding iptables.
00512  * 
00513  * Arguments: p => pointer to decoded packet struct
00514  *            user => Utility pointer, unused
00515  *            pkthdr => ptr to the packet header
00516  *            pkt => pointer to the real live packet data
00517  * 
00518  */
00519 void DecodeIptablesPkt(Packet * p, struct pcap_pkthdr * pkthdr, u_int8_t * pkt)
00520 {
00521     u_int32_t len;
00522     u_int32_t cap_len;
00523 
00524     bzero((char *) p, sizeof(Packet));
00525     p->pkth = pkthdr;
00526     p->pkt = pkt;
00527 
00528     len = pkthdr->len;
00529     cap_len = pkthdr->caplen;
00530 
00531     DecodeIP(p->pkt, cap_len, p);
00532 }
00533 #else
00534 /*
00535  * Function: DecodeIpfwPkt(Packet *, char *, struct pcap_pkthdr*, u_int8_t*)
00536  *
00537  * Purpose: Decoding ipfw divert socket
00538  * 
00539  * Arguments: p => pointer to decoded packet struct
00540  *            user => Utility pointer, unused
00541  *            pkthdr => ptr to the packet header
00542  *            pkt => pointer to the real live packet data
00543  * 
00544  */
00545 void DecodeIpfwPkt(Packet * p, struct pcap_pkthdr * pkthdr, u_int8_t * pkt)
00546 {
00547     u_int32_t len;
00548     u_int32_t cap_len;
00549         
00550     bzero((char *) p, sizeof(Packet));
00551     p->pkth = pkthdr;
00552     p->pkt = pkt;
00553 
00554     len = pkthdr->len;
00555     cap_len = pkthdr->caplen;
00556 
00557     DecodeIP(p->pkt, cap_len, p);
00558 
00559 }
00560 #endif
00561 #endif /* GIDS */
00562 
00563 
00564 /*
00565  * Function: DecodeNullPkt(Packet *, char *, struct pcap_pkthdr*, u_int8_t*)
00566  *
00567  * Purpose: Decoding on loopback devices.
00568  *
00569  * Arguments: p => pointer to decoded packet struct
00570  *            user => Utility pointer, unused
00571  *            pkthdr => ptr to the packet header
00572  *            pkt => pointer to the real live packet data
00573  *
00574  * Returns: void function
00575  */
00576 void DecodeNullPkt(Packet * p, struct pcap_pkthdr * pkthdr, u_int8_t * pkt)
00577 {
00578     u_int32_t len;
00579     u_int32_t cap_len;
00580 
00581     bzero((char *) p, sizeof(Packet));
00582 
00583     p->pkth = pkthdr;
00584     p->pkt = pkt;
00585 
00586     len = pkthdr->len;
00587     cap_len = pkthdr->caplen;
00588 
00589     DEBUG_WRAP(DebugMessage(DEBUG_DECODE, "Packet!\n"); );
00590 
00591     /* do a little validation */
00592     if(cap_len < NULL_HDRLEN)
00593     {
00594         if(pv.verbose_flag)
00595         {
00596             ErrorMessage("NULL header length < captured len! (%d bytes)\n",
00597                     cap_len);
00598         }
00599 
00600         return;
00601     }
00602 
00603     DecodeIP(p->pkt + NULL_HDRLEN, cap_len - NULL_HDRLEN, p);
00604 }
00605 
00606 /*
00607  * Function: DecodeTRPkt(Packet *, char *, struct pcap_pkthdr*, u_int8_t*)
00608  *
00609  * Purpose: Decode Token Ring packets!
00610  *
00611  * Arguments: p=> pointer to decoded packet struct
00612  *            user => Utility pointer, unused
00613  *            pkthdr => ptr to the packet header
00614  *            pkt => pointer to the real live packet data
00615  *
00616  * Returns: void function
00617  */
00618 void DecodeTRPkt(Packet * p, struct pcap_pkthdr * pkthdr, u_int8_t * pkt)
00619 {
00620     u_int32_t pkt_len;      /* suprisingly, the length of the packet */
00621     u_int32_t cap_len;      /* caplen value */
00622     u_int32_t dataoff;      /* data offset is variable here */
00623 
00624     bzero((char *) p, sizeof(Packet));
00625 
00626     p->pkth = pkthdr;
00627     p->pkt = pkt;
00628 
00629 
00630     /* set the lengths we need */
00631     pkt_len = pkthdr->len;  /* total packet length */
00632     cap_len = pkthdr->caplen;   /* captured packet length */
00633 
00634     if(snaplen < pkt_len)
00635         pkt_len = cap_len;
00636 
00637     DEBUG_WRAP(DebugMessage(DEBUG_DECODE, "Packet!\n");
00638             DebugMessage(DEBUG_DECODE, "caplen: %lu    pktlen: %lu\n",
00639                 (unsigned long)cap_len,(unsigned long) pkt_len);
00640             );
00641 
00642     if(cap_len < sizeof(Trh_hdr))
00643     {
00644         if(pv.verbose_flag)
00645             ErrorMessage("Captured data length < Token Ring header length! "
00646                          "(%d < %d bytes)\n", p->pkth->caplen, TR_HLEN);
00647 
00648         if((runMode == MODE_IDS) && pv.decoder_flags.decode_alerts)
00649         {
00650             SnortEventqAdd(GENERATOR_SNORT_DECODE, DECODE_BAD_TRH, 1, 
00651                     DECODE_CLASS, 3, DECODE_BAD_TRH_STR, 0);
00652             if ((InlineMode()) && pv.decoder_flags.drop_alerts)
00653             {
00654                DEBUG_WRAP(DebugMessage(DEBUG_DECODE, "Dropping bad packet\n"););
00655                InlineDrop();
00656             }
00657 
00658         }
00659 
00660         return;
00661     }
00662 
00663     /* lay the tokenring header structure over the packet data */
00664     p->trh = (Trh_hdr *) pkt;
00665 
00666     /*
00667      * according to rfc 1042:
00668      *
00669      *   The presence of a Routing Information Field is indicated by the Most
00670      *   Significant Bit (MSB) of the source address, called the Routing
00671      *   Information Indicator (RII).  If the RII equals zero, a RIF is
00672      *   not present.  If the RII equals 1, the RIF is present.
00673      *   ..
00674      *   However the MSB is already zeroed by this moment, so there's no
00675      *   real way to figure out whether RIF is presented in packet, so we are
00676      *   doing some tricks to find IPARP signature..
00677      */
00678 
00679     /*
00680      * first I assume that we have single-ring network with no RIF
00681      * information presented in frame
00682      */
00683     if(cap_len < (sizeof(Trh_hdr) + sizeof(Trh_llc)))
00684     {
00685         if(pv.verbose_flag)
00686             ErrorMessage("Captured data length < Token Ring header length! "
00687                          "(%d < %d bytes)\n", cap_len,
00688                          (sizeof(Trh_hdr) + sizeof(Trh_llc)));
00689         
00690         if((runMode == MODE_IDS) && pv.decoder_flags.decode_alerts)
00691         {
00692             SnortEventqAdd(GENERATOR_SNORT_DECODE, DECODE_BAD_TR_ETHLLC, 1, 
00693                     DECODE_CLASS, 3, DECODE_BAD_TR_ETHLLC_STR, 0);
00694             if ((InlineMode()) && pv.decoder_flags.drop_alerts)
00695             {
00696               DEBUG_WRAP(DebugMessage(DEBUG_DECODE, "Dropping bad packet\n"););
00697               InlineDrop();
00698             }
00699 
00700         }
00701         return;
00702     }
00703 
00704     
00705     p->trhllc = (Trh_llc *) (pkt + sizeof(Trh_hdr));
00706 
00707     if(p->trhllc->dsap != IPARP_SAP && p->trhllc->ssap != IPARP_SAP)
00708     {
00709         /*
00710          * DSAP != SSAP != 0xAA .. either we are having frame which doesn't
00711          * carry IP datagrams or has RIF information present. We assume
00712          * lattest ...
00713          */
00714 
00715         if(cap_len < (sizeof(Trh_hdr) + sizeof(Trh_llc) + sizeof(Trh_mr)))
00716         {
00717             if(pv.verbose_flag)
00718                 ErrorMessage("Captured data length < Token Ring header length! "
00719                              "(%d < %d bytes)\n", cap_len,
00720                              (sizeof(Trh_hdr) + sizeof(Trh_llc) + sizeof(Trh_mr)));
00721             
00722             if((runMode == MODE_IDS) && pv.decoder_flags.decode_alerts)
00723             {
00724                 SnortEventqAdd(GENERATOR_SNORT_DECODE, DECODE_BAD_TRHMR, 1, 
00725                         DECODE_CLASS, 3, DECODE_BAD_TRHMR_STR, 0);
00726                 if ((InlineMode()) && pv.decoder_flags.drop_alerts)
00727                 {
00728                    DEBUG_WRAP(DebugMessage(DEBUG_DECODE, "Dropping bad packet\n"););
00729                    InlineDrop();
00730                 }
00731 
00732             }
00733             
00734             return;
00735         }
00736         
00737         p->trhmr = (Trh_mr *) (pkt + sizeof(Trh_hdr));
00738 
00739         
00740         if(cap_len < (sizeof(Trh_hdr) + sizeof(Trh_llc) +
00741                       sizeof(Trh_mr) + TRH_MR_LEN(p->trhmr)))
00742         {
00743             if(pv.verbose_flag)
00744                 ErrorMessage("Captured data length < Token Ring header length! "
00745                              "(%d < %d bytes)\n", cap_len,
00746                              (sizeof(Trh_hdr) + sizeof(Trh_llc) + sizeof(Trh_mr)));
00747 
00748             
00749             if((runMode == MODE_IDS) && pv.decoder_flags.decode_alerts)
00750             {
00751                 SnortEventqAdd(GENERATOR_SNORT_DECODE, DECODE_BAD_TR_MR_LEN, 1, 
00752                         DECODE_CLASS, 3, DECODE_BAD_TR_MR_LEN_STR, 0);
00753                 if ((InlineMode()) && pv.decoder_flags.drop_alerts)
00754                 {
00755                    DEBUG_WRAP(DebugMessage(DEBUG_DECODE, "Dropping bad packet\n"););
00756                    InlineDrop();
00757                 }
00758  
00759             }
00760             
00761             return;
00762         }
00763         
00764         p->trhllc = (Trh_llc *) (pkt + sizeof(Trh_hdr) + TRH_MR_LEN(p->trhmr));
00765         dataoff   = sizeof(Trh_hdr) + TRH_MR_LEN(p->trhmr) + sizeof(Trh_llc);
00766 
00767     }
00768     else
00769     {
00770         p->trhllc = (Trh_llc *) (pkt + sizeof(Trh_hdr));
00771         dataoff = sizeof(Trh_hdr) + sizeof(Trh_llc);
00772     }
00773 
00774     /*
00775      * ideally we would need to check both SSAP, DSAP, and protoid fields: IP
00776      * datagrams and ARP requests and replies are transmitted in standard
00777      * 802.2 LLC Type 1 Unnumbered Information format, control code 3, with
00778      * the DSAP and the SSAP fields of the 802.2 header set to 170, the
00779      * assigned global SAP value for SNAP [6].  The 24-bit Organization Code
00780      * in the SNAP is zero, and the remaining 16 bits are the EtherType from
00781      * Assigned Numbers [7] (IP = 2048, ARP = 2054). .. but we would check
00782      * SSAP and DSAP and assume this would be enough to trust.
00783      */
00784     if(p->trhllc->dsap != IPARP_SAP && p->trhllc->ssap != IPARP_SAP)
00785     {
00786         DEBUG_WRAP(
00787                    DebugMessage(DEBUG_DECODE, "DSAP and SSAP arent set to SNAP\n");
00788                 );
00789         p->trhllc = NULL;
00790         return;
00791     }
00792 
00793     switch(htons(p->trhllc->ethertype))
00794     {
00795         case ETHERNET_TYPE_IP:
00796             DEBUG_WRAP(DebugMessage(DEBUG_DECODE, "Decoding IP\n"););
00797             DecodeIP(p->pkt + dataoff, cap_len - dataoff, p);
00798             return;
00799 
00800         case ETHERNET_TYPE_ARP:
00801         case ETHERNET_TYPE_REVARP:
00802             DEBUG_WRAP(
00803                     DebugMessage(DEBUG_DECODE, "Decoding ARP\n");
00804                     );
00805             pc.arp++;
00806 
00807             return;
00808 
00809         case ETHERNET_TYPE_8021Q:
00810             DecodeVlan(p->pkt + dataoff, cap_len - dataoff, p);
00811             return; 
00812 
00813         default:
00814             DEBUG_WRAP(DebugMessage(DEBUG_DECODE, "Unknown network protocol: %d\n", 
00815                         htons(p->trhllc->ethertype)));
00816             pc.other++;
00817             return;
00818     }
00819 
00820     return;
00821 }
00822 
00823 
00824 /*
00825  * Function: DecodeFDDIPkt(Packet *, char *, struct pcap_pkthdr*, u_int8_t*)
00826  *
00827  * Purpose: Mainly taken from CyberPsycotic's Token Ring Code -worm5er
00828  *
00829  * Arguments: p => pointer to decoded packet struct
00830  *            user => Utility pointer, unused
00831  *            pkthdr => ptr to the packet header
00832  *            pkt => pointer to the real live packet data
00833  *
00834  * Returns: void function
00835  */
00836 void DecodeFDDIPkt(Packet * p, struct pcap_pkthdr * pkthdr, u_int8_t * pkt)
00837 {
00838     u_int32_t pkt_len;      /* length of the packet */
00839     u_int32_t cap_len;      /* capture length variable */
00840     u_int32_t dataoff = sizeof(Fddi_hdr) + sizeof(Fddi_llc_saps);
00841 
00842     bzero((char *) p, sizeof(Packet));
00843 
00844     p->pkth = pkthdr;
00845     p->pkt = pkt;
00846 
00847     pkt_len = pkthdr->len;
00848     cap_len = pkthdr->caplen;
00849 
00850     if(snaplen < pkt_len)
00851     {
00852         pkt_len = cap_len;
00853     }
00854 
00855     DEBUG_WRAP(DebugMessage(DEBUG_DECODE,"Packet!\n");
00856             DebugMessage(DEBUG_DECODE, "caplen: %lu    pktlen: %lu\n",
00857                 (unsigned long) cap_len,(unsigned long) pkt_len);
00858             );
00859 
00860     /* Bounds checking (might not be right yet -worm5er) */
00861     if(p->pkth->caplen < dataoff)
00862     {
00863         if(pv.verbose_flag)
00864         {
00865             ErrorMessage("Captured data length < FDDI header length! "
00866                          "(%d %d bytes)\n", p->pkth->caplen, dataoff);
00867             return;
00868         }
00869     }
00870     /* let's put this in as the fddi header structure */
00871     p->fddihdr = (Fddi_hdr *) pkt;
00872 
00873     p->fddisaps = (Fddi_llc_saps *) (pkt + sizeof(Fddi_hdr));
00874 
00875     /* First we'll check and see if it's an IP/ARP Packet... */
00876     /* Then we check to see if it's a SNA packet */
00877     /*
00878      * Lastly we'll declare it none of the above and just slap something
00879      * generic on it to discard it with (I know that sucks, but heck we're
00880      * only looking for IP/ARP type packets currently...  -worm5er
00881      */
00882     if((p->fddisaps->dsap == FDDI_DSAP_IP) && (p->fddisaps->ssap == FDDI_SSAP_IP))
00883     {
00884         dataoff += sizeof(Fddi_llc_iparp);
00885         
00886         if(p->pkth->caplen < dataoff)
00887         {
00888             if(pv.verbose_flag)
00889             {
00890                 ErrorMessage("Captured data length < FDDI header length! "
00891                              "(%d %d bytes)\n", p->pkth->caplen, dataoff);
00892                 return;
00893             }
00894         }
00895             
00896         p->fddiiparp = (Fddi_llc_iparp *) (pkt + sizeof(Fddi_hdr) + sizeof(Fddi_llc_saps));
00897     }
00898     else if((p->fddisaps->dsap == FDDI_DSAP_SNA) &&
00899             (p->fddisaps->ssap == FDDI_SSAP_SNA))
00900     {
00901         dataoff += sizeof(Fddi_llc_sna);
00902 
00903         if(p->pkth->caplen < dataoff)
00904         {
00905             if(pv.verbose_flag)
00906             {
00907                 ErrorMessage("Captured data length < FDDI header length! "
00908                              "(%d %d bytes)\n", p->pkth->caplen, dataoff);
00909                 return;
00910             }
00911         }
00912         
00913         p->fddisna = (Fddi_llc_sna *) (pkt + sizeof(Fddi_hdr) +
00914                                        sizeof(Fddi_llc_saps));
00915     }
00916     else
00917     {
00918         dataoff += sizeof(Fddi_llc_other);
00919         p->fddiother = (Fddi_llc_other *) (pkt + sizeof(Fddi_hdr) +
00920                 sizeof(Fddi_llc_other));
00921 
00922         if(p->pkth->caplen < dataoff)
00923         {
00924             if(pv.verbose_flag)
00925             {
00926                 ErrorMessage("Captured data length < FDDI header length! "
00927                              "(%d %d bytes)\n", p->pkth->caplen, dataoff);
00928                 return;
00929             }
00930         }
00931     }
00932 
00933     /*
00934      * Now let's see if we actually care about the packet... If we don't,
00935      * throw it out!!!
00936      */
00937     if((p->fddisaps->dsap != FDDI_DSAP_IP) && 
00938             (p->fddisaps->ssap != FDDI_SSAP_IP))
00939     {
00940         DEBUG_WRAP(
00941                 DebugMessage(DEBUG_DECODE, 
00942                     "This FDDI Packet isn't an IP/ARP packet...\n");
00943                 );
00944         return;
00945     }
00946 
00947     pkt_len -= dataoff;
00948     cap_len -= dataoff;
00949 
00950     switch(htons(p->fddiiparp->ethertype))
00951     {
00952         case ETHERNET_TYPE_IP:
00953             DEBUG_WRAP(DebugMessage(DEBUG_DECODE, "Decoding IP\n"););
00954             DecodeIP(p->pkt + dataoff, cap_len, p);
00955             return;
00956 
00957         case ETHERNET_TYPE_ARP:
00958         case ETHERNET_TYPE_REVARP:
00959             DEBUG_WRAP(DebugMessage(DEBUG_DECODE, "Decoding ARP\n"););
00960             pc.arp++;
00961 
00962             return;
00963 
00964         case ETHERNET_TYPE_8021Q:
00965             DecodeVlan(p->pkt + dataoff, cap_len, p);
00966             return; 
00967 
00968 
00969         default:
00970             DEBUG_WRAP(DebugMessage(DEBUG_DECODE, "Unknown network protocol: %d\n",
00971                         htons(p->fddiiparp->ethertype));
00972                     );
00973             pc.other++;
00974 
00975             return;
00976     }
00977 
00978     return;
00979 }
00980 
00981 /*
00982  * Function: DecodeLinuxSLLPkt(Packet *, char *, struct pcap_pkthdr*, u_int8_t*)
00983  *
00984  * Purpose: Decode those fun loving LinuxSLL (linux cooked sockets) 
00985  *          packets, one at a time!
00986  *
00987  * Arguments: p => pointer to the decoded packet struct
00988  *            user => Utility pointer (unused)
00989  *            pkthdr => ptr to the packet header
00990  *            pkt => pointer to the real live packet data
00991  *
00992  * Returns: void function
00993  */
00994  
00995 #ifdef DLT_LINUX_SLL 
00996 
00997 void DecodeLinuxSLLPkt(Packet * p, struct pcap_pkthdr * pkthdr, u_int8_t * pkt)
00998 {
00999     u_int32_t pkt_len;      /* the length of the packet */
01000     u_int32_t cap_len;      /* caplen value */
01001 
01002     bzero((char *) p, sizeof(Packet));
01003 
01004     p->pkth = pkthdr;
01005     p->pkt = pkt;
01006 
01007     /* set the lengths we need */
01008     pkt_len = pkthdr->len;  /* total packet length */
01009     cap_len = pkthdr->caplen;   /* captured packet length */
01010 
01011     if(snaplen < pkt_len)
01012         pkt_len = cap_len;
01013 
01014     DEBUG_WRAP(DebugMessage(DEBUG_DECODE,"Packet!\n");
01015             DebugMessage(DEBUG_DECODE, "caplen: %lu    pktlen: %lu\n",
01016                 (unsigned long)cap_len, (unsigned long)pkt_len););
01017 
01018     /* do a little validation */
01019     if(p->pkth->caplen < SLL_HDR_LEN)
01020     {
01021         if(pv.verbose_flag)
01022         {
01023             ErrorMessage("Captured data length < SLL header length (your "
01024                          "libpcap is broken?)! (%d bytes)\n", p->pkth->caplen);
01025         }
01026         return;
01027     }
01028     /* lay the ethernet structure over the packet data */
01029     p->sllh = (SLLHdr *) pkt;
01030 
01031     /* grab out the network type */
01032     switch(ntohs(p->sllh->sll_protocol))
01033     {
01034         case ETHERNET_TYPE_IP:
01035             DEBUG_WRAP(DebugMessage(DEBUG_DECODE,
01036                         "IP datagram size calculated to be %lu bytes\n",
01037                         (unsigned long)(cap_len - SLL_HDR_LEN)););
01038 
01039             DecodeIP(p->pkt + SLL_HDR_LEN, cap_len - SLL_HDR_LEN, p);
01040             return;
01041 
01042         case ETHERNET_TYPE_ARP:
01043         case ETHERNET_TYPE_REVARP:
01044             DecodeARP(p->pkt + SLL_HDR_LEN, cap_len - SLL_HDR_LEN, p);
01045             return;
01046 
01047         case ETHERNET_TYPE_IPV6:
01048             DecodeIPV6(p->pkt + SLL_HDR_LEN, (cap_len - SLL_HDR_LEN));
01049             return;
01050 
01051         case ETHERNET_TYPE_IPX:
01052             DecodeIPX(p->pkt + SLL_HDR_LEN, (cap_len - SLL_HDR_LEN));
01053             return;
01054 
01055         case LINUX_SLL_P_802_3:
01056             DEBUG_WRAP(DebugMessage(DEBUG_DATALINK,
01057                         "Linux SLL P 802.3 is not supported.\n"););
01058             pc.other++;
01059             return;
01060 
01061         case LINUX_SLL_P_802_2:
01062             DEBUG_WRAP(DebugMessage(DEBUG_DATALINK,
01063                         "Linux SLL P 802.2 is not supported.\n"););
01064             pc.other++;
01065             return;
01066 
01067         case ETHERNET_TYPE_8021Q:
01068             DecodeVlan(p->pkt + SLL_HDR_LEN, cap_len - SLL_HDR_LEN, p);
01069             return; 
01070 
01071         default:
01072             /* shouldn't go here unless pcap library changes again */
01073             /* should be a DECODE generated alert */
01074             DEBUG_WRAP(DebugMessage(DEBUG_DATALINK,"(Unknown) %X is not supported. "
01075                         "(need tcpdump snapshots to test. Please contact us)\n",
01076                         p->sllh->sll_protocol););
01077             pc.other++;
01078             return;
01079     }
01080 
01081     return;
01082 }
01083 
01084 #endif /* DLT_LINUX_SLL */
01085 
01086 /*
01087  * Function: DecodeOldPflog(Packet *, struct pcap_pkthdr *, u_int8_t *)
01088  *
01089  * Purpose: Pass old pflog format device packets off to IP or IP6 -fleck
01090  *
01091  * Arguments: p => pointer to the decoded packet struct
01092  *            pkthdr => ptr to the packet header
01093  *            pkt => pointer to the packet data
01094  *
01095  * Returns: void function
01096  *
01097  */
01098 void DecodeOldPflog(Packet * p, struct pcap_pkthdr * pkthdr, u_int8_t * pkt)
01099 {
01100     u_int32_t pkt_len;      /* suprisingly, the length of the packet */
01101     u_int32_t cap_len;      /* caplen value */
01102 
01103     bzero((char *) p, sizeof(Packet));
01104 
01105     p->pkth = pkthdr;
01106     p->pkt = pkt;
01107 
01108     /* set the lengths we need */
01109     pkt_len = pkthdr->len;  /* total packet length */
01110     cap_len = pkthdr->caplen;   /* captured packet length */
01111 
01112     if(snaplen < pkt_len)
01113         pkt_len = cap_len;
01114 
01115     DEBUG_WRAP(DebugMessage(DEBUG_DECODE, "Packet!\n");
01116             DebugMessage(DEBUG_DECODE, "caplen: %lu    pktlen: %lu\n", 
01117                 (unsigned long)cap_len, (unsigned long)pkt_len););
01118 
01119     /* do a little validation */
01120     if(p->pkth->caplen < OLDPFLOG_HDRLEN)
01121     {
01122         if(pv.verbose_flag)
01123         {
01124             ErrorMessage("Captured data length < Pflog header length! "
01125                     "(%d bytes)\n", p->pkth->caplen);
01126         }
01127         return;
01128     }
01129 
01130     /* lay the pf header structure over the packet data */
01131     p->opfh = (OldPflogHdr *) pkt;
01132 
01133     /*  get the network type - should only be AF_INET or AF_INET6 */
01134     switch(ntohl(p->opfh->af))
01135     {
01136         case AF_INET:   /* IPv4 */
01137             DEBUG_WRAP(DebugMessage(DEBUG_DECODE, "IP datagram size calculated to be %lu "
01138                         "bytes\n", (unsigned long)(cap_len - OLDPFLOG_HDRLEN)););
01139 
01140             DecodeIP(p->pkt + OLDPFLOG_HDRLEN, cap_len - OLDPFLOG_HDRLEN, p);
01141             return;
01142 
01143 #ifdef AF_INET6
01144         case AF_INET6:  /* IPv6 */
01145             DecodeIPV6(p->pkt + OLDPFLOG_HDRLEN, (cap_len - OLDPFLOG_HDRLEN));
01146             return;
01147 #endif
01148 
01149         default:
01150             /* To my knowledge, pflog devices can only 
01151              * pass IP and IP6 packets. -fleck 
01152              */
01153             pc.other++;
01154             return;
01155     }
01156 
01157     return;
01158 }
01159 /*
01160  * Function: DecodePflog(Packet *, struct pcap_pkthdr *, u_int8_t *)
01161  *
01162  * Purpose: Pass pflog device packets off to IP or IP6 -fleck
01163  *
01164  * Arguments: p => pointer to the decoded packet struct
01165  *            pkthdr => ptr to the packet header
01166  *            pkt => pointer to the packet data
01167  *
01168  * Returns: void function
01169  *
01170  */
01171 void DecodePflog(Packet * p, struct pcap_pkthdr * pkthdr, u_int8_t * pkt)
01172 {
01173     u_int32_t pkt_len;      /* suprisingly, the length of the packet */
01174     u_int32_t cap_len;      /* caplen value */
01175 
01176     bzero((char *) p, sizeof(Packet));
01177 
01178     p->pkth = pkthdr;
01179     p->pkt = pkt;
01180 
01181     /* set the lengths we need */
01182     pkt_len = pkthdr->len;  /* total packet length */
01183     cap_len = pkthdr->caplen;   /* captured packet length */
01184 
01185     if(snaplen < pkt_len)
01186         pkt_len = cap_len;
01187 
01188     DEBUG_WRAP(DebugMessage(DEBUG_DECODE, "Packet!\n");
01189             DebugMessage(DEBUG_DECODE, "caplen: %lu    pktlen: %lu\n", 
01190                 (unsigned long)cap_len, (unsigned long)pkt_len););
01191 
01192     /* do a little validation */
01193     if(p->pkth->caplen < PFLOG_HDRLEN)
01194     {
01195         if(pv.verbose_flag)
01196         {
01197             ErrorMessage("Captured data length < Pflog header length! "
01198                     "(%d bytes)\n", p->pkth->caplen);
01199         }
01200         return;
01201     }
01202 
01203     /* lay the pf header structure over the packet data */
01204     p->pfh = (PflogHdr *) pkt;
01205 
01206     /*  get the network type - should only be AF_INET or AF_INET6 */
01207     switch(ntohs(p->pfh->af))
01208     {
01209         case AF_INET:   /* IPv4 */
01210             DEBUG_WRAP(DebugMessage(DEBUG_DECODE, "IP datagram size calculated to be %lu "
01211                         "bytes\n", (unsigned long)(cap_len - PFLOG_HDRLEN)););
01212 
01213             DecodeIP(p->pkt + PFLOG_HDRLEN, cap_len - PFLOG_HDRLEN, p);
01214             return;
01215 
01216 #ifdef AF_INET6
01217         case AF_INET6:  /* IPv6 */
01218             DecodeIPV6(p->pkt + PFLOG_HDRLEN, (cap_len - PFLOG_HDRLEN));
01219             return;
01220 #endif
01221 
01222         default:
01223             /* To my knowledge, pflog devices can only 
01224              * pass IP and IP6 packets. -fleck 
01225              */
01226             pc.other++;
01227             return;
01228     }
01229 
01230     return;
01231 }
01232 
01233 
01234 /*
01235  * Function: DecodePPPoEPkt(Packet *, char *, struct pcap_pkthdr*, u_int8_t*)
01236  *
01237  * Purpose: Decode those fun loving ethernet packets, one at a time!
01238  *
01239  * Arguments: p => pointer to the decoded packet struct
01240  *            user => Utility pointer (unused)
01241  *            pkthdr => ptr to the packet header
01242  *            pkt => pointer to the real live packet data
01243  *
01244  * Returns: void function
01245  *
01246  * see http://www.faqs.org/rfcs/rfc2516.html
01247  *
01248  */
01249 void DecodePPPoEPkt(Packet * p, struct pcap_pkthdr * pkthdr, u_int8_t * pkt)
01250 {
01251     u_int32_t pkt_len;      /* suprisingly, the length of the packet */
01252     u_int32_t cap_len;      /* caplen value */
01253     PPPoEHdr *ppppoep=0;
01254     PPPoE_Tag *ppppoe_tag=0;
01255     PPPoE_Tag tag;  /* needed to avoid alignment problems */
01256 
01257 #ifdef DEBUG
01258     char *buf;
01259     int i;
01260 #endif
01261 
01262     /* set the lengths we need */
01263     pkt_len = pkthdr->len;  /* total packet length */
01264     cap_len = pkthdr->caplen;   /* captured packet length */
01265 
01266     if(snaplen < pkt_len)
01267         pkt_len = cap_len;
01268 
01269     DEBUG_WRAP(DebugMessage(DEBUG_DECODE, "Packet!\n");
01270             DebugMessage(DEBUG_DECODE, "caplen: %lu    pktlen: %lu\n", 
01271                 (unsigned long)cap_len, (unsigned long)pkt_len););
01272 
01273     /* do a little validation */
01274     if(cap_len < PPPOE_HEADER_LEN)
01275     {
01276         if(pv.verbose_flag)
01277         {
01278             ErrorMessage("Captured data length < Ethernet header length! "
01279                          "(%d bytes)\n", p->pkth->caplen);
01280         }
01281         
01282         if((runMode == MODE_IDS) && pv.decoder_flags.decode_alerts)
01283         {
01284             SnortEventqAdd(GENERATOR_SNORT_DECODE, DECODE_BAD_PPPOE, 1, 
01285                     DECODE_CLASS, 3, DECODE_BAD_PPPOE_STR, 0);
01286             if ((InlineMode()) && pv.decoder_flags.drop_alerts)
01287             {
01288               DEBUG_WRAP(DebugMessage(DEBUG_DECODE, "Dropping bad packet\n"););
01289               InlineDrop();
01290             }
01291 
01292         }
01293         
01294         return;
01295     }
01296 
01297     /* XXX - MFR
01298      * This code breaks the decode model that Snort uses, we should 
01299      * reimplement it properly ASAP
01300      */
01301     /*
01302      * Not sure how long ago the above comment was added, but
01303      * it is now fixed.  It may or may not fall under the 'ASAP'
01304      * category.
01305      */
01306 
01307     /* lay the ethernet structure over the packet data */
01308     /* Don't need to do this.  It is already done in the decoding
01309      * of the ethernet header, which then calls this function for
01310      * PPP over Ethernet.
01311     p->eh = (EtherHdr *) pkt;
01312      */
01313 
01314     DEBUG_WRAP(DebugMessage(DEBUG_DECODE, "%X   %X\n", 
01315                 *p->eh->ether_src, *p->eh->ether_dst););
01316 
01317     /* lay the PPP over ethernet structure over the packet data */
01318     ppppoep = p->pppoeh = (PPPoEHdr *)pkt;
01319 
01320     /* grab out the network type */
01321     switch(ntohs(p->eh->ether_type))
01322     {
01323         case ETHERNET_TYPE_PPPoE_DISC:
01324             DEBUG_WRAP(DebugMessage(DEBUG_DECODE, "(PPPOE Discovery) "););
01325             break;
01326 
01327         case ETHERNET_TYPE_PPPoE_SESS:
01328             DEBUG_WRAP(DebugMessage(DEBUG_DECODE, "(PPPOE Session) "););
01329             break;
01330 
01331         default:
01332             return;
01333     }
01334 
01335 #ifdef DEBUG
01336     switch(ppppoep->code)
01337     {
01338         case PPPoE_CODE_PADI:
01339             /* The Host sends the PADI packet with the DESTINATION_ADDR set 
01340              * to the broadcast address.  The CODE field is set to 0x09 and
01341              * the SESSION_ID MUST be set to 0x0000.
01342              *
01343              * The PADI packet MUST contain exactly one TAG of TAG_TYPE 
01344              * Service-Name, indicating the service the Host is requesting, 
01345              * and any number of other TAG types.  An entire PADI packet 
01346              * (including the PPPoE header) MUST NOT exceed 1484 octets so 
01347              * as to leave sufficient room for a relay agent to add a 
01348              * Relay-Session-Id TAG.
01349              */ 
01350             DebugMessage(DEBUG_DECODE, "Active Discovery Initiation (PADI)\n");
01351             break;
01352 
01353         case PPPoE_CODE_PADO:
01354             /* When the Access Concentrator receives a PADI that it can 
01355              * serve, it replies by sending a PADO packet.  The 
01356              * DESTINATION_ADDR is the unicast address of the Host that 
01357              * sent the PADI.  The CODE field is set to 0x07 and the 
01358              * SESSION_ID MUST be set to 0x0000.  
01359              * 
01360              * The PADO packet MUST contain one AC-Name TAG containing the 
01361              * Access Concentrator's name, a Service-Name TAG identical to 
01362              * the one in the PADI, and any number of other Service-Name 
01363              * TAGs indicating other services that the Access Concentrator 
01364              * offers.  If the Access Concentrator can not serve the PADI 
01365              * it MUST NOT respond with a PADO.
01366              */ 
01367             DebugMessage(DEBUG_DECODE, "Active Discovery Offer (PADO)\n");
01368             break;
01369 
01370         case PPPoE_CODE_PADR:
01371             /* Since the PADI was broadcast, the Host may receive more than 
01372              * one PADO.  The Host looks through the PADO packets it receives 
01373              * and chooses one.  The choice can be based on the AC-Name or 
01374              * the Services offered.  The Host then sends one PADR packet 
01375              * to the Access Concentrator that it has chosen.  The 
01376              * DESTINATION_ADDR field is set to the unicast Ethernet address 
01377              * of the Access Concentrator that sent the PADO.  The CODE 
01378              * field is set to 0x19 and the SESSION_ID MUST be set to 0x0000.
01379              *
01380              * The PADR packet MUST contain exactly one TAG of TAG_TYPE 
01381              * Service-Name, indicating the service the Host is requesting, 
01382              * and any number of other TAG types.
01383              */ 
01384             DebugMessage(DEBUG_DECODE, "Active Discovery Request (PADR)\n");
01385             break;
01386 
01387         case PPPoE_CODE_PADS:
01388             /* When the Access Concentrator receives a PADR packet, it 
01389              * prepares to begin a PPP session.  It generates a unique 
01390              * SESSION_ID for the PPPoE session and replies to the Host with 
01391              * a PADS packet.  The DESTINATION_ADDR field is the unicast 
01392              * Ethernet address of the Host that sent the PADR.  The CODE 
01393              * field is set to 0x65 and the SESSION_ID MUST be set to the 
01394              * unique value generated for this PPPoE session.
01395              *
01396              * The PADS packet contains exactly one TAG of TAG_TYPE 
01397              * Service-Name, indicating the service under which Access 
01398              * Concentrator has accepted the PPPoE session, and any number 
01399              * of other TAG types.
01400              *
01401              * If the Access Concentrator does not like the Service-Name in 
01402              * the PADR, then it MUST reply with a PADS containing a TAG of 
01403              * TAG_TYPE Service-Name-Error (and any number of other TAG 
01404              * types).  In this case the SESSION_ID MUST be set to 0x0000.
01405              */ 
01406             DebugMessage(DEBUG_DECODE, "Active Discovery "
01407                          "Session-confirmation (PADS)\n");
01408             break;
01409 
01410         case PPPoE_CODE_PADT:
01411             /* This packet may be sent anytime after a session is established 
01412              * to indicate that a PPPoE session has been terminated.  It may 
01413              * be sent by either the Host or the Access Concentrator.  The 
01414              * DESTINATION_ADDR field is a unicast Ethernet address, the 
01415              * CODE field is set to 0xa7 and the SESSION_ID MUST be set to 
01416              * indicate which session is to be terminated.  No TAGs are 
01417              * required.  
01418              *
01419              * When a PADT is received, no further PPP traffic is allowed to 
01420              * be sent using that session.  Even normal PPP termination 
01421              * packets MUST NOT be sent after sending or receiving a PADT.  
01422              * A PPP peer SHOULD use the PPP protocol itself to bring down a 
01423              * PPPoE session, but the PADT MAY be used when PPP can not be 
01424              * used.
01425              */ 
01426             DebugMessage(DEBUG_DECODE, "Active Discovery Terminate (PADT)\n");
01427             break;
01428 
01429         case PPPoE_CODE_SESS: 
01430             DebugMessage(DEBUG_DECODE, "Session Packet (SESS)\n");
01431             break;
01432 
01433         default:
01434             DebugMessage(DEBUG_DECODE, "(Unknown)\n");
01435             break;
01436     }
01437 #endif
01438 
01439     if (ntohs(p->eh->ether_type) != ETHERNET_TYPE_PPPoE_DISC)
01440     {
01441         DecodePppPktEncapsulated(p, cap_len - PPPOE_HEADER_LEN, pkt + PPPOE_HEADER_LEN);
01442         return;
01443     }
01444     else
01445     {
01446         DEBUG_WRAP(DebugMessage(DEBUG_DECODE, "Returning early on PPPOE discovery packet\n"););
01447         return;
01448     }
01449 
01450     ppppoe_tag = (PPPoE_Tag *)(pkt + sizeof(PPPoEHdr));
01451 
01452     while (ppppoe_tag < (PPPoE_Tag *)(pkt + pkthdr->caplen))
01453     {
01454         /* no guarantee in PPPoE spec that ppppoe_tag is aligned at all... */
01455         memcpy(&tag, ppppoe_tag, sizeof(tag));
01456 
01457         DEBUG_WRAP(
01458                 DebugMessage(DEBUG_DECODE, "\tPPPoE tag:\ntype: %04x length: %04x ", 
01459                     ntohs(tag.type), ntohs(tag.length)););
01460 
01461 #ifdef DEBUG
01462         switch(ntohs(tag.type))
01463         {
01464             case PPPoE_TAG_END_OF_LIST:
01465                 DebugMessage(DEBUG_DECODE, "(End of list)\n\t");
01466                 break;
01467             case PPPoE_TAG_SERVICE_NAME:
01468                 DebugMessage(DEBUG_DECODE, "(Service name)\n\t");
01469                 break;
01470             case PPPoE_TAG_AC_NAME:
01471                 DebugMessage(DEBUG_DECODE, "(AC Name)\n\t");
01472                 break;
01473             case PPPoE_TAG_HOST_UNIQ:
01474                 DebugMessage(DEBUG_DECODE, "(Host Uniq)\n\t");
01475                 break;
01476             case PPPoE_TAG_AC_COOKIE:
01477                 DebugMessage(DEBUG_DECODE, "(AC Cookie)\n\t");
01478                 break;
01479             case PPPoE_TAG_VENDOR_SPECIFIC:
01480                 DebugMessage(DEBUG_DECODE, "(Vendor Specific)\n\t");
01481                 break;
01482             case PPPoE_TAG_RELAY_SESSION_ID:
01483                 DebugMessage(DEBUG_DECODE, "(Relay Session ID)\n\t");
01484                 break;
01485             case PPPoE_TAG_SERVICE_NAME_ERROR:
01486                 DebugMessage(DEBUG_DECODE, "(Service Name Error)\n\t");
01487                 break;
01488             case PPPoE_TAG_AC_SYSTEM_ERROR:
01489                 DebugMessage(DEBUG_DECODE, "(AC System Error)\n\t");
01490                 break;
01491             case PPPoE_TAG_GENERIC_ERROR:
01492                 DebugMessage(DEBUG_DECODE, "(Generic Error)\n\t");
01493                 break;
01494             default:
01495                 DebugMessage(DEBUG_DECODE, "(Unknown)\n\t");
01496                 break;
01497         }
01498 #endif
01499 
01500         if (ntohs(tag.length) > 0)
01501         {
01502 #ifdef DEBUG
01503             switch (ntohs(tag.type))
01504             {
01505                 case PPPoE_TAG_SERVICE_NAME:
01506                 case PPPoE_TAG_AC_NAME:
01507                 case PPPoE_TAG_SERVICE_NAME_ERROR:
01508                 case PPPoE_TAG_AC_SYSTEM_ERROR:
01509                 case PPPoE_TAG_GENERIC_ERROR: /* ascii data */
01510                     buf = (char *) calloc(ntohs(tag.length) + 1, sizeof(char));
01511                     strlcpy(buf, (char *)(ppppoe_tag+1), ntohs(tag.length));
01512                     DebugMessage(DEBUG_DECODE, "data (UTF-8): %s\n", buf);
01513                     free(buf);
01514                     break;
01515 
01516                 case PPPoE_TAG_HOST_UNIQ:
01517                 case PPPoE_TAG_AC_COOKIE:
01518                 case PPPoE_TAG_RELAY_SESSION_ID:
01519                     DebugMessage(DEBUG_DECODE, "data (bin): ");
01520                     for (i = 0; i < ntohs(tag.length); i++)
01521                         DebugMessage(DEBUG_DECODE,
01522                                 "%02x", *(((unsigned char *)ppppoe_tag) + 
01523                                     sizeof(PPPoE_Tag) + i));
01524                     DebugMessage(DEBUG_DECODE, "\n");
01525                     break;
01526 
01527                 default:
01528                     DebugMessage(DEBUG_DECODE, "unrecognized data\n");
01529                     break;
01530             }
01531 #endif
01532         }
01533 
01534         ppppoe_tag = (PPPoE_Tag *)((char *)(ppppoe_tag+1)+ntohs(tag.length));
01535     }
01536 
01537     return;
01538 }
01539 
01540 
01541 /*
01542  * Function: DecodePppPktEncapsulated(Packet *, const u_int32_t len, u_int8_t*)
01543  *
01544  * Purpose: Decode PPP traffic (RFC1661 framing).
01545  *
01546  * Arguments: p => pointer to decoded packet struct 
01547  *            len => length of data to process
01548  *            pkt => pointer to the real live packet data
01549  *
01550  * Returns: void function
01551  */
01552 void DecodePppPktEncapsulated(Packet * p, const u_int32_t len, u_int8_t * pkt)
01553 {
01554     static int had_vj = 0;
01555     u_int16_t protocol;
01556     u_int32_t hlen = 1; /* HEADER - try 1 then 2 */    
01557     
01558     DEBUG_WRAP(DebugMessage(DEBUG_DECODE, "Packet!\n"););
01559 
01560     /* do a little validation:
01561      * 
01562      */
01563     if(len < 2)
01564     {
01565         if(pv.verbose_flag)
01566         {
01567             ErrorMessage("Length not big enough for even a single "
01568                          "header or a one byte payload\n");
01569         }
01570         return;
01571     }
01572 
01573     
01574     if(pkt[0] & 0x01)
01575     {
01576         /* Check for protocol compression rfc1661 section 5
01577          *
01578          */
01579         hlen = 1;
01580         protocol = pkt[0];
01581     }
01582     else
01583     {
01584         protocol = ntohs(*((u_int16_t *)pkt));
01585         hlen = 2;
01586     }
01587     
01588     /* 
01589      * We only handle uncompressed packets. Handling VJ compression would mean
01590      * to implement a PPP state machine.
01591      */
01592     switch (protocol) 
01593     {
01594         case PPP_VJ_COMP:
01595             if (!had_vj)
01596                 ErrorMessage("PPP link seems to use VJ compression, "
01597                         "cannot handle compressed packets!\n");
01598             had_vj = 1;
01599             break;
01600         case PPP_VJ_UCOMP:
01601             /* VJ compression modifies the protocol field. It must be set
01602              * to tcp (only TCP packets can be VJ compressed) */
01603             if(len < (hlen + IP_HEADER_LEN))
01604             {
01605                 if(pv.verbose_flag)
01606                     ErrorMessage("PPP VJ min packet length > captured len! "
01607                                  "(%d bytes)\n", len);
01608                 return;
01609             }
01610 
01611             ((IPHdr *)(pkt + hlen))->ip_proto = IPPROTO_TCP;
01612             /* fall through */
01613 
01614         case PPP_IP:
01615             DecodeIP(pkt + hlen, len - hlen, p);
01616             break;
01617 
01618         case PPP_IPX:
01619             DecodeIPX(pkt + hlen, len - hlen);
01620             break;
01621     }
01622 }
01623 
01624 
01625 /*
01626  * Function: DecodePppPkt(Packet *, char *, struct pcap_pkthdr*, u_int8_t*)
01627  *
01628  * Purpose: Decode PPP traffic (either RFC1661 or RFC1662 framing).
01629  *          This really is intended to handle IPCP
01630  *
01631  * Arguments: p => pointer to decoded packet struct 
01632  *            user => Utility pointer, unused
01633  *            pkthdr => ptr to the packet header
01634  *            pkt => pointer to the real live packet data
01635  *
01636  * Returns: void function
01637  */
01638 void DecodePppPkt(Packet * p, struct pcap_pkthdr * pkthdr, u_int8_t * pkt)
01639 {
01640     int hlen = 0;
01641 
01642     bzero((char *) p, sizeof(Packet));
01643 
01644     p->pkth = pkthdr;
01645     p->pkt = pkt;
01646 
01647     DEBUG_WRAP(DebugMessage(DEBUG_DECODE, "Packet!\n"););
01648 
01649     if(p->pkth->caplen < 2)
01650     {
01651         if(pv.verbose_flag)
01652         {
01653             ErrorMessage("Length not big enough for even a single "
01654                          "header or a one byte payload\n");
01655         }
01656         return;
01657     }
01658 
01659     if(pkt[0] == CHDLC_ADDR_BROADCAST && pkt[1] == CHDLC_CTRL_UNNUMBERED)
01660     {
01661         /*
01662          * Check for full HDLC header (rfc1662 section 3.2)
01663          */
01664         hlen = 2;
01665     }
01666 
01667     DecodePppPktEncapsulated(p, p->pkth->caplen - hlen, p->pkt + hlen);
01668 
01669     return;
01670 }
01671 
01672 
01673 /*
01674  * Function: DecodePppSerialPkt(Packet *, char *, struct pcap_pkthdr*, u_int8_t*)
01675  *
01676  * Purpose: Decode Mixed PPP/CHDLC traffic. The PPP frames will always have the
01677  *          full HDLC header.
01678  *
01679  * Arguments: p => pointer to decoded packet struct 
01680  *            user => Utility pointer, unused
01681  *            pkthdr => ptr to the packet header
01682  *            pkt => pointer to the real live packet data
01683  *
01684  * Returns: void function
01685  */
01686 void DecodePppSerialPkt(Packet * p, struct pcap_pkthdr * pkthdr, u_int8_t * pkt)
01687 {
01688     bzero((char *) p, sizeof(Packet));
01689 
01690     p->pkth = pkthdr;
01691     p->pkt = pkt;
01692 
01693     DEBUG_WRAP(DebugMessage(DEBUG_DECODE, "Packet!\n"););
01694 
01695     if(p->pkth->caplen < PPP_HDRLEN)
01696     {
01697         if(pv.verbose_flag)
01698         {
01699             ErrorMessage("Captured data length < PPP header length"
01700                          " (%d bytes)\n", p->pkth->caplen);
01701         }
01702         return;
01703     }
01704 
01705     if(pkt[0] == CHDLC_ADDR_BROADCAST && pkt[1] == CHDLC_CTRL_UNNUMBERED)
01706     {
01707         DecodePppPktEncapsulated(p, p->pkth->caplen - 2, p->pkt + 2);
01708     } else {
01709         DecodeChdlcPkt(p, pkthdr, pkt);
01710     }
01711 
01712     return;
01713 }
01714 
01715 
01716 /*
01717  * Function: DecodeSlipPkt(Packet *, char *, struct pcap_pkthdr*, u_int8_t*)
01718  *
01719  * Purpose: Decode SLIP traffic
01720  *
01721  * Arguments: p => pointer to decoded packet struct 
01722  *            user => Utility pointer, unused
01723  *            pkthdr => ptr to the packet header
01724  *            pkt => pointer to the real live packet data
01725  *
01726  * Returns: void function
01727  */
01728 void DecodeSlipPkt(Packet * p, struct pcap_pkthdr * pkthdr, u_int8_t * pkt)
01729 {
01730     u_int32_t len;
01731     u_int32_t cap_len;
01732 
01733     bzero((char *) p, sizeof(Packet));
01734 
01735     p->pkth = pkthdr;
01736     p->pkt = pkt;
01737 
01738     len = pkthdr->len;
01739     cap_len = pkthdr->caplen;
01740 
01741     DEBUG_WRAP(DebugMessage(DEBUG_DECODE, "Packet!\n"););
01742 
01743     /* do a little validation */
01744     if(cap_len < SLIP_HEADER_LEN)
01745     {
01746         ErrorMessage("SLIP header length < captured len! (%d bytes)\n",
01747                      cap_len);
01748         return;
01749     }
01750 
01751     DecodeIP(p->pkt + SLIP_HEADER_LEN, cap_len - SLIP_HEADER_LEN, p);
01752 }
01753 
01754 
01755 
01756 /*
01757  * Function: DecodeRawPkt(Packet *, char *, struct pcap_pkthdr*, u_int8_t*)
01758  *
01759  * Purpose: Decodes packets coming in raw on layer 2, like PPP.  Coded and
01760  *          in by Jed Pickle (thanks Jed!) and modified for a few little tweaks
01761  *          by me.
01762  *
01763  * Arguments: p => pointer to decoded packet struct 
01764  *            user => Utility pointer, unused
01765  *            pkthdr => ptr to the packet header
01766  *            pkt => pointer to the real live packet data
01767  *
01768  * Returns: void function
01769  */
01770 void DecodeRawPkt(Packet * p, struct pcap_pkthdr * pkthdr, u_int8_t * pkt)
01771 {
01772     bzero((char *) p, sizeof(Packet));
01773 
01774     p->pkth = pkthdr;
01775     p->pkt = pkt;
01776 
01777     DEBUG_WRAP(DebugMessage(DEBUG_DECODE, "Packet!\n"););
01778 
01779     DecodeIP(pkt, p->pkth->caplen, p);
01780 
01781     return;
01782 }
01783 
01784 
01785 
01786 /*
01787  * Function: DecodeI4LRawIPPkt(Packet *, char *, struct pcap_pkthdr*, u_int8_t*)
01788  *
01789  * Purpose: Decodes packets coming in raw on layer 2, like PPP.  Coded and
01790  *          in by Jed Pickle (thanks Jed!) and modified for a few little tweaks
01791  *          by me.
01792  *
01793  * Arguments: p => pointer to decoded packet struct
01794  *            user => Utility pointer, unused
01795  *            pkthdr => ptr to the packet header
01796  *            pkt => pointer to the real live packet data
01797  *
01798  * Returns: void function
01799  */
01800 void DecodeI4LRawIPPkt(Packet * p, struct pcap_pkthdr * pkthdr, u_int8_t * pkt)
01801 {
01802     bzero((char *) p, sizeof(Packet));
01803 
01804     p->pkth = pkthdr;
01805     p->pkt = pkt;
01806 
01807     if(p->pkth->len < 2)
01808     {
01809         DEBUG_WRAP(DebugMessage(DEBUG_DECODE, "What the hell is this?\n"););
01810         pc.other++;
01811         return;
01812     }
01813 
01814     DEBUG_WRAP(DebugMessage(DEBUG_DECODE, "Packet!\n"););
01815     DecodeIP(pkt + 2, p->pkth->len - 2, p);
01816 
01817     return;
01818 }
01819 
01820 
01821 
01822 /*
01823  * Function: DecodeI4LCiscoIPPkt(Packet *, char *, 
01824  *                               struct pcap_pkthdr*, u_int8_t*)
01825  *
01826  * Purpose: Decodes packets coming in raw on layer 2, like PPP.  Coded and
01827  *          in by Jed Pickle (thanks Jed!) and modified for a few little tweaks
01828  *          by me.
01829  *
01830  * Arguments: p => pointer to decoded packet struct 
01831  *            user => Utility pointer, unused
01832  *            pkthdr => ptr to the packet header
01833  *            pkt => pointer to the real live packet data
01834  *
01835  * Returns: void function
01836  */
01837 void DecodeI4LCiscoIPPkt(Packet *p, struct pcap_pkthdr *pkthdr, u_int8_t *pkt)
01838 {
01839     bzero((char *) p, sizeof(Packet));
01840 
01841     p->pkth = pkthdr;
01842     p->pkt = pkt;
01843 
01844     if(p->pkth->len < 4)
01845     {
01846         DEBUG_WRAP(DebugMessage(DEBUG_DECODE, "What the hell is this?\n"););
01847         pc.other++;
01848         return;
01849     }
01850 
01851 
01852     DEBUG_WRAP(DebugMessage(DEBUG_DECODE, "Packet!\n"););
01853 
01854     DecodeIP(pkt + 4, p->pkth->caplen - 4, p);
01855 
01856     return;
01857 }
01858 
01859 /*
01860  * Function: DecodeChdlcPkt(Packet *, char *, 
01861  *                               struct pcap_pkthdr*, u_int8_t*)
01862  *
01863  * Purpose: Decodes Cisco HDLC encapsulated packets, f.ex. from SONET.
01864  *
01865  * Arguments: p => pointer to decoded packet struct 
01866  *            user => Utility pointer, unused
01867  *            pkthdr => ptr to the packet header
01868  *            pkt => pointer to the real live packet data
01869  *
01870  * Returns: void function
01871  */
01872 void DecodeChdlcPkt(Packet *p, struct pcap_pkthdr *pkthdr, u_int8_t *pkt)
01873 {
01874     bzero((char *) p, sizeof(Packet));
01875 
01876     p->pkth = pkthdr;
01877     p->pkt = pkt;
01878 
01879     if(p->pkth->caplen < CHDLC_HEADER_LEN)
01880     {
01881         if(pv.verbose_flag)
01882         {
01883             ErrorMessage("Captured data length < CHDLC header length"
01884                          " (%d bytes)\n", p->pkth->caplen);
01885         }
01886         return;
01887     }
01888 
01889     DEBUG_WRAP(DebugMessage(DEBUG_DECODE, "Packet!\n"););
01890 
01891     if ((pkt[0] == CHDLC_ADDR_UNICAST || pkt[0] == CHDLC_ADDR_MULTICAST) &&
01892            ntohs((u_int16_t)(pkt[2] | pkt[3] << 8)) == ETHERNET_TYPE_IP)
01893     {
01894         DecodeIP(p->pkt + CHDLC_HEADER_LEN,
01895                  p->pkth->caplen - CHDLC_HEADER_LEN, p);
01896     } else {
01897         pc.other++;
01898     }
01899 
01900     return;
01901 }
01902 
01903 /*
01904  * Some IP Header tests
01905  * Land Attack(same src/dst ip)
01906  * Loopback (src or dst in 127/8 block)
01907  * Modified: 2/22/05-man for High Endian Architecture.
01908  */
01909 void IPHdrTests( IPHdr * p )
01910 {
01911     /* Land attack */
01912     if( p->ip_src.s_addr == p->ip_dst.s_addr )
01913     {
01914         if((runMode == MODE_IDS) && pv.decoder_flags.decode_alerts)
01915         {
01916             SnortEventqAdd(GENERATOR_SNORT_DECODE, 
01917                     DECODE_BAD_TRAFFIC_SAME_SRCDST, 1, DECODE_CLASS, 3, 
01918                     DECODE_BAD_TRAFFIC_SAME_SRCDST_STR, 0);
01919             if ((InlineMode()) && pv.decoder_flags.drop_alerts)
01920             {
01921                DEBUG_WRAP(DebugMessage(DEBUG_DECODE, "Dropping bad packet"
01922                            "-- same IP\n"););
01923                InlineDrop();
01924             }
01925         }
01926     }
01927     
01928     /* Loopback traffic  - don't use htonl for speed reasons - s_addr is always in network order */
01929 #ifdef WORDS_BIGENDIAN
01930     if( (p->ip_src.s_addr & 0xff000000) == 0x7f000000  || (p->ip_dst.s_addr & 0xff000000 ) == 0x7f000000 )/* BE */
01931 #else
01932     if( (p->ip_src.s_addr & 0xff) == 0x7f || (p->ip_dst.s_addr & 0xff ) == 0x7f ) /* LE */
01933 #endif
01934     {
01935         if((runMode == MODE_IDS) && pv.decoder_flags.decode_alerts)
01936         {
01937             SnortEventqAdd(GENERATOR_SNORT_DECODE, 
01938                     DECODE_BAD_TRAFFIC_LOOPBACK, 1, DECODE_CLASS, 3, 
01939                     DECODE_BAD_TRAFFIC_LOOPBACK_STR, 0);
01940             if ((InlineMode()) && pv.decoder_flags.drop_alerts)
01941             {
01942                DEBUG_WRAP(DebugMessage(DEBUG_DECODE, "Dropping bad packet"
01943                            "-- loopback\n"););
01944                InlineDrop();
01945             }
01946         }
01947     }
01948 }
01949 
01950 #ifdef DLT_ENC
01951 /* see http://sourceforge.net/mailarchive/message.php?msg_id=1000380 */
01952 /*
01953  * Function: DecodeEncPkt(Packet *, struct pcap_pkthdr *, u_int8_t *)
01954  *
01955  * Purpose: Decapsulate packets of type DLT_ENC.
01956  *          XXX Are these always going to be IP in IP?
01957  *
01958  * Arguments: p => pointer to decoded packet struct
01959  *            pkthdr => pointer to the packet header
01960  *            pkt => pointer to the real live packet data
01961  */
01962 void DecodeEncPkt(Packet *p, struct pcap_pkthdr *pkthdr, u_int8_t *pkt)
01963 {
01964     struct enc_header *enc_h;
01965 
01966     bzero((char *)p, sizeof(Packet));
01967     p->pkth = pkthdr;
01968     p->pkt = pkt;
01969 
01970     if (p->pkth->caplen < ENC_HEADER_LEN)
01971     {
01972         if (pv.verbose_flag)
01973         {
01974             ErrorMessage("Captured data length < Encap header length!  (%d bytes)\n", p->pkth->caplen);
01975         }
01976         return;
01977     }
01978 
01979     enc_h = (struct enc_header *)p->pkt;
01980     if (enc_h->af == AF_INET)
01981     {
01982         DecodeIP(p->pkt + ENC_HEADER_LEN + IP_HEADER_LEN,
01983                  pkthdr->caplen - ENC_HEADER_LEN - IP_HEADER_LEN, p);
01984     }
01985     else
01986     {
01987         ErrorMessage("[!] WARNING: Unknown address family! (af: 0x%x)\n",
01988                 enc_h->af);
01989     }
01990     return;
01991 }
01992 #endif /* DLT_ENC */
01993 
01994 /*
01995  * Function: DecodeIP(u_int8_t *, const u_int32_t, Packet *)
01996  *
01997  * Purpose: Decode the IP network layer
01998  *
01999  * Arguments: pkt => ptr to the packet data
02000  *            len => length from here to the end of the packet
02001  *            p   => pointer to the packet decode struct
02002  *
02003  * Returns: void function
02004  */
02005 void DecodeIP(u_int8_t * pkt, const u_int32_t len, Packet * p)
02006 {
02007     u_int32_t ip_len; /* length from the start of the ip hdr to the pkt end */
02008     u_int32_t hlen;   /* ip header length */
02009 #ifndef IPFW
02010     u_int16_t csum;   /* checksum */
02011 #endif
02012 
02013     /* lay the IP struct over the raw data */
02014     p->iph = (IPHdr *) pkt;
02015 
02016     DEBUG_WRAP(DebugMessage(DEBUG_DECODE, "Packet!\n"););
02017 
02018     /* do a little validation */
02019     if(len < IP_HEADER_LEN)
02020     {
02021         if(pv.verbose_flag)
02022         {
02023             ErrorMessage("IP header truncated! (%d bytes)\n", len);
02024         }
02025         p->iph = NULL;
02026 
02027         return;
02028     }
02029 
02030     /*
02031      * with datalink DLT_RAW it's impossible to differ ARP datagrams from IP.
02032      * So we are just ignoring non IP datagrams
02033      */
02034     if(IP_VER(p->iph) != 4)
02035     {
02036         if(pv.verbose_flag)
02037         {
02038             ErrorMessage("Not IPv4 datagram! "
02039                     "([ver: 0x%x][len: 0x%x])\n", 
02040                     IP_VER(p->iph), p->iph->ip_len);
02041         }
02042         if((runMode == MODE_IDS) && pv.decoder_flags.decode_alerts)
02043         {
02044             SnortEventqAdd(GENERATOR_SNORT_DECODE, DECODE_NOT_IPV4_DGRAM, 1,
02045                     DECODE_CLASS, 3, DECODE_NOT_IPV4_DGRAM_STR, 0);
02046             if ((InlineMode()) && pv.decoder_flags.drop_alerts)
02047             {
02048                 DEBUG_WRAP(DebugMessage(DEBUG_DECODE, "Dropping bad packet\n"););
02049                 InlineDrop();
02050             }
02051         }
02052         p->iph = NULL;
02053         pc.discards++;
02054 
02055         return;
02056     }
02057 
02058     /* set the IP datagram length */
02059     ip_len = ntohs(p->iph->ip_len);
02060 
02061     /* set the IP header length */
02062     hlen = IP_HLEN(p->iph) << 2;
02063 
02064 
02065     /* header length sanity check */
02066     if(hlen < IP_HEADER_LEN)
02067     {
02068 #ifdef DEBUG
02069         if(pv.verbose_flag)
02070             ErrorMessage("Bogus IP header length of %i bytes\n", 
02071                     hlen);
02072 #endif
02073         if((runMode == MODE_IDS) && pv.decoder_flags.decode_alerts) 
02074         {
02075             SnortEventqAdd(GENERATOR_SNORT_DECODE, 
02076                     DECODE_IPV4_INVALID_HEADER_LEN, 1, DECODE_CLASS, 3, 
02077                     DECODE_IPV4_INVALID_HEADER_LEN_STR, 0);
02078             if ((InlineMode()) && pv.decoder_flags.drop_alerts)
02079             {
02080                 DEBUG_WRAP(DebugMessage(DEBUG_DECODE, "Dropping bad packet\n"););
02081                 InlineDrop();
02082             }
02083 
02084         }
02085 
02086 
02087         p->iph = NULL;
02088         pc.discards++;
02089         return;
02090     }
02091 
02092     if (ip_len != len)
02093     {
02094         if (ip_len > len) 
02095         {
02096 #ifdef DEBUG
02097             if (pv.verbose_flag)
02098                 ErrorMessage("IP Len field is %d bytes bigger"
02099                         " than captured length.\n"
02100                         "    (ip.len: %lu, cap.len: %lu)\n",
02101                         ip_len - len, ip_len, len);
02102 #endif
02103             ip_len = len;
02104         }
02105         else
02106         {
02107 #ifdef DEBUG
02108             if (pv.verbose_flag)
02109                 ErrorMessage("IP Len field is %d bytes "
02110                         "smaller than captured length.\n"
02111                         "    (ip.len: %lu, cap.len: %lu)\n",
02112                         len - ip_len, ip_len, len);
02113 #endif
02114 
02115         }
02116     }
02117 
02118     if(ip_len < hlen)
02119     {
02120         if(pv.verbose_flag)
02121         {
02122             ErrorMessage("IP dgm len (%d bytes) < IP hdr "
02123                     "len (%d bytes), packet discarded\n", ip_len, hlen);
02124         }
02125 
02126         if((runMode == MODE_IDS) && pv.decoder_flags.decode_alerts) 
02127         {
02128             SnortEventqAdd(GENERATOR_SNORT_DECODE, DECODE_IPV4_DGRAM_LT_IPHDR, 
02129                     1, DECODE_CLASS, 3, DECODE_IPV4_DGRAM_LT_IPHDR_STR, 0);
02130             if ((InlineMode()) && pv.decoder_flags.drop_alerts)
02131             { 
02132                 DEBUG_WRAP(DebugMessage(DEBUG_DECODE, "Dropping bad packet\n"););
02133                 InlineDrop();
02134             }
02135 
02136         }
02137 
02138         p->iph = NULL;
02139         pc.discards++;
02140         return;
02141     }
02142 
02143 
02144     /* 
02145      * IP Header tests: Land attack, and Loop back test 
02146      */
02147     if((runMode == MODE_IDS) && pv.decoder_flags.decode_alerts) 
02148     {
02149         IPHdrTests( p->iph );
02150     }
02151 
02152 #ifndef IPFW
02153     if(pv.checksums_mode & DO_IP_CHECKSUMS)
02154     {
02155         /* routers drop packets with bad IP checksums, we don't really 
02156          * need to check them (should make this a command line/config
02157          * option
02158          */
02159         csum = in_chksum_ip((u_short *)p->iph, hlen);
02160 
02161         if(csum)
02162         {
02163             p->csum_flags |= CSE_IP;
02164             DEBUG_WRAP(DebugMessage(DEBUG_DECODE, "Bad IP checksum\n"););
02165 
02166             if(InlineMode())
02167             {
02168                 DEBUG_WRAP(DebugMessage(DEBUG_DECODE, 
02169                             "Dropping packet with Bad IP checksum\n"););
02170                 InlineDrop();
02171             }
02172         }
02173 #ifdef DEBUG
02174         else
02175         {
02176             DebugMessage(DEBUG_DECODE, "IP Checksum: OK\n");
02177         }
02178 #endif /* DEBUG */
02179     }
02180 #endif /* IPFW */
02181 
02182     /* test for IP options */
02183     p->ip_options_len = hlen - IP_HEADER_LEN;
02184 
02185     if(p->ip_options_len > 0)
02186     {
02187         p->ip_options_data = pkt + IP_HEADER_LEN;
02188         DecodeIPOptions((pkt + IP_HEADER_LEN), p->ip_options_len, p);
02189     }
02190     else
02191     {
02192         p->ip_option_count = 0;
02193     }
02194 
02195     /* set the real IP length for logging */
02196     p->actual_ip_len = (u_int16_t) ip_len;
02197 
02198     /* set the remaining packet length */
02199     ip_len -= hlen;
02200 
02201     /* check for fragmented packets */
02202     p->frag_offset = ntohs(p->iph->ip_off);
02203 
02204     /* 
02205      * get the values of the reserved, more 
02206      * fragments and don't fragment flags 
02207      */
02208     p->rf = (u_int8_t)((p->frag_offset & 0x8000) >> 15);
02209     p->df = (u_int8_t)((p->frag_offset & 0x4000) >> 14);
02210     p->mf = (u_int8_t)((p->frag_offset & 0x2000) >> 13);
02211 
02212     /* mask off the high bits in the fragment offset field */
02213     p->frag_offset &= 0x1FFF;
02214 
02215     if(p->frag_offset || p->mf)
02216     {
02217         /* set the packet fragment flag */
02218         p->frag_flag = 1;
02219         pc.frags++;
02220     }
02221 
02222     /* if this packet isn't a fragment
02223      * or if it is, its a UDP packet and offset isn't 0 */
02224     if(!(p->frag_flag) || 
02225             (p->frag_flag && (p->frag_offset == 0) && (p->iph->ip_proto == IPPROTO_UDP)))
02226     {
02227         DEBUG_WRAP(DebugMessage(DEBUG_DECODE, "IP header length: %lu\n", 
02228                     (unsigned long)hlen););
02229 
02230         switch(p->iph->ip_proto)
02231         {
02232             case IPPROTO_TCP:
02233                 pc.tcp++;
02234                 DecodeTCP(pkt + hlen, ip_len, p);
02235                 ClearDumpBuf();
02236                 return;
02237 
02238             case IPPROTO_UDP:
02239                 pc.udp++;
02240                 DecodeUDP(pkt + hlen, ip_len, p);
02241                 ClearDumpBuf();
02242                 return;
02243 
02244             case IPPROTO_ICMP:
02245                 pc.icmp++;
02246                 DecodeICMP(pkt + hlen, ip_len, p);
02247                 ClearDumpBuf();
02248                 return;
02249 
02250             default:
02251                 pc.other++;
02252                 p->data = pkt + hlen;
02253                 p->dsize = (u_short) ip_len;
02254                 ClearDumpBuf();
02255                 return;
02256         }
02257     }
02258     else
02259     {
02260         /* set the payload pointer and payload size */
02261         p->data = pkt + hlen;
02262         p->dsize = (u_short) ip_len;
02263     }
02264 }
02265 
02266 /*
02267  * Function: DecodeIPOnly(u_int8_t *, const u_int32_t, Packet *)
02268  *
02269  * Purpose: Decode the IP network layer but not recurse
02270  *
02271  * Arguments: pkt => ptr to the packet data
02272  *            len => length from here to the end of the packet
02273  *            p   => pointer to dummy packet decode struct
02274  *
02275  * Returns: void function
02276  */
02277 int DecodeIPOnly(u_int8_t * pkt, const u_int32_t len, Packet * p)
02278 {
02279     u_int32_t ip_len;       /* length from the start of the ip hdr to the
02280                              * pkt end */
02281     u_int32_t hlen;             /* ip header length */
02282 
02283     /* lay the IP struct over the raw data */
02284     p->orig_iph = (IPHdr *) pkt;
02285 
02286     DEBUG_WRAP(DebugMessage(DEBUG_DECODE, "DecodeIPOnly: ip header starts at: %p, "
02287                 "length is %lu\n", p->orig_iph, (unsigned long) len););
02288 
02289     /* do a little validation */
02290     if(len < IP_HEADER_LEN)
02291     {
02292         if(pv.verbose_flag)
02293         {
02294             ErrorMessage("ICMP Unreachable IP short header (%d bytes)\n", len);
02295         }
02296         p->orig_iph = NULL;
02297         return(0);
02298     }
02299 
02300     /*
02301      * with datalink DLT_RAW it's impossible to differ ARP datagrams from IP.
02302      * So we are just ignoring non IP datagrams
02303      */
02304     if(IP_VER(p->orig_iph) != 4)
02305     {
02306         if(pv.verbose_flag)
02307         {
02308             ErrorMessage("ICMP Unreachable not IPv4 datagram "
02309                          "([ver: 0x%x][len: 0x%x])\n", 
02310                          IP_VER(p->orig_iph), p->orig_iph->ip_len);
02311 
02312         }
02313 
02314         p->orig_iph = NULL;
02315 
02316         return(0);
02317     }
02318 
02319     /* set the IP datagram length */
02320     ip_len = ntohs(p->orig_iph->ip_len);
02321 
02322     /* set the IP header length */
02323     hlen = IP_HLEN(p->orig_iph) << 2;
02324 
02325     if(len < hlen)
02326     {
02327         if(pv.verbose_flag)
02328         {
02329             ErrorMessage("ICMP Unreachable IP len (%d bytes) < "
02330                          "IP hdr len (%d bytes), packet discarded\n", ip_len, hlen);
02331         }
02332         
02333         p->orig_iph = NULL;
02334 
02335         return(0);
02336     }
02337 
02338     p->ip_option_count = 0;
02339 
02340     /* set the remaining packet length */
02341     ip_len = len - hlen;
02342 
02343     /* check for fragmented packets */
02344     p->frag_offset = ntohs(p->orig_iph->ip_off);
02345 
02346     /* get the values of the reserved, more 
02347      * fragments and don't fragment flags 
02348      */
02349     p->rf = (u_int8_t)(p->frag_offset & 0x8000) >> 15;
02350     p->df = (u_int8_t)(p->frag_offset & 0x4000) >> 14;
02351     p->mf = (u_int8_t)(p->frag_offset & 0x2000) >> 13;
02352 
02353     /* mask off the high bits in the fragment offset field */
02354     p->frag_offset &= 0x1FFF;
02355 
02356     if(p->frag_offset || p->mf)
02357     {
02358         /* set the packet fragment flag */
02359         p->frag_flag = 1;
02360 
02361         /* set the payload pointer and payload size */
02362         p->data = pkt + hlen;
02363         p->dsize = (u_short) ip_len;
02364     }
02365     else
02366     {
02367         p->frag_flag = 0;
02368 
02369         DEBUG_WRAP(
02370                 DebugMessage(DEBUG_DECODE, "ICMP Unreachable IP header length: "
02371                     "%lu\n", (unsigned long)hlen););
02372 
02373         switch(p->orig_iph->ip_proto)
02374         {
02375             case IPPROTO_TCP: /* decode the interesting part of the header */
02376                 if(ip_len > 4)
02377                 {
02378                     p->orig_tcph =(TCPHdr *)(pkt + hlen);
02379 
02380                     /* stuff more data into the printout data struct */
02381                     p->orig_sp = ntohs(p->orig_tcph->th_sport);
02382                     p->orig_dp = ntohs(p->orig_tcph->th_dport);
02383                 }
02384 
02385                 break;
02386 
02387             case IPPROTO_UDP:
02388                 if(ip_len > 4)
02389                 {
02390                     p->orig_udph = (UDPHdr *)(pkt + hlen);
02391 
02392                     /* fill in the printout data structs */
02393                     p->orig_sp = ntohs(p->orig_udph->uh_sport);
02394                     p->orig_dp = ntohs(p->orig_udph->uh_dport);
02395                 }
02396 
02397                 break;
02398 
02399             case IPPROTO_ICMP:
02400                 if(ip_len > 4)
02401                 {
02402                     p->orig_icmph = (ICMPHdr *) (pkt+hlen);
02403                 }
02404 
02405                 break;
02406         }
02407     }
02408 
02409     return(1);
02410 }
02411 
02412 
02413 
02414 /*
02415  * Function: DecodeTCP(u_int8_t *, const u_int32_t, Packet *)
02416  *
02417  * Purpose: Decode the TCP transport layer
02418  *
02419  * Arguments: pkt => ptr to the packet data
02420  *            len => length from here to the end of the packet
02421  *            p   => Pointer to packet decode struct
02422  *
02423  * Returns: void function
02424  */
02425 void DecodeTCP(u_int8_t * pkt, const u_int32_t len, Packet * p)
02426 {
02427     struct pseudoheader       /* pseudo header for TCP checksum calculations */
02428     {
02429         u_int32_t sip, dip;   /* IP addr */
02430         u_int8_t  zero;       /* checksum placeholder */
02431         u_int8_t  protocol;   /* protocol number */
02432         u_int16_t tcplen;     /* tcp packet length */
02433     };
02434     u_int32_t hlen;            /* TCP header length */
02435     u_short csum;              /* checksum */
02436     struct pseudoheader ph;    /* pseudo header declaration */
02437 
02438     if(len < 20)
02439     {
02440         if(pv.verbose_flag)
02441         {
02442             ErrorMessage("TCP packet (len = %d) cannot contain "
02443                          "20 byte header\n", len);
02444         }
02445 
02446         if((runMode == MODE_IDS) && pv.decoder_flags.decode_alerts) 
02447         {
02448             SnortEventqAdd(GENERATOR_SNORT_DECODE, DECODE_TCP_DGRAM_LT_TCPHDR, 
02449                     1, DECODE_CLASS, 3, DECODE_TCP_DGRAM_LT_TCPHDR_STR, 0);
02450             if ((InlineMode()) && pv.decoder_flags.drop_alerts)
02451             {  
02452                DEBUG_WRAP(DebugMessage(DEBUG_DECODE, "Dropping bad packet\n"););
02453                InlineDrop();
02454             }
02455  
02456         }
02457 
02458         p->tcph = NULL;
02459         pc.discards++;
02460         return;
02461     }
02462 
02463     /* lay TCP on top of the data cause there is enough of it! */
02464     p->tcph = (TCPHdr *) pkt;
02465 
02466     /* multiply the payload offset value by 4 */
02467     hlen = TCP_OFFSET(p->tcph) << 2;
02468 
02469     DEBUG_WRAP(DebugMessage(DEBUG_DECODE, "TCP th_off is %d, passed len is %lu\n", 
02470                 TCP_OFFSET(p->tcph), (unsigned long)len););
02471 
02472     if(hlen < 20)
02473     {
02474         if(pv.verbose_flag)
02475         {
02476             ErrorMessage("TCP Data Offset (%d) < hlen (%d) \n",
02477                          TCP_OFFSET(p->tcph), hlen);
02478         }
02479 
02480         if((runMode == MODE_IDS) && pv.decoder_flags.decode_alerts)
02481         {
02482             SnortEventqAdd(GENERATOR_SNORT_DECODE, DECODE_TCP_INVALID_OFFSET, 
02483                     1, DECODE_CLASS, 3, DECODE_TCP_INVALID_OFFSET_STR, 0);
02484             if ((InlineMode()) && pv.decoder_flags.drop_alerts)
02485             {  
02486                DEBUG_WRAP(DebugMessage(DEBUG_DECODE, "Dropping bad packet\n"););
02487                InlineDrop();
02488             }
02489 
02490         }
02491 
02492         p->tcph = NULL;
02493         pc.discards++;
02494 
02495         return;
02496     }
02497 
02498     if(hlen > len)
02499     {
02500         if(pv.verbose_flag)
02501         {
02502             ErrorMessage("TCP Data Offset(%d) < longer than payload(%d)!\n",
02503                          TCP_OFFSET(p->tcph) << 2, len);
02504         }
02505 
02506         if((runMode == MODE_IDS) && pv.decoder_flags.decode_alerts)
02507         {
02508             SnortEventqAdd(GENERATOR_SNORT_DECODE, DECODE_TCP_LARGE_OFFSET, 1, 
02509                     DECODE_CLASS, 3, DECODE_TCP_LARGE_OFFSET_STR, 0);
02510             if ((InlineMode()) && pv.decoder_flags.drop_alerts)
02511             {  
02512                DEBUG_WRAP(DebugMessage(DEBUG_DECODE, "Dropping bad packet\n");); 
02513                InlineDrop();
02514             }
02515  
02516         }
02517 
02518         p->tcph = NULL;
02519         pc.discards++;
02520 
02521         return;
02522     }
02523 
02524     /* stuff more data into the printout data struct */
02525     p->sp = ntohs(p->tcph->th_sport);
02526     p->dp = ntohs(p->tcph->th_dport);
02527 
02528     if(pv.checksums_mode & DO_TCP_CHECKSUMS)
02529     {
02530         /* setup the pseudo header for checksum calculation */
02531         ph.sip = (u_int32_t)(p->iph->ip_src.s_addr);
02532         ph.dip = (u_int32_t)(p->iph->ip_dst.s_addr);
02533         ph.zero = 0;
02534         ph.protocol = p->iph->ip_proto;
02535         ph.tcplen = htons((u_short)len);
02536 
02537         /* if we're being "stateless" we probably don't care about the TCP 
02538          * checksum, but it's not bad to keep around for shits and giggles */
02539         /* calculate the checksum */
02540         csum = in_chksum_tcp((u_int16_t *)&ph, (u_int16_t *)(p->tcph), len);
02541         
02542         if(csum)
02543         {
02544             p->csum_flags |= CSE_TCP;
02545             DEBUG_WRAP(DebugMessage(DEBUG_DECODE, "Bad TCP checksum\n",
02546                                     "0x%x versus 0x%x\n", csum,
02547                                     ntohs(p->tcph->th_sum)););
02548             if(InlineMode())
02549             {     
02550                 DEBUG_WRAP(DebugMessage(DEBUG_DECODE, 
02551                             "Dropping packet with Bad TCP checksum\n"););
02552                 InlineDrop();
02553             }
02554         }
02555         else
02556         {
02557             DEBUG_WRAP(DebugMessage(DEBUG_DECODE,"TCP Checksum: OK\n"););
02558         }
02559     }
02560 
02561     DEBUG_WRAP(DebugMessage(DEBUG_DECODE, "tcp header starts at: %p\n", p->tcph););
02562 
02563 
02564     /* if options are present, decode them */
02565     p->tcp_options_len = hlen - 20;
02566     
02567     if(p->tcp_options_len > 0)
02568     {
02569         DEBUG_WRAP(DebugMessage(DEBUG_DECODE, "%lu bytes of tcp options....\n", 
02570                     (unsigned long)(p->tcp_options_len)););
02571 
02572         p->tcp_options_data = pkt + 20;
02573         DecodeTCPOptions((u_int8_t *) (pkt + 20), p->tcp_options_len, p);
02574     }
02575     else
02576     {
02577         p->tcp_option_count = 0;
02578     }
02579 
02580     /* set the data pointer and size */
02581     p->data = (u_int8_t *) (pkt + hlen);
02582 
02583     if(hlen < len)
02584     {
02585         p->dsize = (u_short)(len - hlen);
02586     }
02587     else
02588     {
02589         p->dsize = 0;
02590     }
02591 
02592     /*  Drop packet if we ignore this port  */
02593     if ((pv.ignore_ports[p->sp] == IPPROTO_TCP) || (pv.ignore_ports[p->dp] == IPPROTO_TCP) )
02594     {
02595         /*  Ignore all preprocessors for this packet */
02596         p->packet_flags |= PKT_IGNORE_PORT;
02597     }
02598 }
02599 
02600 
02601 /*
02602  * Function: DecodeUDP(u_int8_t *, const u_int32_t, Packet *)
02603  *
02604  * Purpose: Decode the UDP transport layer
02605  *
02606  * Arguments: pkt => ptr to the packet data
02607  *            len => length from here to the end of the packet
02608  *            p   => pointer to decoded packet struct  
02609  *
02610  * Returns: void function
02611  */
02612 void DecodeUDP(u_int8_t * pkt, const u_int32_t len, Packet * p)
02613 {
02614     struct pseudoheader 
02615     {
02616         u_int32_t sip, dip;
02617         u_int8_t  zero;
02618         u_int8_t  protocol;
02619         u_int16_t udplen;
02620     };
02621     u_short csum;
02622     u_int16_t uhlen;
02623     struct pseudoheader ph;
02624 
02625     if(len < sizeof(UDPHdr))
02626     {
02627         if(pv.verbose_flag)
02628         {
02629             ErrorMessage("Truncated UDP header (%d bytes)\n", len);
02630         }
02631 
02632         if((runMode == MODE_IDS) && pv.decoder_flags.decode_alerts) 
02633         {
02634             SnortEventqAdd(GENERATOR_SNORT_DECODE, DECODE_UDP_DGRAM_LT_UDPHDR, 
02635                     1, DECODE_CLASS, 3, DECODE_UDP_DGRAM_LT_UDPHDR_STR, 0);
02636             if ((InlineMode()) && pv.decoder_flags.drop_alerts)
02637             {
02638                DEBUG_WRAP(DebugMessage(DEBUG_DECODE, "Dropping bad packet\n"););
02639                InlineDrop();
02640             }
02641  
02642         }
02643 
02644         p->udph = NULL;
02645         pc.discards++;
02646 
02647         return;
02648     }
02649 
02650     /* set the ptr to the start of the UDP header */
02651     p->udph = (UDPHdr *) pkt;
02652 
02653     if (!p->frag_flag)
02654     {
02655         uhlen = ntohs(p->udph->uh_len);
02656     }
02657     else
02658     {
02659         u_int16_t ip_len = ntohs(p->iph->ip_len);
02660         /* Don't forget, IP_HLEN is a word - multiply x 4 */
02661         uhlen = ip_len - (IP_HLEN(p->iph) * 4 );
02662         p->udph->uh_chk = 0;
02663     }
02664     
02665     /* verify that the header len is a valid value */
02666     if(uhlen < UDP_HEADER_LEN)
02667     {
02668         if(pv.verbose_flag)
02669         {
02670             ErrorMessage("Invalid UDP Packet, length field < 8\n");
02671         }
02672         
02673         if((runMode == MODE_IDS) && pv.decoder_flags.decode_alerts)
02674         {
02675             SnortEventqAdd(GENERATOR_SNORT_DECODE, 
02676                     DECODE_UDP_DGRAM_INVALID_LENGTH, 1, DECODE_CLASS, 3, 
02677                     DECODE_UDP_DGRAM_INVALID_LENGTH_STR, 0);
02678             if ((InlineMode()) && pv.decoder_flags.drop_alerts)
02679             {
02680                DEBUG_WRAP(DebugMessage(DEBUG_DECODE, "Dropping bad packet\n"););
02681                InlineDrop();
02682             }
02683 
02684         }
02685         p->udph = NULL;
02686         pc.discards++;
02687 
02688         return;
02689     }
02690 
02691     /* make sure there are enough bytes as designated by length field */
02692     if(len < uhlen)
02693     {
02694         if(pv.verbose_flag)
02695         {
02696             ErrorMessage("Short UDP packet, length field > payload length\n");
02697         }
02698 
02699         if((runMode == MODE_IDS) && pv.decoder_flags.decode_alerts) 
02700         {
02701             SnortEventqAdd(GENERATOR_SNORT_DECODE, 
02702                     DECODE_UDP_DGRAM_SHORT_PACKET, 1, DECODE_CLASS, 3, 
02703                     DECODE_UDP_DGRAM_SHORT_PACKET_STR, 0);
02704             if ((InlineMode()) && pv.decoder_flags.drop_alerts)
02705             {  
02706                DEBUG_WRAP(DebugMessage(DEBUG_DECODE, "Dropping bad packet\n");); 
02707                InlineDrop();
02708             }
02709  
02710         }
02711 
02712         p->udph = NULL;
02713         pc.discards++;
02714 
02715         return;
02716     }
02717 
02718     /* fill in the printout data structs */
02719     p->sp = ntohs(p->udph->uh_sport);
02720     p->dp = ntohs(p->udph->uh_dport);
02721 
02722     if(pv.checksums_mode & DO_UDP_CHECKSUMS)
02723     {
02724         /* look at the UDP checksum to make sure we've got a good packet */
02725         ph.sip = (u_int32_t)(p->iph->ip_src.s_addr);
02726         ph.dip = (u_int32_t)(p->iph->ip_dst.s_addr);
02727         ph.zero = 0;
02728         ph.protocol = p->iph->ip_proto;
02729         ph.udplen = p->udph->uh_len; 
02730 
02731         if(p->udph->uh_chk)
02732         {
02733             csum = in_chksum_udp((u_int16_t *)&ph, (u_int16_t *)(p->udph), uhlen);
02734         }
02735         else
02736         {
02737             csum = 0;
02738         }
02739 
02740         if(csum)
02741         {
02742             p->csum_flags |= CSE_UDP;
02743             DEBUG_WRAP(DebugMessage(DEBUG_DECODE, "Bad UDP Checksum\n"););
02744 
02745             if(InlineMode())
02746             {     
02747                 DEBUG_WRAP(DebugMessage(DEBUG_DECODE, 
02748                             "Dropping packet with Bad UDP checksum\n"););
02749                 InlineDrop();
02750             }
02751         }
02752         else
02753         {
02754             DEBUG_WRAP(DebugMessage(DEBUG_DECODE, "UDP Checksum: OK\n"););
02755         }
02756     }
02757 
02758     DEBUG_WRAP(DebugMessage(DEBUG_DECODE, "UDP header starts at: %p\n", p->udph););
02759 
02760     p->data = (u_int8_t *) (pkt + UDP_HEADER_LEN);
02761     
02762     /* length was validated up above */
02763     p->dsize = uhlen - UDP_HEADER_LEN; 
02764 
02765     /*  Drop packet if we ignore this port  */
02766     if ( (pv.ignore_ports[p->sp] == IPPROTO_UDP) || (pv.ignore_ports[p->dp] == IPPROTO_UDP) )
02767     {
02768         /*  Ignore all preprocessors for this packet */
02769         p->packet_flags |= PKT_IGNORE_PORT;
02770     }
02771 
02772     return;
02773 }
02774 
02775 
02776 
02777 /*
02778  * Function: DecodeICMP(u_int8_t *, const u_int32_t, Packet *)
02779  *
02780  * Purpose: Decode the ICMP transport layer
02781  *
02782  * Arguments: pkt => ptr to the packet data
02783  *            len => length from here to the end of the packet
02784  *            p   => pointer to the decoded packet struct
02785  *
02786  * Returns: void function
02787  */
02788 void DecodeICMP(u_int8_t * pkt, const u_int32_t len, Packet * p)
02789 {
02790     u_int16_t csum;
02791     u_int32_t orig_p_caplen;
02792 
02793     if(len < ICMP_HEADER_LEN)
02794     {
02795         if(pv.verbose_flag)
02796         {
02797             ErrorMessage("WARNING: Truncated ICMP header "
02798                          "(%d bytes)\n", len);
02799         }
02800         
02801         p->icmph = NULL;
02802         pc.discards++;
02803 
02804         return;
02805     }
02806 
02807     /* set the header ptr first */
02808     p->icmph = (ICMPHdr *) pkt;
02809 
02810     switch (p->icmph->type)
02811     {
02812         case ICMP_ECHOREPLY:
02813         case ICMP_DEST_UNREACH:
02814         case ICMP_SOURCE_QUENCH:
02815         case ICMP_REDIRECT:
02816         case ICMP_ECHO:
02817         case ICMP_ROUTER_ADVERTISE:
02818         case ICMP_ROUTER_SOLICIT:
02819         case ICMP_TIME_EXCEEDED:
02820         case ICMP_PARAMETERPROB:
02821         case ICMP_INFO_REQUEST:
02822         case ICMP_INFO_REPLY:
02823             if (len < 8)
02824             {
02825                 if(pv.verbose_flag)
02826                 {
02827                     ErrorMessage("Truncated ICMP header(%d bytes)\n", len);
02828                 }
02829 
02830                 if((runMode == MODE_IDS) && pv.decoder_flags.decode_alerts)
02831                 {
02832                     SnortEventqAdd(GENERATOR_SNORT_DECODE, 
02833                             DECODE_ICMP_DGRAM_LT_ICMPHDR, 1, DECODE_CLASS, 3, 
02834                             DECODE_ICMP_DGRAM_LT_ICMPHDR_STR, 0);
02835                     if ((InlineMode()) && pv.decoder_flags.drop_alerts)
02836                     { 
02837                       DEBUG_WRAP(DebugMessage(DEBUG_DECODE, "Dropping bad packet\n"););
02838                       InlineDrop();
02839                     }
02840  
02841                 }
02842 
02843                 p->icmph = NULL;
02844                 pc.discards++;
02845 
02846                 return;
02847             }
02848 
02849             break;
02850 
02851         case ICMP_TIMESTAMP:
02852         case ICMP_TIMESTAMPREPLY:
02853             if (len < 20)
02854             {
02855                 if(pv.verbose_flag)
02856                 {
02857                     ErrorMessage("Truncated ICMP header(%d bytes)\n", len);
02858                 }
02859 
02860                 if((runMode == MODE_IDS) && pv.decoder_flags.decode_alerts)
02861                 {
02862                     SnortEventqAdd(GENERATOR_SNORT_DECODE, 
02863                             DECODE_ICMP_DGRAM_LT_TIMESTAMPHDR, 1, DECODE_CLASS,
02864                             3, DECODE_ICMP_DGRAM_LT_TIMESTAMPHDR_STR, 0);
02865                     if ((InlineMode()) && pv.decoder_flags.drop_alerts)
02866                     { 
02867                       DEBUG_WRAP(DebugMessage(DEBUG_DECODE, "Dropping bad packet\n"););
02868                       InlineDrop();
02869                     }
02870 
02871                 }
02872 
02873                 p->icmph = NULL;
02874                 pc.discards++;
02875 
02876                 return;
02877             }
02878 
02879             break;
02880 
02881         case ICMP_ADDRESS:
02882         case ICMP_ADDRESSREPLY:
02883             if (len < 12)
02884             {
02885                 if(pv.verbose_flag)
02886                 {
02887                     ErrorMessage("Truncated ICMP header(%d bytes)\n", len);
02888                 }
02889 
02890 
02891                 if((runMode == MODE_IDS) && pv.decoder_flags.decode_alerts)
02892                 {
02893                     SnortEventqAdd(GENERATOR_SNORT_DECODE, 
02894                             DECODE_ICMP_DGRAM_LT_ADDRHDR, 1, DECODE_CLASS, 3, 
02895                             DECODE_ICMP_DGRAM_LT_ADDRHDR_STR, 0);
02896                     if ((InlineMode()) && pv.decoder_flags.drop_alerts)
02897                     {
02898                       DEBUG_WRAP(DebugMessage(DEBUG_DECODE, "Dropping bad packet\n"););
02899                       InlineDrop();
02900                     }
02901  
02902                 }
02903 
02904                 p->icmph = NULL;
02905                 pc.discards++;
02906 
02907                 return;
02908             }
02909 
02910             break;
02911     }
02912 
02913 
02914     if(pv.checksums_mode & DO_ICMP_CHECKSUMS)
02915     {
02916         csum = in_chksum_icmp((u_int16_t *)p->icmph, len);
02917 
02918         if(csum)
02919         {
02920             p->csum_flags |= CSE_ICMP;
02921 
02922             DEBUG_WRAP(DebugMessage(DEBUG_DECODE, "Bad ICMP Checksum\n"););
02923  
02924             if(InlineMode())
02925             {     
02926                 DEBUG_WRAP(DebugMessage(DEBUG_DECODE, 
02927                             "Dropping packet with Bad ICMP checksum\n"););
02928                 InlineDrop();
02929             }
02930         }
02931         else
02932         {
02933             DEBUG_WRAP(DebugMessage(DEBUG_DECODE,"ICMP Checksum: OK\n"););
02934         }
02935     }
02936 
02937     p->dsize = (u_short)(len - ICMP_HEADER_LEN);
02938     p->data = pkt + ICMP_HEADER_LEN;
02939 
02940     DEBUG_WRAP(DebugMessage(DEBUG_DECODE, "ICMP type: %d   code: %d\n", 
02941                 p->icmph->code, p->icmph->type););
02942 
02943     switch(p->icmph->type)
02944     {
02945         case ICMP_ECHOREPLY:
02946             /* setup the pkt id ans seq numbers */
02947             p->dsize -= sizeof(struct idseq);
02948             p->data += sizeof(struct idseq);
02949             break;
02950 
02951         case ICMP_ECHO:
02952             /* setup the pkt id and seq numbers */
02953             p->dsize -= sizeof(struct idseq);   /* add the size of the 
02954                                                  * echo ext to the data
02955                                                  * ptr and subtract it 
02956                                                  * from the data size */
02957             p->data += sizeof(struct idseq);
02958             break;
02959 
02960         case ICMP_DEST_UNREACH:
02961             {
02962                 /* if unreach packet is smaller than expected! */
02963                 if(len < 16)
02964                 {
02965                     if(pv.verbose_flag)
02966                     {
02967                         ErrorMessage("Truncated ICMP-UNREACH "
02968                                      "header (%d bytes)\n", len);
02969                     }
02970 
02971                     /* if it is less than 8 we are in trouble */
02972                     if(len < 8)
02973                         break;
02974                 }
02975 
02976                 orig_p_caplen = len - 8;
02977 
02978                 if(!DecodeIPOnly(pkt + 8, orig_p_caplen, p))
02979                 {
02980                     if((runMode == MODE_IDS) && pv.decoder_flags.decode_alerts)
02981                     {
02982                         SnortEventqAdd(GENERATOR_SNORT_DECODE, 
02983                                 DECODE_IPV4_DGRAM_UNKNOWN, 1, DECODE_CLASS, 3,
02984                                 DECODE_IPV4_DGRAM_UNKNOWN_STR, 0);
02985                          if ((InlineMode()) && pv.decoder_flags.drop_alerts)
02986                         { 
02987                           DEBUG_WRAP(DebugMessage(DEBUG_DECODE, "Dropping bad packet\n"););
02988                           InlineDrop();
02989                         }
02990  
02991                     }
02992                 }
02993             }
02994 
02995             break;
02996 
02997         case ICMP_REDIRECT:
02998             {
02999                 /* if unreach packet is smaller than expected! */
03000                 if(p->dsize < 28)
03001                 {
03002                     if(pv.verbose_flag)
03003                     {
03004                         ErrorMessage("Truncated ICMP-REDIRECT "
03005                                      "header (%d bytes)\n", len);
03006                     }
03007                         
03008                     /* if it is less than 8 we are in trouble */
03009                     if(p->dsize < 8)
03010                         break;
03011                 }
03012 
03013                 orig_p_caplen = p->dsize - 8;
03014 
03015                 if(!DecodeIPOnly(pkt + 8, orig_p_caplen, p))
03016                 {
03017                     if((runMode == MODE_IDS) && pv.decoder_flags.decode_alerts)
03018                     {
03019                         SnortEventqAdd(GENERATOR_SNORT_DECODE, 
03020                                 DECODE_IPV4_DGRAM_UNKNOWN, 1, DECODE_CLASS, 3, 
03021                                 DECODE_IPV4_DGRAM_UNKNOWN_STR, 0);
03022                         if ((InlineMode()) && pv.decoder_flags.drop_alerts)
03023                         { 
03024                           DEBUG_WRAP(DebugMessage(DEBUG_DECODE, "Dropping bad packet\n"););
03025                           InlineDrop();
03026                         }
03027  
03028                     }
03029                 }
03030             }
03031 
03032             break;
03033     }
03034 
03035     return;
03036 }
03037 
03038 
03039 
03040 /*
03041  * Function: DecodeARP(u_int8_t *, u_int32_t, Packet *)
03042  *
03043  * Purpose: Decode ARP stuff
03044  *
03045  * Arguments: pkt => ptr to the packet data
03046  *            len => length from here to the end of the packet
03047  *            p   => pointer to decoded packet struct
03048  *
03049  * Returns: void function
03050  */
03051 void DecodeARP(u_int8_t * pkt, u_int32_t len, Packet * p)
03052 {
03053 
03054     pc.arp++;
03055     p->ah = (EtherARP *) pkt;
03056 
03057     if(len < sizeof(EtherARP))
03058     {
03059         if(pv.verbose_flag)
03060             ErrorMessage("Truncated packet\n");
03061 
03062         if((runMode == MODE_IDS) && pv.decoder_flags.decode_alerts)
03063         {
03064             SnortEventqAdd(GENERATOR_SNORT_DECODE, DECODE_ARP_TRUNCATED, 1, 
03065                     DECODE_CLASS, 3, DECODE_ARP_TRUNCATED_STR, 0);
03066             if ((InlineMode()) && pv.decoder_flags.drop_alerts)
03067             {
03068               DEBUG_WRAP(DebugMessage(DEBUG_DECODE, "Dropping bad packet\n");); 
03069               InlineDrop();
03070             }
03071         }
03072 
03073         pc.discards++;
03074         return;
03075     }
03076 
03077     return;
03078 }
03079 
03080 /*
03081  * Function: DecodeEapol(u_int8_t *, u_int32_t, Packet *)
03082  *
03083  * Purpose: Decode 802.1x eapol stuff
03084  *
03085  * Arguments: pkt => ptr to the packet data
03086  *            len => length from here to the end of the packet
03087  *            p   => pointer to decoded packet struct
03088  *
03089  * Returns: void function
03090  */
03091 void DecodeEapol(u_int8_t * pkt, u_int32_t len, Packet * p)
03092 {
03093     p->eplh = (EtherEapol *) pkt;
03094     pc.eapol++;
03095     if(len < sizeof(EtherEapol))
03096     {
03097         if(pv.verbose_flag)
03098             ErrorMessage("Truncated packet\n");
03099 
03100         if((runMode == MODE_IDS) && pv.decoder_flags.decode_alerts)
03101         {
03102             SnortEventqAdd(GENERATOR_SNORT_DECODE, DECODE_EAPOL_TRUNCATED, 1, 
03103                     DECODE_CLASS, 3, DECODE_EAPOL_TRUNCATED_STR, 0);
03104             if ((InlineMode()) && pv.decoder_flags.drop_alerts)
03105             {
03106               DEBUG_WRAP(DebugMessage(DEBUG_DECODE, "Dropping bad packet\n"););
03107               InlineDrop();
03108             } 
03109 
03110         }
03111 
03112         pc.discards++;
03113         return;
03114     }
03115     if (p->eplh->eaptype == EAPOL_TYPE_EAP) {
03116         DecodeEAP(pkt + sizeof(EtherEapol), len - sizeof(EtherEapol), p);
03117     }    
03118     else if(p->eplh->eaptype == EAPOL_TYPE_KEY) {
03119         DecodeEapolKey(pkt + sizeof(EtherEapol), len - sizeof(EtherEapol), p);
03120     }
03121     return;
03122 }
03123 
03124 /*
03125  * Function: DecodeEapolKey(u_int8_t *, u_int32_t, Packet *)
03126  *
03127  * Purpose: Decode 1x key setup
03128  *
03129  * Arguments: pkt => ptr to the packet data
03130  *            len => length from here to the end of the packet
03131  *            p   => pointer to decoded packet struct
03132  *
03133  * Returns: void function
03134  */
03135 void DecodeEapolKey(u_int8_t * pkt, u_int32_t len, Packet * p)
03136 {
03137     p->eapolk = (EapolKey *) pkt;
03138     if(len < sizeof(EapolKey))
03139     {
03140         if(pv.verbose_flag)
03141             printf("Truncated packet\n");
03142 
03143         if((runMode == MODE_IDS) && pv.decoder_flags.decode_alerts)
03144         {
03145             SnortEventqAdd(GENERATOR_SNORT_DECODE, DECODE_EAPKEY_TRUNCATED, 1, 
03146                     DECODE_CLASS, 3, DECODE_EAPKEY_TRUNCATED_STR, 0);
03147             if ((InlineMode()) && pv.decoder_flags.drop_alerts)
03148             {
03149               DEBUG_WRAP(DebugMessage(DEBUG_DECODE, "Dropping bad packet\n"););
03150               InlineDrop();
03151             } 
03152 
03153         }
03154 
03155         pc.discards++;
03156         return;
03157     }
03158 
03159     return;  
03160 }
03161 
03162 /*
03163  * Function: DecodeEAP(u_int8_t *, u_int32_t, Packet *)
03164  *
03165  * Purpose: Decode Extensible Authentication Protocol
03166  *
03167  * Arguments: pkt => ptr to the packet data
03168  *            len => length from here to the end of the packet
03169  *            p   => pointer to decoded packet struct
03170  *
03171  * Returns: void function
03172  */
03173 void DecodeEAP(u_int8_t * pkt, const u_int32_t len, Packet * p)
03174 {
03175     p->eaph = (EAPHdr *) pkt;
03176     if(len < sizeof(EAPHdr))
03177     {
03178         if(pv.verbose_flag)
03179             printf("Truncated packet\n");
03180 
03181         if((runMode == MODE_IDS) && pv.decoder_flags.decode_alerts)
03182         {
03183             SnortEventqAdd(GENERATOR_SNORT_DECODE, DECODE_EAP_TRUNCATED, 1, 
03184                     DECODE_CLASS, 3, DECODE_EAP_TRUNCATED_STR, 0);
03185             if ((InlineMode()) && pv.decoder_flags.drop_alerts)
03186             {
03187               DEBUG_WRAP(DebugMessage(DEBUG_DECODE, "Dropping bad packet\n"););
03188               InlineDrop();
03189             } 
03190 
03191         }
03192 
03193         pc.discards++;
03194         return;
03195     }
03196     if (p->eaph->code == EAP_CODE_REQUEST ||
03197             p->eaph->code == EAP_CODE_RESPONSE) {
03198         p->eaptype = pkt + sizeof(EAPHdr);
03199     }
03200     return;
03201 }
03202 
03203 
03204 /*
03205  * Function: DecodeIPV6(u_int8_t *, u_int32_t)
03206  *
03207  * Purpose: Just like IPX, it's just for counting.
03208  *
03209  * Arguments: pkt => ptr to the packet data
03210  *            len => length from here to the end of the packet
03211  *
03212  * Returns: void function
03213  */
03214 void DecodeIPV6(u_int8_t *pkt, u_int32_t len)
03215 {
03216     DEBUG_WRAP(DebugMessage(DEBUG_DECODE, "IPv6 is not supported.\n"););
03217     pc.ipv6++;
03218     return;
03219 }
03220 
03221 
03222 /*
03223  * Function: DecodeEthLoopback(u_int8_t *, u_int32_t)
03224  *
03225  * Purpose: Just like IPX, it's just for counting.
03226  *
03227  * Arguments: pkt => ptr to the packet data
03228  *            len => length from here to the end of the packet
03229  *
03230  * Returns: void function
03231  */
03232 void DecodeEthLoopback(u_int8_t *pkt, u_int32_t len)
03233 {
03234     DEBUG_WRAP(DebugMessage(DEBUG_DECODE, "EthLoopback is not supported.\n"););
03235     pc.ethloopback++;
03236     return;
03237 }
03238 
03239 
03240 /*
03241  * Function: DecodeIPX(u_int8_t *, u_int32_t)
03242  *
03243  * Purpose: Well, it doesn't do much of anything right now...
03244  *
03245  * Arguments: pkt => ptr to the packet data
03246  *            len => length from here to the end of the packet
03247  *
03248  * Returns: void function
03249  *
03250  */
03251 void DecodeIPX(u_int8_t *pkt, u_int32_t len)
03252 {
03253     DEBUG_WRAP(DebugMessage(DEBUG_DECODE, "IPX is not supported.\n"););
03254     pc.ipx++;
03255     return;
03256 }
03257 
03258 
03259 
03260 /** 
03261  * Validate that the length is an expected length AND that it's in bounds
03262  *
03263  * EOL and NOP are handled separately
03264  * 
03265  * @param option_ptr current location
03266  * @param end the byte past the end of the decode list
03267  * @param len_ptr the pointer to the length field
03268  * @param expected_len the number of bytes we expect to see per rfc KIND+LEN+DATA, -1 means dynamic.
03269  * @param tcpopt options structure to populate
03270  * @param byte_skip distance to move upon completion
03271  *
03272  * @return returns 0 on success, < 0 on error
03273  */
03274 static inline int OptLenValidate(u_int8_t *option_ptr,
03275                                     u_int8_t *end,
03276                                     u_int8_t *len_ptr,
03277                                     int expected_len,
03278                                     Options *tcpopt,
03279                                     u_int8_t *byte_skip)
03280 {
03281     *byte_skip = 0;
03282     
03283     if(len_ptr == NULL)
03284     {
03285         return TCP_OPT_TRUNC;
03286     }
03287     
03288     if(len_ptr == 0 || expected_len == 0 || expected_len == 1)
03289     {
03290         return TCP_OPT_BADLEN;
03291     }
03292     else if(expected_len > 1)
03293     {
03294         if((option_ptr + expected_len) > end)
03295         {
03296             /* not enough data to read in a perfect world */
03297             return TCP_OPT_TRUNC;
03298         }
03299 
03300         if(*len_ptr != expected_len)
03301         {
03302             /* length is not valid */
03303             return TCP_OPT_BADLEN;
03304         }
03305     }
03306     else /* expected_len < 0 (i.e. variable length) */
03307     {
03308         if(*len_ptr < 2)
03309         {
03310             /* RFC sez that we MUST have atleast this much data */
03311             return TCP_OPT_BADLEN;
03312         }
03313            
03314         if((option_ptr + *len_ptr) > end)
03315         {
03316             /* not enough data to read in a perfect world */
03317             return TCP_OPT_TRUNC;
03318         }
03319     }
03320 
03321     tcpopt->len = *len_ptr - 2;
03322 
03323     if(*len_ptr == 2)
03324     {
03325         tcpopt->data = NULL;
03326     }
03327     else
03328     {
03329         tcpopt->data = option_ptr + 2;
03330     }
03331 
03332     *byte_skip = *len_ptr;
03333     
03334     return 0;
03335 }
03336 
03337 /*
03338  * Function: DecodeTCPOptions(u_int8_t *, u_int32_t, Packet *)
03339  *
03340  * Purpose: Fairly self explainatory name, don't you think?
03341  *
03342  *          TCP Option Header length validation is left to the caller
03343  *
03344  *          For a good listing of TCP Options, 
03345  *          http://www.iana.org/assignments/tcp-parameters 
03346  *
03347  *   ------------------------------------------------------------
03348  *   From: "Kastenholz, Frank" <FKastenholz@unispherenetworks.com>
03349  *   Subject: Re: skeeter & bubba TCP options?
03350  *
03351  *   ah, the sins of ones youth that never seem to be lost...
03352  *
03353  *   it was something that ben levy and stev and i did at ftp many
03354  *   many moons ago. bridgham and stev were the instigators of it.
03355  *   the idea was simple, put a dh key exchange directly in tcp
03356  *   so that all tcp sessions could be encrypted without requiring
03357  *   any significant key management system. authentication was not
03358  *   a part of the idea, it was to be provided by passwords or
03359  *   whatever, which could now be transmitted over the internet
03360  *   with impunity since they were encrypted... we implemented
03361  *   a simple form of this (doing the math was non trivial on the
03362  *   machines of the day). it worked. the only failure that i 
03363  *   remember was that it was vulnerable to man-in-the-middle 
03364  *   attacks.
03365  *   
03366  *   why "skeeter" and "bubba"? well, that's known only to stev...
03367  *   ------------------------------------------------------------
03368  *
03369  * 4.2.2.5 TCP Options: RFC-793 Section 3.1
03370  *
03371  *    A TCP MUST be able to receive a TCP option in any segment. A TCP
03372  *    MUST ignore without error any TCP option it does not implement,
03373  *    assuming that the option has a length field (all TCP options
03374  *    defined in the future will have length fields). TCP MUST be
03375  *    prepared to handle an illegal option length (e.g., zero) without
03376  *    crashing; a suggested procedure is to reset the connection and log
03377  *    the reason.
03378  *
03379  * Arguments: o_list => ptr to the option list
03380  *            o_len => length of the option list
03381  *            p     => pointer to decoded packet struct
03382  *
03383  * Returns: void function
03384  */
03385 void DecodeTCPOptions(u_int8_t *start, u_int32_t o_len, Packet *p)
03386 {
03387     u_int8_t *option_ptr = start;
03388     u_int8_t *end_ptr = start + o_len; /* points to byte after last option */
03389     u_int8_t *len_ptr;
03390     u_int32_t opt_count = 0;
03391     u_char done = 0; /* have we reached TCPOPT_EOL yet?*/
03392     u_char experimental_option_found = 0;      /* are all options RFC compliant? */
03393     u_char obsolete_option_found = 0;
03394     u_char ttcp_found = 0;
03395     
03396     int code = 2;
03397     u_int8_t byte_skip;
03398 
03399     /* Here's what we're doing so that when we find out what these
03400      * other buggers of TCP option codes are, we can do something
03401      * useful
03402      * 
03403      * 1) get option code
03404      * 2) check for enough space for current option code
03405      * 3) set option data ptr
03406      * 4) increment option code ptr
03407      *
03408      * TCP_OPTLENMAX = 40 because of
03409      *        (((2^4) - 1) * 4  - TCP_HEADER_LEN)
03410      *      
03411      */
03412 
03413     if(o_len > TCP_OPTLENMAX)
03414     {
03415         /* This shouldn't ever alert if we are doing our job properly
03416          * in the caller */        
03417         p->tcph = NULL; /* let's just alert */
03418         DEBUG_WRAP(DebugMessage(DEBUG_DECODE,
03419                                 "o_len(%u) > TCP_OPTLENMAX(%u)\n",
03420                                 o_len, TCP_OPTLENMAX));
03421         return;
03422     }
03423     
03424     while((option_ptr < end_ptr) && (opt_count < TCP_OPTLENMAX) && (code >= 0) && !done)
03425     {
03426         p->tcp_options[opt_count].code = *option_ptr;
03427 
03428         if((option_ptr + 1) < end_ptr)
03429         {
03430             len_ptr = option_ptr + 1;
03431         }
03432         else
03433         {
03434             len_ptr = NULL;
03435         }
03436         
03437         switch(*option_ptr)
03438         {
03439         case TCPOPT_EOL:
03440             done = 1; /* fall through to the NOP case */
03441         case TCPOPT_NOP:
03442             p->tcp_options[opt_count].len = 0; 
03443             p->tcp_options[opt_count].data = NULL;
03444             byte_skip = 1;
03445             code = 0;
03446             break;
03447         case TCPOPT_MAXSEG:
03448             code = OptLenValidate(option_ptr, end_ptr, len_ptr, TCPOLEN_MAXSEG,
03449                                   &p->tcp_options[opt_count], &byte_skip);
03450             break;            
03451         case TCPOPT_SACKOK:
03452             code = OptLenValidate(option_ptr, end_ptr, len_ptr, TCPOLEN_SACKOK,
03453                                   &p->tcp_options[opt_count], &byte_skip);
03454             break;            
03455         case TCPOPT_WSCALE:
03456             code = OptLenValidate(option_ptr, end_ptr, len_ptr, TCPOLEN_WSCALE,
03457                                   &p->tcp_options[opt_count], &byte_skip);
03458             break;            
03459         case TCPOPT_ECHO: /* both use the same lengths */
03460         case TCPOPT_ECHOREPLY:
03461             obsolete_option_found = 1;
03462             code = OptLenValidate(option_ptr, end_ptr, len_ptr, TCPOLEN_ECHO,
03463                                   &p->tcp_options[opt_count], &byte_skip);
03464             break;
03465         case TCPOPT_MD5SIG:
03466             experimental_option_found = 1;
03467             code = OptLenValidate(option_ptr, end_ptr, len_ptr, TCPOLEN_MD5SIG,
03468                                   &p->tcp_options[opt_count], &byte_skip);
03469             break;
03470         case TCPOPT_SACK:
03471             code = OptLenValidate(option_ptr, end_ptr, len_ptr, -1,
03472                                   &p->tcp_options[opt_count], &byte_skip);
03473             if(p->tcp_options[opt_count].data == NULL)
03474                 code = TCP_OPT_BADLEN;
03475 
03476             break;
03477         case TCPOPT_CC_ECHO:
03478             ttcp_found = 1;
03479             /* fall through */
03480         case TCPOPT_CC:  /* all 3 use the same lengths / T/TCP */
03481         case TCPOPT_CC_NEW:
03482             code = OptLenValidate(option_ptr, end_ptr, len_ptr, TCPOLEN_CC,
03483                                   &p->tcp_options[opt_count], &byte_skip);
03484             break;
03485         case TCPOPT_TRAILER_CSUM:
03486             experimental_option_found = 1;
03487             code = OptLenValidate(option_ptr, end_ptr, len_ptr, TCPOLEN_TRAILER_CSUM,
03488                                   &p->tcp_options[opt_count], &byte_skip);
03489             break;
03490 
03491         case TCPOPT_TIMESTAMP:
03492             code = OptLenValidate(option_ptr, end_ptr, len_ptr, TCPOLEN_TIMESTAMP,
03493                                   &p->tcp_options[opt_count], &byte_skip);
03494             break;
03495     
03496         case TCPOPT_SKEETER:
03497         case TCPOPT_BUBBA:
03498         case TCPOPT_UNASSIGNED:
03499             obsolete_option_found = 1;
03500         default:
03501         case TCPOPT_SCPS:  
03502         case TCPOPT_SELNEGACK:
03503         case TCPOPT_RECORDBOUND:
03504         case TCPOPT_CORRUPTION:
03505         case TCPOPT_PARTIAL_PERM:
03506         case TCPOPT_PARTIAL_SVC:
03507         case TCPOPT_ALTCSUM:
03508         case TCPOPT_SNAP:
03509             experimental_option_found = 1;
03510             code = OptLenValidate(option_ptr, end_ptr, len_ptr, -1,
03511                                   &p->tcp_options[opt_count], &byte_skip);
03512             break;
03513         }
03514 
03515         if(code < 0)
03516         {
03517             if(runMode == MODE_IDS)
03518             {
03519                 if(code == TCP_OPT_BADLEN && pv.decoder_flags.tcpopt_decode)
03520                 {
03521                     SnortEventqAdd(GENERATOR_SNORT_DECODE, 
03522                             DECODE_TCPOPT_BADLEN, 1, DECODE_CLASS, 3, 
03523                             DECODE_TCPOPT_BADLEN_STR, 0);
03524 
03525                     if ((InlineMode()) && pv.decoder_flags.drop_tcpopt_decode)
03526                     {
03527                         DEBUG_WRAP( DebugMessage(DEBUG_DECODE, "Dropping bad packet\n"););
03528                         InlineDrop();
03529                     }
03530                 }
03531                 else if(code == TCP_OPT_TRUNC && pv.decoder_flags.tcpopt_decode)
03532                 {
03533                     SnortEventqAdd(GENERATOR_SNORT_DECODE, 
03534                             DECODE_TCPOPT_TRUNCATED, 1, DECODE_CLASS, 3, 
03535                             DECODE_TCPOPT_TRUNCATED_STR, 0);
03536                     if ((InlineMode()) && pv.decoder_flags.drop_tcpopt_decode)
03537                     {
03538                         DEBUG_WRAP(DebugMessage(DEBUG_DECODE, "Dropping bad packet\n"););
03539                         InlineDrop();
03540                     }
03541                 }
03542             }
03543 
03544             return;
03545         }
03546 
03547         opt_count++;
03548 
03549         option_ptr += byte_skip;
03550     }
03551 
03552     p->tcp_option_count = opt_count;
03553 
03554     if(runMode == MODE_IDS &&
03555        experimental_option_found && pv.decoder_flags.tcpopt_experiment)
03556     {
03557         SnortEventqAdd(GENERATOR_SNORT_DECODE, DECODE_TCPOPT_EXPERIMENT, 1, 
03558                 DECODE_CLASS, 3, DECODE_TCPOPT_EXPERIMENT_STR, 0);
03559         if ((InlineMode()) && pv.decoder_flags.drop_tcpopt_experiment)
03560         {
03561           DEBUG_WRAP(DebugMessage(DEBUG_DECODE, "Dropping bad packet\n"););
03562           InlineDrop();
03563         }
03564 
03565     }
03566     else if(runMode == MODE_IDS &&
03567             obsolete_option_found && pv.decoder_flags.tcpopt_obsolete)
03568     {
03569         SnortEventqAdd(GENERATOR_SNORT_DECODE, DECODE_TCPOPT_OBSOLETE, 1, 
03570                 DECODE_CLASS, 3, DECODE_TCPOPT_OBSOLETE_STR, 0);
03571         if ((InlineMode()) && pv.decoder_flags.drop_tcpopt_obsolete)
03572         {
03573           DEBUG_WRAP(DebugMessage(DEBUG_DECODE, "Dropping bad packet\n"););
03574           InlineDrop();
03575         }
03576 
03577     }
03578     else if(runMode == MODE_IDS &&
03579             ttcp_found && pv.decoder_flags.tcpopt_ttcp)
03580     {
03581         SnortEventqAdd(GENERATOR_SNORT_DECODE, DECODE_TCPOPT_TTCP, 1, 
03582                 DECODE_CLASS, 3, DECODE_TCPOPT_TTCP_STR, 0);
03583         if ((InlineMode()) && pv.decoder_flags.drop_tcpopt_ttcp)
03584         {
03585           DEBUG_WRAP(DebugMessage(DEBUG_DECODE, "Dropping bad packet\n"););
03586           InlineDrop();
03587         }
03588 
03589     }
03590     
03591     return;
03592 }
03593 
03594 
03595 /*
03596  * Function: DecodeIPOptions(u_int8_t *, u_int32_t, Packet *)
03597  *
03598  * Purpose: Once again, a fairly self-explainatory name
03599  *
03600  * Arguments: o_list => ptr to the option list
03601  *            o_len => length of the option list
03602  *            p     => pointer to decoded packet struct
03603  *
03604  * Returns: void function
03605  */
03606 void DecodeIPOptions(u_int8_t *start, u_int32_t o_len, Packet *p)
03607 {
03608     u_int8_t *option_ptr = start;
03609     u_char done = 0; /* have we reached IP_OPTEOL yet? */
03610     u_int8_t *end_ptr = start + o_len;
03611     u_int32_t opt_count = 0; /* what option are we processing right now */
03612     u_int8_t byte_skip;
03613     u_int8_t *len_ptr;
03614     int code = 0;  /* negative error codes are returned from bad options */
03615     
03616 
03617     DEBUG_WRAP(DebugMessage(DEBUG_DECODE,  "Decoding %d bytes of IP options\n", o_len););
03618 
03619 
03620     while((option_ptr < end_ptr) && (opt_count < IP_OPTMAX) && (code >= 0))
03621     {
03622         p->ip_options[opt_count].code = *option_ptr;
03623 
03624         if((option_ptr + 1) < end_ptr)
03625         {
03626             len_ptr = option_ptr + 1;
03627         }
03628         else
03629         {
03630             len_ptr = NULL;
03631         }
03632 
03633         switch(*option_ptr)
03634         {
03635         case IPOPT_RTRALT:
03636         case IPOPT_NOP:
03637         case IPOPT_EOL:
03638             /* if we hit an EOL, we're done */
03639             if(*option_ptr == IPOPT_EOL)
03640                 done = 1;
03641             
03642             p->ip_options[opt_count].len = 0;
03643             p->ip_options[opt_count].data = NULL;
03644             byte_skip = 1;
03645             break;
03646         default:
03647             /* handle all the dynamic features */
03648             code = OptLenValidate(option_ptr, end_ptr, len_ptr, -1,
03649                                   &p->ip_options[opt_count], &byte_skip);
03650         }
03651 
03652         if(code < 0)
03653         {
03654             if(runMode == MODE_IDS)
03655             {
03656                 /* Yes, we use TCP_OPT_* for the IP option decoder.
03657                 */
03658                 if(code == TCP_OPT_BADLEN && pv.decoder_flags.ipopt_decode)
03659                 {
03660                     SnortEventqAdd(GENERATOR_SNORT_DECODE, 
03661                             DECODE_IPV4OPT_BADLEN, 1, DECODE_CLASS, 3, 
03662                             DECODE_IPV4OPT_BADLEN_STR, 0);
03663 
03664                     if ((InlineMode()) && pv.decoder_flags.drop_ipopt_decode)
03665                     {
03666                         DEBUG_WRAP(DebugMessage(DEBUG_DECODE, "Dropping bad packet\n"););
03667                         InlineDrop();
03668                     }
03669                 }
03670                 else if(code == TCP_OPT_TRUNC && pv.decoder_flags.ipopt_decode)
03671                 {
03672                     SnortEventqAdd(GENERATOR_SNORT_DECODE, 
03673                             DECODE_IPV4OPT_TRUNCATED, 1, DECODE_CLASS, 3, 
03674                             DECODE_IPV4OPT_TRUNCATED_STR, 0);
03675                     
03676                     if ((InlineMode()) && pv.decoder_flags.drop_ipopt_decode)
03677                     {
03678                         DEBUG_WRAP(DebugMessage(DEBUG_DECODE, "Dropping bad packet\n"););
03679                         InlineDrop();
03680                     }
03681                 }
03682             }
03683 
03684             return;
03685         }
03686 
03687         if(!done)
03688             opt_count++;
03689 
03690         option_ptr += byte_skip;
03691     }
03692     
03693     p->ip_option_count = opt_count;
03694 
03695     return;
03696 }
03697 
03698 
03699 /** 
03700  * Setup all the flags for the decoder alerts
03701  */
03702 void InitDecoderFlags(void)
03703 {
03704     /* turn on decoder alerts by default -- useful for bug reports.. */
03705     pv.decoder_flags.decode_alerts          = 1;
03706     pv.decoder_flags.drop_alerts            = 1;
03707     pv.decoder_flags.tcpopt_experiment      = 1;
03708     pv.decoder_flags.drop_tcpopt_experiment = 1;
03709     pv.decoder_flags.tcpopt_obsolete        = 1;
03710     pv.decoder_flags.drop_tcpopt_obsolete   = 1;
03711     pv.decoder_flags.tcpopt_ttcp            = 1;
03712     pv.decoder_flags.drop_tcpopt_ttcp       = 1;
03713     pv.decoder_flags.tcpopt_decode          = 1;
03714     pv.decoder_flags.drop_tcpopt_decode     = 1;
03715     pv.decoder_flags.ipopt_decode           = 1;
03716     pv.decoder_flags.drop_ipopt_decode      = 1;
03717 }
03718 
03719 #if defined(WORDS_MUSTALIGN) && !defined(__GNUC__)
03720 u_int32_t
03721 EXTRACT_32BITS (u_char *p)
03722 {
03723   u_int32_t __tmp;
03724 
03725   memmove(&__tmp, p, sizeof(u_int32_t));
03726   return (u_int32_t) ntohl(__tmp);
03727 }
03728 #endif /* WORDS_MUSTALIGN && !__GNUC__ */

Generated on Sun May 14 14:51:12 2006 by  doxygen 1.4.2