u_int juniper_mlfr_print(const struct pcap_pkthdr *h, packetbody_t p) { struct juniper_l2info_t l2info; l2info.pictype = DLT_JUNIPER_MLFR; if(juniper_parse_header(p, h, &l2info) == 0) return l2info.header_len; p+=l2info.header_len; /* suppress Bundle-ID if frame was captured on a child-link */ if (eflag && EXTRACT_32BITS(cheri_ptr(l2info.cookie, 4)) != 1) printf("Bundle-ID %u, ",l2info.bundle); switch (l2info.proto) { case (LLC_UI): case (LLC_UI<<8): isoclns_print(p, l2info.length, l2info.caplen); break; case (LLC_UI<<8 | NLPID_Q933): case (LLC_UI<<8 | NLPID_IP): case (LLC_UI<<8 | NLPID_IP6): /* pass IP{4,6} to the OSI layer for proper link-layer printing */ isoclns_print(PACKET_SUBTRACT(p, 1), l2info.length+1, l2info.caplen+1); break; default: printf("unknown protocol 0x%04x, length %u",l2info.proto, l2info.length); } return l2info.header_len; }
u_int juniper_mfr_print(const struct pcap_pkthdr *h, packetbody_t p) { struct juniper_l2info_t l2info; l2info.pictype = DLT_JUNIPER_MFR; if(juniper_parse_header(p, h, &l2info) == 0) 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(gndo, 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(cheri_ptr(l2info.cookie, 4)) != 1) printf("Bundle-ID %u, ",l2info.bundle); switch (l2info.proto) { case (LLCSAP_ISONS<<8 | LLCSAP_ISONS): isoclns_print(p+1, l2info.length-1, l2info.caplen-1); break; case (LLC_UI<<8 | NLPID_Q933): case (LLC_UI<<8 | NLPID_IP): case (LLC_UI<<8 | NLPID_IP6): /* pass IP{4,6} to the OSI layer for proper link-layer printing */ isoclns_print(PACKET_SUBTRACT(p, 1), l2info.length+1, l2info.caplen+1); break; default: printf("unknown protocol 0x%04x, length %u",l2info.proto, l2info.length); } return l2info.header_len; }
u_int juniper_mlppp_print(const struct pcap_pkthdr *h, packetbody_t p) { struct juniper_l2info_t l2info; l2info.pictype = DLT_JUNIPER_MLPPP; if(juniper_parse_header(p, h, &l2info) == 0) return l2info.header_len; /* suppress Bundle-ID if frame was captured on a child-link * best indicator if the cookie looks like a proto */ if (eflag && EXTRACT_16BITS(cheri_ptr(&l2info.cookie, 2)) != PPP_OSI && EXTRACT_16BITS(cheri_ptr(&l2info.cookie, 2)) != (PPP_ADDRESS << 8 | PPP_CONTROL)) printf("Bundle-ID %u: ",l2info.bundle); p+=l2info.header_len; /* first try the LSQ protos */ switch(l2info.proto) { case JUNIPER_LSQ_L3_PROTO_IPV4: /* 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(gndo, 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; } /* zero length cookie ? */ switch (EXTRACT_16BITS(cheri_ptr(&l2info.cookie, 2))) { case PPP_OSI: ppp_print(PACKET_SUBTRACT(p,2),l2info.length+2); break; case (PPP_ADDRESS << 8 | PPP_CONTROL): /* fall through */ default: ppp_print(p,l2info.length); break; } return l2info.header_len; }
/* generic Control Protocol (e.g. LCP, IPCP, CCP, etc.) handler */ static void handle_ctrl_proto(u_int proto, packetbody_t pptr, int length) { const char *typestr; u_int code, len; int (*pfunc)(packetbody_t, int); int x, j; packetbody_t tptr; tptr=pptr; typestr = tok2str(ppptype2str, "unknown ctrl-proto (0x%04x)", proto); printf("%s, ",typestr); if (length < 4) /* FIXME weak boundary checking */ goto trunc; PACKET_HAS_SPACE_OR_TRUNC(tptr, 2); code = *tptr++; printf("%s (0x%02x), id %u, length %u", tok2str(cpcodes, "Unknown Opcode",code), code, *tptr++, /* ID */ length+2); if (!vflag) return; if (length <= 4) return; /* there may be a NULL confreq etc. */ PACKET_HAS_SPACE_OR_TRUNC(tptr, 2); len = EXTRACT_16BITS(tptr); tptr += 2; printf("\n\tencoded length %u (=Option(s) length %u)",len,len-4); if (vflag>1) print_unknown_data(PACKET_SUBTRACT(pptr,2), "\n\t", 6); switch (code) { case CPCODES_VEXT: if (length < 11) break; PACKET_HAS_SPACE_OR_TRUNC(tptr, 4); printf("\n\t Magic-Num 0x%08x", EXTRACT_32BITS(tptr)); tptr += 4; PACKET_HAS_SPACE_OR_TRUNC(tptr, 3); printf(" Vendor: %s (%u)", tok2str(oui_values,"Unknown",EXTRACT_24BITS(tptr)), EXTRACT_24BITS(tptr)); /* XXX: need to decode Kind and Value(s)? */ break; case CPCODES_CONF_REQ: case CPCODES_CONF_ACK: case CPCODES_CONF_NAK: case CPCODES_CONF_REJ: x = len - 4; /* Code(1), Identifier(1) and Length(2) */ do { switch (proto) { case PPP_LCP: pfunc = print_lcp_config_options; break; case PPP_IPCP: pfunc = print_ipcp_config_options; break; case PPP_IPV6CP: pfunc = print_ip6cp_config_options; break; case PPP_CCP: pfunc = print_ccp_config_options; break; case PPP_BACP: pfunc = print_bacp_config_options; break; default: /* * No print routine for the options for * this protocol. */ pfunc = NULL; break; } if (pfunc == NULL) /* catch the above null pointer if unknown CP */ break; if ((j = (*pfunc)(tptr, len)) == 0) break; x -= j; tptr += j; } while (x > 0); break; case CPCODES_TERM_REQ: case CPCODES_TERM_ACK: /* XXX: need to decode Data? */ break; case CPCODES_CODE_REJ: /* XXX: need to decode Rejected-Packet? */ break; case CPCODES_PROT_REJ: if (length < 6) break; PACKET_HAS_SPACE_OR_TRUNC(tptr, 2); printf("\n\t Rejected %s Protocol (0x%04x)", tok2str(ppptype2str,"unknown", EXTRACT_16BITS(tptr)), EXTRACT_16BITS(tptr)); /* XXX: need to decode Rejected-Information? - hexdump for now */ if (len > 6) { printf("\n\t Rejected Packet"); print_unknown_data(tptr+2,"\n\t ",len-2); } break; case CPCODES_ECHO_REQ: case CPCODES_ECHO_RPL: case CPCODES_DISC_REQ: if (length < 8) break; PACKET_HAS_SPACE_OR_TRUNC(tptr, 4); printf("\n\t Magic-Num 0x%08x", EXTRACT_32BITS(tptr)); /* XXX: need to decode Data? - hexdump for now */ if (len > 8) { printf("\n\t -----trailing data-----"); PACKET_HAS_SPACE_OR_TRUNC(tptr, 4 + len-8); print_unknown_data(tptr+4,"\n\t ",len-8); } break; case CPCODES_ID: if (length < 8) break; PACKET_HAS_SPACE_OR_TRUNC(tptr, 4); printf("\n\t Magic-Num 0x%08x", EXTRACT_32BITS(tptr)); /* RFC 1661 says this is intended to be human readable */ if (len > 8) { printf("\n\t Message\n\t "); fn_printn(tptr+4,len-4,snapend); } break; case CPCODES_TIME_REM: if (length < 12) break; PACKET_HAS_SPACE_OR_TRUNC(tptr, 4); printf("\n\t Magic-Num 0x%08x", EXTRACT_32BITS(tptr)); PACKET_HAS_SPACE_OR_TRUNC(tptr, 8); printf(", Seconds-Remaining %us", EXTRACT_32BITS(tptr + 4)); /* XXX: need to decode Message? */ break; default: /* XXX this is dirty but we do not get the * original pointer passed to the begin * the PPP packet */ if (vflag <= 1) print_unknown_data(PACKET_SUBTRACT(pptr, 2), "\n\t ", length+2); break; } return; trunc: printf("[|%s]", typestr); }