From: hannes Date: Tue, 19 Oct 2004 15:59:39 +0000 (+0000) Subject: add support for dissecting DLT_JUNIPER_ATM1 (137) and DLT_JUNIPER_ATM2 (135) X-Git-Tag: tcpdump-3.9.1~256 X-Git-Url: https://git.tcpdump.org/tcpdump/commitdiff_plain/ecd1d49fcd5245a35b7057327fb1d14685cc4e93 add support for dissecting DLT_JUNIPER_ATM1 (137) and DLT_JUNIPER_ATM2 (135) --- diff --git a/FILES b/FILES index ca9f5f72..73d0f6fe 100644 --- a/FILES +++ b/FILES @@ -150,6 +150,7 @@ print-ipfc.c print-ipx.c print-isakmp.c print-isoclns.c +print-juniper.c print-krb.c print-l2tp.c print-lane.c diff --git a/Makefile.in b/Makefile.in index fffe83e2..46d8e439 100644 --- a/Makefile.in +++ b/Makefile.in @@ -17,7 +17,7 @@ # WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF # MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. # -# @(#) $Header: /tcpdump/master/tcpdump/Makefile.in,v 1.291 2004-10-07 14:53:10 hannes Exp $ (LBL) +# @(#) $Header: /tcpdump/master/tcpdump/Makefile.in,v 1.292 2004-10-19 15:59:39 hannes Exp $ (LBL) # # Various configurable paths (remember to edit Makefile.in, not Makefile) @@ -76,7 +76,7 @@ CSRC = addrtoname.c cpack.c gmpls.c oui.c gmt2local.c ipproto.c \ print-esp.c print-ether.c print-fddi.c print-fr.c \ print-gre.c print-hsrp.c print-icmp.c print-igmp.c \ print-igrp.c print-ip.c print-ipcomp.c print-ipfc.c \ - print-ipx.c print-isakmp.c print-isoclns.c print-krb.c \ + print-ipx.c print-isakmp.c print-isoclns.c print-juniper.c print-krb.c \ print-l2tp.c print-lane.c print-ldp.c print-llc.c \ print-lmp.c print-lspping.c \ print-lwres.c print-mobile.c print-mpls.c print-msdp.c \ diff --git a/interface.h b/interface.h index eac64f56..4dfbf388 100644 --- a/interface.h +++ b/interface.h @@ -18,7 +18,7 @@ * WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. * - * @(#) $Header: /tcpdump/master/tcpdump/interface.h,v 1.234 2004-10-18 16:26:20 hannes Exp $ (LBL) + * @(#) $Header: /tcpdump/master/tcpdump/interface.h,v 1.235 2004-10-19 15:59:40 hannes Exp $ (LBL) */ #ifndef tcpdump_interface_h @@ -246,6 +246,8 @@ extern u_int lane_if_print(const struct pcap_pkthdr *, const u_char *); extern u_int cip_if_print(const struct pcap_pkthdr *, const u_char *); extern u_int sl_bsdos_if_print(const struct pcap_pkthdr *, const u_char *); extern u_int chdlc_if_print(const struct pcap_pkthdr *, const u_char *); +extern u_int juniper_atm1_print(const struct pcap_pkthdr *, const u_char *); +extern u_int juniper_atm2_print(const struct pcap_pkthdr *, const u_char *); extern u_int sll_if_print(const struct pcap_pkthdr *, const u_char *); extern void snmp_print(const u_char *, u_int); extern void sunrpcrequest_print(const u_char *, u_int, const u_char *); diff --git a/print-juniper.c b/print-juniper.c new file mode 100644 index 00000000..c98c8708 --- /dev/null +++ b/print-juniper.c @@ -0,0 +1,287 @@ +/* + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that: (1) source code + * distributions retain the above copyright notice and this paragraph + * in its entirety, and (2) distributions including binary code include + * the above copyright notice and this paragraph in its entirety in + * the documentation or other materials provided with the distribution. + * THIS SOFTWARE IS PROVIDED ``AS IS'' AND + * WITHOUT ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, WITHOUT + * LIMITATION, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + * FOR A PARTICULAR PURPOSE. + * + * Original code by Hannes Gredler (hannes@juniper.net) + */ + +#ifndef lint +static const char rcsid[] _U_ = + "@(#) $Header: /tcpdump/master/tcpdump/print-juniper.c,v 1.1 2004-10-19 15:59:41 hannes Exp $ (LBL)"; +#endif + +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + +#include + +#include +#include + +#include "interface.h" +#include "extract.h" +#include "ppp.h" + +#define BPF_OUT 0 /* Outgoing packet */ +#define BPF_IN 1 /* Incoming packet */ +#define BPF_PKT_IN 0x1 /* Incoming packet */ +#define BPF_NO_L2 0x2 /* L2 header stripped */ + +#define ATM2_PKT_TYPE_MASK 0x70 +#define ATM2_GAP_COUNT_MASK 0x3F + +int ip_heuristic_guess(register const u_char *, u_int); +int ppp_heuristic_guess(register const u_char *, u_int); +static int juniper_parse_header (const u_char *, u_int8_t *, u_int); + +/* + * ATM1 PIC cookie format + * + * +-----+-------------------------+-------------------------------+ + * |fmtid| vc index | channel ID | + * +-----+-------------------------+-------------------------------+ + */ + +u_int +juniper_atm1_print(const struct pcap_pkthdr *h, register const u_char *p) +{ + register u_int length = h->len; + register u_int caplen = h->caplen; + u_int16_t extracted_ethertype; + u_int8_t direction; + u_int32_t cookie1; + + if(juniper_parse_header(p, &direction,length) == 0) + return 0; + + p+=4; + length-=4; + caplen-=4; + + cookie1=EXTRACT_32BITS(p); + + if (eflag) { + /* FIXME decode channel-id, vc-index, fmt-id + for once lets just hexdump the cookie */ + + printf("ATM1 cookie 0x%08x, ", EXTRACT_32BITS(p)); + } + + p+=4; + length-=4; + caplen-=4; + + if (cookie1 & 0x80000000) { /* OAM cell ? */ + oam_print(p,length); + } + + if (EXTRACT_24BITS(p) == 0xfefe03 || /* NLPID encaps ? */ + EXTRACT_24BITS(p) == 0xaaaa03) { /* SNAP encaps ? */ + + if (llc_print(p, length, caplen, NULL, NULL, + &extracted_ethertype) != 0) + return 8; + } + + if (p[0] == 0x03) { /* Cisco style NLPID encaps ? */ + isoclns_print(p + 1, length - 1, caplen - 1); + /* FIXME check if frame was recognized */ + return 8; + } + + if(ip_heuristic_guess(p, length) != 0) /* last try - vcmux encaps ? */ + return 0; + + return (8); +} + +/* + * ATM2 PIC cookie format + * + * +-------------------------------+---------+---+-----+-----------+ + * | channel ID | reserv |AAL| CCRQ| gap cnt | + * +-------------------------------+---------+---+-----+-----------+ + */ + +u_int +juniper_atm2_print(const struct pcap_pkthdr *h, register const u_char *p) +{ + register u_int length = h->len; + register u_int caplen = h->caplen; + u_int16_t extracted_ethertype; + u_int8_t direction; + u_int32_t cookie1,cookie2; + + if(juniper_parse_header(p, &direction,length) == 0) + return 0; + + p+=4; + length-=4; + caplen-=4; + + cookie1=EXTRACT_32BITS(p); + cookie2=EXTRACT_32BITS(p+4); + + if (eflag) { + /* FIXME decode channel, fmt-id, ccrq, aal, gap cnt + for once lets just hexdump the cookie */ + + printf("ATM2 cookie 0x%08x%08x, ", + EXTRACT_32BITS(p), + EXTRACT_32BITS(p+4)); + } + + p+=8; + length-=8; + caplen-=8; + + if (cookie2 & ATM2_PKT_TYPE_MASK) { /* OAM cell ? */ + oam_print(p,length); + return 12; + } + + if (EXTRACT_24BITS(p) == 0xfefe03 || /* NLPID encaps ? */ + EXTRACT_24BITS(p) == 0xaaaa03) { /* SNAP encaps ? */ + + if (llc_print(p, length, caplen, NULL, NULL, + &extracted_ethertype) != 0) + return 12; + } + + if (direction != BPF_PKT_IN && /* ether-over-1483 encaps ? */ + (cookie1 & ATM2_GAP_COUNT_MASK)) { + ether_print(p, length, caplen); + return 12; + } + + if (p[0] == 0x03) { /* Cisco style NLPID encaps ? */ + isoclns_print(p + 1, length - 1, caplen - 1); + /* FIXME check if frame was recognized */ + return 12; + } + + if(ppp_heuristic_guess(p, length) != 0) /* PPPoA vcmux encaps ? */ + return 12; + + if(ip_heuristic_guess(p, length) != 0) /* last try - vcmux encaps ? */ + return 12; + + return (12); +} + + +int +ppp_heuristic_guess(register const u_char *p, u_int length) { + + switch(EXTRACT_16BITS(p)) { + case PPP_IP : + case PPP_OSI : + case PPP_MPLS_UCAST : + case PPP_MPLS_MCAST : + case PPP_IPCP : + case PPP_OSICP : + case PPP_MPLSCP : + case PPP_LCP : + case PPP_PAP : + case PPP_CHAP : + case PPP_MP : +#ifdef INET6 + case PPP_IPV6 : + case PPP_IPV6CP : +#endif + ppp_print(p, length); + break; + + default: + return 0; /* did not find a ppp header */ + break; + } + return 1; /* we printed a ppp packet */ +} + +int +ip_heuristic_guess(register const u_char *p, u_int length) { + + switch(p[0]) { + case 0x45: + case 0x46: + case 0x47: + case 0x48: + case 0x49: + case 0x4a: + case 0x4b: + case 0x4c: + case 0x4d: + case 0x4e: + case 0x4f: + ip_print(p, length); + break; +#ifdef INET6 + case 0x60: + case 0x61: + case 0x62: + case 0x63: + case 0x64: + case 0x65: + case 0x66: + case 0x67: + case 0x68: + case 0x69: + case 0x6a: + case 0x6b: + case 0x6c: + case 0x6d: + case 0x6e: + case 0x6f: + ip6_print(p, length); + break; +#endif + default: + return 0; /* did not find a ip header */ + break; + } + return 1; /* we printed an v4/v6 packet */ +} + +static int +juniper_parse_header (const u_char *p, u_int8_t *direction, u_int length) { + + *direction = p[3]&BPF_PKT_IN; + + if (EXTRACT_24BITS(p) != 0x4d4743) /* magic number found ? */ + return -1; + + if (*direction == BPF_PKT_IN) { + if (eflag) + printf("%3s ", "In"); + } + else { + if (eflag) + printf("%3s ", "Out"); + } + + if ((p[3] & BPF_NO_L2 ) == BPF_NO_L2 ) { + if (eflag) + printf("no-L2-hdr, "); + + /* there is no link-layer present - + * perform the v4/v6 heuristics + * to figure out what it is + */ + if(ip_heuristic_guess(p+8,length-8) == 0) + printf("no IP-hdr found!"); + + return 0; /* stop parsing the output further */ + + } + return 1; /* everything went ok so far. continue parsing */ +} diff --git a/tcpdump.c b/tcpdump.c index 9bf61bbc..ac6a6c8e 100644 --- a/tcpdump.c +++ b/tcpdump.c @@ -30,7 +30,7 @@ static const char copyright[] _U_ = "@(#) Copyright (c) 1988, 1989, 1990, 1991, 1992, 1993, 1994, 1995, 1996, 1997, 2000\n\ The Regents of the University of California. All rights reserved.\n"; static const char rcsid[] _U_ = - "@(#) $Header: /tcpdump/master/tcpdump/tcpdump.c,v 1.248 2004-09-04 00:08:04 guy Exp $ (LBL)"; + "@(#) $Header: /tcpdump/master/tcpdump/tcpdump.c,v 1.249 2004-10-19 15:59:40 hannes Exp $ (LBL)"; #endif /* @@ -217,6 +217,12 @@ static struct printer printers[] = { #endif #ifdef DLT_APPLE_IP_OVER_IEEE1394 { ap1394_if_print, DLT_APPLE_IP_OVER_IEEE1394 }, +#endif +#ifdef DLT_JUNIPER_ATM1 + { juniper_atm1_print, DLT_JUNIPER_ATM1 }, +#endif +#ifdef DLT_JUNIPER_ATM2 + { juniper_atm2_print, DLT_JUNIPER_ATM2 }, #endif { NULL, 0 }, };