void otv_print(netdissect_options *ndo, const u_char *bp, u_int len) { uint8_t flags; ND_PRINT((ndo, "OTV, ")); if (len < 8) goto trunc; ND_TCHECK(*bp); flags = *bp; ND_PRINT((ndo, "flags [%s] (0x%02x), ", flags & 0x08 ? "I" : ".", flags)); bp += 1; ND_TCHECK2(*bp, 3); ND_PRINT((ndo, "overlay %u, ", EXTRACT_24BITS(bp))); bp += 3; ND_TCHECK2(*bp, 3); ND_PRINT((ndo, "instance %u\n", EXTRACT_24BITS(bp))); bp += 3; /* Reserved */ ND_TCHECK(*bp); bp += 1; ether_print(ndo, bp, len - 8, ndo->ndo_snapend - bp, NULL, NULL); return; trunc: ND_PRINT((ndo, " [|OTV]")); }
static void igrp_entry_print(register struct igrprte *igr, register int is_interior, register int is_exterior) { register u_int delay, bandwidth; u_int metric, mtu; if (is_interior) printf(" *.%d.%d.%d", igr->igr_net[0], igr->igr_net[1], igr->igr_net[2]); else if (is_exterior) printf(" X%d.%d.%d.0", igr->igr_net[0], igr->igr_net[1], igr->igr_net[2]); else printf(" %d.%d.%d.0", igr->igr_net[0], igr->igr_net[1], igr->igr_net[2]); delay = EXTRACT_24BITS(igr->igr_dly); bandwidth = EXTRACT_24BITS(igr->igr_bw); metric = bandwidth + delay; if (metric > 0xffffff) metric = 0xffffff; mtu = EXTRACT_16BITS(igr->igr_mtu); printf(" d=%d b=%d r=%d l=%d M=%d mtu=%d in %d hops", 10 * delay, bandwidth == 0 ? 0 : 10000000 / bandwidth, igr->igr_rel, igr->igr_ld, metric, mtu, igr->igr_hct); }
u_int juniper_services_print(const struct pcap_pkthdr *h, register const u_char *p) { struct juniper_l2info_t l2info; struct juniper_services_header { u_int8_t svc_id; u_int8_t flags_len; u_int8_t svc_set_id[2]; u_int8_t dir_iif[4]; }; const struct juniper_services_header *sh; l2info.pictype = DLT_JUNIPER_SERVICES; if(juniper_parse_header(p, h, &l2info) == 0) return l2info.header_len; p+=l2info.header_len; sh = (struct juniper_services_header *)p; if (eflag) printf("service-id %u flags 0x%02x service-set-id 0x%04x iif %u: ", sh->svc_id, sh->flags_len, EXTRACT_16BITS(&sh->svc_set_id), EXTRACT_24BITS(&sh->dir_iif[1])); ip_heuristic_guess(p, l2info.length); return l2info.header_len; }
u_int juniper_services_print(const struct pcap_pkthdr *h, packetbody_t p) { struct juniper_l2info_t l2info; struct juniper_services_header { u_int8_t svc_id; u_int8_t flags_len; u_int8_t svc_set_id[2]; u_int8_t dir_iif[4]; }; __capability const struct juniper_services_header *sh; l2info.pictype = DLT_JUNIPER_SERVICES; if(juniper_parse_header(p, h, &l2info) == 0) return l2info.header_len; p+=l2info.header_len; sh = (__capability const struct juniper_services_header *)p; if (eflag) printf("service-id %u flags 0x%02x service-set-id 0x%04x iif %u: ", sh->svc_id, sh->flags_len, EXTRACT_16BITS(&sh->svc_set_id), EXTRACT_24BITS(&sh->dir_iif[1])); /* no proto field - lets guess by first byte of IP header*/ ip_heuristic_guess(p, l2info.length); return l2info.header_len; }
u_int juniper_services_print(netdissect_options *ndo, const struct pcap_pkthdr *h, register const u_char *p) { struct juniper_l2info_t l2info; struct juniper_services_header { uint8_t svc_id; uint8_t flags_len; uint8_t svc_set_id[2]; uint8_t dir_iif[4]; }; const struct juniper_services_header *sh; l2info.pictype = DLT_JUNIPER_SERVICES; if (juniper_parse_header(ndo, p, h, &l2info) == 0) return l2info.header_len; p+=l2info.header_len; sh = (struct juniper_services_header *)p; if (ndo->ndo_eflag) ND_PRINT((ndo, "service-id %u flags 0x%02x service-set-id 0x%04x iif %u: ", sh->svc_id, sh->flags_len, EXTRACT_16BITS(&sh->svc_set_id), EXTRACT_24BITS(&sh->dir_iif[1]))); /* no proto field - lets guess by first byte of IP header*/ ip_heuristic_guess (ndo, p, l2info.length); return l2info.header_len; }
static void dccp_print_ack_no(const u_char *bp) { const struct dccp_hdr *dh = (const struct dccp_hdr *)bp; const struct dccp_hdr_ack_bits *dh_ack = (struct dccp_hdr_ack_bits *)(bp + dccp_basic_hdr_len(dh)); u_int32_t ack_high; u_int64_t ackno; TCHECK2(*dh_ack,4); ack_high = DCCPH_ACK(dh_ack); ackno = EXTRACT_24BITS(&ack_high) & 0xFFFFFF; if (DCCPH_X(dh) != 0) { u_int32_t ack_low; TCHECK2(*dh_ack,8); ack_low = dh_ack->dccph_ack_nr_low; ackno &= 0x00FFFF; /* clear reserved field */ ackno = (ackno << 32) + EXTRACT_32BITS(&ack_low); } (void)printf("(ack=%" PRIu64 ") ", ackno); trunc: return; }
static void sig_print(const u_char *p, int caplen) { bpf_u_int32 call_ref; if (caplen < PROTO_POS) { printf("[|atm]"); return; } if (p[PROTO_POS] == Q2931) { /* * protocol:Q.2931 for User to Network Interface * (UNI 3.1) signalling */ printf("Q.2931"); if (caplen < MSG_TYPE_POS) { printf(" [|atm]"); return; } printf(":%s ", tok2str(msgtype2str, "msgtype#%d", p[MSG_TYPE_POS])); /* * The call reference comes before the message type, * so if we know we have the message type, which we * do from the caplen test above, we also know we have * the call reference. */ call_ref = EXTRACT_24BITS(&p[CALL_REF_POS]); printf("CALL_REF:0x%06x", call_ref); } else { /* SCCOP with some unknown protocol atop it */ printf("SSCOP, proto %d ", p[PROTO_POS]); } }
void vxlan_print(netdissect_options *ndo, const u_char *bp, u_int len) { uint8_t flags; uint32_t vni; if (len < VXLAN_HDR_LEN) goto trunc; ND_TCHECK2(*bp, VXLAN_HDR_LEN); flags = *bp; bp += 4; vni = EXTRACT_24BITS(bp); bp += 4; ND_PRINT((ndo, "VXLAN, ")); ND_PRINT((ndo, "flags [%s] (0x%02x), ", flags & 0x08 ? "I" : ".", flags)); ND_PRINT((ndo, "vni %u\n", vni)); ether_print(ndo, bp, len - VXLAN_HDR_LEN, len - VXLAN_HDR_LEN, NULL, NULL); return; trunc: ND_PRINT((ndo, "%s", tstr)); }
static void sig_print(const u_char *p, int caplen) { bpf_u_int32 call_ref; if (caplen < PROTO_POS) { printf("[|atm]"); return; } if (p[PROTO_POS] == Q2931) { /* * protocol:Q.2931 for User to Network Interface * (UNI 3.1) signalling */ printf("Q.2931"); if (caplen < MSG_TYPE_POS) { printf(" [|atm]"); return; } printf(":%s ", tok2str(msgtype2str, "msgtype#%d", p[MSG_TYPE_POS])); if (caplen < CALL_REF_POS+3) { printf("[|atm]"); return; } call_ref = EXTRACT_24BITS(&p[CALL_REF_POS]); printf("CALL_REF:0x%06x", call_ref); } else { /* SCCOP with some unknown protocol atop it */ printf("SSCOP, proto %d ", p[PROTO_POS]); } }
static void handle_llc_packet(const struct llc* llc, int dir) { struct ip* ip = (struct ip*)((void*)llc + sizeof(struct llc)); /* Taken from tcpdump/print-llc.c */ if(llc->ssap == LLCSAP_SNAP && llc->dsap == LLCSAP_SNAP && llc->llcui == LLC_UI) { u_int32_t orgcode; register u_short et; orgcode = EXTRACT_24BITS(&llc->llc_orgcode[0]); et = EXTRACT_16BITS(&llc->llc_ethertype[0]); switch(orgcode) { case OUI_ENCAP_ETHER: case OUI_CISCO_90: handle_ip_packet(ip, dir); break; case OUI_APPLETALK: if(et == ETHERTYPE_ATALK) { handle_ip_packet(ip, dir); } break; default:; /* Not a lot we can do */ } } }
u_int juniper_atm2_print(netdissect_options *ndo, const struct pcap_pkthdr *h, register const u_char *p) { uint16_t extracted_ethertype; struct juniper_l2info_t l2info; l2info.pictype = DLT_JUNIPER_ATM2; if (juniper_parse_header(ndo, p, h, &l2info) == 0) return l2info.header_len; p+=l2info.header_len; if (l2info.cookie[7] & ATM2_PKT_TYPE_MASK) { /* OAM cell ? */ oam_print(ndo, p, l2info.length, ATM_OAM_NOHEC); return l2info.header_len; } if (EXTRACT_24BITS(p) == 0xfefe03 || /* NLPID encaps ? */ EXTRACT_24BITS(p) == 0xaaaa03) { /* SNAP encaps ? */ if (llc_print(ndo, p, l2info.length, l2info.caplen, NULL, NULL, &extracted_ethertype) != 0) return l2info.header_len; } if (l2info.direction != JUNIPER_BPF_PKT_IN && /* ether-over-1483 encaps ? */ (EXTRACT_32BITS(l2info.cookie) & ATM2_GAP_COUNT_MASK)) { ether_print(ndo, p, l2info.length, l2info.caplen, NULL, NULL); return l2info.header_len; } if (p[0] == 0x03) { /* Cisco style NLPID encaps ? */ isoclns_print(ndo, p + 1, l2info.length - 1, l2info.caplen - 1); /* FIXME check if frame was recognized */ return l2info.header_len; } if(juniper_ppp_heuristic_guess(ndo, p, l2info.length) != 0) /* PPPoA vcmux encaps ? */ return l2info.header_len; if (ip_heuristic_guess(ndo, p, l2info.length) != 0) /* last try - vcmux encaps ? */ return l2info.header_len; return l2info.header_len; }
u_int juniper_atm2_print(const struct pcap_pkthdr *h, register const u_char *p) { u_int16_t extracted_ethertype; struct juniper_l2info_t l2info; l2info.pictype = DLT_JUNIPER_ATM2; if(juniper_parse_header(p, h, &l2info) == 0) return l2info.header_len; p+=l2info.header_len; if (l2info.cookie[7] & ATM2_PKT_TYPE_MASK) { oam_print(p,l2info.length,ATM_OAM_NOHEC); return l2info.header_len; } if (EXTRACT_24BITS(p) == 0xfefe03 || EXTRACT_24BITS(p) == 0xaaaa03) { if (llc_print(p, l2info.length, l2info.caplen, NULL, NULL, &extracted_ethertype) != 0) return l2info.header_len; } if (l2info.direction != JUNIPER_BPF_PKT_IN && (EXTRACT_32BITS(l2info.cookie) & ATM2_GAP_COUNT_MASK)) { ether_print(p, l2info.length, l2info.caplen); return l2info.header_len; } if (p[0] == 0x03) { isoclns_print(p + 1, l2info.length - 1, l2info.caplen - 1); return l2info.header_len; } if(juniper_ppp_heuristic_guess(p, l2info.length) != 0) return l2info.header_len; if(ip_heuristic_guess(p, l2info.length) != 0) return l2info.header_len; return l2info.header_len; }
static int ospf_print_lshdr(register const struct lsa_hdr *lshp) { u_int ls_length; TCHECK(lshp->ls_length); ls_length = EXTRACT_16BITS(&lshp->ls_length); if (ls_length < sizeof(struct lsa_hdr)) { printf("\n\t Bogus length %u < %lu", ls_length, (unsigned long)sizeof(struct lsa_hdr)); return(-1); } TCHECK(lshp->ls_seq); /* XXX - ls_length check checked this */ printf("\n\t Advertising Router: %s, seq 0x%08x, age %us, length: %u", ipaddr_string(&lshp->ls_router), EXTRACT_32BITS(&lshp->ls_seq), EXTRACT_16BITS(&lshp->ls_age), ls_length-(u_int)sizeof(struct lsa_hdr)); TCHECK(lshp->ls_type); /* XXX - ls_length check checked this */ switch (lshp->ls_type) { /* the LSA header for opaque LSAs was slightly changed */ case LS_TYPE_OPAQUE_LL: case LS_TYPE_OPAQUE_AL: case LS_TYPE_OPAQUE_DW: printf("\n\t %s LSA (%d), Opaque-Type: %s LSA (%u), Opaque-ID: %u", tok2str(lsa_values,"unknown",lshp->ls_type), lshp->ls_type, tok2str(lsa_opaque_values, "unknown", *(&lshp->un_lsa_id.opaque_field.opaque_type)), *(&lshp->un_lsa_id.opaque_field.opaque_type), EXTRACT_24BITS(&lshp->un_lsa_id.opaque_field.opaque_id) ); break; /* all other LSA types use regular style LSA headers */ default: printf("\n\t %s LSA (%d), LSA-ID: %s", tok2str(lsa_values,"unknown",lshp->ls_type), lshp->ls_type, ipaddr_string(&lshp->un_lsa_id.lsa_id)); break; } TCHECK(lshp->ls_options); /* XXX - ls_length check checked this */ printf("\n\t Options: [%s]", bittok2str(ospf_option_values,"none",lshp->ls_options)); return (ls_length); trunc: return (-1); }
void vxlan_gpe_print(netdissect_options *ndo, const u_char *bp, u_int len) { uint8_t flags; uint8_t next_protocol; uint32_t vni; if (len < VXLAN_GPE_HDR_LEN) goto trunc; ND_TCHECK2(*bp, VXLAN_GPE_HDR_LEN); flags = *bp; bp += 3; next_protocol = *bp; bp += 1; vni = EXTRACT_24BITS(bp); bp += 4; ND_PRINT((ndo, "VXLAN-GPE, ")); ND_PRINT((ndo, "flags [%s], ", bittok2str_nosep(vxlan_gpe_flags, "none", flags))); ND_PRINT((ndo, "vni %u", vni)); ND_PRINT((ndo, ndo->ndo_vflag ? "\n " : ": ")); switch (next_protocol) { case 0x1: ip_print(ndo, bp, len - 8); break; case 0x2: ip6_print(ndo, bp, len - 8); break; case 0x3: ether_print(ndo, bp, len - 8, len - 8, NULL, NULL); break; case 0x4: nsh_print(ndo, bp, len - 8); break; case 0x5: mpls_print(ndo, bp, len - 8); break; default: ND_PRINT((ndo, "ERROR: unknown-next-protocol")); return; } return; trunc: ND_PRINT((ndo, "%s", tstr)); }
static u_int64_t dccp_seqno(const struct dccp_hdr *dh) { u_int32_t seq_high = DCCPH_SEQ(dh); u_int64_t seqno = EXTRACT_24BITS(&seq_high) & 0xFFFFFF; if (DCCPH_X(dh) != 0) { const struct dccp_hdr_ext *dhx = (void *)(dh + 1); u_int32_t seq_low = dhx->dccph_seq_low; seqno &= 0x00FFFF; /* clear reserved field */ seqno = (seqno << 32) + EXTRACT_32BITS(&seq_low); } return seqno; }
static u_int64_t dccp_seqno(const u_char *bp) { const struct dccp_hdr *dh = (const struct dccp_hdr *)bp; u_int64_t seqno; if (DCCPH_X(dh) != 0) { const struct dccp_hdr_ext *dhx = (const struct dccp_hdr_ext *)bp; seqno = EXTRACT_48BITS(dhx->dccph_seq); } else { seqno = EXTRACT_24BITS(dh->dccph_seq); } return seqno; }
u_int juniper_atm1_print(const struct pcap_pkthdr *h, register const u_char *p) { u_int16_t extracted_ethertype; struct juniper_l2info_t l2info; l2info.pictype = DLT_JUNIPER_ATM1; if(juniper_parse_header(p, h, &l2info) == 0) return l2info.header_len; p+=l2info.header_len; if (l2info.cookie[0] == 0x80) { oam_print(p,l2info.length,ATM_OAM_NOHEC); return l2info.header_len; } if (EXTRACT_24BITS(p) == 0xfefe03 || EXTRACT_24BITS(p) == 0xaaaa03) { if (llc_print(p, l2info.length, l2info.caplen, NULL, NULL, &extracted_ethertype) != 0) return l2info.header_len; } if (p[0] == 0x03) { isoclns_print(p + 1, l2info.length - 1, l2info.caplen - 1); return l2info.header_len; } if(ip_heuristic_guess(p, l2info.length) != 0) return l2info.header_len; return l2info.header_len; }
u_int juniper_atm1_print(const struct pcap_pkthdr *h, register const u_char *p) { u_int16_t extracted_ethertype; struct juniper_l2info_t l2info; l2info.pictype = DLT_JUNIPER_ATM1; if(juniper_parse_header(p, h, &l2info) == 0) return l2info.header_len; p+=l2info.header_len; if (l2info.cookie[0] == 0x80) { /* OAM cell ? */ oam_print(p,l2info.length,ATM_OAM_NOHEC); return l2info.header_len; } if (EXTRACT_24BITS(p) == 0xfefe03 || /* NLPID encaps ? */ EXTRACT_24BITS(p) == 0xaaaa03) { /* SNAP encaps ? */ if (llc_print(p, l2info.length, l2info.caplen, NULL, NULL, &extracted_ethertype) != 0) return l2info.header_len; } if (p[0] == 0x03) { /* Cisco style NLPID encaps ? */ isoclns_print(p + 1, l2info.length - 1, l2info.caplen - 1); /* FIXME check if frame was recognized */ return l2info.header_len; } if(ip_heuristic_guess(p, l2info.length) != 0) /* last try - vcmux encaps ? */ return l2info.header_len; return l2info.header_len; }
int juniper_read_tlv_value(packetbody_t p, u_int tlv_type, u_int tlv_len) { int tlv_value; /* TLVs < 128 are little endian encoded */ if (tlv_type < 128) { switch (tlv_len) { case 1: tlv_value = *p; break; case 2: tlv_value = EXTRACT_LE_16BITS(p); break; case 3: tlv_value = EXTRACT_LE_24BITS(p); break; case 4: tlv_value = EXTRACT_LE_32BITS(p); break; default: tlv_value = -1; break; } } else { /* TLVs >= 128 are big endian encoded */ switch (tlv_len) { case 1: tlv_value = *p; break; case 2: tlv_value = EXTRACT_16BITS(p); break; case 3: tlv_value = EXTRACT_24BITS(p); break; case 4: tlv_value = EXTRACT_32BITS(p); break; default: tlv_value = -1; break; } } return tlv_value; }
static void dccp_print_ack_no(netdissect_options *ndo, const u_char *bp) { const struct dccp_hdr *dh = (const struct dccp_hdr *)bp; const u_char *ackp = bp + dccp_basic_hdr_len(dh); u_int64_t ackno; if (DCCPH_X(dh) != 0) { ND_TCHECK2(*ackp, 8); ackno = EXTRACT_48BITS(ackp + 2); } else { ND_TCHECK2(*ackp, 4); ackno = EXTRACT_24BITS(ackp + 1); } ND_PRINT((ndo, "(ack=%" PRIu64 ") ", ackno)); trunc: return; }
static void dccp_print_ack_no(const u_char *bp) { const struct dccp_hdr *dh = (const struct dccp_hdr *)bp; const u_char *ackp = bp + dccp_basic_hdr_len(dh); u_int64_t ackno; if (DCCPH_X(dh) != 0) { TCHECK2(*ackp, 8); ackno = EXTRACT_48BITS(ackp + 2); } else { TCHECK2(*ackp, 4); ackno = EXTRACT_24BITS(ackp + 1); } (void)printf("(ack=%" PRIu64 ") ", ackno); trunc: return; }
static void sig_print(netdissect_options *ndo, const u_char *p, int caplen) { uint32_t call_ref; if (caplen < PROTO_POS) { ND_PRINT((ndo, "%s", tstr)); return; } if (p[PROTO_POS] == Q2931) { /* * protocol:Q.2931 for User to Network Interface * (UNI 3.1) signalling */ ND_PRINT((ndo, "Q.2931")); if (caplen < MSG_TYPE_POS) { ND_PRINT((ndo, " %s", tstr)); return; } ND_PRINT((ndo, ":%s ", tok2str(msgtype2str, "msgtype#%d", p[MSG_TYPE_POS]))); /* * The call reference comes before the message type, * so if we know we have the message type, which we * do from the caplen test above, we also know we have * the call reference. */ call_ref = EXTRACT_24BITS(&p[CALL_REF_POS]); ND_PRINT((ndo, "CALL_REF:0x%06x", call_ref)); } else { /* SCCOP with some unknown protocol atop it */ ND_PRINT((ndo, "SSCOP, proto %d ", p[PROTO_POS])); } }
void geneve_print(netdissect_options *ndo, const u_char *bp, u_int len) { uint8_t ver_opt; u_int version; uint8_t flags; uint16_t prot; uint32_t vni; uint8_t reserved; u_int opts_len; ND_PRINT((ndo, "Geneve")); ND_TCHECK2(*bp, 8); ver_opt = *bp; bp += 1; len -= 1; version = ver_opt >> VER_SHIFT; if (version != 0) { ND_PRINT((ndo, " ERROR: unknown-version %u", version)); return; } flags = *bp; bp += 1; len -= 1; prot = EXTRACT_16BITS(bp); bp += 2; len -= 2; vni = EXTRACT_24BITS(bp); bp += 3; len -= 3; reserved = *bp; bp += 1; len -= 1; ND_PRINT((ndo, ", Flags [%s]", bittok2str_nosep(geneve_flag_values, "none", flags))); ND_PRINT((ndo, ", vni 0x%x", vni)); if (reserved) ND_PRINT((ndo, ", rsvd 0x%x", reserved)); if (ndo->ndo_eflag) ND_PRINT((ndo, ", proto %s (0x%04x)", tok2str(ethertype_values, "unknown", prot), prot)); opts_len = (ver_opt & HDR_OPTS_LEN_MASK) * 4; if (len < opts_len) { ND_PRINT((ndo, " truncated-geneve - %u bytes missing", opts_len - len)); return; } ND_TCHECK2(*bp, opts_len); if (opts_len > 0) { ND_PRINT((ndo, ", options [")); if (ndo->ndo_vflag) geneve_opts_print(ndo, bp, opts_len); else ND_PRINT((ndo, "%u bytes", opts_len)); ND_PRINT((ndo, "]")); } bp += opts_len; len -= opts_len; if (ndo->ndo_vflag < 1) ND_PRINT((ndo, ": ")); else ND_PRINT((ndo, "\n\t")); if (ethertype_print(ndo, prot, bp, len, len) == 0) { if (prot == ETHERTYPE_TEB) ether_print(ndo, bp, len, len, NULL, NULL); else ND_PRINT((ndo, "geneve-proto-0x%x", prot)); } return; trunc: ND_PRINT((ndo, " [|geneve]")); }
void eigrp_print(netdissect_options *ndo, register const u_char *pptr, register u_int len) { const struct eigrp_common_header *eigrp_com_header; const struct eigrp_tlv_header *eigrp_tlv_header; const u_char *tptr,*tlv_tptr; u_int tlen,eigrp_tlv_len,eigrp_tlv_type,tlv_tlen, byte_length, bit_length; uint8_t prefix[4]; union { const struct eigrp_tlv_general_parm_t *eigrp_tlv_general_parm; const struct eigrp_tlv_sw_version_t *eigrp_tlv_sw_version; const struct eigrp_tlv_ip_int_t *eigrp_tlv_ip_int; const struct eigrp_tlv_ip_ext_t *eigrp_tlv_ip_ext; const struct eigrp_tlv_at_cable_setup_t *eigrp_tlv_at_cable_setup; const struct eigrp_tlv_at_int_t *eigrp_tlv_at_int; const struct eigrp_tlv_at_ext_t *eigrp_tlv_at_ext; } tlv_ptr; tptr=pptr; eigrp_com_header = (const struct eigrp_common_header *)pptr; ND_TCHECK(*eigrp_com_header); /* * Sanity checking of the header. */ if (eigrp_com_header->version != EIGRP_VERSION) { ND_PRINT((ndo, "EIGRP version %u packet not supported",eigrp_com_header->version)); return; } /* in non-verbose mode just lets print the basic Message Type*/ if (ndo->ndo_vflag < 1) { ND_PRINT((ndo, "EIGRP %s, length: %u", tok2str(eigrp_opcode_values, "unknown (%u)",eigrp_com_header->opcode), len)); return; } /* ok they seem to want to know everything - lets fully decode it */ tlen=len-sizeof(struct eigrp_common_header); /* FIXME print other header info */ ND_PRINT((ndo, "\n\tEIGRP v%u, opcode: %s (%u), chksum: 0x%04x, Flags: [%s]\n\tseq: 0x%08x, ack: 0x%08x, AS: %u, length: %u", eigrp_com_header->version, tok2str(eigrp_opcode_values, "unknown, type: %u",eigrp_com_header->opcode), eigrp_com_header->opcode, EXTRACT_16BITS(&eigrp_com_header->checksum), tok2str(eigrp_common_header_flag_values, "none", EXTRACT_32BITS(&eigrp_com_header->flags)), EXTRACT_32BITS(&eigrp_com_header->seq), EXTRACT_32BITS(&eigrp_com_header->ack), EXTRACT_32BITS(&eigrp_com_header->asn), tlen)); tptr+=sizeof(const struct eigrp_common_header); while(tlen>0) { /* did we capture enough for fully decoding the object header ? */ ND_TCHECK2(*tptr, sizeof(struct eigrp_tlv_header)); eigrp_tlv_header = (const struct eigrp_tlv_header *)tptr; eigrp_tlv_len=EXTRACT_16BITS(&eigrp_tlv_header->length); eigrp_tlv_type=EXTRACT_16BITS(&eigrp_tlv_header->type); if (eigrp_tlv_len < sizeof(struct eigrp_tlv_header) || eigrp_tlv_len > tlen) { print_unknown_data(ndo,tptr+sizeof(struct eigrp_tlv_header),"\n\t ",tlen); return; } ND_PRINT((ndo, "\n\t %s TLV (0x%04x), length: %u", tok2str(eigrp_tlv_values, "Unknown", eigrp_tlv_type), eigrp_tlv_type, eigrp_tlv_len)); tlv_tptr=tptr+sizeof(struct eigrp_tlv_header); tlv_tlen=eigrp_tlv_len-sizeof(struct eigrp_tlv_header); /* did we capture enough for fully decoding the object ? */ ND_TCHECK2(*tptr, eigrp_tlv_len); switch(eigrp_tlv_type) { case EIGRP_TLV_GENERAL_PARM: tlv_ptr.eigrp_tlv_general_parm = (const struct eigrp_tlv_general_parm_t *)tlv_tptr; ND_PRINT((ndo, "\n\t holdtime: %us, k1 %u, k2 %u, k3 %u, k4 %u, k5 %u", EXTRACT_16BITS(tlv_ptr.eigrp_tlv_general_parm->holdtime), tlv_ptr.eigrp_tlv_general_parm->k1, tlv_ptr.eigrp_tlv_general_parm->k2, tlv_ptr.eigrp_tlv_general_parm->k3, tlv_ptr.eigrp_tlv_general_parm->k4, tlv_ptr.eigrp_tlv_general_parm->k5)); break; case EIGRP_TLV_SW_VERSION: tlv_ptr.eigrp_tlv_sw_version = (const struct eigrp_tlv_sw_version_t *)tlv_tptr; ND_PRINT((ndo, "\n\t IOS version: %u.%u, EIGRP version %u.%u", tlv_ptr.eigrp_tlv_sw_version->ios_major, tlv_ptr.eigrp_tlv_sw_version->ios_minor, tlv_ptr.eigrp_tlv_sw_version->eigrp_major, tlv_ptr.eigrp_tlv_sw_version->eigrp_minor)); break; case EIGRP_TLV_IP_INT: tlv_ptr.eigrp_tlv_ip_int = (const struct eigrp_tlv_ip_int_t *)tlv_tptr; bit_length = tlv_ptr.eigrp_tlv_ip_int->plen; if (bit_length > 32) { ND_PRINT((ndo, "\n\t illegal prefix length %u",bit_length)); break; } byte_length = (bit_length + 7) / 8; /* variable length encoding */ memset(prefix, 0, 4); memcpy(prefix,&tlv_ptr.eigrp_tlv_ip_int->destination,byte_length); ND_PRINT((ndo, "\n\t IPv4 prefix: %15s/%u, nexthop: ", ipaddr_string(ndo, prefix), bit_length)); if (EXTRACT_32BITS(&tlv_ptr.eigrp_tlv_ip_int->nexthop) == 0) ND_PRINT((ndo, "self")); else ND_PRINT((ndo, "%s",ipaddr_string(ndo, &tlv_ptr.eigrp_tlv_ip_int->nexthop))); ND_PRINT((ndo, "\n\t delay %u ms, bandwidth %u Kbps, mtu %u, hop %u, reliability %u, load %u", (EXTRACT_32BITS(&tlv_ptr.eigrp_tlv_ip_int->delay)/100), EXTRACT_32BITS(&tlv_ptr.eigrp_tlv_ip_int->bandwidth), EXTRACT_24BITS(&tlv_ptr.eigrp_tlv_ip_int->mtu), tlv_ptr.eigrp_tlv_ip_int->hopcount, tlv_ptr.eigrp_tlv_ip_int->reliability, tlv_ptr.eigrp_tlv_ip_int->load)); break; case EIGRP_TLV_IP_EXT: tlv_ptr.eigrp_tlv_ip_ext = (const struct eigrp_tlv_ip_ext_t *)tlv_tptr; bit_length = tlv_ptr.eigrp_tlv_ip_ext->plen; if (bit_length > 32) { ND_PRINT((ndo, "\n\t illegal prefix length %u",bit_length)); break; } byte_length = (bit_length + 7) / 8; /* variable length encoding */ memset(prefix, 0, 4); memcpy(prefix,&tlv_ptr.eigrp_tlv_ip_ext->destination,byte_length); ND_PRINT((ndo, "\n\t IPv4 prefix: %15s/%u, nexthop: ", ipaddr_string(ndo, prefix), bit_length)); if (EXTRACT_32BITS(&tlv_ptr.eigrp_tlv_ip_ext->nexthop) == 0) ND_PRINT((ndo, "self")); else ND_PRINT((ndo, "%s",ipaddr_string(ndo, &tlv_ptr.eigrp_tlv_ip_ext->nexthop))); ND_PRINT((ndo, "\n\t origin-router %s, origin-as %u, origin-proto %s, flags [0x%02x], tag 0x%08x, metric %u", ipaddr_string(ndo, tlv_ptr.eigrp_tlv_ip_ext->origin_router), EXTRACT_32BITS(tlv_ptr.eigrp_tlv_ip_ext->origin_as), tok2str(eigrp_ext_proto_id_values,"unknown",tlv_ptr.eigrp_tlv_ip_ext->proto_id), tlv_ptr.eigrp_tlv_ip_ext->flags, EXTRACT_32BITS(tlv_ptr.eigrp_tlv_ip_ext->tag), EXTRACT_32BITS(tlv_ptr.eigrp_tlv_ip_ext->metric))); ND_PRINT((ndo, "\n\t delay %u ms, bandwidth %u Kbps, mtu %u, hop %u, reliability %u, load %u", (EXTRACT_32BITS(&tlv_ptr.eigrp_tlv_ip_ext->delay)/100), EXTRACT_32BITS(&tlv_ptr.eigrp_tlv_ip_ext->bandwidth), EXTRACT_24BITS(&tlv_ptr.eigrp_tlv_ip_ext->mtu), tlv_ptr.eigrp_tlv_ip_ext->hopcount, tlv_ptr.eigrp_tlv_ip_ext->reliability, tlv_ptr.eigrp_tlv_ip_ext->load)); break; case EIGRP_TLV_AT_CABLE_SETUP: tlv_ptr.eigrp_tlv_at_cable_setup = (const struct eigrp_tlv_at_cable_setup_t *)tlv_tptr; ND_PRINT((ndo, "\n\t Cable-range: %u-%u, Router-ID %u", EXTRACT_16BITS(&tlv_ptr.eigrp_tlv_at_cable_setup->cable_start), EXTRACT_16BITS(&tlv_ptr.eigrp_tlv_at_cable_setup->cable_end), EXTRACT_32BITS(&tlv_ptr.eigrp_tlv_at_cable_setup->router_id))); break; case EIGRP_TLV_AT_INT: tlv_ptr.eigrp_tlv_at_int = (const struct eigrp_tlv_at_int_t *)tlv_tptr; ND_PRINT((ndo, "\n\t Cable-Range: %u-%u, nexthop: ", EXTRACT_16BITS(&tlv_ptr.eigrp_tlv_at_int->cable_start), EXTRACT_16BITS(&tlv_ptr.eigrp_tlv_at_int->cable_end))); if (EXTRACT_32BITS(&tlv_ptr.eigrp_tlv_at_int->nexthop) == 0) ND_PRINT((ndo, "self")); else ND_PRINT((ndo, "%u.%u", EXTRACT_16BITS(&tlv_ptr.eigrp_tlv_at_int->nexthop), EXTRACT_16BITS(&tlv_ptr.eigrp_tlv_at_int->nexthop[2]))); ND_PRINT((ndo, "\n\t delay %u ms, bandwidth %u Kbps, mtu %u, hop %u, reliability %u, load %u", (EXTRACT_32BITS(&tlv_ptr.eigrp_tlv_at_int->delay)/100), EXTRACT_32BITS(&tlv_ptr.eigrp_tlv_at_int->bandwidth), EXTRACT_24BITS(&tlv_ptr.eigrp_tlv_at_int->mtu), tlv_ptr.eigrp_tlv_at_int->hopcount, tlv_ptr.eigrp_tlv_at_int->reliability, tlv_ptr.eigrp_tlv_at_int->load)); break; case EIGRP_TLV_AT_EXT: tlv_ptr.eigrp_tlv_at_ext = (const struct eigrp_tlv_at_ext_t *)tlv_tptr; ND_PRINT((ndo, "\n\t Cable-Range: %u-%u, nexthop: ", EXTRACT_16BITS(&tlv_ptr.eigrp_tlv_at_ext->cable_start), EXTRACT_16BITS(&tlv_ptr.eigrp_tlv_at_ext->cable_end))); if (EXTRACT_32BITS(&tlv_ptr.eigrp_tlv_at_ext->nexthop) == 0) ND_PRINT((ndo, "self")); else ND_PRINT((ndo, "%u.%u", EXTRACT_16BITS(&tlv_ptr.eigrp_tlv_at_ext->nexthop), EXTRACT_16BITS(&tlv_ptr.eigrp_tlv_at_ext->nexthop[2]))); ND_PRINT((ndo, "\n\t origin-router %u, origin-as %u, origin-proto %s, flags [0x%02x], tag 0x%08x, metric %u", EXTRACT_32BITS(tlv_ptr.eigrp_tlv_at_ext->origin_router), EXTRACT_32BITS(tlv_ptr.eigrp_tlv_at_ext->origin_as), tok2str(eigrp_ext_proto_id_values,"unknown",tlv_ptr.eigrp_tlv_at_ext->proto_id), tlv_ptr.eigrp_tlv_at_ext->flags, EXTRACT_32BITS(tlv_ptr.eigrp_tlv_at_ext->tag), EXTRACT_16BITS(tlv_ptr.eigrp_tlv_at_ext->metric))); ND_PRINT((ndo, "\n\t delay %u ms, bandwidth %u Kbps, mtu %u, hop %u, reliability %u, load %u", (EXTRACT_32BITS(&tlv_ptr.eigrp_tlv_at_ext->delay)/100), EXTRACT_32BITS(&tlv_ptr.eigrp_tlv_at_ext->bandwidth), EXTRACT_24BITS(&tlv_ptr.eigrp_tlv_at_ext->mtu), tlv_ptr.eigrp_tlv_at_ext->hopcount, tlv_ptr.eigrp_tlv_at_ext->reliability, tlv_ptr.eigrp_tlv_at_ext->load)); break; /* * FIXME those are the defined TLVs that lack a decoder * you are welcome to contribute code ;-) */ case EIGRP_TLV_AUTH: case EIGRP_TLV_SEQ: case EIGRP_TLV_MCAST_SEQ: case EIGRP_TLV_IPX_INT: case EIGRP_TLV_IPX_EXT: default: if (ndo->ndo_vflag <= 1) print_unknown_data(ndo,tlv_tptr,"\n\t ",tlv_tlen); break; } /* do we want to see an additionally hexdump ? */ if (ndo->ndo_vflag > 1) print_unknown_data(ndo,tptr+sizeof(struct eigrp_tlv_header),"\n\t ", eigrp_tlv_len-sizeof(struct eigrp_tlv_header)); tptr+=eigrp_tlv_len; tlen-=eigrp_tlv_len; } return; trunc: ND_PRINT((ndo, "\n\t\t packet exceeded snapshot")); }
static void print_attr_num(register u_char *data, u_int length, u_short attr_code ) { u_int8_t tag; u_int32_t timeout; if (length != 4) { printf("ERROR: length %u != 4", length); return; } TCHECK2(data[0],4); /* This attribute has standard values */ if (attr_type[attr_code].siz_subtypes) { static const char **table; u_int32_t data_value; table = attr_type[attr_code].subtypes; if ( (attr_code == TUNNEL_TYPE) || (attr_code == TUNNEL_MEDIUM) ) { if (!*data) printf("Tag[Unused]"); else printf("Tag[%d]", *data); data++; data_value = EXTRACT_24BITS(data); } else { data_value = EXTRACT_32BITS(data); } if ( data_value <= (u_int32_t)(attr_type[attr_code].siz_subtypes - 1 + attr_type[attr_code].first_subtype) && data_value >= attr_type[attr_code].first_subtype ) printf("%s",table[data_value]); else printf("#%u",data_value); } else { switch(attr_code) /* Be aware of special cases... */ { case FRM_IPX: if (EXTRACT_32BITS( data) == 0xFFFFFFFE ) printf("NAS Select"); else printf("%d",EXTRACT_32BITS( data) ); break; case SESSION_TIMEOUT: case IDLE_TIMEOUT: case ACCT_DELAY: case ACCT_SESSION_TIME: case ACCT_INT_INTERVAL: timeout = EXTRACT_32BITS( data); if ( timeout < 60 ) printf( "%02d secs", timeout); else { if ( timeout < 3600 ) printf( "%02d:%02d min", timeout / 60, timeout % 60); else printf( "%02d:%02d:%02d hours", timeout / 3600, (timeout % 3600) / 60, timeout % 60); } break; case FRM_ATALK_LINK: if (EXTRACT_32BITS(data) ) printf("%d",EXTRACT_32BITS(data) ); else printf("Unnumbered" ); break; case FRM_ATALK_NETWORK: if (EXTRACT_32BITS(data) ) printf("%d",EXTRACT_32BITS(data) ); else printf("NAS assigned" ); break; case TUNNEL_PREFERENCE: tag = *data; data++; if (tag == 0) printf("Tag (Unused) %d",EXTRACT_24BITS(data) ); else printf("Tag (%d) %d", tag, EXTRACT_24BITS(data) ); break; default: printf("%d",EXTRACT_32BITS( data) ); break; } /* switch */ } /* if-else */ return; trunc: printf(" [|radius]"); }
void slow_oam_print(register const u_char *tptr, register u_int tlen) { u_int hexdump; struct slow_oam_common_header_t { u_int8_t flags[2]; u_int8_t code; }; struct slow_oam_tlv_header_t { u_int8_t type; u_int8_t length; }; union { const struct slow_oam_common_header_t *slow_oam_common_header; const struct slow_oam_tlv_header_t *slow_oam_tlv_header; } ptr; union { const struct slow_oam_info_t *slow_oam_info; const struct slow_oam_link_event_t *slow_oam_link_event; const struct slow_oam_variablerequest_t *slow_oam_variablerequest; const struct slow_oam_variableresponse_t *slow_oam_variableresponse; const struct slow_oam_loopbackctrl_t *slow_oam_loopbackctrl; } tlv; ptr.slow_oam_common_header = (struct slow_oam_common_header_t *)tptr; tptr += sizeof(struct slow_oam_common_header_t); tlen -= sizeof(struct slow_oam_common_header_t); printf("\n\tCode %s OAM PDU, Flags [%s]", tok2str(slow_oam_code_values, "Unknown (%u)", ptr.slow_oam_common_header->code), bittok2str(slow_oam_flag_values, "none", EXTRACT_16BITS(&ptr.slow_oam_common_header->flags))); switch (ptr.slow_oam_common_header->code) { case SLOW_OAM_CODE_INFO: while (tlen > 0) { ptr.slow_oam_tlv_header = (const struct slow_oam_tlv_header_t *)tptr; printf("\n\t %s Information Type (%u), length %u", tok2str(slow_oam_info_type_values, "Reserved", ptr.slow_oam_tlv_header->type), ptr.slow_oam_tlv_header->type, ptr.slow_oam_tlv_header->length); hexdump = FALSE; switch (ptr.slow_oam_tlv_header->type) { case SLOW_OAM_INFO_TYPE_END_OF_TLV: if (ptr.slow_oam_tlv_header->length != 0) { printf("\n\t ERROR: illegal length - should be 0"); } return; case SLOW_OAM_INFO_TYPE_LOCAL: /* identical format - fall through */ case SLOW_OAM_INFO_TYPE_REMOTE: tlv.slow_oam_info = (const struct slow_oam_info_t *)tptr; if (tlv.slow_oam_info->info_length != sizeof(struct slow_oam_info_t)) { printf("\n\t ERROR: illegal length - should be %lu", (unsigned long) sizeof(struct slow_oam_info_t)); return; } printf("\n\t OAM-Version %u, Revision %u", tlv.slow_oam_info->oam_version, EXTRACT_16BITS(&tlv.slow_oam_info->revision)); printf("\n\t State-Parser-Action %s, State-MUX-Action %s", tok2str(slow_oam_info_type_state_parser_values, "Reserved", tlv.slow_oam_info->state & OAM_INFO_TYPE_PARSER_MASK), tok2str(slow_oam_info_type_state_mux_values, "Reserved", tlv.slow_oam_info->state & OAM_INFO_TYPE_MUX_MASK)); printf("\n\t OAM-Config Flags [%s], OAM-PDU-Config max-PDU size %u", bittok2str(slow_oam_info_type_oam_config_values, "none", tlv.slow_oam_info->oam_config), EXTRACT_16BITS(&tlv.slow_oam_info->oam_pdu_config) & OAM_INFO_TYPE_PDU_SIZE_MASK); printf("\n\t OUI %s (0x%06x), Vendor-Private 0x%08x", tok2str(oui_values, "Unknown", EXTRACT_24BITS(&tlv.slow_oam_info->oui)), EXTRACT_24BITS(&tlv.slow_oam_info->oui), EXTRACT_32BITS(&tlv.slow_oam_info->vendor_private)); break; case SLOW_OAM_INFO_TYPE_ORG_SPECIFIC: hexdump = TRUE; break; default: hexdump = TRUE; break; } /* infinite loop check */ if (!ptr.slow_oam_tlv_header->length) { return; } /* do we also want to see a hex dump ? */ if (vflag > 1 || hexdump==TRUE) { print_unknown_data(tptr,"\n\t ", ptr.slow_oam_tlv_header->length); } tlen -= ptr.slow_oam_tlv_header->length; tptr += ptr.slow_oam_tlv_header->length; } break; case SLOW_OAM_CODE_EVENT_NOTIF: while (tlen > 0) { ptr.slow_oam_tlv_header = (const struct slow_oam_tlv_header_t *)tptr; printf("\n\t %s Link Event Type (%u), length %u", tok2str(slow_oam_link_event_values, "Reserved", ptr.slow_oam_tlv_header->type), ptr.slow_oam_tlv_header->type, ptr.slow_oam_tlv_header->length); hexdump = FALSE; switch (ptr.slow_oam_tlv_header->type) { case SLOW_OAM_LINK_EVENT_END_OF_TLV: if (ptr.slow_oam_tlv_header->length != 0) { printf("\n\t ERROR: illegal length - should be 0"); } return; case SLOW_OAM_LINK_EVENT_ERR_SYM_PER: /* identical format - fall through */ case SLOW_OAM_LINK_EVENT_ERR_FRM: case SLOW_OAM_LINK_EVENT_ERR_FRM_PER: case SLOW_OAM_LINK_EVENT_ERR_FRM_SUMM: tlv.slow_oam_link_event = (const struct slow_oam_link_event_t *)tptr; if (tlv.slow_oam_link_event->event_length != sizeof(struct slow_oam_link_event_t)) { printf("\n\t ERROR: illegal length - should be %lu", (unsigned long) sizeof(struct slow_oam_link_event_t)); return; } printf("\n\t Timestamp %u ms, Errored Window %" PRIu64 "\n\t Errored Threshold %" PRIu64 "\n\t Errors %" PRIu64 "\n\t Error Running Total %" PRIu64 "\n\t Event Running Total %u", EXTRACT_16BITS(&tlv.slow_oam_link_event->time_stamp)*100, EXTRACT_64BITS(&tlv.slow_oam_link_event->window), EXTRACT_64BITS(&tlv.slow_oam_link_event->threshold), EXTRACT_64BITS(&tlv.slow_oam_link_event->errors), EXTRACT_64BITS(&tlv.slow_oam_link_event->errors_running_total), EXTRACT_32BITS(&tlv.slow_oam_link_event->event_running_total)); break; case SLOW_OAM_LINK_EVENT_ORG_SPECIFIC: hexdump = TRUE; break; default: hexdump = TRUE; break; } /* infinite loop check */ if (!ptr.slow_oam_tlv_header->length) { return; } /* do we also want to see a hex dump ? */ if (vflag > 1 || hexdump==TRUE) { print_unknown_data(tptr,"\n\t ", ptr.slow_oam_tlv_header->length); } tlen -= ptr.slow_oam_tlv_header->length; tptr += ptr.slow_oam_tlv_header->length; } break; case SLOW_OAM_CODE_LOOPBACK_CTRL: tlv.slow_oam_loopbackctrl = (const struct slow_oam_loopbackctrl_t *)tptr; printf("\n\t Command %s (%u)", tok2str(slow_oam_loopbackctrl_cmd_values, "Unknown", tlv.slow_oam_loopbackctrl->command), tlv.slow_oam_loopbackctrl->command); tptr ++; tlen --; break; /* * FIXME those are the defined codes that lack a decoder * you are welcome to contribute code ;-) */ case SLOW_OAM_CODE_VAR_REQUEST: case SLOW_OAM_CODE_VAR_RESPONSE: case SLOW_OAM_CODE_PRIVATE: default: if (vflag <= 1) { print_unknown_data(tptr,"\n\t ", tlen); } break; } return; }
/* * This is the top level routine of the printer. 'p' points * to the LLC/SNAP header of the packet, 'h->ts' is the timestamp, * 'h->len' is the length of the packet off the wire, and 'h->caplen' * is the number of bytes actually captured. */ u_int atm_if_print(const struct pcap_pkthdr *h, const u_char *p) { u_int caplen = h->caplen; u_int length = h->len; u_int32_t llchdr; u_int hdrlen = 0; if (caplen < 8) { printf("[|atm]"); return (caplen); } /* Cisco Style NLPID ? */ if (*p == LLC_UI) { if (eflag) printf("CNLPID "); isoclns_print(p+1, length-1, caplen-1); return hdrlen; } /* * Extract the presumed LLC header into a variable, for quick * testing. * Then check for a header that's neither a header for a SNAP * packet nor an RFC 2684 routed NLPID-formatted PDU nor * an 802.2-but-no-SNAP IP packet. */ llchdr = EXTRACT_24BITS(p); if (llchdr != LLC_UI_HDR(LLCSAP_SNAP) && llchdr != LLC_UI_HDR(LLCSAP_ISONS) && llchdr != LLC_UI_HDR(LLCSAP_IP)) { /* * XXX - assume 802.6 MAC header from Fore driver. * * Unfortunately, the above list doesn't check for * all known SAPs, doesn't check for headers where * the source and destination SAP aren't the same, * and doesn't check for non-UI frames. It also * runs the risk of an 802.6 MAC header that happens * to begin with one of those values being * incorrectly treated as an 802.2 header. * * So is that Fore driver still around? And, if so, * is it still putting 802.6 MAC headers on ATM * packets? If so, could it be changed to use a * new DLT_IEEE802_6 value if we added it? */ if (eflag) printf("%08x%08x %08x%08x ", EXTRACT_32BITS(p), EXTRACT_32BITS(p+4), EXTRACT_32BITS(p+8), EXTRACT_32BITS(p+12)); p += 20; length -= 20; caplen -= 20; hdrlen += 20; } atm_llc_print(p, length, caplen); return (hdrlen); }
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, offset; #ifdef DLT_JUNIPER_ATM2 u_int32_t control_word; #endif l2info->header_len = 0; l2info->cookie_len = 0; l2info->proto = 0; l2info->length = h->len; l2info->caplen = h->caplen; l2info->direction = p[3]&JUNIPER_BPF_PKT_IN; TCHECK2(p[0],4); if (EXTRACT_24BITS(p) != JUNIPER_MGC_NUMBER) { printf("no magic-number found!"); return 0; } if (eflag) printf("%3s ",tok2str(juniper_direction_values,"---",l2info->direction)); 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, "); 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=offset+4; return 0; } l2info->header_len = offset; p+=l2info->header_len; l2info->length -= l2info->header_len; l2info->caplen -= l2info->header_len; while (lp->s != NULL) { if (lp->pictype == l2info->pictype) { l2info->cookie_len += lp->cookie_len; switch (p[0]) { case LS_COOKIE_ID: l2info->cookie_type = LS_COOKIE_ID; l2info->cookie_len += 2; break; case AS_COOKIE_ID: l2info->cookie_type = AS_COOKIE_ID; l2info->cookie_len = 8; break; default: l2info->bundle = l2info->cookie[0]; break; } #ifdef DLT_JUNIPER_MFR 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, l2info->cookie_len); if (l2info->cookie_len > 0) { TCHECK2(p[0],l2info->cookie_len); if (eflag) printf(", cookie 0x"); for (idx = 0; idx < l2info->cookie_len; idx++) { l2info->cookie[idx] = p[idx]; if (eflag) printf("%02x",p[idx]); } } if (eflag) printf(": "); l2info->proto = EXTRACT_16BITS(p+l2info->cookie_len); break; } ++lp; } p+=l2info->cookie_len; switch(l2info->pictype) { #ifdef DLT_JUNIPER_MLPPP case DLT_JUNIPER_MLPPP: switch (l2info->cookie_type) { case LS_COOKIE_ID: l2info->bundle = l2info->cookie[1]; 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; } break; #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; } break; #endif #ifdef DLT_JUNIPER_ATM2 case DLT_JUNIPER_ATM2: TCHECK2(p[0],4); if (l2info->cookie[7] & ATM2_PKT_TYPE_MASK) { control_word = EXTRACT_32BITS(p); switch(control_word) { case 0: case 0x08000000: case 0x08380000: l2info->header_len += 4; break; default: break; } if (eflag) printf("control-word 0x%08x ", control_word); } break; #endif #ifdef DLT_JUNIPER_ATM1 case DLT_JUNIPER_ATM1: break; #endif #ifdef DLT_JUNIPER_PPP case DLT_JUNIPER_PPP: break; #endif #ifdef DLT_JUNIPER_CHDLC case DLT_JUNIPER_CHDLC: break; #endif #ifdef DLT_JUNIPER_ETHER case DLT_JUNIPER_ETHER: break; #endif #ifdef DLT_JUNIPER_FRELAY case DLT_JUNIPER_FRELAY: break; #endif default: printf("Unknown Juniper DLT_ type %u: ", l2info->pictype); break; } if (eflag > 1) printf("hlen %u, proto 0x%04x, ",l2info->header_len,l2info->proto); return 1; trunc: printf("[|juniper_hdr], length %u",h->len); return 0; }
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, offset; #ifdef DLT_JUNIPER_ATM2 u_int32_t control_word; #endif l2info->header_len = 0; l2info->cookie_len = 0; l2info->proto = 0; l2info->length = h->len; l2info->caplen = h->caplen; l2info->direction = p[3]&JUNIPER_BPF_PKT_IN; TCHECK2(p[0],4); if (EXTRACT_24BITS(p) != JUNIPER_MGC_NUMBER) { /* magic number found ? */ printf("no magic-number found!"); return 0; } 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, "); /* there is no link-layer present - * perform the v4/v6 heuristics * to figure out what it is */ 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=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; /* search through the cookie table and copy values matching for our PIC type */ while (lp->s != NULL) { if (lp->pictype == l2info->pictype) { l2info->cookie_len += lp->cookie_len; switch (p[0]) { case LS_COOKIE_ID: l2info->cookie_type = LS_COOKIE_ID; l2info->cookie_len += 2; break; case AS_COOKIE_ID: l2info->cookie_type = AS_COOKIE_ID; l2info->cookie_len = 8; break; default: l2info->bundle = l2info->cookie[0]; 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, l2info->cookie_len); if (l2info->cookie_len > 0) { TCHECK2(p[0],l2info->cookie_len); if (eflag) printf(", cookie 0x"); for (idx = 0; idx < l2info->cookie_len; idx++) { l2info->cookie[idx] = p[idx]; /* copy cookie data */ if (eflag) printf("%02x",p[idx]); } } if (eflag) printf(": "); /* print demarc b/w L2/L3*/ l2info->proto = EXTRACT_16BITS(p+l2info->cookie_len); break; } ++lp; } p+=l2info->cookie_len; /* DLT_ specific parsing */ switch(l2info->pictype) { #ifdef DLT_JUNIPER_MLPPP case DLT_JUNIPER_MLPPP: switch (l2info->cookie_type) { case LS_COOKIE_ID: l2info->bundle = l2info->cookie[1]; 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; } break; #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; } break; #endif #ifdef DLT_JUNIPER_ATM2 case DLT_JUNIPER_ATM2: TCHECK2(p[0],4); /* ATM cell relay control word present ? */ if (l2info->cookie[7] & ATM2_PKT_TYPE_MASK) { control_word = EXTRACT_32BITS(p); /* some control word heuristics */ switch(control_word) { case 0: /* zero control word */ case 0x08000000: /* < JUNOS 7.4 control-word */ case 0x08380000: /* cntl word plus cell length (56) >= JUNOS 7.4*/ l2info->header_len += 4; break; default: break; } if (eflag) printf("control-word 0x%08x ", control_word); } break; #endif #ifdef DLT_JUNIPER_ATM1 case DLT_JUNIPER_ATM1: break; #endif #ifdef DLT_JUNIPER_PPP case DLT_JUNIPER_PPP: break; #endif #ifdef DLT_JUNIPER_CHDLC case DLT_JUNIPER_CHDLC: break; #endif #ifdef DLT_JUNIPER_ETHER case DLT_JUNIPER_ETHER: break; #endif #ifdef DLT_JUNIPER_FRELAY case DLT_JUNIPER_FRELAY: break; #endif default: printf("Unknown Juniper DLT_ type %u: ", l2info->pictype); break; } if (eflag > 1) printf("hlen %u, proto 0x%04x, ",l2info->header_len,l2info->proto); return 1; /* everything went ok so far. continue parsing */ trunc: printf("[|juniper_hdr], length %u",h->len); return 0; }
static void print_attr_num(netdissect_options *ndo, register u_char *data, u_int length, u_short attr_code) { uint32_t timeout; if (length != 4) { ND_PRINT((ndo, "ERROR: length %u != 4", length)); return; } ND_TCHECK2(data[0],4); /* This attribute has standard values */ if (attr_type[attr_code].siz_subtypes) { static const char **table; uint32_t data_value; table = attr_type[attr_code].subtypes; if ( (attr_code == TUNNEL_TYPE) || (attr_code == TUNNEL_MEDIUM) ) { if (!*data) ND_PRINT((ndo, "Tag[Unused] ")); else ND_PRINT((ndo, "Tag[%d] ", *data)); data++; data_value = EXTRACT_24BITS(data); } else { data_value = EXTRACT_32BITS(data); } if ( data_value <= (uint32_t)(attr_type[attr_code].siz_subtypes - 1 + attr_type[attr_code].first_subtype) && data_value >= attr_type[attr_code].first_subtype ) ND_PRINT((ndo, "%s", table[data_value])); else ND_PRINT((ndo, "#%u", data_value)); } else { switch(attr_code) /* Be aware of special cases... */ { case FRM_IPX: if (EXTRACT_32BITS( data) == 0xFFFFFFFE ) ND_PRINT((ndo, "NAS Select")); else ND_PRINT((ndo, "%d", EXTRACT_32BITS(data))); break; case SESSION_TIMEOUT: case IDLE_TIMEOUT: case ACCT_DELAY: case ACCT_SESSION_TIME: case ACCT_INT_INTERVAL: timeout = EXTRACT_32BITS( data); if ( timeout < 60 ) ND_PRINT((ndo, "%02d secs", timeout)); else { if ( timeout < 3600 ) ND_PRINT((ndo, "%02d:%02d min", timeout / 60, timeout % 60)); else ND_PRINT((ndo, "%02d:%02d:%02d hours", timeout / 3600, (timeout % 3600) / 60, timeout % 60)); } break; case FRM_ATALK_LINK: if (EXTRACT_32BITS(data) ) ND_PRINT((ndo, "%d", EXTRACT_32BITS(data))); else ND_PRINT((ndo, "Unnumbered")); break; case FRM_ATALK_NETWORK: if (EXTRACT_32BITS(data) ) ND_PRINT((ndo, "%d", EXTRACT_32BITS(data))); else ND_PRINT((ndo, "NAS assigned")); break; case TUNNEL_PREFERENCE: if (*data) ND_PRINT((ndo, "Tag[%d] ", *data)); else ND_PRINT((ndo, "Tag[Unused] ")); data++; ND_PRINT((ndo, "%d", EXTRACT_24BITS(data))); break; case EGRESS_VLAN_ID: ND_PRINT((ndo, "%s (0x%02x) ", tok2str(rfc4675_tagged,"Unknown tag",*data), *data)); data++; ND_PRINT((ndo, "%d", EXTRACT_24BITS(data))); break; default: ND_PRINT((ndo, "%d", EXTRACT_32BITS(data))); break; } /* switch */ } /* if-else */ return; trunc: ND_PRINT((ndo, "%s", tstr)); }