1 /* $Id$ */
2 
3 /*
4 ** Copyright (C) 2002-2009 Sourcefire, Inc.
5 ** Copyright (C) 1998-2002 Martin Roesch <roesch@sourcefire.com>
6 **
7 ** This program is free software; you can redistribute it and/or modify
8 ** it under the terms of the GNU General Public License Version 2 as
9 ** published by the Free Software Foundation.  You may not use, modify or
10 ** distribute this program under any other version of the GNU General
11 ** Public License.
12 **
13 ** This program is distributed in the hope that it will be useful,
14 ** but WITHOUT ANY WARRANTY; without even the implied warranty of
15 ** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
16 ** GNU General Public License for more details.
17 **
18 ** You should have received a copy of the GNU General Public License
19 ** along with this program; if not, write to the Free Software
20 ** Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
21 */
22 
23 #ifdef HAVE_CONFIG_H
24 #include "config.h"
25 #endif
26 
27 #ifdef HAVE_STRINGS_H
28 #include <strings.h>
29 #endif
30 
31 #include <string.h>
32 #include <stdlib.h>
33 
34 #include "decode.h"
35 #include "barnyard2.h"
36 #include "debug.h"
37 #include "util.h"
38 #include "checksum.h"
39 #include "log.h"
40 #include "generators.h"
41 #include "bounds.h"
42 #include "strlcpyu.h"
43 #include "sf_iph.h"
44 #include "sfxhash.h"
45 
46 extern uint32_t pcap_snaplen;
47 
48 /* No great place to put this right now */
49 HttpUri UriBufs[URI_COUNT];
50 uint8_t DecodeBuffer[DECODE_BLEN];
51 #ifndef SUP_IP6
52 Packet *BsdPseudoPacket;
53 /* For the BSD fragmentation vulnerability */
54 SFXHASH *ipv6_frag_hash;
55 #endif
56 
57 #ifdef SUP_IP6
58 IPH_API ip4 =
59     {
60        ip4_ret_src,
61        ip4_ret_dst,
62        ip4_ret_tos,
63        ip4_ret_ttl,
64        ip4_ret_len,
65        ip4_ret_id,
66        ip4_ret_proto,
67        ip4_ret_off,
68        ip4_ret_ver,
69        ip4_ret_hlen,
70 
71        orig_ip4_ret_src,
72        orig_ip4_ret_dst,
73        orig_ip4_ret_tos,
74        orig_ip4_ret_ttl,
75        orig_ip4_ret_len,
76        orig_ip4_ret_id,
77        orig_ip4_ret_proto,
78        orig_ip4_ret_off,
79        orig_ip4_ret_ver,
80        orig_ip4_ret_hlen,
81        IPH_API_V4
82     };
83 
84 IPH_API ip6 =
85     {
86        ip6_ret_src,
87        ip6_ret_dst,
88        ip6_ret_toc,
89        ip6_ret_hops,
90        ip6_ret_len,
91        ip6_ret_id,
92        ip6_ret_next,
93        ip6_ret_off,
94        ip6_ret_ver,
95        ip6_ret_hlen,
96 
97        orig_ip6_ret_src,
98        orig_ip6_ret_dst,
99        orig_ip6_ret_toc,
100        orig_ip6_ret_hops,
101        orig_ip6_ret_len,
102        orig_ip6_ret_id,
103        orig_ip6_ret_next,
104        orig_ip6_ret_off,
105        orig_ip6_ret_ver,
106        orig_ip6_ret_hlen,
107        IPH_API_V6
108     };
109 #endif
110 
DecodePacket(int linktype,Packet * p,const struct pcap_pkthdr * pkthdr,const uint8_t * pkt)111 int DecodePacket(int linktype, Packet *p, const struct pcap_pkthdr *pkthdr, const uint8_t *pkt)
112 {
113 	DEBUG_WRAP(DebugMessage(DEBUG_DECODE,"Decoding linktype %d\n",linktype););
114     switch(linktype)
115     {
116 		case DLT_EN10MB:        /* Ethernet */
117             DecodeEthPkt(p, pkthdr, pkt);
118             break;
119 
120 #ifdef DLT_IEEE802_11
121         case DLT_IEEE802_11:
122             DecodeIEEE80211Pkt(p, pkthdr, pkt);
123             break;
124 #endif
125 #ifdef DLT_ENC
126         case DLT_ENC:           /* Encapsulated data */
127             DecodeEncPkt(p, pkthdr, pkt);
128             break;
129 
130 #else
131         case 13:
132 #endif /* DLT_ENC */
133         case DLT_IEEE802:                /* Token Ring */
134             DecodeTRPkt(p, pkthdr, pkt);
135             break;
136 
137         case DLT_FDDI:                /* FDDI */
138             DecodeFDDIPkt(p, pkthdr, pkt);
139             break;
140 
141 #ifdef DLT_CHDLC
142         case DLT_CHDLC:              /* Cisco HDLC */
143             DecodeChdlcPkt(p, pkthdr, pkt);
144             break;
145 #endif
146 
147         case DLT_SLIP:                /* Serial Line Internet Protocol */
148             if (BcOutputDataLink())
149             {
150                 LogMessage("Second layer header parsing for this datalink "
151                         "isn't implemented yet\n");
152 
153                 barnyard2_conf->output_flags &= ~OUTPUT_FLAG__SHOW_DATA_LINK;
154             }
155             DecodeSlipPkt(p, pkthdr, pkt);
156 
157             break;
158 
159         case DLT_PPP:                /* point-to-point protocol */
160             if (BcOutputDataLink())
161             {
162                 /* do we need ppp header showup? it's only 4 bytes anyway ;-) */
163                 LogMessage("Second layer header parsing for this datalink "
164                         "isn't implemented yet\n");
165 
166                 barnyard2_conf->output_flags &= ~OUTPUT_FLAG__SHOW_DATA_LINK;
167             }
168             DecodePppPkt(p, pkthdr, pkt);
169             break;
170 
171 #ifdef DLT_PPP_SERIAL
172         case DLT_PPP_SERIAL:         /* PPP with full HDLC header*/
173             if (BcOutputDataLink())
174             {
175                 /* do we need ppp header showup? it's only 4 bytes anyway ;-) */
176                 LogMessage("Second layer header parsing for this datalink "
177                         "isn't implemented yet\n");
178 
179                 barnyard2_conf->output_flags &= ~OUTPUT_FLAG__SHOW_DATA_LINK;
180             }
181             DecodePppSerialPkt(p, pkthdr, pkt);
182             break;
183 #endif
184 
185 #ifdef DLT_LINUX_SLL
186         case DLT_LINUX_SLL:
187             DecodeLinuxSLLPkt(p, pkthdr, pkt);
188             break;
189 #endif
190 
191 #ifdef DLT_PFLOG
192         case DLT_PFLOG:
193             DecodePflog(p, pkthdr, pkt);
194             break;
195 #endif
196 
197 #ifdef DLT_OLDPFLOG
198         case DLT_OLDPFLOG:
199             DecodeOldPflog(p, pkthdr, pkt);
200             break;
201 #endif
202 
203 #ifdef DLT_LOOP
204         case DLT_LOOP:
205 #endif
206         case DLT_NULL:            /* loopback and stuff.. you wouldn't perform
207                                    * intrusion detection on it, but it's ok for
208                                    * testing. */
209             if (BcOutputDataLink())
210             {
211                 LogMessage("Data link layer header parsing for this network "
212                         " type isn't implemented yet\n");
213 
214                 barnyard2_conf->output_flags &= ~OUTPUT_FLAG__SHOW_DATA_LINK;
215             }
216             DecodeNullPkt(p, pkthdr, pkt);
217             break;
218 
219 
220 #ifdef DLT_RAW
221         case DLT_RAW:
222 #endif
223         case 228:       /*Defined in some bpf implementation as  DLT_IPV4: */
224         case 229:      /* Defined in some bpf implementation as     DLT_IPV6 */
225 
226             if (BcOutputDataLink())
227             {
228                 LogMessage("There's no second layer header available for "
229                      "this datalink\n");
230 
231                 barnyard2_conf->output_flags &= ~OUTPUT_FLAG__SHOW_DATA_LINK;
232             }
233             DecodeRawPkt(p, pkthdr, pkt);
234             break;
235 
236             /*
237              * you need the I4L modified version of libpcap to get this stuff
238              * working
239              */
240 #ifdef DLT_I4L_RAWIP
241         case DLT_I4L_RAWIP:
242             DecodeI4LRawIPPkt(p, pkthdr, pkt);
243             break;
244 #endif
245 
246 #ifdef DLT_I4L_IP
247         case DLT_I4L_IP:
248             DecodeEthPkt(p, pkthdr, pkt);
249             break;
250 #endif
251 
252 #ifdef DLT_I4L_CISCOHDLC
253         case DLT_I4L_CISCOHDLC:
254             DecodeI4LCiscoIPPkt(p, pkthdr, pkt);
255             break;
256 #endif
257 
258         default:            /* oops, don't know how to handle this one */
259             ErrorMessage("\nCannot handle data link type %d\n", linktype);
260     }
261 
262     /* add linktype to this packet for per plugin tracking */
263     p->linktype = linktype;
264 
265     return 0;
266 }
267 
268 //static INLINE void DecoderEvent(
269 //    Packet *p, int gid, char *str, int event_flag, int drop_flag)
270 //{
271 //    if((runMode == MODE_IDS) && event_flag)
272 //    {
273 //        SnortEventqAdd(GENERATOR_SNORT_DECODE, gid, 1,
274 //                       DECODE_CLASS, 3, str, 0);
275 //        if ((InlineMode()) && drop_flag)
276 //        {
277 //            DEBUG_WRAP(DebugMessage(DEBUG_DECODE, "Dropping bad packet\n"););
278 //            InlineDrop(p);
279 //        }
280 //    }
281 //}
282 
283 /*
284  * Function: DecodeEthPkt(Packet *, char *, struct pcap_pkthdr*, uint8_t*)
285  *
286  * Purpose: Decode those fun loving ethernet packets, one at a time!
287  *
288  * Arguments: p => pointer to the decoded packet struct
289  *            user => Utility pointer (unused)
290  *            pkthdr => ptr to the packet header
291  *            pkt => pointer to the real live packet data
292  *
293  * Returns: void function
294  */
DecodeEthPkt(Packet * p,const struct pcap_pkthdr * pkthdr,const uint8_t * pkt)295 void DecodeEthPkt(Packet * p, const struct pcap_pkthdr * pkthdr, const uint8_t * pkt)
296 {
297     uint32_t pkt_len;      /* suprisingly, the length of the packet */
298     uint32_t cap_len;      /* caplen value */
299 
300 	pc.eth++;
301     pc.total_processed++;
302 
303     memset(p, 0, PKT_ZERO_LEN);
304 
305     p->pkth = pkthdr;
306     p->pkt = pkt;
307 
308     /* set the lengths we need */
309     pkt_len = pkthdr->len;  /* total packet length */
310     cap_len = pkthdr->caplen;   /* captured packet length */
311 
312     if(pcap_snaplen < pkt_len)
313         pkt_len = cap_len;
314 
315     DEBUG_WRAP(DebugMessage(DEBUG_DECODE, "Packet!\n");
316             DebugMessage(DEBUG_DECODE, "caplen: %lu    pktlen: %lu\n",
317                 (unsigned long)cap_len, (unsigned long)pkt_len);
318             );
319 
320     /* do a little validation */
321     if(cap_len < ETHERNET_HEADER_LEN)
322     {
323         if (BcLogVerbose())
324         {
325             ErrorMessage("Captured data length < Ethernet header length!"
326                          " (%d bytes)\n", p->pkth->caplen);
327         }
328 
329         p->iph = NULL;
330         pc.discards++;
331         pc.ethdisc++;
332         return;
333     }
334 
335     /* lay the ethernet structure over the packet data */
336     p->eh = (EtherHdr *) pkt;
337 
338     DEBUG_WRAP(
339             DebugMessage(DEBUG_DECODE, "%X:%X:%X:%X:%X:%X -> %X:%X:%X:%X:%X:%X\n",
340                 p->eh->ether_src[0],
341                 p->eh->ether_src[1], p->eh->ether_src[2], p->eh->ether_src[3],
342                 p->eh->ether_src[4], p->eh->ether_src[5], p->eh->ether_dst[0],
343                 p->eh->ether_dst[1], p->eh->ether_dst[2], p->eh->ether_dst[3],
344                 p->eh->ether_dst[4], p->eh->ether_dst[5]);
345             );
346     DEBUG_WRAP(
347             DebugMessage(DEBUG_DECODE, "type:0x%X len:0x%X\n",
348                 ntohs(p->eh->ether_type), p->pkth->len)
349             );
350 
351     /* grab out the network type */
352     switch(ntohs(p->eh->ether_type))
353     {
354         case ETHERNET_TYPE_IP:
355             DEBUG_WRAP(
356                     DebugMessage(DEBUG_DECODE,
357                         "IP datagram size calculated to be %lu bytes\n",
358                         (unsigned long)(cap_len - ETHERNET_HEADER_LEN));
359                     );
360 
361             DecodeIP(p->pkt + ETHERNET_HEADER_LEN,
362                     cap_len - ETHERNET_HEADER_LEN, p);
363 
364             return;
365 
366         case ETHERNET_TYPE_ARP:
367         case ETHERNET_TYPE_REVARP:
368             DecodeARP(p->pkt + ETHERNET_HEADER_LEN,
369                     cap_len - ETHERNET_HEADER_LEN, p);
370             return;
371 
372         case ETHERNET_TYPE_IPV6:
373             DecodeIPV6(p->pkt + ETHERNET_HEADER_LEN,
374                     (cap_len - ETHERNET_HEADER_LEN), p);
375             return;
376 
377 #ifndef NO_NON_ETHER_DECODER
378         case ETHERNET_TYPE_PPPoE_DISC:
379         case ETHERNET_TYPE_PPPoE_SESS:
380             DecodePPPoEPkt(p, pkthdr, pkt);
381            return;
382 
383         case ETHERNET_TYPE_IPX:
384             DecodeIPX(p->pkt + ETHERNET_HEADER_LEN,
385                     (cap_len - ETHERNET_HEADER_LEN), p);
386             return;
387 #endif
388 
389         case ETHERNET_TYPE_LOOP:
390             DecodeEthLoopback(p->pkt + ETHERNET_HEADER_LEN,
391                     (cap_len - ETHERNET_HEADER_LEN), p);
392             return;
393 
394         case ETHERNET_TYPE_8021Q:
395             DecodeVlan(p->pkt + ETHERNET_HEADER_LEN,
396                     cap_len - ETHERNET_HEADER_LEN, p);
397             return;
398 #ifdef MPLS
399         case ETHERNET_TYPE_MPLS_MULTICAST:
400 // barnyard2 should not add additional events
401 //            if(!ScMplsMulticast())
402 //            {
403 //                //additional check for DecoderAlerts will be done now.
404 //            	queueDecoderEvent(GENERATOR_SNORT_DECODE, DECODE_BAD_MPLS, 1, DECODE_CLASS, 3, DECODE_MULTICAST_MPLS_STR, 0);
405 //            }
406         case ETHERNET_TYPE_MPLS_UNICAST:
407             {
408                 struct pcap_pkthdr pkthdrTmp;
409                 pkthdrTmp.caplen = pkthdr->caplen - ETHERNET_HEADER_LEN;
410                 pkthdrTmp.len = pkthdr->len - ETHERNET_HEADER_LEN;
411                 DecodeMPLS(p->pkt + ETHERNET_HEADER_LEN, &pkthdrTmp, p);
412                 return;
413             }
414 #endif
415         default:
416             pc.other++;
417             return;
418     }
419 
420     return;
421 }
422 
423 
424 #ifndef NO_NON_ETHER_DECODER
425 /*
426  * Function: DecodeIEEE80211Pkt(Packet *, char *, struct pcap_pkthdr*,
427  *                               uint8_t*)
428  *
429  * Purpose: Decode those fun loving wireless LAN packets, one at a time!
430  *
431  * Arguments: p => pointer to the decoded packet struct
432  *            user => Utility pointer (unused)
433  *            pkthdr => ptr to the packet header
434  *            pkt => pointer to the real live packet data
435  *
436  * Returns: void function
437  */
DecodeIEEE80211Pkt(Packet * p,const struct pcap_pkthdr * pkthdr,const uint8_t * pkt)438 void DecodeIEEE80211Pkt(Packet * p, const struct pcap_pkthdr * pkthdr,
439                         const uint8_t * pkt)
440 {
441     uint32_t pkt_len;      /* suprisingly, the length of the packet */
442     uint32_t cap_len;      /* caplen value */
443 
444     pc.total_processed++;
445 
446     memset(p, 0, PKT_ZERO_LEN);
447 
448     p->pkth = pkthdr;
449     p->pkt = pkt;
450 
451     /* set the lengths we need */
452     pkt_len = pkthdr->len;  /* total packet length */
453     cap_len = pkthdr->caplen;   /* captured packet length */
454 
455     if (pcap_snaplen < pkt_len)
456         pkt_len = cap_len;
457 
458     DEBUG_WRAP(DebugMessage(DEBUG_DECODE, "Packet!\n"););
459     DEBUG_WRAP(DebugMessage(DEBUG_DECODE, "caplen: %lu    pktlen: %lu\n",
460                 (unsigned long)cap_len, (unsigned long)pkt_len););
461 
462     /* do a little validation */
463     if(p->pkth->caplen < MINIMAL_IEEE80211_HEADER_LEN)
464     {
465         if (BcLogVerbose())
466         {
467             ErrorMessage("Captured data length < IEEE 802.11 header length! "
468                          "(%d bytes)\n", p->pkth->caplen);
469         }
470         return;
471     }
472     /* lay the wireless structure over the packet data */
473     p->wifih = (WifiHdr *) pkt;
474 
475     DEBUG_WRAP(DebugMessage(DEBUG_DECODE, "%X   %X\n", *p->wifih->addr1,
476                 *p->wifih->addr2););
477 
478     /* determine frame type */
479     switch(p->wifih->frame_control & 0x00ff)
480     {
481         /* management frames */
482         case WLAN_TYPE_MGMT_ASREQ:
483         case WLAN_TYPE_MGMT_ASRES:
484         case WLAN_TYPE_MGMT_REREQ:
485         case WLAN_TYPE_MGMT_RERES:
486         case WLAN_TYPE_MGMT_PRREQ:
487         case WLAN_TYPE_MGMT_PRRES:
488         case WLAN_TYPE_MGMT_BEACON:
489         case WLAN_TYPE_MGMT_ATIM:
490         case WLAN_TYPE_MGMT_DIS:
491         case WLAN_TYPE_MGMT_AUTH:
492         case WLAN_TYPE_MGMT_DEAUTH:
493             pc.wifi_mgmt++;
494             break;
495 
496             /* Control frames */
497         case WLAN_TYPE_CONT_PS:
498         case WLAN_TYPE_CONT_RTS:
499         case WLAN_TYPE_CONT_CTS:
500         case WLAN_TYPE_CONT_ACK:
501         case WLAN_TYPE_CONT_CFE:
502         case WLAN_TYPE_CONT_CFACK:
503             pc.wifi_control++;
504             break;
505             /* Data packets without data */
506         case WLAN_TYPE_DATA_NULL:
507         case WLAN_TYPE_DATA_CFACK:
508         case WLAN_TYPE_DATA_CFPL:
509         case WLAN_TYPE_DATA_ACKPL:
510 
511             pc.wifi_data++;
512             break;
513         case WLAN_TYPE_DATA_DTCFACK:
514         case WLAN_TYPE_DATA_DTCFPL:
515         case WLAN_TYPE_DATA_DTACKPL:
516         case WLAN_TYPE_DATA_DATA:
517             pc.wifi_data++;
518 
519             if(cap_len < IEEE802_11_DATA_HDR_LEN + sizeof(EthLlc))
520             {
521                 if(BcLogVerbose())
522                     ErrorMessage("Not enough data for EthLlc header\n");
523 
524                return;
525             }
526 
527             p->ehllc = (EthLlc *) (pkt + IEEE802_11_DATA_HDR_LEN);
528 
529 #ifdef DEBUG
530             PrintNetData(stdout,(uint8_t *)  p->ehllc, sizeof(EthLlc));
531             //ClearDumpBuf();
532 
533             printf("LLC Header:\n");
534             printf("   DSAP: 0x%X\n", p->ehllc->dsap);
535             printf("   SSAP: 0x%X\n", p->ehllc->ssap);
536 #endif
537 
538             if(p->ehllc->dsap == ETH_DSAP_IP && p->ehllc->ssap == ETH_SSAP_IP)
539             {
540                 if(cap_len < IEEE802_11_DATA_HDR_LEN +
541                    sizeof(EthLlc) + sizeof(EthLlcOther))
542                 {
543                     if (BcLogVerbose())
544                         ErrorMessage("Not enough data for EthLlcOther header\n");
545 
546                     return;
547                 }
548 
549                 p->ehllcother = (EthLlcOther *) (pkt + IEEE802_11_DATA_HDR_LEN + sizeof(EthLlc));
550 #ifdef DEBUG
551                 PrintNetData(stdout,(uint8_t *) p->ehllcother, sizeof(EthLlcOther));
552                 //ClearDumpBuf();
553                 printf("LLC Other Header:\n");
554                 printf("   CTRL: 0x%X\n", p->ehllcother->ctrl);
555                 printf("   ORG: 0x%02X%02X%02X\n", p->ehllcother->org_code[0],
556                         p->ehllcother->org_code[1], p->ehllcother->org_code[2]);
557                 printf("   PROTO: 0x%04X\n", ntohs(p->ehllcother->proto_id));
558 #endif
559 
560                 switch(ntohs(p->ehllcother->proto_id))
561                 {
562                     case ETHERNET_TYPE_IP:
563                         DecodeIP(p->pkt + IEEE802_11_DATA_HDR_LEN + sizeof(EthLlc) +
564                                 sizeof(EthLlcOther),
565                                 pkt_len - IEEE802_11_DATA_HDR_LEN - sizeof(EthLlc) -
566                                 sizeof(EthLlcOther), p);
567                         return;
568 
569                     case ETHERNET_TYPE_ARP:
570                     case ETHERNET_TYPE_REVARP:
571                         DecodeARP(p->pkt + IEEE802_11_DATA_HDR_LEN + sizeof(EthLlc) +
572                                 sizeof(EthLlcOther),
573                                 pkt_len - IEEE802_11_DATA_HDR_LEN - sizeof(EthLlc) -
574                                 sizeof(EthLlcOther), p);
575                         return;
576                     case ETHERNET_TYPE_EAPOL:
577                         DecodeEapol(p->pkt + IEEE802_11_DATA_HDR_LEN + sizeof(EthLlc) +
578                                 sizeof(EthLlcOther),
579                                 pkt_len - IEEE802_11_DATA_HDR_LEN - sizeof(EthLlc) -
580                                 sizeof(EthLlcOther), p);
581                         return;
582                     case ETHERNET_TYPE_8021Q:
583                         DecodeVlan(p->pkt + IEEE802_11_DATA_HDR_LEN ,
584                                    cap_len - IEEE802_11_DATA_HDR_LEN , p);
585                         return;
586 
587                     case ETHERNET_TYPE_IPV6:
588                         DecodeIPV6(p->pkt + IEEE802_11_DATA_HDR_LEN,
589                                 cap_len - IEEE802_11_DATA_HDR_LEN, p);
590                         return;
591 
592                     default:
593                         pc.other++;
594                         return;
595                 }
596             }
597             break;
598         default:
599             pc.other++;
600             break;
601     }
602 
603     return;
604 }
605 #endif  //NO_NON_ETHER_DECODER
606 
607 #ifdef MPLS
608 /*
609  * check if reserved labels are used properly
610  */
checkMplsHdr(uint32_t label,uint8_t exp,uint8_t bos,uint8_t ttl,Packet * p)611 static int checkMplsHdr(uint32_t label, uint8_t exp, uint8_t bos, uint8_t ttl, Packet *p)
612 {
613     int iRet = 0;
614     switch(label)
615     {
616         case 0:
617         case 2:
618                /* check if this label is the bottom of the stack */
619                if(bos)
620                {
621                    if ( label == 0 )
622                        iRet = MPLS_PAYLOADTYPE_IPV4;
623                    else if ( label == 2 )
624                        iRet = MPLS_PAYLOADTYPE_IPV6;
625 
626 
627                    /* when label == 2, IPv6 is expected;
628                     * when label == 0, IPv4 is expected */
629                    break;
630                }
631 #if 0
632                /* This is valid per RFC 4182.  Just pop this label off, ignore it
633                 * and move on to the next one.
634                 */
635                if (BcLogVerbose())
636                {
637                    if( !label )
638                        ErrorMessage("Label value zero appears in nonbottom MPLS header\n");
639                    else
640                        ErrorMessage("Label value two appears in nonbottom MPLS header\n");
641                }
642 
643                pc.discards++;
644                p->iph = NULL;
645 #ifdef SUP_IP6
646                p->family = NO_IP;
647 #endif
648                return(-1);
649 #endif
650                break;
651         case 1:
652                if(!bos) break;
653 
654                if (BcLogVerbose())
655                ErrorMessage("Label value one appears in bottom MPLS header\n");
656 
657                pc.discards++;
658                p->iph = NULL;
659 #ifdef SUP_IP6
660                p->family = NO_IP;
661 #endif
662                iRet = MPLS_PAYLOADTYPE_ERROR;
663                break;
664 
665 	    case 3:
666                if (BcLogVerbose())
667                    ErrorMessage("Label value three appears in MPLS header\n");
668 
669                pc.discards++;
670                p->iph = NULL;
671 #ifdef SUP_IP6
672                p->family = NO_IP;
673 #endif
674                iRet = MPLS_PAYLOADTYPE_ERROR;
675                break;
676         case 4:
677         case 5:
678         case 6:
679         case 7:
680         case 8:
681         case 9:
682         case 10:
683         case 11:
684         case 12:
685         case 13:
686         case 14:
687         case 15:
688                 if(BcLogVerbose())
689                     ErrorMessage("Reserved label value appears in MPLS header\n");
690 
691                 break;
692         default:
693                 break;
694     }
695     if ( !iRet )
696     {
697         iRet = BcMplsPayloadType();
698     }
699     return iRet;
700 }
701 
DecodeMPLS(const uint8_t * pkt,struct pcap_pkthdr * pkthdr,Packet * p)702 void DecodeMPLS(const uint8_t * pkt, struct pcap_pkthdr * pkthdr, Packet * p)
703 {
704     uint32_t    *tmpMplsHdr;
705     uint32_t    mpls_h;
706     uint32_t    label;
707     uint8_t     exp;
708     uint8_t     bos = 0;
709     uint8_t     ttl;
710     uint8_t     chainLen = 0;
711     int         iRet = 0;
712 
713     pc.mpls++;
714 //    UpdateMPLSStats(&sfBase, pkthdr->caplen);
715     tmpMplsHdr = (uint32_t *) pkt;
716     p->mpls = NULL;
717     while (!bos)
718     {
719         if(pkthdr->caplen < MPLS_HEADER_LEN)
720         {
721             if (BcLogVerbose())
722                 ErrorMessage("Not enough data to process an MPLS header\n");
723 
724             pc.discards++;
725             p->iph = NULL;
726 #ifdef SUP_IP6
727             p->family = NO_IP;
728 #endif
729             return;
730         }
731 
732         mpls_h  = ntohl(*tmpMplsHdr);
733         ttl = (uint8_t)(mpls_h & 0x000000FF);
734         mpls_h = mpls_h>>8;
735         bos = (uint8_t)(mpls_h & 0x00000001);
736         exp = (uint8_t)(mpls_h & 0x0000000E);
737         label = (mpls_h>>4) & 0x000FFFFF;
738 
739         if((label<NUM_RESERVED_LABELS)&&((iRet = checkMplsHdr(label, exp, bos, ttl, p)) < 0))
740             return;
741 
742         if( bos )
743         {
744             p->mplsHdr.label = label;
745             p->mplsHdr.exp = exp;
746             p->mplsHdr.bos = bos;
747             p->mplsHdr.ttl = ttl;
748             /**
749             p->mpls = &(p->mplsHdr);
750 			**/
751             p->mpls = tmpMplsHdr;
752             if(!iRet)
753             {
754                 iRet = BcMplsPayloadType();
755             }
756         }
757         tmpMplsHdr++;
758         pkthdr->caplen -= MPLS_HEADER_LEN;
759         pkthdr->len -= MPLS_HEADER_LEN;
760         if ((BcMplsStackDepth() != -1) && (chainLen++ >= BcMplsStackDepth()))
761         {
762             if (BcLogVerbose())
763                 ErrorMessage("MPLS header chain too long\n");
764 
765             pc.discards++;
766             p->iph = NULL;
767 #ifdef SUP_IP6
768             p->family = NO_IP;
769 #endif
770             return;
771         }
772     }   /* while bos not 1, peel off more labels */
773 
774     switch (iRet)
775     {
776         case MPLS_PAYLOADTYPE_IPV4:
777             DecodeIP((uint8_t *)tmpMplsHdr, pkthdr->caplen, p);
778             break;
779 
780         case MPLS_PAYLOADTYPE_IPV6:
781             DecodeIPV6((uint8_t *)tmpMplsHdr, pkthdr->caplen, p);
782             break;
783 
784         case MPLS_PAYLOADTYPE_ETHERNET:
785             DecodeEthOverMPLS(p, pkthdr, (uint8_t *)tmpMplsHdr);
786             break;
787 
788         default:
789             break;
790     }
791 
792     return;
793 }
794 
DecodeEthOverMPLS(Packet * p,const struct pcap_pkthdr * pkthdr,const uint8_t * pkt)795 void DecodeEthOverMPLS(Packet * p, const struct pcap_pkthdr * pkthdr, const uint8_t * pkt)
796 {
797     uint32_t pkt_len;
798     uint32_t cap_len;
799 
800     memset(p, 0, PKT_ZERO_LEN);
801 
802     p->pkth = pkthdr;
803     p->pkt = pkt;
804 
805     /* set the lengths we need */
806     pkt_len = pkthdr->len;  /* total packet length */
807     cap_len = pkthdr->caplen;   /* captured packet length */
808 
809     /* do a little validation */
810     if(cap_len < ETHERNET_HEADER_LEN)
811     {
812         if (BcLogVerbose())
813         {
814             ErrorMessage("Captured data length < Ethernet header length!"
815                          " (%d bytes)\n", p->pkth->caplen);
816         }
817 
818         p->iph = NULL;
819         pc.discards++;
820         pc.ethdisc++;
821         return;
822     }
823 
824     /* lay the ethernet structure over the packet data */
825     p->eh = (EtherHdr *) pkt;
826 
827     DEBUG_WRAP(
828             DebugMessage(DEBUG_DECODE, "%X   %X\n",
829                 *p->eh->ether_src, *p->eh->ether_dst);
830             );
831 
832     /* grab out the network type */
833     switch(ntohs(p->eh->ether_type))
834     {
835         case ETHERNET_TYPE_IP:
836             DEBUG_WRAP(
837                     DebugMessage(DEBUG_DECODE,
838                         "IP datagram size calculated to be %lu bytes\n",
839                         (unsigned long)(cap_len - ETHERNET_HEADER_LEN));
840                     );
841 
842             DecodeIP(p->pkt + ETHERNET_HEADER_LEN,
843                     cap_len - ETHERNET_HEADER_LEN, p);
844 
845             return;
846 
847         case ETHERNET_TYPE_ARP:
848         case ETHERNET_TYPE_REVARP:
849             DecodeARP(p->pkt + ETHERNET_HEADER_LEN,
850                     cap_len - ETHERNET_HEADER_LEN, p);
851             return;
852 
853         case ETHERNET_TYPE_IPV6:
854             DecodeIPV6(p->pkt + ETHERNET_HEADER_LEN,
855                     (cap_len - ETHERNET_HEADER_LEN), p);
856             return;
857 
858 #ifndef NO_NON_ETHER_DECODER
859         case ETHERNET_TYPE_PPPoE_DISC:
860         case ETHERNET_TYPE_PPPoE_SESS:
861             DecodePPPoEPkt(p, pkthdr, pkt);
862             return;
863 
864         case ETHERNET_TYPE_IPX:
865             DecodeIPX(p->pkt + ETHERNET_HEADER_LEN,
866                     (cap_len - ETHERNET_HEADER_LEN), p);
867             return;
868 #endif
869 
870         case ETHERNET_TYPE_LOOP:
871             DecodeEthLoopback(p->pkt + ETHERNET_HEADER_LEN,
872                     (cap_len - ETHERNET_HEADER_LEN), p);
873             return;
874 
875         case ETHERNET_TYPE_8021Q:
876             DecodeVlan(p->pkt + ETHERNET_HEADER_LEN,
877                     cap_len - ETHERNET_HEADER_LEN, p);
878             return;
879 
880         default:
881             pc.other++;
882             return;
883     }
884 
885     return;
886 }
887 #endif
888 
DecodeVlan(const uint8_t * pkt,const uint32_t len,Packet * p)889 void DecodeVlan(const uint8_t * pkt, const uint32_t len, Packet * p)
890 {
891     pc.vlan++;
892 
893 #ifdef GRE
894     if (p->greh != NULL)
895         pc.gre_vlan++;
896 #endif
897 
898     if(len < sizeof(VlanTagHdr))
899     {
900         if (BcLogVerbose())
901             ErrorMessage("Not enough data to process a vlan header\n");
902 
903         pc.discards++;
904         p->iph = NULL;
905 #ifdef SUP_IP6
906         p->family = NO_IP;
907 #endif
908         return;
909     }
910 
911     p->vh = (VlanTagHdr *) pkt;
912 
913     DEBUG_WRAP(DebugMessage(DEBUG_DECODE, "Vlan traffic:\n");
914                DebugMessage(DEBUG_DECODE, "   Priority: %d(0x%X)\n",
915                             VTH_PRIORITY(p->vh), VTH_PRIORITY(p->vh));
916                DebugMessage(DEBUG_DECODE, "   CFI: %d\n", VTH_CFI(p->vh));
917                DebugMessage(DEBUG_DECODE, "   Vlan ID: %d(0x%04X)\n",
918                             VTH_VLAN(p->vh), VTH_VLAN(p->vh));
919                DebugMessage(DEBUG_DECODE, "   Vlan Proto: 0x%04X\n",
920                             ntohs(p->vh->vth_proto));
921                );
922 
923     /* check to see if we've got an encapsulated LLC layer
924      * http://www.geocities.com/billalexander/ethernet.html
925      */
926     if(ntohs(p->vh->vth_proto) <= ETHERNET_MAX_LEN_ENCAP)
927     {
928         if(len < sizeof(VlanTagHdr) + sizeof(EthLlc))
929         {
930             if (BcLogVerbose())
931             {
932                 ErrorMessage("Not enough data for EthLlc header");
933             }
934 
935             pc.discards++;
936             p->iph = NULL;
937 #ifdef SUP_IP6
938             p->family = NO_IP;
939 #endif
940             return;
941         }
942 
943         p->ehllc = (EthLlc *) (pkt + sizeof(VlanTagHdr));
944 
945         DEBUG_WRAP(
946                 DebugMessage(DEBUG_DECODE, "LLC Header:\n");
947                 DebugMessage(DEBUG_DECODE, "   DSAP: 0x%X\n", p->ehllc->dsap);
948                 DebugMessage(DEBUG_DECODE, "   SSAP: 0x%X\n", p->ehllc->ssap);
949                 );
950 
951         if(p->ehllc->dsap == ETH_DSAP_IP && p->ehllc->ssap == ETH_SSAP_IP)
952         {
953             if(len < sizeof(VlanTagHdr) + sizeof(EthLlc) + sizeof(EthLlcOther))
954             {
955                 if (BcLogVerbose())
956                 {
957                     ErrorMessage("Not enough data for VLAN header");
958                 }
959 
960                 pc.discards++;
961                 p->iph = NULL;
962 #ifdef SUP_IP6
963                 p->family = NO_IP;
964 #endif
965 
966                 return;
967             }
968 
969             p->ehllcother = (EthLlcOther *) (pkt + sizeof(VlanTagHdr) + sizeof(EthLlc));
970 
971             DEBUG_WRAP(
972                     DebugMessage(DEBUG_DECODE, "LLC Other Header:\n");
973                     DebugMessage(DEBUG_DECODE, "   CTRL: 0x%X\n",
974                         p->ehllcother->ctrl);
975                     DebugMessage(DEBUG_DECODE, "   ORG: 0x%02X%02X%02X\n",
976                         p->ehllcother->org_code[0], p->ehllcother->org_code[1],
977                         p->ehllcother->org_code[2]);
978                     DebugMessage(DEBUG_DECODE, "   PROTO: 0x%04X\n",
979                         ntohs(p->ehllcother->proto_id));
980                     );
981 
982             switch(ntohs(p->ehllcother->proto_id))
983             {
984                 case ETHERNET_TYPE_IP:
985                     DecodeIP(p->pkt + sizeof(VlanTagHdr) + sizeof(EthLlc) + sizeof(EthLlcOther),
986                              len - sizeof(VlanTagHdr) - sizeof(EthLlc) - sizeof(EthLlcOther), p);
987                     return;
988 
989                 case ETHERNET_TYPE_ARP:
990                 case ETHERNET_TYPE_REVARP:
991                     DecodeARP(p->pkt + sizeof(VlanTagHdr) + sizeof(EthLlc) + sizeof(EthLlcOther),
992                               len - sizeof(VlanTagHdr) - sizeof(EthLlc) - sizeof(EthLlcOther), p);
993                     return;
994 
995                 case ETHERNET_TYPE_IPV6:
996                     DecodeIPV6(p->pkt + sizeof(VlanTagHdr) + sizeof(EthLlc) + sizeof(EthLlcOther),
997                                len - sizeof(VlanTagHdr) - sizeof(EthLlc) - sizeof(EthLlcOther), p);
998                     return;
999 
1000                 case ETHERNET_TYPE_8021Q:
1001                     pc.nested_vlan++;
1002                     DecodeVlan(p->pkt + sizeof(VlanTagHdr) + sizeof(EthLlc) + sizeof(EthLlcOther),
1003                                len - sizeof(VlanTagHdr) - sizeof(EthLlc) - sizeof(EthLlcOther), p);
1004                     return;
1005 
1006                 case ETHERNET_TYPE_LOOP:
1007                     DecodeEthLoopback(p->pkt + sizeof(VlanTagHdr) + sizeof(EthLlc) + sizeof(EthLlcOther),
1008                                       len - sizeof(VlanTagHdr) - sizeof(EthLlc) - sizeof(EthLlcOther), p);
1009                     return;
1010 
1011 #ifndef NO_NON_ETHER_DECODER
1012                 case ETHERNET_TYPE_IPX:
1013                     DecodeIPX(p->pkt + sizeof(VlanTagHdr) + sizeof(EthLlc) + sizeof(EthLlcOther),
1014                               len - sizeof(VlanTagHdr) - sizeof(EthLlc) - sizeof(EthLlcOther), p);
1015                     return;
1016 
1017                 /* Add these after DecodePPPoEPkt() has been reimplemented */
1018                 case ETHERNET_TYPE_PPPoE_DISC:
1019                 case ETHERNET_TYPE_PPPoE_SESS:
1020 	            {
1021                         struct pcap_pkthdr pkthdrTmp;
1022                         pkthdrTmp.caplen = len - sizeof(VlanTagHdr) - sizeof(EthLlc) - sizeof(EthLlcOther);
1023                         pkthdrTmp.len = len - sizeof(VlanTagHdr) - sizeof(EthLlc) - sizeof(EthLlcOther);
1024                         DecodePPPoEPkt(p,&pkthdrTmp, p->pkt + sizeof(VlanTagHdr) + sizeof(EthLlc) + sizeof(EthLlcOther));
1025                         return;
1026                     }
1027 #endif
1028 #ifdef MPLS
1029                 case ETHERNET_TYPE_MPLS_MULTICAST:
1030                 case ETHERNET_TYPE_MPLS_UNICAST:
1031                     {
1032                         struct pcap_pkthdr pkthdrTmp;
1033                         pkthdrTmp.caplen = len - sizeof(VlanTagHdr) - sizeof(EthLlc) - sizeof(EthLlcOther);
1034                         pkthdrTmp.len = len - sizeof(VlanTagHdr) - sizeof(EthLlc) - sizeof(EthLlcOther);
1035                         DecodeMPLS(p->pkt + sizeof(VlanTagHdr) + sizeof(EthLlc) + sizeof(EthLlcOther), &pkthdrTmp, p);
1036                         return;
1037                     }
1038 #endif
1039 
1040 
1041                 default:
1042                     pc.other++;
1043                     return;
1044             }
1045         }
1046     }
1047     else
1048     {
1049         switch(ntohs(p->vh->vth_proto))
1050         {
1051             case ETHERNET_TYPE_IP:
1052                 DecodeIP(pkt + sizeof(VlanTagHdr),
1053                          len - sizeof(VlanTagHdr), p);
1054                 return;
1055 
1056             case ETHERNET_TYPE_ARP:
1057             case ETHERNET_TYPE_REVARP:
1058                 DecodeARP(pkt + sizeof(VlanTagHdr),
1059                           len - sizeof(VlanTagHdr), p);
1060                 return;
1061 
1062             case ETHERNET_TYPE_IPV6:
1063                 DecodeIPV6(pkt +sizeof(VlanTagHdr),
1064                            len - sizeof(VlanTagHdr), p);
1065                 return;
1066 
1067             case ETHERNET_TYPE_8021Q:
1068                 pc.nested_vlan++;
1069                 DecodeVlan(pkt + sizeof(VlanTagHdr),
1070                            len - sizeof(VlanTagHdr), p);
1071                 return;
1072 
1073             case ETHERNET_TYPE_LOOP:
1074                 DecodeEthLoopback(pkt + sizeof(VlanTagHdr),
1075                                   len - sizeof(VlanTagHdr), p);
1076                 return;
1077 
1078 #ifndef NO_NON_ETHER_DECODER
1079             case ETHERNET_TYPE_IPX:
1080                 DecodeIPX(pkt + sizeof(VlanTagHdr),
1081                            len - sizeof(VlanTagHdr), p);
1082                 return;
1083 
1084 #if 0
1085             /* Add these after DecodePPPoEPkt() has been reimplemented */
1086             case ETHERNET_TYPE_PPPoE_DISC:
1087             case ETHERNET_TYPE_PPPoE_SESS:
1088                 DecodePPPoEPkt(pkt + sizeof(VlanTagHdr),
1089                                len - sizeof(VlanTagHdr), p);
1090                 return;
1091 #endif
1092 #endif
1093 
1094 #ifdef MPLS
1095             case ETHERNET_TYPE_MPLS_MULTICAST:
1096             case ETHERNET_TYPE_MPLS_UNICAST:
1097                 {
1098                     struct pcap_pkthdr pkthdrTmp;
1099                     pkthdrTmp.caplen = len - sizeof(VlanTagHdr);
1100                     pkthdrTmp.len = len - sizeof(VlanTagHdr);
1101                     DecodeMPLS(pkt + sizeof(VlanTagHdr), &pkthdrTmp, p);
1102                     return;
1103                 }
1104 #endif
1105             default:
1106                 pc.other++;
1107                 return;
1108         }
1109     }
1110 
1111     pc.other++;
1112     return;
1113 }
1114 
1115 #ifdef GIDS
1116 #ifndef IPFW
1117 /*
1118  * Function: DecodeIptablesPkt(Packet *, char *, struct pcap_pkthdr*, uint8_t*)
1119  *
1120  * Purpose: Decoding iptables.
1121  *
1122  * Arguments: p => pointer to decoded packet struct
1123  *            user => Utility pointer, unused
1124  *            pkthdr => ptr to the packet header
1125  *            pkt => pointer to the real live packet data
1126  *
1127  */
DecodeIptablesPkt(Packet * p,const struct pcap_pkthdr * pkthdr,const uint8_t * pkt)1128 void DecodeIptablesPkt(Packet * p, const struct pcap_pkthdr * pkthdr, const uint8_t * pkt)
1129 {
1130     uint32_t len;
1131     uint32_t cap_len;
1132 
1133     pc.iptables++;
1134     pc.total_processed++;
1135 
1136     memset(p, 0, PKT_ZERO_LEN);
1137     p->pkth = pkthdr;
1138     p->pkt = pkt;
1139 
1140     len = pkthdr->len;
1141     cap_len = pkthdr->caplen;
1142 
1143     DecodeIP(p->pkt, cap_len, p);
1144 
1145 }
1146 #else
1147 /*
1148  * Function: DecodeIpfwPkt(Packet *, char *, struct pcap_pkthdr*, uint8_t*)
1149  *
1150  * Purpose: Decoding ipfw divert socket
1151  *
1152  * Arguments: p => pointer to decoded packet struct
1153  *            user => Utility pointer, unused
1154  *            pkthdr => ptr to the packet header
1155  *            pkt => pointer to the real live packet data
1156  *
1157  */
DecodeIpfwPkt(Packet * p,const struct pcap_pkthdr * pkthdr,const uint8_t * pkt)1158 void DecodeIpfwPkt(Packet * p, const struct pcap_pkthdr * pkthdr, const uint8_t * pkt)
1159 {
1160     uint32_t len;
1161     uint32_t cap_len;
1162 
1163     pc.ipfw++;
1164     pc.total_processed++;
1165 
1166     memset(p, 0, PKT_ZERO_LEN);
1167     p->pkth = pkthdr;
1168     p->pkt = pkt;
1169 
1170     len = pkthdr->len;
1171     cap_len = pkthdr->caplen;
1172 
1173     DecodeIP(p->pkt, cap_len, p);
1174 
1175 }
1176 #endif
1177 #endif /* GIDS */
1178 
1179 
1180 /*
1181  * Function: DecodeNullPkt(Packet *, char *, struct pcap_pkthdr*, uint8_t*)
1182  *
1183  * Purpose: Decoding on loopback devices.
1184  *
1185  * Arguments: p => pointer to decoded packet struct
1186  *            user => Utility pointer, unused
1187  *            pkthdr => ptr to the packet header
1188  *            pkt => pointer to the real live packet data
1189  *
1190  * Returns: void function
1191  */
DecodeNullPkt(Packet * p,const struct pcap_pkthdr * pkthdr,const uint8_t * pkt)1192 void DecodeNullPkt(Packet * p, const struct pcap_pkthdr * pkthdr, const uint8_t * pkt)
1193 {
1194     uint32_t len;
1195     uint32_t cap_len;
1196 
1197     pc.total_processed++;
1198 
1199     memset(p, 0, PKT_ZERO_LEN);
1200 
1201     p->pkth = pkthdr;
1202     p->pkt = pkt;
1203 
1204     len = pkthdr->len;
1205     cap_len = pkthdr->caplen;
1206 
1207     DEBUG_WRAP(DebugMessage(DEBUG_DECODE, "Packet!\n"); );
1208 
1209     /* do a little validation */
1210     if(cap_len < NULL_HDRLEN)
1211     {
1212         if (BcLogVerbose())
1213         {
1214             ErrorMessage("NULL header length < captured len! (%d bytes)\n",
1215                     cap_len);
1216         }
1217 
1218         return;
1219     }
1220 
1221     DecodeIP(p->pkt + NULL_HDRLEN, cap_len - NULL_HDRLEN, p);
1222 }
1223 
1224 #ifndef NO_NON_ETHER_DECODER
1225 /*
1226  * Function: DecodeTRPkt(Packet *, char *, struct pcap_pkthdr*, uint8_t*)
1227  *
1228  * Purpose: Decode Token Ring packets!
1229  *
1230  * Arguments: p=> pointer to decoded packet struct
1231  *            user => Utility pointer, unused
1232  *            pkthdr => ptr to the packet header
1233  *            pkt => pointer to the real live packet data
1234  *
1235  * Returns: void function
1236  */
DecodeTRPkt(Packet * p,const struct pcap_pkthdr * pkthdr,const uint8_t * pkt)1237 void DecodeTRPkt(Packet * p, const struct pcap_pkthdr * pkthdr, const uint8_t * pkt)
1238 {
1239     uint32_t pkt_len;      /* suprisingly, the length of the packet */
1240     uint32_t cap_len;      /* caplen value */
1241     uint32_t dataoff;      /* data offset is variable here */
1242 
1243     pc.total_processed++;
1244 
1245     memset(p, 0, PKT_ZERO_LEN);
1246 
1247     p->pkth = pkthdr;
1248     p->pkt = pkt;
1249 
1250 
1251     /* set the lengths we need */
1252     pkt_len = pkthdr->len;  /* total packet length */
1253     cap_len = pkthdr->caplen;   /* captured packet length */
1254 
1255     if (pcap_snaplen < pkt_len)
1256         pkt_len = cap_len;
1257 
1258     DEBUG_WRAP(DebugMessage(DEBUG_DECODE, "Packet!\n");
1259             DebugMessage(DEBUG_DECODE, "caplen: %lu    pktlen: %lu\n",
1260                 (unsigned long)cap_len,(unsigned long) pkt_len);
1261             );
1262 
1263     if(cap_len < sizeof(Trh_hdr))
1264     {
1265         if (BcLogVerbose())
1266             ErrorMessage("Captured data length < Token Ring header length! "
1267                          "(%d < %d bytes)\n", p->pkth->caplen, TR_HLEN);
1268 
1269         return;
1270     }
1271 
1272     /* lay the tokenring header structure over the packet data */
1273     p->trh = (Trh_hdr *) pkt;
1274 
1275     /*
1276      * according to rfc 1042:
1277      *
1278      *   The presence of a Routing Information Field is indicated by the Most
1279      *   Significant Bit (MSB) of the source address, called the Routing
1280      *   Information Indicator (RII).  If the RII equals zero, a RIF is
1281      *   not present.  If the RII equals 1, the RIF is present.
1282      *   ..
1283      *   However the MSB is already zeroed by this moment, so there's no
1284      *   real way to figure out whether RIF is presented in packet, so we are
1285      *   doing some tricks to find IPARP signature..
1286      */
1287 
1288     /*
1289      * first I assume that we have single-ring network with no RIF
1290      * information presented in frame
1291      */
1292     if(cap_len < (sizeof(Trh_hdr) + sizeof(Trh_llc)))
1293     {
1294         if (BcLogVerbose())
1295         {
1296             ErrorMessage("Captured data length < Token Ring header length! "
1297                          "(%d < %d bytes)\n", cap_len,
1298                          (sizeof(Trh_hdr) + sizeof(Trh_llc)));
1299         }
1300 
1301         return;
1302     }
1303 
1304 
1305     p->trhllc = (Trh_llc *) (pkt + sizeof(Trh_hdr));
1306 
1307     if(p->trhllc->dsap != IPARP_SAP && p->trhllc->ssap != IPARP_SAP)
1308     {
1309         /*
1310          * DSAP != SSAP != 0xAA .. either we are having frame which doesn't
1311          * carry IP datagrams or has RIF information present. We assume
1312          * lattest ...
1313          */
1314 
1315         if(cap_len < (sizeof(Trh_hdr) + sizeof(Trh_llc) + sizeof(Trh_mr)))
1316         {
1317             if (BcLogVerbose())
1318                 ErrorMessage("Captured data length < Token Ring header length! "
1319                              "(%d < %d bytes)\n", cap_len,
1320                              (sizeof(Trh_hdr) + sizeof(Trh_llc) + sizeof(Trh_mr)));
1321 
1322             return;
1323         }
1324 
1325         p->trhmr = (Trh_mr *) (pkt + sizeof(Trh_hdr));
1326 
1327 
1328         if(cap_len < (sizeof(Trh_hdr) + sizeof(Trh_llc) +
1329                       sizeof(Trh_mr) + TRH_MR_LEN(p->trhmr)))
1330         {
1331             if (BcLogVerbose())
1332                 ErrorMessage("Captured data length < Token Ring header length! "
1333                              "(%d < %d bytes)\n", cap_len,
1334                              (sizeof(Trh_hdr) + sizeof(Trh_llc) + sizeof(Trh_mr)));
1335 
1336             return;
1337         }
1338 
1339         p->trhllc = (Trh_llc *) (pkt + sizeof(Trh_hdr) + TRH_MR_LEN(p->trhmr));
1340         dataoff   = sizeof(Trh_hdr) + TRH_MR_LEN(p->trhmr) + sizeof(Trh_llc);
1341 
1342     }
1343     else
1344     {
1345         p->trhllc = (Trh_llc *) (pkt + sizeof(Trh_hdr));
1346         dataoff = sizeof(Trh_hdr) + sizeof(Trh_llc);
1347     }
1348 
1349     /*
1350      * ideally we would need to check both SSAP, DSAP, and protoid fields: IP
1351      * datagrams and ARP requests and replies are transmitted in standard
1352      * 802.2 LLC Type 1 Unnumbered Information format, control code 3, with
1353      * the DSAP and the SSAP fields of the 802.2 header set to 170, the
1354      * assigned global SAP value for SNAP [6].  The 24-bit Organization Code
1355      * in the SNAP is zero, and the remaining 16 bits are the EtherType from
1356      * Assigned Numbers [7] (IP = 2048, ARP = 2054). .. but we would check
1357      * SSAP and DSAP and assume this would be enough to trust.
1358      */
1359     if(p->trhllc->dsap != IPARP_SAP && p->trhllc->ssap != IPARP_SAP)
1360     {
1361         DEBUG_WRAP(
1362                    DebugMessage(DEBUG_DECODE, "DSAP and SSAP arent set to SNAP\n");
1363                 );
1364         p->trhllc = NULL;
1365         return;
1366     }
1367 
1368     switch(htons(p->trhllc->ethertype))
1369     {
1370         case ETHERNET_TYPE_IP:
1371             DEBUG_WRAP(DebugMessage(DEBUG_DECODE, "Decoding IP\n"););
1372             DecodeIP(p->pkt + dataoff, cap_len - dataoff, p);
1373             return;
1374 
1375         case ETHERNET_TYPE_ARP:
1376         case ETHERNET_TYPE_REVARP:
1377             DEBUG_WRAP(
1378                     DebugMessage(DEBUG_DECODE, "Decoding ARP\n");
1379                     );
1380             pc.arp++;
1381 
1382             return;
1383 
1384         case ETHERNET_TYPE_8021Q:
1385             DecodeVlan(p->pkt + dataoff, cap_len - dataoff, p);
1386             return;
1387 
1388         default:
1389             DEBUG_WRAP(DebugMessage(DEBUG_DECODE, "Unknown network protocol: %d\n",
1390                         htons(p->trhllc->ethertype)));
1391             pc.other++;
1392             return;
1393     }
1394 
1395     return;
1396 }
1397 
1398 
1399 /*
1400  * Function: DecodeFDDIPkt(Packet *, char *, struct pcap_pkthdr*, uint8_t*)
1401  *
1402  * Purpose: Mainly taken from CyberPsycotic's Token Ring Code -worm5er
1403  *
1404  * Arguments: p => pointer to decoded packet struct
1405  *            user => Utility pointer, unused
1406  *            pkthdr => ptr to the packet header
1407  *            pkt => pointer to the real live packet data
1408  *
1409  * Returns: void function
1410  */
DecodeFDDIPkt(Packet * p,const struct pcap_pkthdr * pkthdr,const uint8_t * pkt)1411 void DecodeFDDIPkt(Packet * p, const struct pcap_pkthdr * pkthdr, const uint8_t * pkt)
1412 {
1413     uint32_t pkt_len;      /* length of the packet */
1414     uint32_t cap_len;      /* capture length variable */
1415     uint32_t dataoff = sizeof(Fddi_hdr) + sizeof(Fddi_llc_saps);
1416 
1417     pc.total_processed++;
1418 
1419     memset(p, 0, PKT_ZERO_LEN);
1420 
1421     p->pkth = pkthdr;
1422     p->pkt = pkt;
1423 
1424     pkt_len = pkthdr->len;
1425     cap_len = pkthdr->caplen;
1426 
1427     if (pcap_snaplen < pkt_len)
1428     {
1429         pkt_len = cap_len;
1430     }
1431 
1432     DEBUG_WRAP(DebugMessage(DEBUG_DECODE,"Packet!\n");
1433             DebugMessage(DEBUG_DECODE, "caplen: %lu    pktlen: %lu\n",
1434                 (unsigned long) cap_len,(unsigned long) pkt_len);
1435             );
1436 
1437     /* Bounds checking (might not be right yet -worm5er) */
1438     if(p->pkth->caplen < dataoff)
1439     {
1440         if (BcLogVerbose())
1441         {
1442             ErrorMessage("Captured data length < FDDI header length! "
1443                          "(%d %d bytes)\n", p->pkth->caplen, dataoff);
1444             return;
1445         }
1446     }
1447     /* let's put this in as the fddi header structure */
1448     p->fddihdr = (Fddi_hdr *) pkt;
1449 
1450     p->fddisaps = (Fddi_llc_saps *) (pkt + sizeof(Fddi_hdr));
1451 
1452     /* First we'll check and see if it's an IP/ARP Packet... */
1453     /* Then we check to see if it's a SNA packet */
1454     /*
1455      * Lastly we'll declare it none of the above and just slap something
1456      * generic on it to discard it with (I know that sucks, but heck we're
1457      * only looking for IP/ARP type packets currently...  -worm5er
1458      */
1459     if((p->fddisaps->dsap == FDDI_DSAP_IP) && (p->fddisaps->ssap == FDDI_SSAP_IP))
1460     {
1461         dataoff += sizeof(Fddi_llc_iparp);
1462 
1463         if(p->pkth->caplen < dataoff)
1464         {
1465             if (BcLogVerbose())
1466             {
1467                 ErrorMessage("Captured data length < FDDI header length! "
1468                              "(%d %d bytes)\n", p->pkth->caplen, dataoff);
1469                 return;
1470             }
1471         }
1472 
1473         p->fddiiparp = (Fddi_llc_iparp *) (pkt + sizeof(Fddi_hdr) + sizeof(Fddi_llc_saps));
1474     }
1475     else if((p->fddisaps->dsap == FDDI_DSAP_SNA) &&
1476             (p->fddisaps->ssap == FDDI_SSAP_SNA))
1477     {
1478         dataoff += sizeof(Fddi_llc_sna);
1479 
1480         if(p->pkth->caplen < dataoff)
1481         {
1482             if (BcLogVerbose())
1483             {
1484                 ErrorMessage("Captured data length < FDDI header length! "
1485                              "(%d %d bytes)\n", p->pkth->caplen, dataoff);
1486                 return;
1487             }
1488         }
1489 
1490         p->fddisna = (Fddi_llc_sna *) (pkt + sizeof(Fddi_hdr) +
1491                                        sizeof(Fddi_llc_saps));
1492     }
1493     else
1494     {
1495         dataoff += sizeof(Fddi_llc_other);
1496         p->fddiother = (Fddi_llc_other *) (pkt + sizeof(Fddi_hdr) +
1497                 sizeof(Fddi_llc_other));
1498 
1499         if(p->pkth->caplen < dataoff)
1500         {
1501             if (BcLogVerbose())
1502             {
1503                 ErrorMessage("Captured data length < FDDI header length! "
1504                              "(%d %d bytes)\n", p->pkth->caplen, dataoff);
1505                 return;
1506             }
1507         }
1508     }
1509 
1510     /*
1511      * Now let's see if we actually care about the packet... If we don't,
1512      * throw it out!!!
1513      */
1514     if((p->fddisaps->dsap != FDDI_DSAP_IP) &&
1515             (p->fddisaps->ssap != FDDI_SSAP_IP))
1516     {
1517         DEBUG_WRAP(
1518                 DebugMessage(DEBUG_DECODE,
1519                     "This FDDI Packet isn't an IP/ARP packet...\n");
1520                 );
1521         return;
1522     }
1523 
1524     pkt_len -= dataoff;
1525     cap_len -= dataoff;
1526 
1527     switch(htons(p->fddiiparp->ethertype))
1528     {
1529         case ETHERNET_TYPE_IP:
1530             DEBUG_WRAP(DebugMessage(DEBUG_DECODE, "Decoding IP\n"););
1531             DecodeIP(p->pkt + dataoff, cap_len, p);
1532             return;
1533 
1534         case ETHERNET_TYPE_ARP:
1535         case ETHERNET_TYPE_REVARP:
1536             DEBUG_WRAP(DebugMessage(DEBUG_DECODE, "Decoding ARP\n"););
1537             pc.arp++;
1538 
1539             return;
1540 
1541         case ETHERNET_TYPE_8021Q:
1542             DecodeVlan(p->pkt + dataoff, cap_len, p);
1543             return;
1544 
1545 
1546         default:
1547             DEBUG_WRAP(DebugMessage(DEBUG_DECODE, "Unknown network protocol: %d\n",
1548                         htons(p->fddiiparp->ethertype));
1549                     );
1550             pc.other++;
1551 
1552             return;
1553     }
1554 
1555     return;
1556 }
1557 
1558 /*
1559  * Function: DecodeLinuxSLLPkt(Packet *, char *, struct pcap_pkthdr*, uint8_t*)
1560  *
1561  * Purpose: Decode those fun loving LinuxSLL (linux cooked sockets)
1562  *          packets, one at a time!
1563  *
1564  * Arguments: p => pointer to the decoded packet struct
1565  *            user => Utility pointer (unused)
1566  *            pkthdr => ptr to the packet header
1567  *            pkt => pointer to the real live packet data
1568  *
1569  * Returns: void function
1570  */
1571 
1572 #ifdef DLT_LINUX_SLL
1573 
DecodeLinuxSLLPkt(Packet * p,const struct pcap_pkthdr * pkthdr,const uint8_t * pkt)1574 void DecodeLinuxSLLPkt(Packet * p, const struct pcap_pkthdr * pkthdr, const uint8_t * pkt)
1575 {
1576     uint32_t pkt_len;      /* the length of the packet */
1577     uint32_t cap_len;      /* caplen value */
1578 
1579     pc.total_processed++;
1580 
1581     memset(p, 0, PKT_ZERO_LEN);
1582 
1583     p->pkth = pkthdr;
1584     p->pkt = pkt;
1585 
1586     /* set the lengths we need */
1587     pkt_len = pkthdr->len;  /* total packet length */
1588     cap_len = pkthdr->caplen;   /* captured packet length */
1589 
1590     if (pcap_snaplen < pkt_len)
1591         pkt_len = cap_len;
1592 
1593     DEBUG_WRAP(DebugMessage(DEBUG_DECODE,"Packet!\n");
1594             DebugMessage(DEBUG_DECODE, "caplen: %lu    pktlen: %lu\n",
1595                 (unsigned long)cap_len, (unsigned long)pkt_len););
1596 
1597     /* do a little validation */
1598     if(p->pkth->caplen < SLL_HDR_LEN)
1599     {
1600         if (BcLogVerbose())
1601         {
1602             ErrorMessage("Captured data length < SLL header length (your "
1603                          "libpcap is broken?)! (%d bytes)\n", p->pkth->caplen);
1604         }
1605         return;
1606     }
1607     /* lay the ethernet structure over the packet data */
1608     p->sllh = (SLLHdr *) pkt;
1609 
1610     /* grab out the network type */
1611     switch(ntohs(p->sllh->sll_protocol))
1612     {
1613         case ETHERNET_TYPE_IP:
1614             DEBUG_WRAP(DebugMessage(DEBUG_DECODE,
1615                         "IP datagram size calculated to be %lu bytes\n",
1616                         (unsigned long)(cap_len - SLL_HDR_LEN)););
1617 
1618             DecodeIP(p->pkt + SLL_HDR_LEN, cap_len - SLL_HDR_LEN, p);
1619             return;
1620 
1621         case ETHERNET_TYPE_ARP:
1622         case ETHERNET_TYPE_REVARP:
1623             DecodeARP(p->pkt + SLL_HDR_LEN, cap_len - SLL_HDR_LEN, p);
1624             return;
1625 
1626         case ETHERNET_TYPE_IPV6:
1627             DecodeIPV6(p->pkt + SLL_HDR_LEN, (cap_len - SLL_HDR_LEN), p);
1628             return;
1629 
1630         case ETHERNET_TYPE_IPX:
1631             DecodeIPX(p->pkt + SLL_HDR_LEN, (cap_len - SLL_HDR_LEN), p);
1632             return;
1633 
1634         case LINUX_SLL_P_802_3:
1635             DEBUG_WRAP(DebugMessage(DEBUG_DATALINK,
1636                         "Linux SLL P 802.3 is not supported.\n"););
1637             pc.other++;
1638             return;
1639 
1640         case LINUX_SLL_P_802_2:
1641             DEBUG_WRAP(DebugMessage(DEBUG_DATALINK,
1642                         "Linux SLL P 802.2 is not supported.\n"););
1643             pc.other++;
1644             return;
1645 
1646         case ETHERNET_TYPE_8021Q:
1647             DecodeVlan(p->pkt + SLL_HDR_LEN, cap_len - SLL_HDR_LEN, p);
1648             return;
1649 
1650         default:
1651             /* shouldn't go here unless pcap library changes again */
1652             /* should be a DECODE generated alert */
1653             DEBUG_WRAP(DebugMessage(DEBUG_DATALINK,"(Unknown) %X is not supported. "
1654                         "(need tcpdump snapshots to test. Please contact us)\n",
1655                         p->sllh->sll_protocol););
1656             pc.other++;
1657             return;
1658     }
1659 
1660     return;
1661 }
1662 
1663 #endif /* DLT_LINUX_SLL */
1664 
1665 /*
1666  * Function: DecodeOldPflog(Packet *, struct pcap_pkthdr *, uint8_t *)
1667  *
1668  * Purpose: Pass old pflog format device packets off to IP or IP6 -fleck
1669  *
1670  * Arguments: p => pointer to the decoded packet struct
1671  *            pkthdr => ptr to the packet header
1672  *            pkt => pointer to the packet data
1673  *
1674  * Returns: void function
1675  *
1676  */
DecodeOldPflog(Packet * p,const struct pcap_pkthdr * pkthdr,const uint8_t * pkt)1677 void DecodeOldPflog(Packet * p, const struct pcap_pkthdr * pkthdr, const uint8_t * pkt)
1678 {
1679     uint32_t pkt_len;      /* suprisingly, the length of the packet */
1680     uint32_t cap_len;      /* caplen value */
1681 
1682     pc.total_processed++;
1683 
1684     memset(p, 0, PKT_ZERO_LEN);
1685 
1686     p->pkth = pkthdr;
1687     p->pkt = pkt;
1688 
1689     /* set the lengths we need */
1690     pkt_len = pkthdr->len;  /* total packet length */
1691     cap_len = pkthdr->caplen;   /* captured packet length */
1692 
1693     if (pcap_snaplen < pkt_len)
1694         pkt_len = cap_len;
1695 
1696     DEBUG_WRAP(DebugMessage(DEBUG_DECODE, "Packet!\n");
1697             DebugMessage(DEBUG_DECODE, "caplen: %lu    pktlen: %lu\n",
1698                 (unsigned long)cap_len, (unsigned long)pkt_len););
1699 
1700     /* do a little validation */
1701     if(p->pkth->caplen < PFLOG1_HDRLEN)
1702     {
1703         if (BcLogVerbose())
1704         {
1705             ErrorMessage("Captured data length < Pflog header length! "
1706                     "(%d bytes)\n", p->pkth->caplen);
1707         }
1708         return;
1709     }
1710 
1711     /* lay the pf header structure over the packet data */
1712     p->pf1h = (Pflog1Hdr*)pkt;
1713 
1714     /*  get the network type - should only be AF_INET or AF_INET6 */
1715     switch(ntohl(p->pf1h->af))
1716     {
1717         case AF_INET:   /* IPv4 */
1718             DEBUG_WRAP(DebugMessage(DEBUG_DECODE, "IP datagram size calculated to be %lu "
1719                         "bytes\n", (unsigned long)(cap_len - PFLOG1_HDRLEN)););
1720 
1721             DecodeIP(p->pkt + PFLOG1_HDRLEN, cap_len - PFLOG1_HDRLEN, p);
1722             return;
1723 
1724 #if defined(AF_INET6) || defined(SUP_IP6)
1725         case AF_INET6:  /* IPv6 */
1726             DecodeIPV6(p->pkt + PFLOG1_HDRLEN, cap_len - PFLOG1_HDRLEN, p);
1727             return;
1728 #endif
1729 
1730         default:
1731             /* To my knowledge, pflog devices can only
1732              * pass IP and IP6 packets. -fleck
1733              */
1734             pc.other++;
1735             return;
1736     }
1737 
1738     return;
1739 }
1740 
1741 /*
1742  * Function: DecodePflog(Packet *, struct pcap_pkthdr *, uint8_t *)
1743  *
1744  * Purpose: Pass pflog device packets off to IP or IP6 -fleck
1745  *
1746  * Arguments: p => pointer to the decoded packet struct
1747  *            pkthdr => ptr to the packet header
1748  *            pkt => pointer to the packet data
1749  *
1750  * Returns: void function
1751  *
1752  */
DecodePflog(Packet * p,const struct pcap_pkthdr * pkthdr,const uint8_t * pkt)1753 void DecodePflog(Packet * p, const struct pcap_pkthdr * pkthdr, const uint8_t * pkt)
1754 {
1755     uint32_t pkt_len;      /* suprisingly, the length of the packet */
1756     uint32_t cap_len;      /* caplen value */
1757     uint8_t af, pflen;
1758     uint32_t hlen;
1759 
1760     pc.total_processed++;
1761 
1762     memset(p, 0, PKT_ZERO_LEN);
1763 
1764     p->pkth = pkthdr;
1765     p->pkt = pkt;
1766 
1767     /* set the lengths we need */
1768     pkt_len = pkthdr->len;  /* total packet length */
1769     cap_len = pkthdr->caplen;   /* captured packet length */
1770 
1771     if (pcap_snaplen < pkt_len)
1772         pkt_len = cap_len;
1773 
1774     DEBUG_WRAP(DebugMessage(DEBUG_DECODE, "Packet!\n");
1775             DebugMessage(DEBUG_DECODE, "caplen: %lu    pktlen: %lu\n",
1776                 (unsigned long)cap_len, (unsigned long)pkt_len););
1777 
1778     /* do a little validation */
1779     if(p->pkth->caplen < PFLOG2_HDRMIN)
1780     {
1781         if (BcLogVerbose())
1782         {
1783             ErrorMessage("Captured data length < minimum Pflog length! "
1784                     "(%d < %d)\n", p->pkth->caplen, PFLOG2_HDRMIN);
1785         }
1786         return;
1787     }
1788     /* lay the pf header structure over the packet data */
1789     if ( *((uint8_t*)pkt) < PFLOG3_HDRMIN )
1790     {
1791         p->pf2h = (Pflog2Hdr*)pkt;
1792         pflen = p->pf2h->length;
1793         hlen = PFLOG2_HDRLEN;
1794         af = p->pf2h->af;
1795     }
1796     else
1797     {
1798         p->pf3h = (Pflog3Hdr*)pkt;
1799         pflen = p->pf3h->length;
1800         hlen = PFLOG3_HDRLEN;
1801         af = p->pf3h->af;
1802     }
1803     /* now that we know a little more, do a little more validation */
1804     if(p->pkth->caplen < hlen)
1805     {
1806         if (BcLogVerbose())
1807         {
1808             ErrorMessage("Captured data length < Pflog header length! "
1809                     "(%d < %d)\n", p->pkth->caplen, hlen);
1810         }
1811         return;
1812     }
1813     /* note that the pflen may exclude the padding which is always present */
1814     if(pflen < hlen - PFLOG_PADLEN || pflen > hlen)
1815     {
1816         if (BcLogVerbose())
1817         {
1818             ErrorMessage("Bad Pflog header length! (%d bytes)\n", pflen);
1819         }
1820 
1821         return;
1822     }
1823     DEBUG_WRAP(DebugMessage(DEBUG_DECODE, "IP datagram size calculated to be "
1824                 "%lu bytes\n", (unsigned long)(cap_len - hlen)););
1825 
1826     /* check the network type - should only be AF_INET or AF_INET6 */
1827     switch(af)
1828     {
1829         case AF_INET:   /* IPv4 */
1830             DecodeIP(p->pkt + hlen, cap_len - hlen, p);
1831             return;
1832 
1833 #if defined(AF_INET6) || defined(SUP_IP6)
1834         case AF_INET6:  /* IPv6 */
1835             DecodeIPV6(p->pkt + hlen, cap_len - hlen, p);
1836             return;
1837 #endif
1838 
1839         default:
1840             /* To my knowledge, pflog devices can only
1841              * pass IP and IP6 packets. -fleck
1842              */
1843             pc.other++;
1844             return;
1845     }
1846 
1847     return;
1848 }
1849 
1850 
1851 /*
1852  * Function: DecodePPPoEPkt(Packet *, char *, struct pcap_pkthdr*, uint8_t*)
1853  *
1854  * Purpose: Decode those fun loving ethernet packets, one at a time!
1855  *
1856  * Arguments: p => pointer to the decoded packet struct
1857  *            user => Utility pointer (unused)
1858  *            pkthdr => ptr to the packet header
1859  *            pkt => pointer to the real live packet data
1860  *
1861  * Returns: void function
1862  *
1863  * see http://www.faqs.org/rfcs/rfc2516.html
1864  *
1865  */
DecodePPPoEPkt(Packet * p,const struct pcap_pkthdr * pkthdr,const uint8_t * pkt)1866 void DecodePPPoEPkt(Packet * p, const struct pcap_pkthdr * pkthdr, const uint8_t * pkt)
1867 {
1868     uint32_t pkt_len;      /* suprisingly, the length of the packet */
1869     uint32_t cap_len;      /* caplen value */
1870     const PPPoEHdr *ppppoep=NULL;
1871     //PPPoE_Tag *ppppoe_tag=0;
1872     //PPPoE_Tag tag;  /* needed to avoid alignment problems */
1873 
1874     /* set the lengths we need */
1875     pkt_len = pkthdr->len;  /* total packet length */
1876     cap_len = pkthdr->caplen;   /* captured packet length */
1877 
1878     if (pcap_snaplen < pkt_len)
1879         pkt_len = cap_len;
1880 
1881     DEBUG_WRAP(DebugMessage(DEBUG_DECODE, "Packet!\n");
1882             DebugMessage(DEBUG_DECODE, "caplen: %lu    pktlen: %lu\n",
1883                 (unsigned long)cap_len, (unsigned long)pkt_len););
1884 
1885     /* do a little validation */
1886     if(cap_len < PPPOE_HEADER_LEN)
1887     {
1888         if (BcLogVerbose())
1889         {
1890             ErrorMessage("Captured data length < Ethernet header length! "
1891                          "(%d bytes)\n", p->pkth->caplen);
1892         }
1893 
1894         return;
1895     }
1896 
1897     /* XXX - MFR
1898      * This code breaks the decode model that Snort uses, we should
1899      * reimplement it properly ASAP
1900      */
1901     /*
1902      * Not sure how long ago the above comment was added, but
1903      * it is now fixed.  It may or may not fall under the 'ASAP'
1904      * category.
1905      */
1906 
1907     /* lay the ethernet structure over the packet data */
1908     /* Don't need to do this.  It is already done in the decoding
1909      * of the ethernet header, which then calls this function for
1910      * PPP over Ethernet.
1911     p->eh = (EtherHdr *) pkt;
1912      */
1913 
1914     DEBUG_WRAP(DebugMessage(DEBUG_DECODE, "%X   %X\n",
1915                 *p->eh->ether_src, *p->eh->ether_dst););
1916 
1917     /* lay the PPP over ethernet structure over the packet data */
1918     ppppoep = p->pppoeh = (PPPoEHdr *)pkt;
1919 
1920     /* grab out the network type */
1921     switch(ntohs(p->eh->ether_type))
1922     {
1923         case ETHERNET_TYPE_PPPoE_DISC:
1924             DEBUG_WRAP(DebugMessage(DEBUG_DECODE, "(PPPOE Discovery) "););
1925             break;
1926 
1927         case ETHERNET_TYPE_PPPoE_SESS:
1928             DEBUG_WRAP(DebugMessage(DEBUG_DECODE, "(PPPOE Session) "););
1929             break;
1930 
1931         default:
1932             return;
1933     }
1934 
1935 #ifdef DEBUG
1936     switch(ppppoep->code)
1937     {
1938         case PPPoE_CODE_PADI:
1939             /* The Host sends the PADI packet with the DESTINATION_ADDR set
1940              * to the broadcast address.  The CODE field is set to 0x09 and
1941              * the SESSION_ID MUST be set to 0x0000.
1942              *
1943              * The PADI packet MUST contain exactly one TAG of TAG_TYPE
1944              * Service-Name, indicating the service the Host is requesting,
1945              * and any number of other TAG types.  An entire PADI packet
1946              * (including the PPPoE header) MUST NOT exceed 1484 octets so
1947              * as to leave sufficient room for a relay agent to add a
1948              * Relay-Session-Id TAG.
1949              */
1950             DebugMessage(DEBUG_DECODE, "Active Discovery Initiation (PADI)\n");
1951             break;
1952 
1953         case PPPoE_CODE_PADO:
1954             /* When the Access Concentrator receives a PADI that it can
1955              * serve, it replies by sending a PADO packet.  The
1956              * DESTINATION_ADDR is the unicast address of the Host that
1957              * sent the PADI.  The CODE field is set to 0x07 and the
1958              * SESSION_ID MUST be set to 0x0000.
1959              *
1960              * The PADO packet MUST contain one AC-Name TAG containing the
1961              * Access Concentrator's name, a Service-Name TAG identical to
1962              * the one in the PADI, and any number of other Service-Name
1963              * TAGs indicating other services that the Access Concentrator
1964              * offers.  If the Access Concentrator can not serve the PADI
1965              * it MUST NOT respond with a PADO.
1966              */
1967             DebugMessage(DEBUG_DECODE, "Active Discovery Offer (PADO)\n");
1968             break;
1969 
1970         case PPPoE_CODE_PADR:
1971             /* Since the PADI was broadcast, the Host may receive more than
1972              * one PADO.  The Host looks through the PADO packets it receives
1973              * and chooses one.  The choice can be based on the AC-Name or
1974              * the Services offered.  The Host then sends one PADR packet
1975              * to the Access Concentrator that it has chosen.  The
1976              * DESTINATION_ADDR field is set to the unicast Ethernet address
1977              * of the Access Concentrator that sent the PADO.  The CODE
1978              * field is set to 0x19 and the SESSION_ID MUST be set to 0x0000.
1979              *
1980              * The PADR packet MUST contain exactly one TAG of TAG_TYPE
1981              * Service-Name, indicating the service the Host is requesting,
1982              * and any number of other TAG types.
1983              */
1984             DebugMessage(DEBUG_DECODE, "Active Discovery Request (PADR)\n");
1985             break;
1986 
1987         case PPPoE_CODE_PADS:
1988             /* When the Access Concentrator receives a PADR packet, it
1989              * prepares to begin a PPP session.  It generates a unique
1990              * SESSION_ID for the PPPoE session and replies to the Host with
1991              * a PADS packet.  The DESTINATION_ADDR field is the unicast
1992              * Ethernet address of the Host that sent the PADR.  The CODE
1993              * field is set to 0x65 and the SESSION_ID MUST be set to the
1994              * unique value generated for this PPPoE session.
1995              *
1996              * The PADS packet contains exactly one TAG of TAG_TYPE
1997              * Service-Name, indicating the service under which Access
1998              * Concentrator has accepted the PPPoE session, and any number
1999              * of other TAG types.
2000              *
2001              * If the Access Concentrator does not like the Service-Name in
2002              * the PADR, then it MUST reply with a PADS containing a TAG of
2003              * TAG_TYPE Service-Name-Error (and any number of other TAG
2004              * types).  In this case the SESSION_ID MUST be set to 0x0000.
2005              */
2006             DebugMessage(DEBUG_DECODE, "Active Discovery "
2007                          "Session-confirmation (PADS)\n");
2008             break;
2009 
2010         case PPPoE_CODE_PADT:
2011             /* This packet may be sent anytime after a session is established
2012              * to indicate that a PPPoE session has been terminated.  It may
2013              * be sent by either the Host or the Access Concentrator.  The
2014              * DESTINATION_ADDR field is a unicast Ethernet address, the
2015              * CODE field is set to 0xa7 and the SESSION_ID MUST be set to
2016              * indicate which session is to be terminated.  No TAGs are
2017              * required.
2018              *
2019              * When a PADT is received, no further PPP traffic is allowed to
2020              * be sent using that session.  Even normal PPP termination
2021              * packets MUST NOT be sent after sending or receiving a PADT.
2022              * A PPP peer SHOULD use the PPP protocol itself to bring down a
2023              * PPPoE session, but the PADT MAY be used when PPP can not be
2024              * used.
2025              */
2026             DebugMessage(DEBUG_DECODE, "Active Discovery Terminate (PADT)\n");
2027             break;
2028 
2029         case PPPoE_CODE_SESS:
2030             DebugMessage(DEBUG_DECODE, "Session Packet (SESS)\n");
2031             break;
2032 
2033         default:
2034             DebugMessage(DEBUG_DECODE, "(Unknown)\n");
2035             break;
2036     }
2037 #endif
2038 
2039     if (ntohs(p->eh->ether_type) != ETHERNET_TYPE_PPPoE_DISC)
2040     {
2041         DecodePppPktEncapsulated(p, cap_len - PPPOE_HEADER_LEN, pkt + PPPOE_HEADER_LEN);
2042         return;
2043     }
2044     else
2045     {
2046         DEBUG_WRAP(DebugMessage(DEBUG_DECODE, "Returning early on PPPOE discovery packet\n"););
2047         return;
2048     }
2049 
2050 #if 0
2051     ppppoe_tag = (PPPoE_Tag *)(pkt + sizeof(PPPoEHdr));
2052 
2053     while (ppppoe_tag < (PPPoE_Tag *)(pkt + pkthdr->caplen))
2054     {
2055         if (((char*)(ppppoe_tag)+(sizeof(PPPoE_Tag)-1)) > (char*)(pkt + pkthdr->caplen))
2056         {
2057             DEBUG_WRAP(DebugMessage(DEBUG_DECODE, "Not enough data in packet for PPPOE Tag\n"););
2058             break;
2059         }
2060 
2061         /* no guarantee in PPPoE spec that ppppoe_tag is aligned at all... */
2062         memcpy(&tag, ppppoe_tag, sizeof(tag));
2063 
2064         DEBUG_WRAP(
2065                 DebugMessage(DEBUG_DECODE, "\tPPPoE tag:\ntype: %04x length: %04x ",
2066                     ntohs(tag.type), ntohs(tag.length)););
2067 
2068 #ifdef DEBUG
2069         switch(ntohs(tag.type))
2070         {
2071             case PPPoE_TAG_END_OF_LIST:
2072                 DebugMessage(DEBUG_DECODE, "(End of list)\n\t");
2073                 break;
2074             case PPPoE_TAG_SERVICE_NAME:
2075                 DebugMessage(DEBUG_DECODE, "(Service name)\n\t");
2076                 break;
2077             case PPPoE_TAG_AC_NAME:
2078                 DebugMessage(DEBUG_DECODE, "(AC Name)\n\t");
2079                 break;
2080             case PPPoE_TAG_HOST_UNIQ:
2081                 DebugMessage(DEBUG_DECODE, "(Host Uniq)\n\t");
2082                 break;
2083             case PPPoE_TAG_AC_COOKIE:
2084                 DebugMessage(DEBUG_DECODE, "(AC Cookie)\n\t");
2085                 break;
2086             case PPPoE_TAG_VENDOR_SPECIFIC:
2087                 DebugMessage(DEBUG_DECODE, "(Vendor Specific)\n\t");
2088                 break;
2089             case PPPoE_TAG_RELAY_SESSION_ID:
2090                 DebugMessage(DEBUG_DECODE, "(Relay Session ID)\n\t");
2091                 break;
2092             case PPPoE_TAG_SERVICE_NAME_ERROR:
2093                 DebugMessage(DEBUG_DECODE, "(Service Name Error)\n\t");
2094                 break;
2095             case PPPoE_TAG_AC_SYSTEM_ERROR:
2096                 DebugMessage(DEBUG_DECODE, "(AC System Error)\n\t");
2097                 break;
2098             case PPPoE_TAG_GENERIC_ERROR:
2099                 DebugMessage(DEBUG_DECODE, "(Generic Error)\n\t");
2100                 break;
2101             default:
2102                 DebugMessage(DEBUG_DECODE, "(Unknown)\n\t");
2103                 break;
2104         }
2105 #endif
2106 
2107         if (ntohs(tag.length) > 0)
2108         {
2109 #ifdef DEBUG
2110             char *buf;
2111             int i;
2112 
2113             switch (ntohs(tag.type))
2114             {
2115                 case PPPoE_TAG_SERVICE_NAME:
2116                 case PPPoE_TAG_AC_NAME:
2117                 case PPPoE_TAG_SERVICE_NAME_ERROR:
2118                 case PPPoE_TAG_AC_SYSTEM_ERROR:
2119                 case PPPoE_TAG_GENERIC_ERROR: * ascii data *
2120                     buf = (char *)SnortAlloc(ntohs(tag.length) + 1);
2121                     strlcpy(buf, (char *)(ppppoe_tag+1), ntohs(tag.length));
2122                     DebugMessage(DEBUG_DECODE, "data (UTF-8): %s\n", buf);
2123                     free(buf);
2124                     break;
2125 
2126                 case PPPoE_TAG_HOST_UNIQ:
2127                 case PPPoE_TAG_AC_COOKIE:
2128                 case PPPoE_TAG_RELAY_SESSION_ID:
2129                     DebugMessage(DEBUG_DECODE, "data (bin): ");
2130                     for (i = 0; i < ntohs(tag.length); i++)
2131                         DebugMessage(DEBUG_DECODE,
2132                                 "%02x", *(((unsigned char *)ppppoe_tag) +
2133                                     sizeof(PPPoE_Tag) + i));
2134                     DebugMessage(DEBUG_DECODE, "\n");
2135                     break;
2136 
2137                 default:
2138                     DebugMessage(DEBUG_DECODE, "unrecognized data\n");
2139                     break;
2140             }
2141 #endif
2142         }
2143 
2144         ppppoe_tag = (PPPoE_Tag *)((char *)(ppppoe_tag+1)+ntohs(tag.length));
2145     }
2146 
2147 #endif   /* #if 0 */
2148 
2149     return;
2150 }
2151 #endif  // NO_NON_ETHER_DECODER
2152 
2153 
2154 /*
2155  * Function: DecodePppPktEncapsulated(Packet *, const uint32_t len, uint8_t*)
2156  *
2157  * Purpose: Decode PPP traffic (RFC1661 framing).
2158  *
2159  * Arguments: p => pointer to decoded packet struct
2160  *            len => length of data to process
2161  *            pkt => pointer to the real live packet data
2162  *
2163  * Returns: void function
2164  */
DecodePppPktEncapsulated(Packet * p,const uint32_t len,const uint8_t * pkt)2165 void DecodePppPktEncapsulated(Packet * p, const uint32_t len, const uint8_t * pkt)
2166 {
2167     static int had_vj = 0;
2168     uint16_t protocol;
2169     uint32_t hlen = 1; /* HEADER - try 1 then 2 */
2170 
2171     DEBUG_WRAP(DebugMessage(DEBUG_DECODE, "PPP Packet!\n"););
2172 
2173 #ifdef WORDS_MUSTALIGN
2174     DEBUG_WRAP(DebugMessage(DEBUG_DECODE, "Packet with PPP header.  "
2175                             "PPP is only 1 or 2 bytes and will throw off "
2176                             "alignment on this architecture when decoding IP, "
2177                             "causing a bus error - stop decoding packet.\n"););
2178 
2179     p->data = pkt;
2180     p->dsize = (uint16_t)len;
2181     return;
2182 #endif  /* WORDS_MUSTALIGN */
2183 
2184 #ifdef GRE
2185     if (p->greh != NULL)
2186         pc.gre_ppp++;
2187 #endif  /* GRE */
2188 
2189     /* do a little validation:
2190      *
2191      */
2192     if(len < 2)
2193     {
2194         if (BcLogVerbose())
2195         {
2196             ErrorMessage("Length not big enough for even a single "
2197                          "header or a one byte payload\n");
2198         }
2199         return;
2200     }
2201 
2202 
2203     if(pkt[0] & 0x01)
2204     {
2205         /* Check for protocol compression rfc1661 section 5
2206          *
2207          */
2208         hlen = 1;
2209         protocol = pkt[0];
2210     }
2211     else
2212     {
2213         protocol = ntohs(*((uint16_t *)pkt));
2214         hlen = 2;
2215     }
2216 
2217     /*
2218      * We only handle uncompressed packets. Handling VJ compression would mean
2219      * to implement a PPP state machine.
2220      */
2221     switch (protocol)
2222     {
2223         case PPP_VJ_COMP:
2224             if (!had_vj)
2225                 ErrorMessage("PPP link seems to use VJ compression, "
2226                         "cannot handle compressed packets!\n");
2227             had_vj = 1;
2228             break;
2229         case PPP_VJ_UCOMP:
2230             /* VJ compression modifies the protocol field. It must be set
2231              * to tcp (only TCP packets can be VJ compressed) */
2232             if(len < (hlen + IP_HEADER_LEN))
2233             {
2234                 if (BcLogVerbose())
2235                     ErrorMessage("PPP VJ min packet length > captured len! "
2236                                  "(%d bytes)\n", len);
2237                 return;
2238             }
2239 
2240             ((IPHdr *)(pkt + hlen))->ip_proto = IPPROTO_TCP;
2241             /* fall through */
2242 
2243         case PPP_IP:
2244             DecodeIP(pkt + hlen, len - hlen, p);
2245             break;
2246 
2247 #ifndef NO_NON_ETHER_DECODER
2248         case PPP_IPX:
2249             DecodeIPX(pkt + hlen, len - hlen, p);
2250             break;
2251 #endif
2252     }
2253 }
2254 
2255 
2256 /*
2257  * Function: DecodePppPkt(Packet *, char *, struct pcap_pkthdr*, uint8_t*)
2258  *
2259  * Purpose: Decode PPP traffic (either RFC1661 or RFC1662 framing).
2260  *          This really is intended to handle IPCP
2261  *
2262  * Arguments: p => pointer to decoded packet struct
2263  *            user => Utility pointer, unused
2264  *            pkthdr => ptr to the packet header
2265  *            pkt => pointer to the real live packet data
2266  *
2267  * Returns: void function
2268  */
DecodePppPkt(Packet * p,const struct pcap_pkthdr * pkthdr,const uint8_t * pkt)2269 void DecodePppPkt(Packet * p, const struct pcap_pkthdr * pkthdr, const uint8_t * pkt)
2270 {
2271     int hlen = 0;
2272 
2273     pc.total_processed++;
2274 
2275     memset(p, 0, PKT_ZERO_LEN);
2276 
2277     p->pkth = pkthdr;
2278     p->pkt = pkt;
2279 
2280     DEBUG_WRAP(DebugMessage(DEBUG_DECODE, "Packet!\n"););
2281 
2282     if(p->pkth->caplen < 2)
2283     {
2284         if (BcLogVerbose())
2285         {
2286             ErrorMessage("Length not big enough for even a single "
2287                          "header or a one byte payload\n");
2288         }
2289         return;
2290     }
2291 
2292     if(pkt[0] == CHDLC_ADDR_BROADCAST && pkt[1] == CHDLC_CTRL_UNNUMBERED)
2293     {
2294         /*
2295          * Check for full HDLC header (rfc1662 section 3.2)
2296          */
2297         hlen = 2;
2298     }
2299 
2300     DecodePppPktEncapsulated(p, p->pkth->caplen - hlen, p->pkt + hlen);
2301 
2302     return;
2303 }
2304 
2305 #ifndef NO_NON_ETHER_DECODER
2306 /*
2307  * Function: DecodePppSerialPkt(Packet *, char *, struct pcap_pkthdr*, uint8_t*)
2308  *
2309  * Purpose: Decode Mixed PPP/CHDLC traffic. The PPP frames will always have the
2310  *          full HDLC header.
2311  *
2312  * Arguments: p => pointer to decoded packet struct
2313  *            user => Utility pointer, unused
2314  *            pkthdr => ptr to the packet header
2315  *            pkt => pointer to the real live packet data
2316  *
2317  * Returns: void function
2318  */
DecodePppSerialPkt(Packet * p,const struct pcap_pkthdr * pkthdr,const uint8_t * pkt)2319 void DecodePppSerialPkt(Packet * p, const struct pcap_pkthdr * pkthdr, const uint8_t * pkt)
2320 {
2321 
2322     pc.total_processed++;
2323 
2324     memset(p, 0, PKT_ZERO_LEN);
2325 
2326     p->pkth = pkthdr;
2327     p->pkt = pkt;
2328 
2329     DEBUG_WRAP(DebugMessage(DEBUG_DECODE, "Packet!\n"););
2330 
2331     if(p->pkth->caplen < PPP_HDRLEN)
2332     {
2333         if (BcLogVerbose())
2334         {
2335             ErrorMessage("Captured data length < PPP header length"
2336                          " (%d bytes)\n", p->pkth->caplen);
2337         }
2338         return;
2339     }
2340 
2341     if(pkt[0] == CHDLC_ADDR_BROADCAST && pkt[1] == CHDLC_CTRL_UNNUMBERED)
2342     {
2343         DecodePppPktEncapsulated(p, p->pkth->caplen - 2, p->pkt + 2);
2344     } else {
2345         DecodeChdlcPkt(p, pkthdr, pkt);
2346     }
2347 
2348     return;
2349 }
2350 
2351 
2352 /*
2353  * Function: DecodeSlipPkt(Packet *, char *, struct pcap_pkthdr*, uint8_t*)
2354  *
2355  * Purpose: Decode SLIP traffic
2356  *
2357  * Arguments: p => pointer to decoded packet struct
2358  *            user => Utility pointer, unused
2359  *            pkthdr => ptr to the packet header
2360  *            pkt => pointer to the real live packet data
2361  *
2362  * Returns: void function
2363  */
DecodeSlipPkt(Packet * p,const struct pcap_pkthdr * pkthdr,const uint8_t * pkt)2364 void DecodeSlipPkt(Packet * p, const struct pcap_pkthdr * pkthdr, const uint8_t * pkt)
2365 {
2366     uint32_t len;
2367     uint32_t cap_len;
2368 
2369     pc.total_processed++;
2370 
2371     memset(p, 0, PKT_ZERO_LEN);
2372 
2373     p->pkth = pkthdr;
2374     p->pkt = pkt;
2375 
2376     len = pkthdr->len;
2377     cap_len = pkthdr->caplen;
2378 
2379     DEBUG_WRAP(DebugMessage(DEBUG_DECODE, "Packet!\n"););
2380 
2381     /* do a little validation */
2382     if(cap_len < SLIP_HEADER_LEN)
2383     {
2384         ErrorMessage("SLIP header length < captured len! (%d bytes)\n",
2385                      cap_len);
2386         return;
2387     }
2388 
2389     DecodeIP(p->pkt + SLIP_HEADER_LEN, cap_len - SLIP_HEADER_LEN, p);
2390 }
2391 #endif  // NO_NON_ETHER_DECODER
2392 
2393 
2394 
2395 /*
2396  * Function: DecodeRawPkt(Packet *, char *, struct pcap_pkthdr*, uint8_t*)
2397  *
2398  * Purpose: Decodes packets coming in raw on layer 2, like PPP.  Coded and
2399  *          in by Jed Pickle (thanks Jed!) and modified for a few little tweaks
2400  *          by me.
2401  *
2402  * Arguments: p => pointer to decoded packet struct
2403  *            user => Utility pointer, unused
2404  *            pkthdr => ptr to the packet header
2405  *            pkt => pointer to the real live packet data
2406  *
2407  * Returns: void function
2408  */
DecodeRawPkt(Packet * p,const struct pcap_pkthdr * pkthdr,const uint8_t * pkt)2409 void DecodeRawPkt(Packet * p, const struct pcap_pkthdr * pkthdr, const uint8_t * pkt)
2410 {
2411     pc.total_processed++;
2412 
2413     memset(p, 0, PKT_ZERO_LEN);
2414 
2415     p->pkth = pkthdr;
2416     p->pkt = pkt;
2417 
2418     DEBUG_WRAP(DebugMessage(DEBUG_DECODE, "Packet!\n"););
2419 
2420     if (p->pkth->caplen > 0) {
2421         IP4Hdr *ip4h = (IP4Hdr *)pkt;
2422         IP6RawHdr *ip6h = (IP6RawHdr *)pkt;
2423 
2424         if (IP_VER(ip4h) == 4) {
2425             DecodeIP(pkt, p->pkth->caplen, p);
2426         } else if (((ip6h->ip6vfc & 0xf0) >> 4) == 6) {
2427             DecodeIPV6(pkt, p->pkth->caplen, p);
2428         }
2429     }
2430 
2431     return;
2432 }
2433 
2434 
2435 
2436 #ifndef NO_NON_ETHER_DECODER
2437 /*
2438  * Function: DecodeI4LRawIPPkt(Packet *, char *, struct pcap_pkthdr*, uint8_t*)
2439  *
2440  * Purpose: Decodes packets coming in raw on layer 2, like PPP.  Coded and
2441  *          in by Jed Pickle (thanks Jed!) and modified for a few little tweaks
2442  *          by me.
2443  *
2444  * Arguments: p => pointer to decoded packet struct
2445  *            user => Utility pointer, unused
2446  *            pkthdr => ptr to the packet header
2447  *            pkt => pointer to the real live packet data
2448  *
2449  * Returns: void function
2450  */
DecodeI4LRawIPPkt(Packet * p,const struct pcap_pkthdr * pkthdr,const uint8_t * pkt)2451 void DecodeI4LRawIPPkt(Packet * p, const struct pcap_pkthdr * pkthdr, const uint8_t * pkt)
2452 {
2453     pc.total_processed++;
2454 
2455     memset(p, 0, PKT_ZERO_LEN);
2456 
2457     p->pkth = pkthdr;
2458     p->pkt = pkt;
2459 
2460     if(p->pkth->len < 2)
2461     {
2462         DEBUG_WRAP(DebugMessage(DEBUG_DECODE, "What the hell is this?\n"););
2463         pc.other++;
2464         return;
2465     }
2466 
2467     DEBUG_WRAP(DebugMessage(DEBUG_DECODE, "Packet!\n"););
2468     DecodeIP(pkt + 2, p->pkth->len - 2, p);
2469 
2470     return;
2471 }
2472 
2473 
2474 
2475 /*
2476  * Function: DecodeI4LCiscoIPPkt(Packet *, char *,
2477  *                               struct pcap_pkthdr*, uint8_t*)
2478  *
2479  * Purpose: Decodes packets coming in raw on layer 2, like PPP.  Coded and
2480  *          in by Jed Pickle (thanks Jed!) and modified for a few little tweaks
2481  *          by me.
2482  *
2483  * Arguments: p => pointer to decoded packet struct
2484  *            user => Utility pointer, unused
2485  *            pkthdr => ptr to the packet header
2486  *            pkt => pointer to the real live packet data
2487  *
2488  * Returns: void function
2489  */
DecodeI4LCiscoIPPkt(Packet * p,const struct pcap_pkthdr * pkthdr,const uint8_t * pkt)2490 void DecodeI4LCiscoIPPkt(Packet *p, const struct pcap_pkthdr *pkthdr, const uint8_t *pkt)
2491 {
2492     pc.total_processed++;
2493 
2494     memset(p, 0, PKT_ZERO_LEN);
2495 
2496     p->pkth = pkthdr;
2497     p->pkt = pkt;
2498 
2499     if(p->pkth->len < 4)
2500     {
2501         DEBUG_WRAP(DebugMessage(DEBUG_DECODE, "What the hell is this?\n"););
2502         pc.other++;
2503         return;
2504     }
2505 
2506 
2507     DEBUG_WRAP(DebugMessage(DEBUG_DECODE, "Packet!\n"););
2508 
2509     DecodeIP(pkt + 4, p->pkth->caplen - 4, p);
2510 
2511     return;
2512 }
2513 
2514 /*
2515  * Function: DecodeChdlcPkt(Packet *, char *,
2516  *                               struct pcap_pkthdr*, uint8_t*)
2517  *
2518  * Purpose: Decodes Cisco HDLC encapsulated packets, f.ex. from SONET.
2519  *
2520  * Arguments: p => pointer to decoded packet struct
2521  *            user => Utility pointer, unused
2522  *            pkthdr => ptr to the packet header
2523  *            pkt => pointer to the real live packet data
2524  *
2525  * Returns: void function
2526  */
DecodeChdlcPkt(Packet * p,const struct pcap_pkthdr * pkthdr,const uint8_t * pkt)2527 void DecodeChdlcPkt(Packet *p, const struct pcap_pkthdr *pkthdr, const uint8_t *pkt)
2528 {
2529     pc.total_processed++;
2530 
2531     memset(p, 0, PKT_ZERO_LEN);
2532 
2533     p->pkth = pkthdr;
2534     p->pkt = pkt;
2535 
2536     if(p->pkth->caplen < CHDLC_HEADER_LEN)
2537     {
2538         if (BcLogVerbose())
2539         {
2540             ErrorMessage("Captured data length < CHDLC header length"
2541                          " (%d bytes)\n", p->pkth->caplen);
2542         }
2543         return;
2544     }
2545 
2546     DEBUG_WRAP(DebugMessage(DEBUG_DECODE, "Packet!\n"););
2547 
2548     if ((pkt[0] == CHDLC_ADDR_UNICAST || pkt[0] == CHDLC_ADDR_MULTICAST) &&
2549     		ntohs(*(uint16_t *)&pkt[2]) == ETHERNET_TYPE_IP)
2550     {
2551         DecodeIP(p->pkt + CHDLC_HEADER_LEN,
2552                  p->pkth->caplen - CHDLC_HEADER_LEN, p);
2553     } else {
2554         pc.other++;
2555     }
2556 
2557     return;
2558 }
2559 #endif  // NO_NON_ETHER_DECODER
2560 
2561 /*
2562  * Some IP Header tests
2563  * Land Attack(same src/dst ip)
2564  * Loopback (src or dst in 127/8 block)
2565  * Modified: 2/22/05-man for High Endian Architecture.
2566  */
IPHdrTestsv4(Packet * p)2567 void IPHdrTestsv4( Packet * p )
2568 {
2569 #if 0
2570 #ifdef WORDS_BIGENDIAN
2571     unsigned int ip4_ip = 0x7f000000;
2572 #else
2573     unsigned int ip4_ip = 0x7f;
2574 #endif
2575 #endif  /* #if 0 */
2576 
2577     /* Loopback traffic  - don't use htonl for speed reasons -
2578      * s_addr is always in network order */
2579 #ifdef WORDS_BIGENDIAN
2580     if( (p->iph->ip_src.s_addr & 0xff000000) == 0x7f000000  ||
2581         (p->iph->ip_dst.s_addr & 0xff000000 ) == 0x7f000000 ) /* BE */
2582 #else
2583     if( (p->iph->ip_src.s_addr & 0xff) == 0x7f ||
2584         (p->iph->ip_dst.s_addr & 0xff ) == 0x7f ) /* LE */
2585 #endif
2586     {
2587     }
2588 }
2589 
2590 #ifdef DLT_ENC
2591 /* see http://sourceforge.net/mailarchive/message.php?msg_id=1000380 */
2592 /*
2593  * Function: DecodeEncPkt(Packet *, struct pcap_pkthdr *, uint8_t *)
2594  *
2595  * Purpose: Decapsulate packets of type DLT_ENC.
2596  *          XXX Are these always going to be IP in IP?
2597  *
2598  * Arguments: p => pointer to decoded packet struct
2599  *            pkthdr => pointer to the packet header
2600  *            pkt => pointer to the real live packet data
2601  */
DecodeEncPkt(Packet * p,const struct pcap_pkthdr * pkthdr,const uint8_t * pkt)2602 void DecodeEncPkt(Packet *p, const struct pcap_pkthdr *pkthdr, const uint8_t *pkt)
2603 {
2604     struct enc_header *enc_h;
2605 
2606     pc.total_processed++;
2607 
2608     memset(p, 0, PKT_ZERO_LEN);
2609     p->pkth = pkthdr;
2610     p->pkt = pkt;
2611 
2612     if (p->pkth->caplen < ENC_HEADER_LEN)
2613     {
2614         if (BcLogVerbose())
2615         {
2616             ErrorMessage("Captured data length < Encap header length!  (%d bytes)\n", p->pkth->caplen);
2617         }
2618         return;
2619     }
2620 
2621     enc_h = (struct enc_header *)p->pkt;
2622     if (enc_h->af == AF_INET)
2623     {
2624         DecodeIP(p->pkt + ENC_HEADER_LEN + IP_HEADER_LEN,
2625                  pkthdr->caplen - ENC_HEADER_LEN - IP_HEADER_LEN, p);
2626     }
2627     else
2628     {
2629         ErrorMessage("[!] WARNING: Unknown address family! (af: 0x%x)\n",
2630                 enc_h->af);
2631     }
2632     return;
2633 }
2634 #endif /* DLT_ENC */
2635 
2636 /*
2637  * Function: DecodeIP(uint8_t *, const uint32_t, Packet *)
2638  *
2639  * Purpose: Decode the IP network layer
2640  *
2641  * Arguments: pkt => ptr to the packet data
2642  *            len => length from here to the end of the packet
2643  *            p   => pointer to the packet decode struct
2644  *
2645  * Returns: void function
2646  */
DecodeIP(const uint8_t * pkt,const uint32_t len,Packet * p)2647 void DecodeIP(const uint8_t * pkt, const uint32_t len, Packet * p)
2648 {
2649     uint32_t ip_len; /* length from the start of the ip hdr to the pkt end */
2650     uint32_t hlen;   /* ip header length */
2651     uint16_t csum;   /* checksum */
2652 
2653 
2654     pc.ip++;
2655 
2656 #ifdef GRE
2657     if (p->greh != NULL)
2658         pc.gre_ip++;
2659 #endif
2660 
2661     DEBUG_WRAP(DebugMessage(DEBUG_DECODE, "Packet!\n"););
2662 
2663     /* do a little validation */
2664     if(len < IP_HEADER_LEN)
2665     {
2666         if (BcLogVerbose())
2667         {
2668             ErrorMessage("IP header truncated! (%d bytes)\n", len);
2669         }
2670         p->iph = NULL;
2671         pc.discards++;
2672         pc.ipdisc++;
2673 
2674 #ifdef SUP_IP6
2675         p->family = NO_IP;
2676 #endif
2677         return;
2678     }
2679 
2680 #ifdef GRE
2681 #ifndef SUP_IP6
2682     if (p->iph != NULL)
2683 #else
2684     if (p->family != NO_IP)
2685 #endif  /* SUP_IP6 */
2686     {
2687         IPHdr *tmp = (IPHdr *)pkt;
2688 
2689         if (p->encapsulated ||
2690             ((tmp->ip_proto == IPPROTO_IPIP) || (tmp->ip_proto == IPPROTO_GRE))
2691 #ifdef SUP_IP6
2692              || (tmp->ip_proto == IPPROTO_IPV6)
2693 #endif
2694            )
2695         {
2696             DecoderAlertGRE(p, DECODE_GRE_MULTIPLE_ENCAPSULATION,
2697                             DECODE_GRE_MULTIPLE_ENCAPSULATION_STR,
2698                             pkt, len);
2699             return;
2700         }
2701         else
2702         {
2703             p->encapsulated = 1;
2704             p->outer_iph = p->iph;
2705             p->outer_ip_data = p->ip_data;
2706             p->outer_ip_dsize = p->ip_dsize;
2707         }
2708     }
2709 #endif  /* GRE */
2710 
2711     /* lay the IP struct over the raw data */
2712     p->inner_iph = p->iph = (IPHdr *)pkt;
2713 
2714     /*
2715      * with datalink DLT_RAW it's impossible to differ ARP datagrams from IP.
2716      * So we are just ignoring non IP datagrams
2717      */
2718     if(IP_VER(p->iph) != 4)
2719     {
2720         if (BcLogVerbose())
2721         {
2722             ErrorMessage("Not IPv4 datagram! "
2723                     "([ver: 0x%x][len: 0x%x])\n",
2724                     IP_VER(p->iph), p->iph->ip_len);
2725         }
2726 
2727         p->iph = NULL;
2728         pc.discards++;
2729         pc.ipdisc++;
2730 
2731 #ifdef SUP_IP6
2732         p->family = NO_IP;
2733 #endif
2734         return;
2735     }
2736 
2737 #ifdef SUP_IP6
2738     sfiph_build(p, p->iph, AF_INET);
2739 #endif
2740 
2741 //    p->ip_payload_len = p->iph->ip_len;
2742 //    p->ip_payload_off = p->ip_payload_len + (int)pkt;
2743 
2744     /* set the IP datagram length */
2745     ip_len = ntohs(p->iph->ip_len);
2746 
2747     /* set the IP header length */
2748     hlen = IP_HLEN(p->iph) << 2;
2749 
2750     /* header length sanity check */
2751     if(hlen < IP_HEADER_LEN)
2752     {
2753 #ifdef DEBUG
2754         if (BcLogVerbose())
2755             ErrorMessage("Bogus IP header length of %i bytes\n",
2756                     hlen);
2757 #endif
2758 
2759         p->iph = NULL;
2760         pc.discards++;
2761         pc.ipdisc++;
2762 #ifdef SUP_IP6
2763         p->family = NO_IP;
2764 #endif
2765         return;
2766     }
2767 
2768     if (ip_len != len)
2769     {
2770         if (ip_len > len)
2771         {
2772 #ifdef DEBUG
2773             if (BcLogVerbose())
2774                 ErrorMessage("IP Len field is %d bytes bigger"
2775                         " than captured length.\n"
2776                         "    (ip.len: %lu, cap.len: %lu)\n",
2777                         ip_len - len, ip_len, len);
2778 #endif
2779 
2780             p->iph = NULL;
2781             pc.discards++;
2782             pc.ipdisc++;
2783 #ifdef SUP_IP6
2784             p->family = NO_IP;
2785 #endif
2786             return;
2787         }
2788         else
2789         {
2790 #ifdef DEBUG
2791             if (BcLogVerbose())
2792                 ErrorMessage("IP Len field is %d bytes "
2793                         "smaller than captured length.\n"
2794                         "    (ip.len: %lu, cap.len: %lu)\n",
2795                         len - ip_len, ip_len, len);
2796 #endif
2797 
2798         }
2799     }
2800 
2801     if(ip_len < hlen)
2802     {
2803         if(BcLogVerbose())
2804         {
2805             ErrorMessage("IP dgm len (%d bytes) < IP hdr "
2806                     "len (%d bytes), packet discarded\n", ip_len, hlen);
2807         }
2808 
2809         p->iph = NULL;
2810         pc.discards++;
2811         pc.ipdisc++;
2812 #ifdef SUP_IP6
2813         p->family = NO_IP;
2814 #endif
2815         return;
2816     }
2817 
2818 
2819 //    if (BcIpChecksums())
2820     {
2821         /* routers drop packets with bad IP checksums, we don't really
2822          * need to check them (should make this a command line/config
2823          * option
2824          */
2825         csum = in_chksum_ip((u_short *)p->iph, hlen);
2826 
2827         if(csum)
2828         {
2829             p->csum_flags |= CSE_IP;
2830             DEBUG_WRAP(DebugMessage(DEBUG_DECODE, "Bad IP checksum\n"););
2831         }
2832 #ifdef DEBUG
2833         else
2834         {
2835             DebugMessage(DEBUG_DECODE, "IP Checksum: OK\n");
2836         }
2837 #endif /* DEBUG */
2838     }
2839 
2840     /* test for IP options */
2841     p->ip_options_len = (uint16_t)(hlen - IP_HEADER_LEN);
2842 
2843     if(p->ip_options_len > 0)
2844     {
2845         p->ip_options_data = pkt + IP_HEADER_LEN;
2846         DecodeIPOptions((pkt + IP_HEADER_LEN), p->ip_options_len, p);
2847     }
2848     else
2849     {
2850 #ifdef GRE
2851         /* If delivery header for GRE encapsulated packet is IP and it
2852          * had options, the packet's ip options will be refering to this
2853          * outer IP's options
2854          * Zero these options so they aren't associated with this inner IP
2855          * since p->iph will be pointing to this inner IP
2856          */
2857         if (p->encapsulated)
2858         {
2859             p->ip_options_data = NULL;
2860             p->ip_options_len = 0;
2861             memset(&(p->ip_options[0]), 0, sizeof(p->ip_options));
2862             p->ip_lastopt_bad = 0;
2863         }
2864 #endif
2865         p->ip_option_count = 0;
2866     }
2867 
2868     /* set the real IP length for logging */
2869     p->actual_ip_len = (uint16_t) ip_len;
2870 
2871     /* set the remaining packet length */
2872     ip_len -= hlen;
2873 
2874     /* check for fragmented packets */
2875     p->frag_offset = ntohs(p->iph->ip_off);
2876 
2877     /*
2878      * get the values of the reserved, more
2879      * fragments and don't fragment flags
2880      */
2881     p->rf = (uint8_t)((p->frag_offset & 0x8000) >> 15);
2882     p->df = (uint8_t)((p->frag_offset & 0x4000) >> 14);
2883     p->mf = (uint8_t)((p->frag_offset & 0x2000) >> 13);
2884 
2885     /* mask off the high bits in the fragment offset field */
2886     p->frag_offset &= 0x1FFF;
2887 
2888     if(p->frag_offset || p->mf)
2889     {
2890         /* set the packet fragment flag */
2891         p->frag_flag = 1;
2892         p->ip_frag_start = pkt + hlen;
2893         p->ip_frag_len = (uint16_t)ip_len;
2894         pc.frags++;
2895     }
2896     else
2897     {
2898         p->frag_flag = 0;
2899     }
2900 
2901     /* Set some convienience pointers */
2902     p->ip_data = pkt + hlen;
2903     p->ip_dsize = (u_short) ip_len;
2904 
2905     /* if this packet isn't a fragment
2906      * or if it is, its a UDP packet and offset isn't 0 */
2907     if(!(p->frag_flag) ||
2908             (p->frag_flag && (p->frag_offset == 0) &&
2909             (p->iph->ip_proto == IPPROTO_UDP)))
2910     {
2911         DEBUG_WRAP(DebugMessage(DEBUG_DECODE, "IP header length: %lu\n",
2912                     (unsigned long)hlen););
2913 
2914         switch(p->iph->ip_proto)
2915         {
2916             case IPPROTO_TCP:
2917                 pc.tcp++;
2918                 DecodeTCP(pkt + hlen, ip_len, p);
2919                 //ClearDumpBuf();
2920                 return;
2921 
2922             case IPPROTO_UDP:
2923                 pc.udp++;
2924                 DecodeUDP(pkt + hlen, ip_len, p);
2925                 //ClearDumpBuf();
2926                 return;
2927 
2928             case IPPROTO_ICMP:
2929                 pc.icmp++;
2930                 DecodeICMP(pkt + hlen, ip_len, p);
2931                 //ClearDumpBuf();
2932                 return;
2933 
2934 #ifdef GRE
2935             case IPPROTO_IPV6:
2936                 if (ip_len < 40)
2937                 {
2938                     /* Insufficient size for IPv6 Header. */
2939                     /* This could be an attempt to exploit Linux kernel
2940                      * vulnerability, so log an alert */
2941 //                    DecoderEvent(p, DECODE_IPV6_TUNNELED_IPV4_TRUNCATED,
2942 //                                DECODE_IPV6_TUNNELED_IPV4_TRUNCATED_STR,
2943 //                                pv.decoder_flags.decode_alerts,
2944 //                                pv.decoder_flags.drop_alerts);
2945                 }
2946                 pc.ip4ip6++;
2947                 DecodeIPV6(pkt + hlen, ip_len, p);
2948                 return;
2949 
2950             case IPPROTO_GRE:
2951                 pc.gre++;
2952                 DecodeGRE(pkt + hlen, ip_len, p);
2953                 //ClearDumpBuf();
2954                 return;
2955 
2956             case IPPROTO_IPIP:
2957                 pc.ip4ip4++;
2958                 DecodeIP(pkt + hlen, ip_len, p);
2959                 return;
2960 #endif
2961 
2962             default:
2963                 pc.other++;
2964                 p->data = pkt + hlen;
2965                 p->dsize = (u_short) ip_len;
2966                 //ClearDumpBuf();
2967                 return;
2968         }
2969     }
2970     else
2971     {
2972         /* set the payload pointer and payload size */
2973         p->data = pkt + hlen;
2974         p->dsize = (u_short) ip_len;
2975     }
2976 }
2977 
2978 /*
2979  * Function: DecodeTCP(uint8_t *, const uint32_t, Packet *)
2980  *
2981  * Purpose: Decode the TCP transport layer
2982  *
2983  * Arguments: pkt => ptr to the packet data
2984  *            len => length from here to the end of the packet
2985  *            p   => Pointer to packet decode struct
2986  *
2987  * Returns: void function
2988  */
DecodeTCP(const uint8_t * pkt,const uint32_t len,Packet * p)2989 void DecodeTCP(const uint8_t * pkt, const uint32_t len, Packet * p)
2990 {
2991     struct pseudoheader6       /* pseudo header for TCP checksum calculations */
2992     {
2993         uint32_t sip[4], dip[4];   /* IP addr */
2994         uint8_t  zero;       /* checksum placeholder */
2995         uint8_t  protocol;   /* protocol number */
2996         uint16_t tcplen;     /* tcp packet length */
2997     };
2998 
2999     struct pseudoheader       /* pseudo header for TCP checksum calculations */
3000     {
3001         uint32_t sip, dip;   /* IP addr */
3002         uint8_t  zero;       /* checksum placeholder */
3003         uint8_t  protocol;   /* protocol number */
3004         uint16_t tcplen;     /* tcp packet length */
3005     };
3006     uint32_t hlen;            /* TCP header length */
3007     u_short csum;              /* checksum */
3008     struct pseudoheader ph;    /* pseudo header declaration */
3009 #ifdef SUP_IP6
3010     struct pseudoheader6 ph6;    /* pseudo header declaration */
3011 #endif
3012 
3013 
3014     if(len < TCP_HEADER_LEN)
3015     {
3016         if (BcLogVerbose())
3017         {
3018             ErrorMessage("TCP packet (len = %d) cannot contain "
3019                          "20 byte header\n", len);
3020         }
3021 
3022         p->tcph = NULL;
3023         pc.discards++;
3024         pc.tdisc++;
3025 
3026         return;
3027     }
3028 
3029     /* lay TCP on top of the data cause there is enough of it! */
3030     p->tcph = (TCPHdr *) pkt;
3031 
3032     /* multiply the payload offset value by 4 */
3033     hlen = TCP_OFFSET(p->tcph) << 2;
3034 
3035     DEBUG_WRAP(DebugMessage(DEBUG_DECODE, "TCP th_off is %d, passed len is %lu\n",
3036                 TCP_OFFSET(p->tcph), (unsigned long)len););
3037 
3038     if(hlen < TCP_HEADER_LEN)
3039     {
3040         if (BcLogVerbose())
3041         {
3042             ErrorMessage("TCP Data Offset (%d) < hlen (%d) \n",
3043                          TCP_OFFSET(p->tcph), hlen);
3044         }
3045 
3046         p->tcph = NULL;
3047         pc.discards++;
3048         pc.tdisc++;
3049 
3050         return;
3051     }
3052 
3053     if(hlen > len)
3054     {
3055         if (BcLogVerbose())
3056         {
3057             ErrorMessage("TCP Data Offset(%d) < longer than payload(%d)!\n",
3058                          TCP_OFFSET(p->tcph) << 2, len);
3059         }
3060 
3061         p->tcph = NULL;
3062         pc.discards++;
3063         pc.tdisc++;
3064 
3065         return;
3066     }
3067 
3068     /* stuff more data into the printout data struct */
3069     p->sp = ntohs(p->tcph->th_sport);
3070     p->dp = ntohs(p->tcph->th_dport);
3071 
3072 //    if (BcTcpChecksums())
3073     {
3074 #ifdef SUP_IP6
3075         if(IS_IP4(p))
3076         {
3077             ph.sip = *p->ip4h->ip_src.ip32;
3078             ph.dip = *p->ip4h->ip_dst.ip32;
3079 #else
3080             ph.sip = (uint32_t)(p->iph->ip_src.s_addr);
3081             ph.dip = (uint32_t)(p->iph->ip_dst.s_addr);
3082 #endif
3083             /* setup the pseudo header for checksum calculation */
3084             ph.zero = 0;
3085             ph.protocol = GET_IPH_PROTO(p);
3086             ph.tcplen = htons((u_short)len);
3087 
3088             /* if we're being "stateless" we probably don't care about the TCP
3089              * checksum, but it's not bad to keep around for shits and giggles */
3090             /* calculate the checksum */
3091             csum = in_chksum_tcp((uint16_t *)&ph, (uint16_t *)(p->tcph), len);
3092 #ifdef SUP_IP6
3093         }
3094         /* IPv6 traffic */
3095         else
3096         {
3097             COPY4(ph6.sip, p->ip6h->ip_src.ip32);
3098             COPY4(ph6.dip, p->ip6h->ip_dst.ip32);
3099             ph6.zero = 0;
3100             ph6.protocol = GET_IPH_PROTO(p);
3101             ph6.tcplen = htons((u_short)len);
3102 
3103             csum = in_chksum_tcp6((uint16_t *)&ph6, (uint16_t *)(p->tcph), len);
3104         }
3105 #endif
3106 
3107         if(csum)
3108         {
3109             p->csum_flags |= CSE_TCP;
3110             DEBUG_WRAP(DebugMessage(DEBUG_DECODE, "Bad TCP checksum\n",
3111                                     "0x%x versus 0x%x\n", csum,
3112                                     ntohs(p->tcph->th_sum)););
3113         }
3114         else
3115         {
3116             DEBUG_WRAP(DebugMessage(DEBUG_DECODE,"TCP Checksum: OK\n"););
3117         }
3118     }
3119 
3120     DEBUG_WRAP(DebugMessage(DEBUG_DECODE, "tcp header starts at: %p\n", p->tcph););
3121 
3122 
3123     /* if options are present, decode them */
3124     p->tcp_options_len = (uint16_t)(hlen - TCP_HEADER_LEN);
3125 
3126     if(p->tcp_options_len > 0)
3127     {
3128         DEBUG_WRAP(DebugMessage(DEBUG_DECODE, "%lu bytes of tcp options....\n",
3129                     (unsigned long)(p->tcp_options_len)););
3130 
3131         p->tcp_options_data = pkt + TCP_HEADER_LEN;
3132         DecodeTCPOptions((uint8_t *) (pkt + TCP_HEADER_LEN), p->tcp_options_len, p);
3133     }
3134     else
3135     {
3136         p->tcp_option_count = 0;
3137     }
3138 
3139     /* set the data pointer and size */
3140     p->data = (uint8_t *) (pkt + hlen);
3141 
3142     if(hlen < len)
3143     {
3144         p->dsize = (u_short)(len - hlen);
3145     }
3146     else
3147     {
3148         p->dsize = 0;
3149     }
3150 
3151     /*  Drop packet if we ignore this port  */
3152 //    if (BcIgnoreTcpPort(p->sp) || BcIgnoreTcpPort(p->dp))
3153 //    {
3154 //        /*  Ignore all preprocessors for this packet */
3155 //        p->packet_flags |= PKT_IGNORE_PORT;
3156 //    }
3157 
3158     p->proto_bits |= PROTO_BIT__TCP;
3159 }
3160 
3161 
3162 /*
3163  * Function: DecodeUDP(uint8_t *, const uint32_t, Packet *)
3164  *
3165  * Purpose: Decode the UDP transport layer
3166  *
3167  * Arguments: pkt => ptr to the packet data
3168  *            len => length from here to the end of the packet
3169  *            p   => pointer to decoded packet struct
3170  *
3171  * Returns: void function
3172  */
DecodeUDP(const uint8_t * pkt,const uint32_t len,Packet * p)3173 void DecodeUDP(const uint8_t * pkt, const uint32_t len, Packet * p)
3174 {
3175     struct pseudoheader6
3176     {
3177         uint32_t sip[4], dip[4];
3178         uint8_t  zero;
3179         uint8_t  protocol;
3180         uint16_t udplen;
3181     };
3182 
3183     struct pseudoheader
3184     {
3185         uint32_t sip, dip;
3186         uint8_t  zero;
3187         uint8_t  protocol;
3188         uint16_t udplen;
3189     };
3190     u_short csum;
3191     uint16_t uhlen;
3192     struct pseudoheader ph;
3193 #ifdef SUP_IP6
3194     struct pseudoheader6 ph6;
3195 #endif
3196     u_char fragmented_udp_flag = 0;
3197 
3198     if(len < sizeof(UDPHdr))
3199     {
3200         if (BcLogVerbose())
3201             ErrorMessage("Truncated UDP header (%d bytes)\n", len);
3202 
3203         p->udph = NULL;
3204         pc.discards++;
3205         pc.udisc++;
3206 
3207         return;
3208     }
3209 
3210     /* set the ptr to the start of the UDP header */
3211     p->udph = (UDPHdr *) pkt;
3212 
3213     if (!p->frag_flag)
3214     {
3215         uhlen = ntohs(p->udph->uh_len);
3216     }
3217     else
3218     {
3219         if(IS_IP6(p))
3220         {
3221             uint16_t ip_len = ntohs(GET_IPH_LEN(p));
3222             /* subtract the distance from udp header to 1st ip6 extension */
3223             /* This gives the length of the UDP "payload", when fragmented */
3224             uhlen = ip_len - ((u_char *)p->udph - (u_char *)p->ip6_extensions[0].data);
3225         }
3226         else
3227         {
3228             uint16_t ip_len = ntohs(GET_IPH_LEN(p));
3229             /* Don't forget, IP_HLEN is a word - multiply x 4 */
3230             uhlen = ip_len - (GET_IPH_HLEN(p) * 4 );
3231         }
3232         fragmented_udp_flag = 1;
3233     }
3234 
3235     /* verify that the header len is a valid value */
3236     if(uhlen < UDP_HEADER_LEN)
3237     {
3238         if (BcLogVerbose())
3239             ErrorMessage("Invalid UDP Packet, length field < 8\n");
3240 
3241         p->udph = NULL;
3242         pc.udisc++;
3243         pc.discards++;
3244 
3245         return;
3246     }
3247 
3248     /* make sure there are enough bytes as designated by length field */
3249     if(len < uhlen)
3250     {
3251         if (BcLogVerbose())
3252         {
3253             ErrorMessage("Short UDP packet, length field > payload length\n");
3254         }
3255 
3256         p->udph = NULL;
3257         pc.discards++;
3258         pc.udisc++;
3259 
3260         return;
3261     }
3262     else if(len > uhlen)
3263     {
3264         if (BcLogVerbose())
3265         {
3266             ErrorMessage("Long UDP packet, length field < payload length\n");
3267         }
3268 
3269         p->udph = NULL;
3270         pc.discards++;
3271         pc.udisc++;
3272 
3273         return;
3274     }
3275 
3276     /* fill in the printout data structs */
3277     p->sp = ntohs(p->udph->uh_sport);
3278     p->dp = ntohs(p->udph->uh_dport);
3279 
3280 //    if (BcUdpChecksums())
3281     {
3282         /* look at the UDP checksum to make sure we've got a good packet */
3283 #ifdef SUP_IP6
3284         if(IS_IP4(p))
3285         {
3286             ph.sip = *p->ip4h->ip_src.ip32;
3287             ph.dip = *p->ip4h->ip_dst.ip32;
3288 #else
3289             ph.sip = (uint32_t)(p->iph->ip_src.s_addr);
3290             ph.dip = (uint32_t)(p->iph->ip_dst.s_addr);
3291 #endif
3292             ph.zero = 0;
3293             ph.protocol = GET_IPH_PROTO(p);
3294             ph.udplen = p->udph->uh_len;
3295             /* Don't do checksum calculation if
3296              * 1) Framented, OR
3297              * 2) UDP header chksum value is 0.
3298              */
3299             if( !fragmented_udp_flag && p->udph->uh_chk )
3300             {
3301                 csum = in_chksum_udp((uint16_t *)&ph,
3302                         (uint16_t *)(p->udph), uhlen);
3303             }
3304             else
3305             {
3306                 csum = 0;
3307             }
3308 #ifdef SUP_IP6
3309         }
3310         else
3311         {
3312             COPY4(ph6.sip, p->ip6h->ip_src.ip32);
3313             COPY4(ph6.dip, p->ip6h->ip_dst.ip32);
3314             ph6.zero = 0;
3315             ph6.protocol = GET_IPH_PROTO(p);
3316             ph6.udplen = htons((u_short)len);
3317             /* Don't do checksum calculation if
3318              * 1) Framented, OR
3319              * 2) UDP header chksum value is 0.
3320              */
3321             if( !fragmented_udp_flag && p->udph->uh_chk )
3322             {
3323                 csum = in_chksum_udp6((uint16_t *)&ph6,
3324                         (uint16_t *)(p->udph), uhlen);
3325             }
3326             else if ( !p->udph->uh_chk )
3327             {
3328                 csum = 1;
3329             }
3330             else
3331             {
3332                 csum = 0;
3333             }
3334         }
3335 #endif
3336         if(csum)
3337         {
3338             p->csum_flags |= CSE_UDP;
3339             DEBUG_WRAP(DebugMessage(DEBUG_DECODE, "Bad UDP Checksum\n"););
3340         }
3341         else
3342         {
3343             DEBUG_WRAP(DebugMessage(DEBUG_DECODE, "UDP Checksum: OK\n"););
3344         }
3345     }
3346 
3347     DEBUG_WRAP(DebugMessage(DEBUG_DECODE, "UDP header starts at: %p\n", p->udph););
3348 
3349     p->data = (uint8_t *) (pkt + UDP_HEADER_LEN);
3350 
3351     /* length was validated up above */
3352     p->dsize = uhlen - UDP_HEADER_LEN;
3353 
3354     /*  Drop packet if we ignore this port  */
3355 //    if (BcIgnoreUdpPort(p->sp) || BcIgnoreUdpPort(p->dp))
3356 //    {
3357 //        /*  Ignore all preprocessors for this packet */
3358 //        p->packet_flags |= PKT_IGNORE_PORT;
3359 //    }
3360 
3361     p->proto_bits |= PROTO_BIT__UDP;
3362 }
3363 
3364 
3365 
3366 /*
3367  * Function: DecodeICMP(uint8_t *, const uint32_t, Packet *)
3368  *
3369  * Purpose: Decode the ICMP transport layer
3370  *
3371  * Arguments: pkt => ptr to the packet data
3372  *            len => length from here to the end of the packet
3373  *            p   => pointer to the decoded packet struct
3374  *
3375  * Returns: void function
3376  */
DecodeICMP(const uint8_t * pkt,const uint32_t len,Packet * p)3377 void DecodeICMP(const uint8_t * pkt, const uint32_t len, Packet * p)
3378 {
3379     uint16_t csum;
3380 
3381     if(len < ICMP_HEADER_LEN)
3382     {
3383         if (BcLogVerbose())
3384         {
3385             ErrorMessage("WARNING: Truncated ICMP header "
3386                          "(%d bytes)\n", len);
3387         }
3388 
3389         p->icmph = NULL;
3390         pc.discards++;
3391         pc.icmpdisc++;
3392 
3393         return;
3394     }
3395 
3396     /* set the header ptr first */
3397     p->icmph = (ICMPHdr *) pkt;
3398 
3399     switch (p->icmph->type)
3400     {
3401         case ICMP_DEST_UNREACH:
3402         case ICMP_SOURCE_QUENCH:
3403         case ICMP_REDIRECT:
3404         case ICMP_TIME_EXCEEDED:
3405         case ICMP_PARAMETERPROB:
3406         case ICMP_ECHOREPLY:
3407         case ICMP_ECHO:
3408         case ICMP_ROUTER_ADVERTISE:
3409         case ICMP_ROUTER_SOLICIT:
3410         case ICMP_INFO_REQUEST:
3411         case ICMP_INFO_REPLY:
3412             if (len < 8)
3413             {
3414                 if (BcLogVerbose())
3415                 {
3416                     ErrorMessage("Truncated ICMP header(%d bytes)\n", len);
3417                 }
3418 
3419                 p->icmph = NULL;
3420                 pc.discards++;
3421                 pc.icmpdisc++;
3422 
3423                 return;
3424             }
3425 
3426             break;
3427 
3428         case ICMP_TIMESTAMP:
3429         case ICMP_TIMESTAMPREPLY:
3430             if (len < 20)
3431             {
3432                 if (BcLogVerbose())
3433                 {
3434                     ErrorMessage("Truncated ICMP header(%d bytes)\n", len);
3435                 }
3436 
3437                 p->icmph = NULL;
3438                 pc.discards++;
3439                 pc.icmpdisc++;
3440 
3441                 return;
3442             }
3443 
3444             break;
3445 
3446         case ICMP_ADDRESS:
3447         case ICMP_ADDRESSREPLY:
3448             if (len < 12)
3449             {
3450                 if (BcLogVerbose())
3451                 {
3452                     ErrorMessage("Truncated ICMP header(%d bytes)\n", len);
3453                 }
3454 
3455                 p->icmph = NULL;
3456                 pc.discards++;
3457                 pc.icmpdisc++;
3458 
3459                 return;
3460             }
3461 
3462             break;
3463     }
3464 
3465 
3466 //    if (BcIcmpChecksums())
3467     {
3468         csum = in_chksum_icmp((uint16_t *)p->icmph, len);
3469 
3470         if(csum)
3471         {
3472             p->csum_flags |= CSE_ICMP;
3473 
3474             DEBUG_WRAP(DebugMessage(DEBUG_DECODE, "Bad ICMP Checksum\n"););
3475         }
3476         else
3477         {
3478             DEBUG_WRAP(DebugMessage(DEBUG_DECODE,"ICMP Checksum: OK\n"););
3479         }
3480     }
3481 
3482     p->dsize = (u_short)(len - ICMP_HEADER_LEN);
3483     p->data = pkt + ICMP_HEADER_LEN;
3484 
3485     DEBUG_WRAP(DebugMessage(DEBUG_DECODE, "ICMP type: %d   code: %d\n",
3486                 p->icmph->code, p->icmph->type););
3487 
3488     switch(p->icmph->type)
3489     {
3490         case ICMP_ECHO:
3491         case ICMP_ECHOREPLY:
3492             /* setup the pkt id and seq numbers */
3493             p->dsize -= sizeof(struct idseq);   /* add the size of the
3494                                                  * echo ext to the data
3495                                                  * ptr and subtract it
3496                                                  * from the data size */
3497             p->data += sizeof(struct idseq);
3498             break;
3499 
3500         case ICMP_DEST_UNREACH:
3501         case ICMP_REDIRECT:
3502         case ICMP_SOURCE_QUENCH:
3503         case ICMP_TIME_EXCEEDED:
3504         case ICMP_PARAMETERPROB:
3505             /* account for extra 4 bytes in header */
3506             p->dsize -= 4;
3507             p->data += 4;
3508 
3509             DecodeICMPEmbeddedIP(p->data, p->dsize, p);
3510 
3511             break;
3512     }
3513 
3514     p->proto_bits |= PROTO_BIT__ICMP;
3515 }
3516 
3517 /*
3518  * Function: DecodeICMPEmbeddedIP(uint8_t *, const uint32_t, Packet *)
3519  *
3520  * Purpose: Decode the ICMP embedded IP header + 64 bits payload
3521  *
3522  * Arguments: pkt => ptr to the packet data
3523  *            len => length from here to the end of the packet
3524  *            p   => pointer to dummy packet decode struct
3525  *
3526  * Returns: void function
3527  */
DecodeICMPEmbeddedIP(const uint8_t * pkt,const uint32_t len,Packet * p)3528 void DecodeICMPEmbeddedIP(const uint8_t *pkt, const uint32_t len, Packet *p)
3529 {
3530     uint32_t ip_len;       /* length from the start of the ip hdr to the
3531                              * pkt end */
3532     uint32_t hlen;             /* ip header length */
3533     uint16_t orig_frag_offset;
3534 
3535     /* do a little validation */
3536     if(len < IP_HEADER_LEN)
3537     {
3538         if (BcLogVerbose())
3539         {
3540             ErrorMessage("ICMP: IP short header (%d bytes)\n", len);
3541         }
3542 
3543 #ifdef SUP_IP6
3544         p->orig_family = NO_IP;
3545 #endif
3546         p->orig_iph = NULL;
3547         return;
3548     }
3549 
3550     /* lay the IP struct over the raw data */
3551 #ifdef SUP_IP6
3552     sfiph_orig_build(p, pkt, AF_INET);
3553 #endif
3554     p->orig_iph = (IPHdr *) pkt;
3555 
3556     DEBUG_WRAP(DebugMessage(DEBUG_DECODE, "DecodeICMPEmbeddedIP: ip header"
3557                     " starts at: %p, length is %lu\n", p->orig_iph,
3558                     (unsigned long) len););
3559     /*
3560      * with datalink DLT_RAW it's impossible to differ ARP datagrams from IP.
3561      * So we are just ignoring non IP datagrams
3562      */
3563     if((GET_ORIG_IPH_VER(p) != 4) && !IS_IP6(p))
3564     {
3565         if (BcLogVerbose())
3566         {
3567             ErrorMessage("ICMP: not IPv4 datagram "
3568                          "([ver: 0x%x][len: 0x%x])\n",
3569                          GET_ORIG_IPH_VER(p), GET_ORIG_IPH_LEN(p));
3570 
3571         }
3572 
3573 #ifdef SUP_IP6
3574         p->orig_family = NO_IP;
3575 #endif
3576         p->orig_iph = NULL;
3577         return;
3578     }
3579 
3580     /* set the IP datagram length */
3581     ip_len = ntohs(GET_ORIG_IPH_LEN(p));
3582 
3583     /* set the IP header length */
3584 #ifdef SUP_IP6
3585     hlen = (p->orig_ip4h->ip_verhl & 0x0f) << 2;
3586 #else
3587     hlen = IP_HLEN(p->orig_iph) << 2;
3588 #endif
3589 
3590     if(len < hlen)
3591     {
3592         if (BcLogVerbose())
3593         {
3594             ErrorMessage("ICMP: IP len (%d bytes) < "
3595                          "IP hdr len (%d bytes), packet discarded\n", ip_len, hlen);
3596         }
3597 
3598 #ifdef SUP_IP6
3599         p->orig_family = NO_IP;
3600 #endif
3601         p->orig_iph = NULL;
3602         return;
3603     }
3604 
3605     /* set the remaining packet length */
3606     ip_len = len - hlen;
3607 
3608     orig_frag_offset = ntohs(GET_ORIG_IPH_OFF(p));
3609     orig_frag_offset &= 0x1FFF;
3610 
3611     if (orig_frag_offset == 0)
3612     {
3613         /* Original IP payload should be 64 bits */
3614         if (ip_len < 8)
3615         {
3616             if (BcLogVerbose())
3617             {
3618                 ErrorMessage("ICMP: IP payload length < 64 bits\n");
3619             }
3620 
3621             return;
3622         }
3623         /* ICMP error packets could contain as much of original payload
3624          * as possible, but not exceed 576 bytes
3625          */
3626         else if (ntohs(GET_IPH_LEN(p)) > 576)
3627         {
3628             if (BcLogVerbose())
3629             {
3630                 ErrorMessage("ICMP: ICMP error packet length > 576 bytes\n");
3631             }
3632         }
3633     }
3634     else
3635     {
3636         return;
3637     }
3638 
3639     DEBUG_WRAP(DebugMessage(DEBUG_DECODE, "ICMP Unreachable IP header length: "
3640                             "%lu\n", (unsigned long)hlen););
3641 
3642     switch(GET_ORIG_IPH_PROTO(p))
3643     {
3644         case IPPROTO_TCP: /* decode the interesting part of the header */
3645             p->orig_tcph = (TCPHdr *)(pkt + hlen);
3646 
3647             /* stuff more data into the printout data struct */
3648             p->orig_sp = ntohs(p->orig_tcph->th_sport);
3649             p->orig_dp = ntohs(p->orig_tcph->th_dport);
3650 
3651             break;
3652 
3653         case IPPROTO_UDP:
3654             p->orig_udph = (UDPHdr *)(pkt + hlen);
3655 
3656             /* fill in the printout data structs */
3657             p->orig_sp = ntohs(p->orig_udph->uh_sport);
3658             p->orig_dp = ntohs(p->orig_udph->uh_dport);
3659 
3660             break;
3661 
3662         case IPPROTO_ICMP:
3663             p->orig_icmph = (ICMPHdr *)(pkt + hlen);
3664             break;
3665     }
3666 
3667     return;
3668 }
3669 
3670 /*
3671  * Function: DecodeARP(uint8_t *, uint32_t, Packet *)
3672  *
3673  * Purpose: Decode ARP stuff
3674  *
3675  * Arguments: pkt => ptr to the packet data
3676  *            len => length from here to the end of the packet
3677  *            p   => pointer to decoded packet struct
3678  *
3679  * Returns: void function
3680  */
DecodeARP(const uint8_t * pkt,uint32_t len,Packet * p)3681 void DecodeARP(const uint8_t * pkt, uint32_t len, Packet * p)
3682 {
3683     pc.arp++;
3684 
3685 #ifdef GRE
3686     if (p->greh != NULL)
3687         pc.gre_arp++;
3688 #endif
3689 
3690     p->ah = (EtherARP *) pkt;
3691 
3692     if(len < sizeof(EtherARP))
3693     {
3694         if (BcLogVerbose())
3695             ErrorMessage("Truncated packet\n");
3696 
3697         pc.discards++;
3698         return;
3699     }
3700 
3701     p->proto_bits |= PROTO_BIT__ARP;
3702 }
3703 
3704 #ifndef NO_NON_ETHER_DECODER
3705 /*
3706  * Function: DecodeEapol(uint8_t *, uint32_t, Packet *)
3707  *
3708  * Purpose: Decode 802.1x eapol stuff
3709  *
3710  * Arguments: pkt => ptr to the packet data
3711  *            len => length from here to the end of the packet
3712  *            p   => pointer to decoded packet struct
3713  *
3714  * Returns: void function
3715  */
DecodeEapol(const uint8_t * pkt,uint32_t len,Packet * p)3716 void DecodeEapol(const uint8_t * pkt, uint32_t len, Packet * p)
3717 {
3718     p->eplh = (EtherEapol *) pkt;
3719     pc.eapol++;
3720     if(len < sizeof(EtherEapol))
3721     {
3722         if (BcLogVerbose())
3723             ErrorMessage("Truncated packet\n");
3724 
3725         pc.discards++;
3726         return;
3727     }
3728     if (p->eplh->eaptype == EAPOL_TYPE_EAP) {
3729         DecodeEAP(pkt + sizeof(EtherEapol), len - sizeof(EtherEapol), p);
3730     }
3731     else if(p->eplh->eaptype == EAPOL_TYPE_KEY) {
3732         DecodeEapolKey(pkt + sizeof(EtherEapol), len - sizeof(EtherEapol), p);
3733     }
3734     return;
3735 }
3736 
3737 /*
3738  * Function: DecodeEapolKey(uint8_t *, uint32_t, Packet *)
3739  *
3740  * Purpose: Decode 1x key setup
3741  *
3742  * Arguments: pkt => ptr to the packet data
3743  *            len => length from here to the end of the packet
3744  *            p   => pointer to decoded packet struct
3745  *
3746  * Returns: void function
3747  */
DecodeEapolKey(const uint8_t * pkt,uint32_t len,Packet * p)3748 void DecodeEapolKey(const uint8_t * pkt, uint32_t len, Packet * p)
3749 {
3750     p->eapolk = (EapolKey *) pkt;
3751     if(len < sizeof(EapolKey))
3752     {
3753         if(BcLogVerbose())
3754             ErrorMessage("Truncated packet\n");
3755 
3756         pc.discards++;
3757         return;
3758     }
3759 
3760     return;
3761 }
3762 
3763 /*
3764  * Function: DecodeEAP(uint8_t *, uint32_t, Packet *)
3765  *
3766  * Purpose: Decode Extensible Authentication Protocol
3767  *
3768  * Arguments: pkt => ptr to the packet data
3769  *            len => length from here to the end of the packet
3770  *            p   => pointer to decoded packet struct
3771  *
3772  * Returns: void function
3773  */
DecodeEAP(const uint8_t * pkt,const uint32_t len,Packet * p)3774 void DecodeEAP(const uint8_t * pkt, const uint32_t len, Packet * p)
3775 {
3776     p->eaph = (EAPHdr *) pkt;
3777     if(len < sizeof(EAPHdr))
3778     {
3779         if (BcLogVerbose())
3780             printf("Truncated packet\n");
3781 
3782         pc.discards++;
3783         return;
3784     }
3785     if (p->eaph->code == EAP_CODE_REQUEST ||
3786             p->eaph->code == EAP_CODE_RESPONSE) {
3787         p->eaptype = pkt + sizeof(EAPHdr);
3788     }
3789     return;
3790 }
3791 #endif  // NO_NON_ETHER_DECODER
3792 
3793 #ifdef SUP_IP6
3794 /*
3795  * Function: DecodeICMPEmbeddedIP6(uint8_t *, const uint32_t, Packet *)
3796  *
3797  * Purpose: Decode the ICMP embedded IP6 header + payload
3798  *
3799  * Arguments: pkt => ptr to the packet data
3800  *            len => length from here to the end of the packet
3801  *            p   => pointer to dummy packet decode struct
3802  *
3803  * Returns: void function
3804  */
DecodeICMPEmbeddedIP6(const uint8_t * pkt,const uint32_t len,Packet * p)3805 void DecodeICMPEmbeddedIP6(const uint8_t *pkt, const uint32_t len, Packet *p)
3806 {
3807     uint32_t ip_len;       /* length from the start of the ip hdr to the
3808                              * pkt end */
3809     uint32_t hlen;             /* ip header length */
3810     uint16_t orig_frag_offset;
3811 
3812 
3813     /* lay the IP struct over the raw data */
3814     IP6Hdr *ip6h = (IP6Hdr *) pkt;
3815     pc.embdip++;
3816 
3817     DEBUG_WRAP(DebugMessage(DEBUG_DECODE, "DecodeICMPEmbeddedIP6: ip header"
3818                     " starts at: %p, length is %lu\n", ip6h,
3819                     (unsigned long) len););
3820 
3821     /* do a little validation */
3822     if(len < IP6_HDR_LEN)
3823     {
3824         if (BcLogVerbose())
3825             ErrorMessage("ICMP6: IP short header (%d bytes)\n", len);
3826 
3827         pc.discards++;
3828         return;
3829     }
3830 
3831     /*
3832      * with datalink DLT_RAW it's impossible to differ ARP datagrams from IP.
3833      * So we are just ignoring non IP datagrams
3834      */
3835 // XXX-IPv6 double check this - checking version in IPv6 header
3836     if((ip6h->vcl & 0xf0) != 0x60)
3837     {
3838         if (BcLogVerbose())
3839         {
3840             ErrorMessage("ICMP: not IPv6 datagram "
3841                          "([ver: 0x%x][len: 0x%x])\n",
3842                         // XXX-IPv6 shouldn't the length be ntohs'ed?
3843                          (ip6h->vcl & 0x0f)>>4, ip6h->len);
3844 
3845         }
3846 
3847         pc.discards++;
3848         return;
3849     }
3850 
3851     /* set the IP datagram length */
3852     ip_len = ntohs(ip6h->len);
3853 
3854     /* set the IP header length */
3855     hlen = (ip6h->vcl & 0x0f ) << 2;
3856 
3857     if(len < hlen)
3858     {
3859         if (BcLogVerbose())
3860         {
3861             ErrorMessage("ICMP6: IP6 len (%d bytes) < "
3862                          "IP6 hdr len (%d bytes), packet discarded\n", ip_len, hlen);
3863         }
3864 
3865         pc.discards++;
3866         return;
3867     }
3868 #ifdef SUP_IP6
3869     sfiph_orig_build(p, pkt, AF_INET6);
3870 #endif
3871 
3872     /* set the remaining packet length */
3873     ip_len = len - hlen;
3874 
3875     orig_frag_offset = ntohs(GET_ORIG_IPH_OFF(p));
3876     orig_frag_offset &= 0x1FFF;
3877 
3878 // XXX NOT YET IMPLEMENTED - fragments inside ICMP payload
3879 #if 0
3880     if (orig_frag_offset == 0)
3881     {
3882         /* Original IP payload should be 64 bits */
3883         if (ip_len < 8)
3884         {
3885             if (BcLogVerbose())
3886             {
3887                 ErrorMessage("ICMP6: IP6 payload length < 64 bits\n");
3888             }
3889 
3890             return;
3891         }
3892         /* ICMP6 error packets could contain as much of original payload
3893          * as possible, but not exceed the MTU
3894          */
3895 #warning "MTU?"
3896         else if (ntohs(p->iph->ip_len) > 576)
3897         {
3898             if (BcLogVerbose())
3899             {
3900                 ErrorMessage("ICMP: ICMP error packet length > 576 bytes\n");
3901             }
3902         }
3903     }
3904     else
3905     {
3906         return;
3907     }
3908 #endif
3909 
3910     DEBUG_WRAP(DebugMessage(DEBUG_DECODE, "ICMP6 Unreachable IP6 header length: "
3911                             "%lu\n", (unsigned long)hlen););
3912 
3913     switch(GET_ORIG_IPH_PROTO(p))
3914     {
3915         case IPPROTO_TCP: /* decode the interesting part of the header */
3916             p->orig_tcph = (TCPHdr *)(pkt + hlen);
3917 
3918             /* stuff more data into the printout data struct */
3919             p->orig_sp = ntohs(p->orig_tcph->th_sport);
3920             p->orig_dp = ntohs(p->orig_tcph->th_dport);
3921 
3922             break;
3923 
3924         case IPPROTO_UDP:
3925             p->orig_udph = (UDPHdr *)(pkt + hlen);
3926 
3927             /* fill in the printout data structs */
3928             p->orig_sp = ntohs(p->orig_udph->uh_sport);
3929             p->orig_dp = ntohs(p->orig_udph->uh_dport);
3930 
3931             break;
3932 
3933         case IPPROTO_ICMP:
3934             p->orig_icmph = (ICMPHdr *)(pkt + hlen);
3935             break;
3936     }
3937 
3938     return;
3939 }
3940 
DecodeICMP6(const uint8_t * pkt,uint32_t len,Packet * p)3941 void DecodeICMP6(const uint8_t *pkt, uint32_t len, Packet *p)
3942 {
3943     if(len < ICMP6_MIN_HEADER_LEN)
3944     {
3945         if (BcLogVerbose())
3946         {
3947             ErrorMessage("WARNING: Truncated ICMP header "
3948                          "(%d bytes)\n", len);
3949         }
3950 
3951         pc.discards++;
3952         return;
3953     }
3954 
3955     p->icmph = (ICMPHdr*)pkt;
3956 //    p->icmp6h = pkt;
3957 //    p->icmph = (ICMPHdr*)p->icmp6h;
3958 //    memcpy(&p->icmp6h, pkt, ICMP6_MIN_HEADER_LEN);
3959 //    p->icmp6h.body = pkt + ICMP6_MIN_HEADER_LEN;
3960 
3961     /* Do checksums */
3962     if(in_chksum_icmp6((uint16_t*)p->icmph, len))
3963     {
3964         p->csum_flags |= CSE_ICMP;
3965 
3966         DEBUG_WRAP(DebugMessage(DEBUG_DECODE, "Bad ICMP Checksum\n"););
3967 
3968 //        if(InlineMode() && (pv.checksums_drop & DO_ICMP_CHECKSUMS))
3969 //        {
3970 //            DEBUG_WRAP(DebugMessage(DEBUG_DECODE,
3971 //                        "Dropping packet with Bad ICMP checksum\n"););
3972 //            InlineDrop(p);
3973 //        }
3974     }
3975     else
3976     {
3977         DEBUG_WRAP(DebugMessage(DEBUG_DECODE,"ICMP Checksum: OK\n"););
3978     }
3979 
3980 
3981     p->dsize = (u_short)(len - ICMP6_MIN_HEADER_LEN);
3982     p->data = pkt + ICMP6_MIN_HEADER_LEN;
3983 
3984     DEBUG_WRAP(DebugMessage(DEBUG_DECODE, "ICMP type: %d   code: %d\n",
3985                 p->icmph->code, p->icmph->type););
3986 
3987     switch(p->icmph->type)
3988     {
3989         case ICMP6_ECHO:
3990         case ICMP6_REPLY:
3991             if (p->dsize >= sizeof(struct idseq))
3992             {
3993                 p->icmp6h = (ICMP6Hdr *)pkt;
3994                 /* Set data pointer to that of the "echo message" */
3995                 p->dsize -= sizeof(struct idseq);   /* add the size of the
3996                                                  * echo ext to the data
3997                                                  * ptr and subtract it
3998                                                  * from the data size */
3999                 p->data += sizeof(struct idseq);
4000             }
4001             else
4002             {
4003                 if (BcLogVerbose())
4004                 {
4005                     ErrorMessage("WARNING: Truncated ICMP Echo header "
4006                          "(%d bytes)\n", len);
4007                 }
4008 
4009                 p->icmp6h = NULL;
4010                 pc.discards++;
4011                 pc.icmpdisc++;
4012                 return;
4013             }
4014             break;
4015 
4016         case ICMP6_TIME:
4017         case ICMP6_PARAMS:
4018         case ICMP6_BIG:
4019         case ICMP6_UNREACH:
4020             if (p->dsize >= 4)
4021             {
4022                 p->icmp6h = (ICMP6Hdr *)pkt;
4023                 /* Set data pointer past the 'unused/mtu/pointer block */
4024                 p->data += 4;
4025                 p->dsize -= 4;
4026                 DecodeICMPEmbeddedIP6(p->data, p->dsize, p);
4027             }
4028             else
4029             {
4030                 if (BcLogVerbose())
4031                 {
4032                     ErrorMessage("WARNING: Truncated ICMP header "
4033                          "(%d bytes)\n", len);
4034                 }
4035 
4036                 p->icmp6h = NULL;
4037                 pc.discards++;
4038                 pc.icmpdisc++;
4039                 return;
4040             }
4041             break;
4042     }
4043 
4044     p->proto_bits |= PROTO_BIT__ICMP;
4045 }
4046 
4047 void DecodeIPV6Extensions(uint8_t next, const uint8_t *pkt, uint32_t len, Packet *p);
4048 
DecodeIPV6Options(int type,const uint8_t * pkt,uint32_t len,Packet * p)4049 void DecodeIPV6Options(int type, const uint8_t *pkt, uint32_t len, Packet *p)
4050 {
4051     IP6Extension *exthdr;
4052     uint32_t hdrlen = 0;
4053 
4054     /* This should only be called by DecodeIPV6 or DecodeIPV6Extensions
4055      * so no validation performed.  Otherwise, uncomment the following: */
4056     /* if(IPH_IS_VALID(p)) return */
4057 
4058     pc.ipv6opts++;
4059 
4060     /* Need at least two bytes, one for next header, one for len. */
4061     /* But size is an integer multiple of 8 octets, so 8 is min.  */
4062     if(len < sizeof(IP6Extension))
4063     {
4064 /*
4065 ** barnyard2
4066 ** As we are reading from the unified2 file, when decoding these packets we
4067 ** don't want additional events to be created.
4068 */
4069 //        DecoderEvent(p, DECODE_IPV6_TRUNCATED_EXT,
4070 //                     DECODE_IPV6_TRUNCATED_EXT_STR,
4071 //                     pv.decoder_flags.decode_alerts,
4072 //                     pv.decoder_flags.drop_alerts);
4073         return;
4074     }
4075 
4076     exthdr = (IP6Extension *)pkt;
4077 
4078     if(p->ip6_extension_count < IP6_EXTMAX)
4079     {
4080         p->ip6_extensions[p->ip6_extension_count].type = type;
4081         p->ip6_extensions[p->ip6_extension_count].data = pkt;
4082 
4083         switch (type)
4084         {
4085             case IPPROTO_HOPOPTS:
4086                 if (len < sizeof(IP6HopByHop))
4087                 {
4088 /*
4089 ** barnyard2
4090 ** As we are reading from the unified2 file, when decoding these packets we
4091 ** don't want additional events to be created.
4092 */
4093 //                    DecoderEvent(p, DECODE_IPV6_TRUNCATED_EXT,
4094 //                                DECODE_IPV6_TRUNCATED_EXT_STR,
4095 //                                pv.decoder_flags.decode_alerts,
4096 //                                pv.decoder_flags.drop_alerts);
4097                     return;
4098                 }
4099                 hdrlen = sizeof(IP6Extension) + (exthdr->ip6e_len << 3);
4100                 break;
4101             case IPPROTO_DSTOPTS:
4102                 if (len < sizeof(IP6Dest))
4103                 {
4104 /*
4105 ** barnyard2
4106 ** As we are reading from the unified2 file, when decoding these packets we
4107 ** don't want additional events to be created.
4108 */
4109 //                    DecoderEvent(p, DECODE_IPV6_TRUNCATED_EXT,
4110 //                                 DECODE_IPV6_TRUNCATED_EXT_STR,
4111 //                                 pv.decoder_flags.decode_alerts,
4112 //                                 pv.decoder_flags.drop_alerts);
4113                     return;
4114                 }
4115                 hdrlen = sizeof(IP6Extension) + (exthdr->ip6e_len << 3);
4116                 break;
4117             case IPPROTO_ROUTING:
4118                 if (len < sizeof(IP6Route))
4119                 {
4120 /*
4121 ** barnyard2
4122 ** As we are reading from the unified2 file, when decoding these packets we
4123 ** don't want additional events to be created.
4124 */
4125 //                    DecoderEvent(p, DECODE_IPV6_TRUNCATED_EXT,
4126 //                                 DECODE_IPV6_TRUNCATED_EXT_STR,
4127 //                                 pv.decoder_flags.decode_alerts,
4128 //                                 pv.decoder_flags.drop_alerts);
4129                     return;
4130                 }
4131                 hdrlen = sizeof(IP6Extension) + (exthdr->ip6e_len << 3);
4132                 break;
4133             case IPPROTO_FRAGMENT:
4134                 {
4135                     IP6Frag *ip6frag_hdr = (IP6Frag *)pkt;
4136                     if (len < sizeof(IP6Frag))
4137                     {
4138 /*
4139 ** barnyard2
4140 ** As we are reading from the unified2 file, when decoding these packets we
4141 ** don't want additional events to be created.
4142 */
4143 //                        DecoderEvent(p, DECODE_IPV6_TRUNCATED_EXT,
4144 //                                     DECODE_IPV6_TRUNCATED_EXT_STR,
4145 //                                     pv.decoder_flags.decode_alerts,
4146 //                                     pv.decoder_flags.drop_alerts);
4147                         return;
4148                     }
4149                     /* If this is an IP Fragment, set some data... */
4150                     p->ip6_frag_index = p->ip6_extension_count;
4151                     p->ip_frag_start = pkt + sizeof(IP6Frag);
4152                     p->frag_flag = 1;
4153                     pc.frag6++;
4154 
4155                     p->df = 0;
4156                     p->rf = IP6F_RES(ip6frag_hdr);
4157                     p->mf = IP6F_MF(ip6frag_hdr);
4158                     p->frag_offset = IP6F_OFFSET(ip6frag_hdr);
4159                 }
4160                 hdrlen = sizeof(IP6Extension) + (exthdr->ip6e_len << 3);
4161                 p->ip_frag_len = (uint16_t)(len - hdrlen);
4162                 break;
4163             default:
4164                 hdrlen = sizeof(IP6Extension) + (exthdr->ip6e_len << 3);
4165                 break;
4166         }
4167 
4168         p->ip6_extension_count++;
4169     }
4170 
4171     if(hdrlen > len)
4172     {
4173 /*
4174 ** barnyard2
4175 ** As we are reading from the unified2 file, when decoding these packets we
4176 ** don't want additional events to be created.
4177 */
4178 //        DecoderEvent(p, DECODE_IPV6_TRUNCATED_EXT,
4179 //                     DECODE_IPV6_TRUNCATED_EXT_STR,
4180 //                    pv.decoder_flags.decode_alerts,
4181 //                     pv.decoder_flags.drop_alerts);
4182         return;
4183     }
4184 
4185     DecodeIPV6Extensions(*pkt, pkt + hdrlen, len - hdrlen, p);
4186 }
4187 
DecodeIPV6Extensions(uint8_t next,const uint8_t * pkt,uint32_t len,Packet * p)4188 void DecodeIPV6Extensions(uint8_t next, const uint8_t *pkt, uint32_t len, Packet *p)
4189 {
4190     pc.ip6ext++;
4191 
4192 #ifdef GRE
4193     if (p->greh != NULL)
4194         pc.gre_ipv6ext++;
4195 #endif
4196 
4197     /* XXX might this introduce an issue if the "next" field is invalid? */
4198     p->ip6h->next = next;
4199 
4200     switch(next) {
4201         case IPPROTO_TCP:
4202             pc.tcp6++;
4203             DecodeTCP(pkt, len, p);
4204             return;
4205         case IPPROTO_UDP:
4206             pc.udp6++;
4207             DecodeUDP(pkt, len, p);
4208             return;
4209         case IPPROTO_ICMP:
4210             pc.icmp++;
4211             DecodeICMP(pkt, len, p);
4212             return;
4213         case IPPROTO_ICMPV6:
4214             pc.icmp6++;
4215             DecodeICMP6(pkt , len, p);
4216             return;
4217 #ifndef SUP_IP6
4218         case IPPROTO_FRAGMENT:
4219             // XXX
4220             // Fragmentation not yet supported
4221             // DecodeIPv6FragHdr(p, pkt);
4222             // XXX
4223 
4224             p->frag_flag = 1;
4225             pc.frag6++;
4226             p->dsize = 0;
4227             return;
4228 #endif
4229         case IPPROTO_NONE:
4230             p->dsize = 0;
4231             return;
4232         case IPPROTO_HOPOPTS:
4233         case IPPROTO_DSTOPTS:
4234         case IPPROTO_ROUTING:
4235 #ifdef SUP_IP6
4236         case IPPROTO_FRAGMENT:
4237 #endif
4238             DecodeIPV6Options(next, pkt, len, p);
4239             // Anything special to do here?  just return?
4240             return;
4241 #ifdef GRE
4242         case IPPROTO_GRE:
4243             pc.gre++;
4244             DecodeGRE(pkt, len, p);
4245             return;
4246         case IPPROTO_IPIP:
4247             pc.ip6ip4++;
4248             DecodeIP(pkt, len, p);
4249             return;
4250         case IPPROTO_IPV6:
4251             pc.ip6ip6++;
4252             DecodeIPV6(pkt, len, p);
4253             return;
4254 #endif
4255         default:
4256             // There may be valid headers after this unsupported one,
4257             // need to decode this header, set "next" and continue
4258             // looping.
4259             pc.other++;
4260             p->data = pkt;
4261             p->dsize = (uint16_t)len;
4262             break;
4263     };
4264 }
4265 #endif /* SUP_IP6 */
4266 
4267 /*
4268  * Function: DecodeIPV6(uint8_t *, uint32_t)
4269  *
4270  * Purpose: Decoding IPv6 headers
4271  *
4272  * Arguments: pkt => ptr to the packet data
4273  *            len => length from here to the end of the packet
4274  *
4275  * Returns: void function
4276  */
DecodeIPV6(const uint8_t * pkt,uint32_t len,Packet * p)4277 void DecodeIPV6(const uint8_t *pkt, uint32_t len, Packet *p)
4278 {
4279 #ifndef SUP_IP6
4280     static uint8_t pseudopacket_buf[SPARC_TWIDDLE + ETHERNET_HEADER_LEN + IP_MAXPACKET];
4281     static Packet pseudopacket;
4282     static struct pcap_pkthdr pseudopcap_header;
4283     IP6RawHdr *ip6h;
4284 //    int alert_status;
4285 
4286     pc.ipv6++;
4287 
4288 #ifdef GRE
4289     if (p->greh != NULL)
4290         pc.gre_ipv6++;
4291 #endif
4292 
4293 //    alert_status = CheckIPV6Frag((char *) pkt, len, p);
4294 
4295 //    if(alert_status == IPV6_FRAG_NO_ALERT)
4296 //    {
4297 //        return;
4298 //    }
4299 
4300     p->packet_flags |= PKT_NO_DETECT;
4301 
4302     /* Need to set up a fake IP header for logging purposes.  First make sure
4303      * there is room */
4304     if(sizeof(IP6RawHdr) <= len)
4305     {
4306         pseudopcap_header.ts.tv_sec = p->pkth->ts.tv_sec;
4307         pseudopcap_header.ts.tv_usec = p->pkth->ts.tv_usec;
4308 
4309         BsdPseudoPacket = &pseudopacket;
4310         pseudopacket.pkt = pseudopacket_buf + SPARC_TWIDDLE;
4311         pseudopacket.pkth = &pseudopcap_header;
4312 
4313         if(p->eh)
4314         {
4315             SafeMemcpy(pseudopacket_buf + SPARC_TWIDDLE, p->eh,
4316                        ETHERNET_HEADER_LEN,
4317                        pseudopacket_buf,
4318                        pseudopacket_buf + SPARC_TWIDDLE + ETHERNET_HEADER_LEN + IP_MAXPACKET);
4319 
4320             pseudopcap_header.len = IP_HEADER_LEN + ETHERNET_HEADER_LEN;
4321 
4322             pseudopacket.eh = (EtherHdr*)(pseudopacket_buf + SPARC_TWIDDLE);
4323             pseudopacket.iph = (IPHdr*)(pseudopacket_buf + SPARC_TWIDDLE + ETHERNET_HEADER_LEN);
4324             ((EtherHdr*)pseudopacket.eh)->ether_type = htons(ETHERNET_TYPE_IP);
4325         }
4326         else
4327         {
4328             SafeMemcpy(pseudopacket_buf, p->pkt,
4329                        (pkt - p->pkt),
4330                        pseudopacket_buf,
4331                        pseudopacket_buf + SPARC_TWIDDLE + ETHERNET_HEADER_LEN + IP_MAXPACKET);
4332 
4333             pseudopcap_header.len = IP_HEADER_LEN + (pkt - p->pkt);
4334 
4335             pseudopacket.iph = (IPHdr*)(pseudopacket_buf + (pkt - p->pkt));
4336             pseudopacket.eh = NULL;
4337         }
4338 
4339         pseudopcap_header.caplen = pseudopcap_header.len;
4340 
4341         /* Need IP addresses for packet logging -- for now, just using the
4342          * lowest 4 bytes of the IPv6 addresses */
4343         memset((IPHdr *)pseudopacket.iph, 0, sizeof(IPHdr));
4344 
4345         ((IPHdr *)pseudopacket.iph)->ip_len = htons(IP_HEADER_LEN);
4346         SET_IP_VER((IPHdr *)pseudopacket.iph, 0x4);
4347         SET_IP_HLEN((IPHdr *)pseudopacket.iph, 0x5);
4348 
4349         ip6h = (IP6RawHdr*)pkt;
4350 
4351 #ifdef WORDS_BIGENDIAN
4352         ((IPHdr *)pseudopacket.iph)->ip_src.s_addr =
4353             ip6h->ip6_src.s6_addr[13] << 16 | ip6h->ip6_src.s6_addr[14] << 8 | ip6h->ip6_src.s6_addr[15];
4354         ((IPHdr *)pseudopacket.iph)->ip_dst.s_addr =
4355             ip6h->ip6_dst.s6_addr[13] << 16 | ip6h->ip6_dst.s6_addr[14] << 8 | ip6h->ip6_dst.s6_addr[15];
4356 #else
4357         ((IPHdr *)pseudopacket.iph)->ip_src.s_addr =
4358             ip6h->ip6_src.s6_addr[15] << 24 | ip6h->ip6_src.s6_addr[14] << 16 | ip6h->ip6_src.s6_addr[13] << 8;
4359         ((IPHdr *)pseudopacket.iph)->ip_dst.s_addr =
4360             ip6h->ip6_dst.s6_addr[15] << 24 | ip6h->ip6_dst.s6_addr[14] << 16 | ip6h->ip6_dst.s6_addr[13] << 8;
4361 #endif
4362     }
4363     else
4364     {
4365         p->iph = NULL;
4366     }
4367 
4368     pc.discards++;
4369     return;
4370 #else
4371 
4372     IP6RawHdr *hdr;
4373     uint32_t payload_len;
4374 
4375     pc.ipv6++;
4376 
4377 #ifdef GRE
4378     if (p->greh != NULL)
4379         pc.gre_ipv6++;
4380 #endif
4381 
4382     hdr = (IP6RawHdr*)pkt;
4383 
4384     if(len < IP6_HDR_LEN)
4385     {
4386         if (BcLogVerbose())
4387         {
4388             ErrorMessage("IP6 header truncated! (%d bytes)\n", len);
4389         }
4390 
4391 /*
4392 ** barnyard2
4393 ** As we are reading from the unified2 file, when decoding these packets we
4394 ** don't want additional events to be created.
4395 */
4396 //        DecoderEvent(p, DECODE_IPV6_TRUNCATED, DECODE_IPV6_TRUNCATED_STR,
4397 //                     pv.decoder_flags.decode_alerts, pv.decoder_flags.drop_alerts);
4398 
4399         goto decodeipv6_fail;
4400     }
4401 
4402     /* Verify version in IP6 Header agrees */
4403     if((hdr->ip6vfc >> 4) != 6)
4404     {
4405         if (BcLogVerbose())
4406         {
4407             ErrorMessage("Not IPv6 datagram! ([ver: 0x%x][len: 0x%x])\n",
4408                     (hdr->ip6vfc >> 4), hdr->ip6plen + IP6_HDR_LEN);
4409         }
4410 
4411 /*
4412 ** barnyard2
4413 ** As we are reading from the unified2 file, when decoding these packets we
4414 ** don't want additional events to be created.
4415 */
4416 //        DecoderEvent(p, DECODE_IPV6_IS_NOT,
4417 //                DECODE_IPV6_IS_NOT_STR,
4418 //                pv.decoder_flags.decode_alerts,
4419 //                pv.decoder_flags.drop_alerts);
4420 
4421         goto decodeipv6_fail;
4422     }
4423 
4424 #ifdef GRE
4425     if (p->family != NO_IP)
4426     {
4427         IP6RawHdr *tmp = (IP6RawHdr *)pkt;
4428 
4429         if (p->encapsulated ||
4430             ((tmp->ip6nxt == IPPROTO_IPIP) || (tmp->ip6nxt == IPPROTO_GRE) ||
4431              (tmp->ip6nxt == IPPROTO_IPV6)))
4432         {
4433 
4434             DecoderAlertGRE(p, DECODE_GRE_MULTIPLE_ENCAPSULATION,
4435                             DECODE_GRE_MULTIPLE_ENCAPSULATION_STR,
4436                             pkt, len);
4437             return;
4438         }
4439         else
4440         {
4441             p->encapsulated = 1;
4442             p->outer_iph = p->iph;
4443             p->outer_ip_data = p->ip_data;
4444             p->outer_ip_dsize = p->ip_dsize;
4445         }
4446     }
4447 #endif
4448     /* lay the IP struct over the raw data */
4449     p->inner_iph = p->iph = (IPHdr *)pkt;
4450 
4451     payload_len = ntohs(hdr->ip6plen) + IP6_HDR_LEN;
4452 
4453     if(payload_len != len)
4454     {
4455         if (payload_len > len)
4456         {
4457 #ifdef DEBUG
4458             if (BcLogVerbose())
4459             {
4460                 ErrorMessage("IP Len field is %d bytes bigger than captured "
4461                              "length (ip.len: %lu, cap.len: %lu)\n",
4462                              payload_len - len, payload_len, len);
4463             }
4464 #endif
4465 /*
4466 ** barnyard2
4467 ** As we are reading from the unified2 file, when decoding these packets we
4468 ** don't want additional events to be created.
4469 */
4470 //            DecoderEvent(p, DECODE_IPV6_DGRAM_GT_CAPLEN,
4471 //                    DECODE_IPV6_DGRAM_GT_CAPLEN_STR,
4472 //                    pv.decoder_flags.oversized_alert,
4473 //                    pv.decoder_flags.oversized_drop);
4474 
4475             goto decodeipv6_fail;
4476         }
4477         else
4478         {
4479 #ifdef DEBUG
4480             if (BcLogVerbose())
4481             {
4482                 ErrorMessage("IP Len field is %d bytes smaller than captured "
4483                              "length (ip.len: %lu, cap.len: %lu)\n",
4484                              len - payload_len, payload_len, len);
4485             }
4486 #endif
4487         }
4488     }
4489 
4490 /*
4491 ** barnyard2
4492 ** As we are reading from the unified2 file, when decoding these packets we
4493 ** don't want additional events to be created.
4494 */
4495     /* Check TTL */
4496 //    if(hdr->ip6hops < pv.min_ttl)
4497 //    {
4498 //        DecoderEvent(p, DECODE_IPV6_MIN_TTL, DECODE_IPV6_MIN_TTL_STR,
4499 //                    pv.decoder_flags.decode_alerts,
4500 //                    pv.decoder_flags.drop_alerts);
4501 //    }
4502 
4503     /* Build Packet structure's version of the IP6 header */
4504     sfiph_build(p, hdr, AF_INET6);
4505 
4506     {
4507 #ifdef GRE
4508         /* Remove outer IP options */
4509         if (p->encapsulated)
4510         {
4511             p->ip_options_data = NULL;
4512             p->ip_options_len = 0;
4513             p->ip_lastopt_bad = 0;
4514         }
4515 #endif
4516         p->ip_option_count = 0;
4517     }
4518 
4519     /* set the real IP length for logging */
4520     p->actual_ip_len = ntohs(p->ip6h->len);
4521     p->ip_data = pkt + IP6_HDR_LEN;
4522     p->ip_dsize = ntohs(p->ip6h->len);
4523 
4524     DecodeIPV6Extensions(GET_IPH_PROTO(p), pkt + IP6_HDR_LEN, ntohs(p->ip6h->len), p);
4525     return;
4526 
4527 decodeipv6_fail:
4528     pc.discards++;
4529     pc.ipv6disc++;
4530     p->iph = NULL;
4531     p->family = NO_IP;
4532 #endif
4533 }
4534 
4535 /*
4536  * Function: DecodeEthLoopback(uint8_t *, uint32_t)
4537  *
4538  * Purpose: Just like IPX, it's just for counting.
4539  *
4540  * Arguments: pkt => ptr to the packet data
4541  *            len => length from here to the end of the packet
4542  *
4543  * Returns: void function
4544  */
DecodeEthLoopback(const uint8_t * pkt,uint32_t len,Packet * p)4545 void DecodeEthLoopback(const uint8_t *pkt, uint32_t len, Packet *p)
4546 {
4547     DEBUG_WRAP(DebugMessage(DEBUG_DECODE, "EthLoopback is not supported.\n"););
4548 
4549     pc.ethloopback++;
4550 
4551 #ifdef GRE
4552     if (p->greh != NULL)
4553         pc.gre_loopback++;
4554 #endif
4555 
4556     return;
4557 }
4558 
4559 
4560 #ifndef NO_NON_ETHER_DECODER
4561 /*
4562  * Function: DecodeIPX(uint8_t *, uint32_t)
4563  *
4564  * Purpose: Well, it doesn't do much of anything right now...
4565  *
4566  * Arguments: pkt => ptr to the packet data
4567  *            len => length from here to the end of the packet
4568  *
4569  * Returns: void function
4570  *
4571  */
DecodeIPX(const uint8_t * pkt,uint32_t len,Packet * p)4572 void DecodeIPX(const uint8_t *pkt, uint32_t len, Packet *p)
4573 {
4574     DEBUG_WRAP(DebugMessage(DEBUG_DECODE, "IPX is not supported.\n"););
4575 
4576     pc.ipx++;
4577 
4578 #ifdef GRE
4579     if (p->greh != NULL)
4580         pc.gre_ipx++;
4581 #endif
4582 
4583     return;
4584 }
4585 #endif  // NO_NON_ETHER_DECODER
4586 
4587 
4588 #ifdef GRE
4589 /*
4590  * Function: DecodeGRE(uint8_t *, uint32_t, Packet *)
4591  *
4592  * Purpose: Decode Generic Routing Encapsulation Protocol
4593  *          This will decode normal GRE and PPTP GRE.
4594  *
4595  * Arguments: pkt => ptr to the packet data
4596  *            len => length from here to the end of the packet
4597  *            p   => pointer to decoded packet struct
4598  *
4599  * Returns: void function
4600  *
4601  * Notes: see RFCs 1701, 2784 and 2637
4602  */
DecodeGRE(const uint8_t * pkt,const uint32_t len,Packet * p)4603 void DecodeGRE(const uint8_t *pkt, const uint32_t len, Packet *p)
4604 {
4605     uint32_t hlen;    /* GRE header length */
4606     uint32_t payload_len;
4607 
4608     if (len < GRE_HEADER_LEN)
4609     {
4610         DecoderAlertGRE(p, DECODE_GRE_DGRAM_LT_GREHDR,
4611                         DECODE_GRE_DGRAM_LT_GREHDR_STR,
4612                         pkt, len);
4613         return;
4614     }
4615 
4616     if (p->encapsulated)
4617     {
4618         /* discard packet - multiple GRE encapsulation */
4619         /* not sure if this is ever used but I am assuming it is not */
4620         DecoderAlertGRE(p, DECODE_GRE_MULTIPLE_ENCAPSULATION,
4621                         DECODE_GRE_MULTIPLE_ENCAPSULATION_STR,
4622                         pkt, len);
4623         return;
4624     }
4625 
4626     /* Note: Since GRE doesn't have a field to indicate header length and
4627      * can contain a few options, we need to walk through the header to
4628      * figure out the length
4629      */
4630 
4631     p->greh = (GREHdr *)pkt;
4632     hlen = GRE_HEADER_LEN;
4633 
4634     switch (GRE_VERSION(p->greh))
4635     {
4636         case 0x00:
4637             /* these must not be set */
4638             if (GRE_RECUR(p->greh) || GRE_FLAGS(p->greh))
4639             {
4640                 DecoderAlertGRE(p, DECODE_GRE_INVALID_HEADER,
4641                                 DECODE_GRE_INVALID_HEADER_STR,
4642                                 pkt, len);
4643                 return;
4644             }
4645 
4646             if (GRE_CHKSUM(p->greh) || GRE_ROUTE(p->greh))
4647                 hlen += GRE_CHKSUM_LEN + GRE_OFFSET_LEN;
4648 
4649             if (GRE_KEY(p->greh))
4650                 hlen += GRE_KEY_LEN;
4651 
4652             if (GRE_SEQ(p->greh))
4653                 hlen += GRE_SEQ_LEN;
4654 
4655             /* if this flag is set, we need to walk through all of the
4656              * Source Route Entries */
4657             if (GRE_ROUTE(p->greh))
4658             {
4659                 uint16_t sre_addrfamily;
4660                 uint8_t sre_offset;
4661                 uint8_t sre_length;
4662                 const uint8_t *sre_ptr;
4663 
4664                 sre_ptr = pkt + hlen;
4665 
4666                 while (1)
4667                 {
4668                     hlen += GRE_SRE_HEADER_LEN;
4669                     if (hlen > len)
4670                         break;
4671 
4672                     sre_addrfamily = ntohs(*((uint16_t *)sre_ptr));
4673                     sre_ptr += sizeof(sre_addrfamily);
4674 
4675                     sre_offset = *((uint8_t *)sre_ptr);
4676                     sre_ptr += sizeof(sre_offset);
4677 
4678                     sre_length = *((uint8_t *)sre_ptr);
4679                     sre_ptr += sizeof(sre_length);
4680 
4681                     if ((sre_addrfamily == 0) && (sre_length == 0))
4682                         break;
4683 
4684                     hlen += sre_length;
4685                     sre_ptr += sre_length;
4686                 }
4687             }
4688 
4689             break;
4690 
4691         /* PPTP */
4692         case 0x01:
4693             /* these flags should never be present */
4694             if (GRE_CHKSUM(p->greh) || GRE_ROUTE(p->greh) || GRE_SSR(p->greh) ||
4695                 GRE_RECUR(p->greh) || GRE_V1_FLAGS(p->greh))
4696             {
4697                 DecoderAlertGRE(p, DECODE_GRE_V1_INVALID_HEADER,
4698                                 DECODE_GRE_V1_INVALID_HEADER_STR,
4699                                 pkt, len);
4700                 return;
4701             }
4702 
4703             /* protocol must be 0x880B - PPP */
4704             if (GRE_PROTO(p->greh) != GRE_TYPE_PPP)
4705             {
4706                 DecoderAlertGRE(p, DECODE_GRE_V1_INVALID_HEADER,
4707                                 DECODE_GRE_V1_INVALID_HEADER_STR,
4708                                 pkt, len);
4709                 return;
4710             }
4711 
4712             /* this flag should always be present */
4713             if (!(GRE_KEY(p->greh)))
4714             {
4715                 DecoderAlertGRE(p, DECODE_GRE_V1_INVALID_HEADER,
4716                                 DECODE_GRE_V1_INVALID_HEADER_STR,
4717                                 pkt, len);
4718                 return;
4719             }
4720 
4721             hlen += GRE_KEY_LEN;
4722 
4723             if (GRE_SEQ(p->greh))
4724                 hlen += GRE_SEQ_LEN;
4725 
4726             if (GRE_V1_ACK(p->greh))
4727                 hlen += GRE_V1_ACK_LEN;
4728 
4729             break;
4730 
4731         default:
4732             DecoderAlertGRE(p, DECODE_GRE_INVALID_VERSION,
4733                             DECODE_GRE_INVALID_VERSION_STR,
4734                             pkt, len);
4735             return;
4736     }
4737 
4738     if (hlen > len)
4739     {
4740         DecoderAlertGRE(p, DECODE_GRE_DGRAM_LT_GREHDR,
4741                         DECODE_GRE_DGRAM_LT_GREHDR_STR,
4742                         pkt, len);
4743         return;
4744     }
4745 
4746     payload_len = len - hlen;
4747 
4748     /* Send to next protocol decoder */
4749     /* As described in RFC 2784 the possible protocols are listed in
4750      * RFC 1700 under "ETHER TYPES"
4751      * See also "Current List of Protocol Types" in RFC 1701
4752      */
4753     switch (GRE_PROTO(p->greh))
4754     {
4755         case ETHERNET_TYPE_IP:
4756             DecodeIP(pkt + hlen, payload_len, p);
4757             return;
4758 
4759         case GRE_TYPE_TRANS_BRIDGING:
4760             DecodeTransBridging(pkt + hlen, payload_len, p);
4761             return;
4762 
4763         case ETHERNET_TYPE_ARP:
4764         case ETHERNET_TYPE_REVARP:
4765             /* clear outer IP headers */
4766             p->iph = NULL;
4767 #ifdef SUP_IP6
4768             p->family = NO_IP;
4769 #endif
4770             DecodeARP(pkt + hlen, payload_len, p);
4771             return;
4772 
4773         case ETHERNET_TYPE_IPV6:
4774             DecodeIPV6(pkt + hlen, payload_len, p);
4775             return;
4776 
4777         case GRE_TYPE_PPP:
4778             DecodePppPktEncapsulated(p, payload_len, pkt + hlen);
4779             return;
4780 
4781 #ifndef NO_NON_ETHER_DECODER
4782         case ETHERNET_TYPE_IPX:
4783             DecodeIPX(pkt + hlen, payload_len, p);
4784             return;
4785 #endif
4786 
4787         case ETHERNET_TYPE_LOOP:
4788             DecodeEthLoopback(pkt + hlen, payload_len, p);
4789             return;
4790 
4791         /* not sure if this occurs, but 802.1q is an Ether type */
4792         case ETHERNET_TYPE_8021Q:
4793             DecodeVlan(pkt + hlen, payload_len, p);
4794             return;
4795 
4796         default:
4797             pc.other++;
4798             p->data = pkt + hlen;
4799             p->dsize = (uint16_t)payload_len;
4800             return;
4801     }
4802 }
4803 
4804 /*
4805  * Function: DecodeTransBridging(uint8_t *, const uint32_t, Packet)
4806  *
4807  * Purpose: Decode Transparent Ethernet Bridging
4808  *
4809  * Arguments: pkt => pointer to the real live packet data
4810  *            len => length of remaining data in packet
4811  *            p => pointer to the decoded packet struct
4812  *
4813  *
4814  * Returns: void function
4815  *
4816  * Note: This is basically the code from DecodeEthPkt but the calling
4817  * convention needed to be changed and the stuff at the beginning
4818  * wasn't needed since we are already deep into the packet
4819  */
DecodeTransBridging(const uint8_t * pkt,const uint32_t len,Packet * p)4820 void DecodeTransBridging(const uint8_t *pkt, const uint32_t len, Packet *p)
4821 {
4822     pc.gre_eth++;
4823 
4824     if(len < ETHERNET_HEADER_LEN)
4825     {
4826         DecoderAlertGRE(p, DECODE_GRE_TRANS_DGRAM_LT_TRANSHDR,
4827                         DECODE_GRE_TRANS_DGRAM_LT_TRANSHDR_STR,
4828                         pkt, len);
4829         return;
4830     }
4831 
4832     /* The Packet struct's ethernet header will now point to the inner ethernet
4833      * header of the packet
4834      */
4835     p->eh = (EtherHdr *)pkt;
4836 
4837     switch (ntohs(p->eh->ether_type))
4838     {
4839         case ETHERNET_TYPE_IP:
4840             DecodeIP(pkt + ETHERNET_HEADER_LEN, len - ETHERNET_HEADER_LEN, p);
4841             return;
4842 
4843         case ETHERNET_TYPE_ARP:
4844         case ETHERNET_TYPE_REVARP:
4845             DecodeARP(pkt + ETHERNET_HEADER_LEN, len - ETHERNET_HEADER_LEN, p);
4846             return;
4847 
4848         case ETHERNET_TYPE_IPV6:
4849             DecodeIPV6(pkt + ETHERNET_HEADER_LEN, len - ETHERNET_HEADER_LEN, p);
4850             return;
4851 
4852 #ifndef NO_NON_ETHER_DECODER
4853         case ETHERNET_TYPE_IPX:
4854             DecodeIPX(pkt + ETHERNET_HEADER_LEN, len - ETHERNET_HEADER_LEN, p);
4855             return;
4856 #endif
4857 
4858         case ETHERNET_TYPE_LOOP:
4859             DecodeEthLoopback(pkt + ETHERNET_HEADER_LEN, len - ETHERNET_HEADER_LEN, p);
4860             return;
4861 
4862         case ETHERNET_TYPE_8021Q:
4863             DecodeVlan(pkt + ETHERNET_HEADER_LEN, len - ETHERNET_HEADER_LEN, p);
4864             return;
4865 
4866         default:
4867             pc.other++;
4868             p->data = pkt + ETHERNET_HEADER_LEN;
4869             p->dsize = (uint16_t)(len - ETHERNET_HEADER_LEN);
4870             return;
4871     }
4872 }
4873 
4874 /* should probably generalize for all decoder alerts */
DecoderAlertGRE(Packet * p,int type,const char * str,const uint8_t * pkt,uint32_t len)4875 void DecoderAlertGRE(Packet *p, int type, const char *str, const uint8_t *pkt, uint32_t len)
4876 {
4877     p->data = pkt;
4878     p->dsize = (uint16_t)len;
4879 
4880     p->greh = NULL;
4881 }
4882 
4883 #endif  /* GRE */
4884 
4885 
4886 /**
4887  * Validate that the length is an expected length AND that it's in bounds
4888  *
4889  * EOL and NOP are handled separately
4890  *
4891  * @param option_ptr current location
4892  * @param end the byte past the end of the decode list
4893  * @param len_ptr the pointer to the length field
4894  * @param expected_len the number of bytes we expect to see per rfc KIND+LEN+DATA, -1 means dynamic.
4895  * @param tcpopt options structure to populate
4896  * @param byte_skip distance to move upon completion
4897  *
4898  * @return returns 0 on success, < 0 on error
4899  */
OptLenValidate(const uint8_t * option_ptr,const uint8_t * end,const uint8_t * len_ptr,int expected_len,Options * tcpopt,uint8_t * byte_skip)4900 static INLINE int OptLenValidate(const uint8_t *option_ptr,
4901                                  const uint8_t *end,
4902                                  const uint8_t *len_ptr,
4903                                  int expected_len,
4904                                  Options *tcpopt,
4905                                  uint8_t *byte_skip)
4906 {
4907     *byte_skip = 0;
4908 
4909     if(len_ptr == NULL)
4910     {
4911         return TCP_OPT_TRUNC;
4912     }
4913 
4914     if(*len_ptr == 0 || expected_len == 0 || expected_len == 1)
4915     {
4916         return TCP_OPT_BADLEN;
4917     }
4918     else if(expected_len > 1)
4919     {
4920         if((option_ptr + expected_len) > end)
4921         {
4922             /* not enough data to read in a perfect world */
4923             return TCP_OPT_TRUNC;
4924         }
4925 
4926         if(*len_ptr != expected_len)
4927         {
4928             /* length is not valid */
4929             return TCP_OPT_BADLEN;
4930         }
4931     }
4932     else /* expected_len < 0 (i.e. variable length) */
4933     {
4934         if(*len_ptr < 2)
4935         {
4936             /* RFC sez that we MUST have atleast this much data */
4937             return TCP_OPT_BADLEN;
4938         }
4939 
4940         if((option_ptr + *len_ptr) > end)
4941         {
4942             /* not enough data to read in a perfect world */
4943             return TCP_OPT_TRUNC;
4944         }
4945     }
4946 
4947     tcpopt->len = *len_ptr - 2;
4948 
4949     if(*len_ptr == 2)
4950     {
4951         tcpopt->data = NULL;
4952     }
4953     else
4954     {
4955         tcpopt->data = option_ptr + 2;
4956     }
4957 
4958     *byte_skip = *len_ptr;
4959 
4960     return 0;
4961 }
4962 
4963 /*
4964  * Function: DecodeTCPOptions(uint8_t *, uint32_t, Packet *)
4965  *
4966  * Purpose: Fairly self explainatory name, don't you think?
4967  *
4968  *          TCP Option Header length validation is left to the caller
4969  *
4970  *          For a good listing of TCP Options,
4971  *          http://www.iana.org/assignments/tcp-parameters
4972  *
4973  *   ------------------------------------------------------------
4974  *   From: "Kastenholz, Frank" <FKastenholz@unispherenetworks.com>
4975  *   Subject: Re: skeeter & bubba TCP options?
4976  *
4977  *   ah, the sins of ones youth that never seem to be lost...
4978  *
4979  *   it was something that ben levy and stev and i did at ftp many
4980  *   many moons ago. bridgham and stev were the instigators of it.
4981  *   the idea was simple, put a dh key exchange directly in tcp
4982  *   so that all tcp sessions could be encrypted without requiring
4983  *   any significant key management system. authentication was not
4984  *   a part of the idea, it was to be provided by passwords or
4985  *   whatever, which could now be transmitted over the internet
4986  *   with impunity since they were encrypted... we implemented
4987  *   a simple form of this (doing the math was non trivial on the
4988  *   machines of the day). it worked. the only failure that i
4989  *   remember was that it was vulnerable to man-in-the-middle
4990  *   attacks.
4991  *
4992  *   why "skeeter" and "bubba"? well, that's known only to stev...
4993  *   ------------------------------------------------------------
4994  *
4995  * 4.2.2.5 TCP Options: RFC-793 Section 3.1
4996  *
4997  *    A TCP MUST be able to receive a TCP option in any segment. A TCP
4998  *    MUST ignore without error any TCP option it does not implement,
4999  *    assuming that the option has a length field (all TCP options
5000  *    defined in the future will have length fields). TCP MUST be
5001  *    prepared to handle an illegal option length (e.g., zero) without
5002  *    crashing; a suggested procedure is to reset the connection and log
5003  *    the reason.
5004  *
5005  * Arguments: o_list => ptr to the option list
5006  *            o_len => length of the option list
5007  *            p     => pointer to decoded packet struct
5008  *
5009  * Returns: void function
5010  */
DecodeTCPOptions(const uint8_t * start,uint32_t o_len,Packet * p)5011 void DecodeTCPOptions(const uint8_t *start, uint32_t o_len, Packet *p)
5012 {
5013     const uint8_t *option_ptr = start;
5014     const uint8_t *end_ptr = start + o_len; /* points to byte after last option */
5015     const uint8_t *len_ptr;
5016     uint8_t opt_count = 0;
5017     u_char done = 0; /* have we reached TCPOPT_EOL yet?*/
5018     u_char experimental_option_found = 0;      /* are all options RFC compliant? */
5019     u_char obsolete_option_found = 0;
5020     u_char ttcp_found = 0;
5021 
5022     int code = 2;
5023     uint8_t byte_skip;
5024 
5025     /* Here's what we're doing so that when we find out what these
5026      * other buggers of TCP option codes are, we can do something
5027      * useful
5028      *
5029      * 1) get option code
5030      * 2) check for enough space for current option code
5031      * 3) set option data ptr
5032      * 4) increment option code ptr
5033      *
5034      * TCP_OPTLENMAX = 40 because of
5035      *        (((2^4) - 1) * 4  - TCP_HEADER_LEN)
5036      *
5037      */
5038 
5039     if(o_len > TCP_OPTLENMAX)
5040     {
5041         /* This shouldn't ever alert if we are doing our job properly
5042          * in the caller */
5043         p->tcph = NULL; /* let's just alert */
5044         DEBUG_WRAP(DebugMessage(DEBUG_DECODE,
5045                                 "o_len(%u) > TCP_OPTLENMAX(%u)\n",
5046                                 o_len, TCP_OPTLENMAX));
5047         return;
5048     }
5049 
5050     while((option_ptr < end_ptr) && (opt_count < TCP_OPTLENMAX) && (code >= 0) && !done)
5051     {
5052         p->tcp_options[opt_count].code = *option_ptr;
5053 
5054         if((option_ptr + 1) < end_ptr)
5055         {
5056             len_ptr = option_ptr + 1;
5057         }
5058         else
5059         {
5060             len_ptr = NULL;
5061         }
5062 
5063         switch(*option_ptr)
5064         {
5065         case TCPOPT_EOL:
5066             done = 1; /* fall through to the NOP case */
5067         case TCPOPT_NOP:
5068             p->tcp_options[opt_count].len = 0;
5069             p->tcp_options[opt_count].data = NULL;
5070             byte_skip = 1;
5071             code = 0;
5072             break;
5073         case TCPOPT_MAXSEG:
5074             code = OptLenValidate(option_ptr, end_ptr, len_ptr, TCPOLEN_MAXSEG,
5075                                   &p->tcp_options[opt_count], &byte_skip);
5076             break;
5077         case TCPOPT_SACKOK:
5078             code = OptLenValidate(option_ptr, end_ptr, len_ptr, TCPOLEN_SACKOK,
5079                                   &p->tcp_options[opt_count], &byte_skip);
5080             break;
5081         case TCPOPT_WSCALE:
5082             code = OptLenValidate(option_ptr, end_ptr, len_ptr, TCPOLEN_WSCALE,
5083                                   &p->tcp_options[opt_count], &byte_skip);
5084             break;
5085         case TCPOPT_ECHO: /* both use the same lengths */
5086         case TCPOPT_ECHOREPLY:
5087             obsolete_option_found = 1;
5088             code = OptLenValidate(option_ptr, end_ptr, len_ptr, TCPOLEN_ECHO,
5089                                   &p->tcp_options[opt_count], &byte_skip);
5090             break;
5091         case TCPOPT_MD5SIG:
5092             experimental_option_found = 1;
5093             code = OptLenValidate(option_ptr, end_ptr, len_ptr, TCPOLEN_MD5SIG,
5094                                   &p->tcp_options[opt_count], &byte_skip);
5095             break;
5096         case TCPOPT_SACK:
5097             code = OptLenValidate(option_ptr, end_ptr, len_ptr, -1,
5098                                   &p->tcp_options[opt_count], &byte_skip);
5099             if(p->tcp_options[opt_count].data == NULL)
5100                 code = TCP_OPT_BADLEN;
5101 
5102             break;
5103         case TCPOPT_CC_ECHO:
5104             ttcp_found = 1;
5105             /* fall through */
5106         case TCPOPT_CC:  /* all 3 use the same lengths / T/TCP */
5107         case TCPOPT_CC_NEW:
5108             code = OptLenValidate(option_ptr, end_ptr, len_ptr, TCPOLEN_CC,
5109                                   &p->tcp_options[opt_count], &byte_skip);
5110             break;
5111         case TCPOPT_TRAILER_CSUM:
5112             experimental_option_found = 1;
5113             code = OptLenValidate(option_ptr, end_ptr, len_ptr, TCPOLEN_TRAILER_CSUM,
5114                                   &p->tcp_options[opt_count], &byte_skip);
5115             break;
5116 
5117         case TCPOPT_TIMESTAMP:
5118             code = OptLenValidate(option_ptr, end_ptr, len_ptr, TCPOLEN_TIMESTAMP,
5119                                   &p->tcp_options[opt_count], &byte_skip);
5120             break;
5121 
5122         case TCPOPT_SKEETER:
5123         case TCPOPT_BUBBA:
5124         case TCPOPT_UNASSIGNED:
5125             obsolete_option_found = 1;
5126             code = OptLenValidate(option_ptr, end_ptr, len_ptr, -1,
5127                                   &p->tcp_options[opt_count], &byte_skip);
5128             break;
5129         default:
5130         case TCPOPT_SCPS:
5131         case TCPOPT_SELNEGACK:
5132         case TCPOPT_RECORDBOUND:
5133         case TCPOPT_CORRUPTION:
5134         case TCPOPT_PARTIAL_PERM:
5135         case TCPOPT_PARTIAL_SVC:
5136         case TCPOPT_ALTCSUM:
5137         case TCPOPT_SNAP:
5138             experimental_option_found = 1;
5139             code = OptLenValidate(option_ptr, end_ptr, len_ptr, -1,
5140                                   &p->tcp_options[opt_count], &byte_skip);
5141             break;
5142         }
5143 
5144         if(code < 0)
5145         {
5146             /* set the option count to the number of valid
5147              * options found before this bad one
5148              * some implementations (BSD and Linux) ignore
5149              * the bad ones, but accept the good ones */
5150             p->tcp_option_count = opt_count;
5151 
5152             return;
5153         }
5154 
5155         opt_count++;
5156 
5157         option_ptr += byte_skip;
5158     }
5159 
5160     p->tcp_option_count = opt_count;
5161 
5162     return;
5163 }
5164 
5165 
5166 /*
5167  * Function: DecodeIPOptions(uint8_t *, uint32_t, Packet *)
5168  *
5169  * Purpose: Once again, a fairly self-explainatory name
5170  *
5171  * Arguments: o_list => ptr to the option list
5172  *            o_len => length of the option list
5173  *            p     => pointer to decoded packet struct
5174  *
5175  * Returns: void function
5176  */
DecodeIPOptions(const uint8_t * start,uint32_t o_len,Packet * p)5177 void DecodeIPOptions(const uint8_t *start, uint32_t o_len, Packet *p)
5178 {
5179     const uint8_t *option_ptr = start;
5180     u_char done = 0; /* have we reached IP_OPTEOL yet? */
5181     const uint8_t *end_ptr = start + o_len;
5182     uint8_t opt_count = 0; /* what option are we processing right now */
5183     uint8_t byte_skip;
5184     const uint8_t *len_ptr;
5185     int code = 0;  /* negative error codes are returned from bad options */
5186 
5187 
5188     DEBUG_WRAP(DebugMessage(DEBUG_DECODE,  "Decoding %d bytes of IP options\n", o_len););
5189 
5190 
5191     while((option_ptr < end_ptr) && (opt_count < IP_OPTMAX) && (code >= 0))
5192     {
5193         p->ip_options[opt_count].code = *option_ptr;
5194 
5195         if((option_ptr + 1) < end_ptr)
5196         {
5197             len_ptr = option_ptr + 1;
5198         }
5199         else
5200         {
5201             len_ptr = NULL;
5202         }
5203 
5204         switch(*option_ptr)
5205         {
5206         case IPOPT_NOP:
5207         case IPOPT_EOL:
5208             /* if we hit an EOL, we're done */
5209             if(*option_ptr == IPOPT_EOL)
5210                 done = 1;
5211 
5212             p->ip_options[opt_count].len = 0;
5213             p->ip_options[opt_count].data = NULL;
5214             byte_skip = 1;
5215             break;
5216         default:
5217             /* handle all the dynamic features */
5218             code = OptLenValidate(option_ptr, end_ptr, len_ptr, -1,
5219                                   &p->ip_options[opt_count], &byte_skip);
5220         }
5221 
5222         if(!done)
5223             opt_count++;
5224 
5225         option_ptr += byte_skip;
5226     }
5227 
5228     p->ip_option_count = opt_count;
5229 
5230     return;
5231 }
5232 
5233 #if defined(WORDS_MUSTALIGN) && !defined(__GNUC__)
5234 uint32_t
EXTRACT_32BITS(u_char * p)5235 EXTRACT_32BITS (u_char *p)
5236 {
5237   uint32_t __tmp;
5238 
5239   memmove(&__tmp, p, sizeof(uint32_t));
5240   return (uint32_t) ntohl(__tmp);
5241 }
5242 #endif /* WORDS_MUSTALIGN && !__GNUC__ */
5243 
5244 #ifdef MPLS
isPrivateIP(uint32_t addr)5245 int isPrivateIP(uint32_t addr)
5246 {
5247     switch (addr & 0xff)
5248     {
5249         case 0x0a:
5250             return 1;
5251             break;
5252         case 0xac:
5253             if ((addr & 0xf000) == 0x1000)
5254                 return 1;
5255             break;
5256         case 0xc0:
5257             if (((addr & 0xff00) ) == 0xa800)
5258                 return 1;
5259             break;
5260     }
5261     return 0;
5262 }
5263 #endif
5264 
5265 /*
5266 void InitSynToMulticastDstIp( void )
5267 {
5268 #ifdef SUP_IP6
5269     extern SnortConfig *snort_conf_for_parsing;
5270     snort_conf_for_parsing = snort_conf;
5271 #endif
5272     SynToMulticastDstIp = IpAddrSetParse("[232.0.0.0/8,233.0.0.0/8,239.0.0.0/8]");
5273 
5274     if( SynToMulticastDstIp == NULL )
5275     {
5276         FatalError("Could not initialize SynToMulticastDstIp\n");
5277     }
5278 #ifdef SUP_IP6
5279     snort_conf_for_parsing = NULL;
5280 #endif
5281 }
5282 
5283 void SynToMulticastDstIpDestroy( void )
5284 {
5285 
5286     if( SynToMulticastDstIp )
5287     {
5288         IpAddrSetDestroy(SynToMulticastDstIp);
5289 #ifndef SUP_IP6
5290         free(SynToMulticastDstIp);
5291         SynToMulticastDstIp = NULL;
5292 #endif
5293     }
5294 }
5295 
5296 */
5297 
5298