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