X-Git-Url: https://git.tcpdump.org/tcpdump/blobdiff_plain/94e46babc871019d30240ee0d4279afc6bca1da8..a3fb5569c6d243350694f60e1eab0a4682b45cdf:/print-juniper.c?ds=inline diff --git a/print-juniper.c b/print-juniper.c index 32b2e11f..aa63d5cf 100644 --- a/print-juniper.c +++ b/print-juniper.c @@ -15,7 +15,7 @@ #ifndef lint static const char rcsid[] _U_ = - "@(#) $Header: /tcpdump/master/tcpdump/print-juniper.c,v 1.8.2.9 2005-05-22 21:25:41 hannes Exp $ (LBL)"; + "@(#) $Header: /tcpdump/master/tcpdump/print-juniper.c,v 1.8.2.19 2005-08-23 10:29:42 hannes Exp $ (LBL)"; #endif #ifdef HAVE_CONFIG_H @@ -34,19 +34,24 @@ static const char rcsid[] _U_ = #include "llc.h" #include "nlpid.h" #include "ethertype.h" +#include "atm.h" #define JUNIPER_BPF_OUT 0 /* Outgoing packet */ #define JUNIPER_BPF_IN 1 /* Incoming packet */ #define JUNIPER_BPF_PKT_IN 0x1 /* Incoming packet */ #define JUNIPER_BPF_NO_L2 0x2 /* L2 header stripped */ +#define JUNIPER_BPF_EXT 0x80 /* extensions present */ #define JUNIPER_MGC_NUMBER 0x4d4743 /* = "MGC" */ +#define JUNIPER_LSQ_COOKIE_RE (1 << 3) +#define JUNIPER_LSQ_COOKIE_DIR (1 << 2) #define JUNIPER_LSQ_L3_PROTO_SHIFT 4 #define JUNIPER_LSQ_L3_PROTO_MASK (0x17 << JUNIPER_LSQ_L3_PROTO_SHIFT) #define JUNIPER_LSQ_L3_PROTO_IPV4 (0 << JUNIPER_LSQ_L3_PROTO_SHIFT) #define JUNIPER_LSQ_L3_PROTO_IPV6 (1 << JUNIPER_LSQ_L3_PROTO_SHIFT) #define JUNIPER_LSQ_L3_PROTO_MPLS (2 << JUNIPER_LSQ_L3_PROTO_SHIFT) #define JUNIPER_LSQ_L3_PROTO_ISO (3 << JUNIPER_LSQ_L3_PROTO_SHIFT) +#define AS_PIC_COOKIE_LEN 8 #define JUNIPER_IPSEC_O_ESP_ENCRYPT_ESP_AUTHEN_TYPE 1 #define JUNIPER_IPSEC_O_ESP_ENCRYPT_AH_AUTHEN_TYPE 2 @@ -76,17 +81,40 @@ struct juniper_cookie_table_t { }; static struct juniper_cookie_table_t juniper_cookie_table[] = { +#ifdef DLT_JUNIPER_ATM1 { DLT_JUNIPER_ATM1, 4, "ATM1"}, +#endif +#ifdef DLT_JUNIPER_ATM2 { DLT_JUNIPER_ATM2, 8, "ATM2"}, +#endif +#ifdef DLT_JUNIPER_MLPPP { DLT_JUNIPER_MLPPP, 2, "MLPPP"}, +#endif +#ifdef DLT_JUNIPER_MLFR { DLT_JUNIPER_MLFR, 2, "MLFR"}, +#endif +#ifdef DLT_JUNIPER_MFR { DLT_JUNIPER_MFR, 4, "MFR"}, +#endif +#ifdef DLT_JUNIPER_PPPOE { DLT_JUNIPER_PPPOE, 0, "PPPoE"}, +#endif +#ifdef DLT_JUNIPER_PPPOE_ATM { DLT_JUNIPER_PPPOE_ATM, 0, "PPPoE ATM"}, +#endif +#ifdef DLT_JUNIPER_GGSN { DLT_JUNIPER_GGSN, 8, "GGSN"}, +#endif +#ifdef DLT_JUNIPER_MONITOR { DLT_JUNIPER_MONITOR, 8, "MONITOR"}, +#endif +#ifdef DLT_JUNIPER_SERVICES { DLT_JUNIPER_SERVICES, 8, "AS"}, +#endif +#ifdef DLT_JUNIPER_ES { DLT_JUNIPER_ES, 0, "ES"}, +#endif + { 0, 0, NULL } }; struct juniper_l2info_t { @@ -117,6 +145,8 @@ struct juniper_l2info_t { #define JUNIPER_PROTO_IPV4 2 #define JUNIPER_PROTO_IPV6 6 +#define MFR_BE_MASK 0xc0 + static struct tok juniper_protocol_values[] = { { JUNIPER_PROTO_NULL, "Null" }, { JUNIPER_PROTO_IPV4, "IPv4" }, @@ -128,6 +158,7 @@ int ip_heuristic_guess(register const u_char *, u_int); int juniper_ppp_heuristic_guess(register const u_char *, u_int); static int juniper_parse_header (const u_char *, const struct pcap_pkthdr *, struct juniper_l2info_t *); +#ifdef DLT_JUNIPER_GGSN u_int juniper_ggsn_print(const struct pcap_pkthdr *h, register const u_char *p) { @@ -171,7 +202,9 @@ juniper_ggsn_print(const struct pcap_pkthdr *h, register const u_char *p) return l2info.header_len; } +#endif +#ifdef DLT_JUNIPER_ES u_int juniper_es_print(const struct pcap_pkthdr *h, register const u_char *p) { @@ -239,7 +272,9 @@ juniper_es_print(const struct pcap_pkthdr *h, register const u_char *p) ip_print(gndo, p, l2info.length); return l2info.header_len; } +#endif +#ifdef DLT_JUNIPER_MONITOR u_int juniper_monitor_print(const struct pcap_pkthdr *h, register const u_char *p) { @@ -270,7 +305,9 @@ juniper_monitor_print(const struct pcap_pkthdr *h, register const u_char *p) return l2info.header_len; } +#endif +#ifdef DLT_JUNIPER_SERVICES u_int juniper_services_print(const struct pcap_pkthdr *h, register const u_char *p) { @@ -302,7 +339,9 @@ juniper_services_print(const struct pcap_pkthdr *h, register const u_char *p) return l2info.header_len; } +#endif +#ifdef DLT_JUNIPER_PPPOE u_int juniper_pppoe_print(const struct pcap_pkthdr *h, register const u_char *p) { @@ -317,7 +356,77 @@ juniper_pppoe_print(const struct pcap_pkthdr *h, register const u_char *p) ether_print(p, l2info.length, l2info.caplen); return l2info.header_len; } +#endif + +#ifdef DLT_JUNIPER_ETHER +u_int +juniper_ether_print(const struct pcap_pkthdr *h, register const u_char *p) +{ + struct juniper_l2info_t l2info; + + l2info.pictype = DLT_JUNIPER_ETHER; + if(juniper_parse_header(p, h, &l2info) == 0) + return l2info.header_len; + + p+=l2info.header_len; + /* this DLT contains nothing but raw Ethernet frames */ + ether_print(p, l2info.length, l2info.caplen); + return l2info.header_len; +} +#endif + +#ifdef DLT_JUNIPER_PPP +u_int +juniper_ppp_print(const struct pcap_pkthdr *h, register const u_char *p) +{ + struct juniper_l2info_t l2info; + + l2info.pictype = DLT_JUNIPER_PPP; + if(juniper_parse_header(p, h, &l2info) == 0) + return l2info.header_len; + + p+=l2info.header_len; + /* this DLT contains nothing but raw ppp frames */ + ppp_print(p, l2info.length); + return l2info.header_len; +} +#endif + +#ifdef DLT_JUNIPER_FRELAY +u_int +juniper_frelay_print(const struct pcap_pkthdr *h, register const u_char *p) +{ + struct juniper_l2info_t l2info; + + l2info.pictype = DLT_JUNIPER_FRELAY; + if(juniper_parse_header(p, h, &l2info) == 0) + return l2info.header_len; + + p+=l2info.header_len; + /* this DLT contains nothing but raw frame-relay frames */ + fr_print(p, l2info.length); + return l2info.header_len; +} +#endif + +#ifdef DLT_JUNIPER_CHDLC +u_int +juniper_chdlc_print(const struct pcap_pkthdr *h, register const u_char *p) +{ + struct juniper_l2info_t l2info; + + l2info.pictype = DLT_JUNIPER_CHDLC; + if(juniper_parse_header(p, h, &l2info) == 0) + return l2info.header_len; + + p+=l2info.header_len; + /* this DLT contains nothing but raw c-hdlc frames */ + chdlc_print(p, l2info.length); + return l2info.header_len; +} +#endif +#ifdef DLT_JUNIPER_PPPOE_ATM u_int juniper_pppoe_atm_print(const struct pcap_pkthdr *h, register const u_char *p) { @@ -343,7 +452,9 @@ juniper_pppoe_atm_print(const struct pcap_pkthdr *h, register const u_char *p) return l2info.header_len; } +#endif +#ifdef DLT_JUNIPER_MLPPP u_int juniper_mlppp_print(const struct pcap_pkthdr *h, register const u_char *p) { @@ -365,11 +476,19 @@ juniper_mlppp_print(const struct pcap_pkthdr *h, register const u_char *p) /* first try the LSQ protos */ switch(l2info.proto) { case JUNIPER_LSQ_L3_PROTO_IPV4: - ip_print(gndo, p, l2info.length); + /* IP traffic going to the RE would not have a cookie + * -> this must be incoming IS-IS over PPP + */ + if (l2info.cookie[4] == (JUNIPER_LSQ_COOKIE_RE|JUNIPER_LSQ_COOKIE_DIR)) + ppp_print(p, l2info.length); + else + ip_print(gndo, p, l2info.length); return l2info.header_len; +#ifdef INET6 case JUNIPER_LSQ_L3_PROTO_IPV6: ip6_print(p,l2info.length); return l2info.header_len; +#endif case JUNIPER_LSQ_L3_PROTO_MPLS: mpls_print(p,l2info.length); return l2info.header_len; @@ -393,8 +512,10 @@ juniper_mlppp_print(const struct pcap_pkthdr *h, register const u_char *p) return l2info.header_len; } +#endif +#ifdef DLT_JUNIPER_MFR u_int juniper_mfr_print(const struct pcap_pkthdr *h, register const u_char *p) { @@ -405,6 +526,36 @@ juniper_mfr_print(const struct pcap_pkthdr *h, register const u_char *p) return l2info.header_len; p+=l2info.header_len; + + /* child-link ? */ + if (l2info.cookie_len == 0) { + mfr_print(p,l2info.length); + return l2info.header_len; + } + + /* first try the LSQ protos */ + if (l2info.cookie_len == AS_PIC_COOKIE_LEN) { + switch(l2info.proto) { + case JUNIPER_LSQ_L3_PROTO_IPV4: + ip_print(gndo, p, l2info.length); + return l2info.header_len; +#ifdef INET6 + case JUNIPER_LSQ_L3_PROTO_IPV6: + ip6_print(p,l2info.length); + return l2info.header_len; +#endif + case JUNIPER_LSQ_L3_PROTO_MPLS: + mpls_print(p,l2info.length); + return l2info.header_len; + case JUNIPER_LSQ_L3_PROTO_ISO: + isoclns_print(p,l2info.length,l2info.caplen); + return l2info.header_len; + default: + break; + } + return l2info.header_len; + } + /* suppress Bundle-ID if frame was captured on a child-link */ if (eflag && EXTRACT_32BITS(l2info.cookie) != 1) printf("Bundle-ID %u, ",l2info.bundle); switch (l2info.proto) { @@ -423,7 +574,9 @@ juniper_mfr_print(const struct pcap_pkthdr *h, register const u_char *p) return l2info.header_len; } +#endif +#ifdef DLT_JUNIPER_MLFR u_int juniper_mlfr_print(const struct pcap_pkthdr *h, register const u_char *p) { @@ -454,6 +607,7 @@ juniper_mlfr_print(const struct pcap_pkthdr *h, register const u_char *p) return l2info.header_len; } +#endif /* * ATM1 PIC cookie format @@ -463,6 +617,7 @@ juniper_mlfr_print(const struct pcap_pkthdr *h, register const u_char *p) * +-----+-------------------------+-------------------------------+ */ +#ifdef DLT_JUNIPER_ATM1 u_int juniper_atm1_print(const struct pcap_pkthdr *h, register const u_char *p) { @@ -477,7 +632,7 @@ juniper_atm1_print(const struct pcap_pkthdr *h, register const u_char *p) p+=l2info.header_len; if (l2info.cookie[0] == 0x80) { /* OAM cell ? */ - oam_print(p,l2info.length); + oam_print(p,l2info.length,ATM_OAM_NOHEC); return l2info.header_len; } @@ -500,6 +655,7 @@ juniper_atm1_print(const struct pcap_pkthdr *h, register const u_char *p) return l2info.header_len; } +#endif /* * ATM2 PIC cookie format @@ -509,10 +665,12 @@ juniper_atm1_print(const struct pcap_pkthdr *h, register const u_char *p) * +-------------------------------+---------+---+-----+-----------+ */ +#ifdef DLT_JUNIPER_ATM2 u_int juniper_atm2_print(const struct pcap_pkthdr *h, register const u_char *p) { u_int16_t extracted_ethertype; + u_int32_t control_word; struct juniper_l2info_t l2info; @@ -523,7 +681,13 @@ juniper_atm2_print(const struct pcap_pkthdr *h, register const u_char *p) p+=l2info.header_len; if (l2info.cookie[7] & ATM2_PKT_TYPE_MASK) { /* OAM cell ? */ - oam_print(p,l2info.length); + control_word = EXTRACT_32BITS(p); + if(control_word == 0 || control_word == 0x08000000) { + l2info.header_len += 4; + l2info.length -= 4; + p += 4; + } + oam_print(p,l2info.length,ATM_OAM_NOHEC); return l2info.header_len; } @@ -555,6 +719,7 @@ juniper_atm2_print(const struct pcap_pkthdr *h, register const u_char *p) return l2info.header_len; } +#endif /* try to guess, based on all PPP protos that are supported in @@ -636,7 +801,7 @@ static int juniper_parse_header (const u_char *p, const struct pcap_pkthdr *h, struct juniper_l2info_t *l2info) { struct juniper_cookie_table_t *lp = juniper_cookie_table; - u_int idx; + u_int idx, offset; l2info->header_len = 0; l2info->cookie_len = 0; @@ -648,14 +813,22 @@ juniper_parse_header (const u_char *p, const struct pcap_pkthdr *h, struct junip l2info->direction = p[3]&JUNIPER_BPF_PKT_IN; TCHECK2(p[0],4); - if (EXTRACT_24BITS(p) != JUNIPER_MGC_NUMBER) /* magic number found ? */ + if (EXTRACT_24BITS(p) != JUNIPER_MGC_NUMBER) { /* magic number found ? */ + printf("no magic-number found!"); return 0; - else - l2info->header_len = 4; + } if (eflag) /* print direction */ printf("%3s ",tok2str(juniper_direction_values,"---",l2info->direction)); + /* extensions present ? - calculate how much bytes to skip */ + if ((p[3] & JUNIPER_BPF_EXT ) == JUNIPER_BPF_EXT ) { + offset = 6 + EXTRACT_16BITS(p+4); + if (eflag>1) + printf("ext-len %u, ",EXTRACT_16BITS(p+4)); + } else + offset = 4; + if ((p[3] & JUNIPER_BPF_NO_L2 ) == JUNIPER_BPF_NO_L2 ) { if (eflag) printf("no-L2-hdr, "); @@ -664,15 +837,15 @@ juniper_parse_header (const u_char *p, const struct pcap_pkthdr *h, struct junip * perform the v4/v6 heuristics * to figure out what it is */ - TCHECK2(p[8],1); - if(ip_heuristic_guess(p+8,l2info->length-8) == 0) + TCHECK2(p[offset+4],1); + if(ip_heuristic_guess(p+offset+4,l2info->length-(offset+4)) == 0) printf("no IP-hdr found!"); - l2info->header_len+=4; + l2info->header_len=offset+4; return 0; /* stop parsing the output further */ } - + l2info->header_len = offset; p+=l2info->header_len; l2info->length -= l2info->header_len; l2info->caplen -= l2info->header_len; @@ -681,19 +854,16 @@ juniper_parse_header (const u_char *p, const struct pcap_pkthdr *h, struct junip while (lp->s != NULL) { if (lp->pictype == l2info->pictype) { - l2info->cookie_len = lp->cookie_len; - l2info->header_len += lp->cookie_len; + l2info->cookie_len += lp->cookie_len; switch (p[0]) { case LS_COOKIE_ID: l2info->cookie_type = LS_COOKIE_ID; l2info->cookie_len += 2; - l2info->header_len += 2; break; case AS_COOKIE_ID: l2info->cookie_type = AS_COOKIE_ID; - l2info->cookie_len += 6; - l2info->header_len += 6; + l2info->cookie_len = 8; break; default: @@ -701,6 +871,19 @@ juniper_parse_header (const u_char *p, const struct pcap_pkthdr *h, struct junip break; } + +#ifdef DLT_JUNIPER_MFR + /* MFR child links don't carry cookies */ + if (l2info->pictype == DLT_JUNIPER_MFR && + (p[0] & MFR_BE_MASK) == MFR_BE_MASK) { + l2info->cookie_len = 0; + } +#endif + + l2info->header_len += l2info->cookie_len; + l2info->length -= l2info->cookie_len; + l2info->caplen -= l2info->cookie_len; + if (eflag) printf("%s-PIC, cookie-len %u", lp->s, @@ -728,6 +911,7 @@ juniper_parse_header (const u_char *p, const struct pcap_pkthdr *h, struct junip /* DLT_ specific parsing */ switch(l2info->pictype) { +#ifdef DLT_JUNIPER_MLPPP case DLT_JUNIPER_MLPPP: switch (l2info->cookie_type) { case LS_COOKIE_ID: @@ -742,24 +926,51 @@ juniper_parse_header (const u_char *p, const struct pcap_pkthdr *h, struct junip break; } break; - case DLT_JUNIPER_MLFR: /* fall through */ +#endif +#ifdef DLT_JUNIPER_MLFR + case DLT_JUNIPER_MLFR: + switch (l2info->cookie_type) { + case LS_COOKIE_ID: + l2info->bundle = l2info->cookie[1]; + l2info->proto = EXTRACT_16BITS(p); + l2info->header_len += 2; + l2info->length -= 2; + l2info->caplen -= 2; + break; + case AS_COOKIE_ID: + l2info->bundle = (EXTRACT_16BITS(&l2info->cookie[6])>>3)&0xfff; + l2info->proto = (l2info->cookie[5])&JUNIPER_LSQ_L3_PROTO_MASK; + break; + default: + l2info->bundle = l2info->cookie[0]; + l2info->header_len += 2; + l2info->length -= 2; + l2info->caplen -= 2; + break; + } + break; +#endif +#ifdef DLT_JUNIPER_MFR case DLT_JUNIPER_MFR: switch (l2info->cookie_type) { case LS_COOKIE_ID: l2info->bundle = l2info->cookie[1]; + l2info->proto = EXTRACT_16BITS(p); + l2info->header_len += 2; + l2info->length -= 2; + l2info->caplen -= 2; break; case AS_COOKIE_ID: l2info->bundle = (EXTRACT_16BITS(&l2info->cookie[6])>>3)&0xfff; + l2info->proto = (l2info->cookie[5])&JUNIPER_LSQ_L3_PROTO_MASK; break; default: l2info->bundle = l2info->cookie[0]; break; } - l2info->proto = EXTRACT_16BITS(p); - l2info->header_len += 2; - l2info->length -= 2; - l2info->caplen -= 2; break; +#endif +#ifdef DLT_JUNIPER_ATM2 case DLT_JUNIPER_ATM2: TCHECK2(p[0],4); /* ATM cell relay control word present ? */ @@ -769,8 +980,13 @@ juniper_parse_header (const u_char *p, const struct pcap_pkthdr *h, struct junip printf("control-word 0x%08x ",EXTRACT_32BITS(p)); } break; +#endif +#ifdef DLT_JUNIPER_ATM1 case DLT_JUNIPER_ATM1: + break; +#endif default: + printf("Unknown Juniper DLT_ type %u: ", l2info->pictype); break; }