?? print-ppp.c
字號:
return 0; if (len < 2) { printf("\n\t %s Option (0x%02x), length %u (bogus, should be >= 2)", tok2str(ccpconfopts_values, "Unknown", opt), opt, len); return 0; } printf("\n\t %s Option (0x%02x), length %u:", tok2str(ccpconfopts_values, "Unknown", opt), opt, len); switch (opt) { /* fall through --> default: nothing supported yet */ case CCPOPT_OUI: case CCPOPT_PRED1: case CCPOPT_PRED2: case CCPOPT_PJUMP: case CCPOPT_HPPPC: case CCPOPT_STACLZS: case CCPOPT_MPPC: case CCPOPT_GFZA: case CCPOPT_V42BIS: case CCPOPT_BSDCOMP: case CCPOPT_LZSDCP: case CCPOPT_MVRCA: case CCPOPT_DEC: case CCPOPT_DEFLATE: case CCPOPT_RESV: default: if(vflag<2) print_unknown_data(&p[2],"\n\t ",len-2); break; } if (vflag>1) print_unknown_data(&p[2],"\n\t ",len-2); /* exclude TLV header */ return len;trunc: printf("[|ccp]"); return 0;}/* BACP config options */static intprint_bacp_config_options(const u_char *p, int length){ int len, opt; if (length < 2) return 0; TCHECK2(*p, 2); len = p[1]; opt = p[0]; if (length < len) return 0; if (len < 2) { printf("\n\t %s Option (0x%02x), length %u (bogus, should be >= 2)", tok2str(bacconfopts_values, "Unknown", opt), opt, len); return 0; } printf("\n\t %s Option (0x%02x), length %u:", tok2str(bacconfopts_values, "Unknown", opt), opt, len); switch (opt) { case BACPOPT_FPEER: TCHECK2(*(p + 2), 4); printf(", Magic-Num 0x%08x", EXTRACT_32BITS(p + 2)); break; default: if(vflag<2) print_unknown_data(&p[2],"\n\t ",len-2); break; } if (vflag>1) print_unknown_data(&p[2],"\n\t ",len-2); /* exclude TLV header */ return len;trunc: printf("[|bacp]"); return 0;}static voidppp_hdlc(const u_char *p, int length){ u_char *b, *s, *t, c; int i, proto; const void *se; b = (u_int8_t *)malloc(length); if (b == NULL) return; /* * Unescape all the data into a temporary, private, buffer. * Do this so that we dont overwrite the original packet * contents. */ for (s = (u_char *)p, t = b, i = length; i > 0; i--) { c = *s++; if (c == 0x7d) { if (i > 1) { i--; c = *s++ ^ 0x20; } else continue; } *t++ = c; } se = snapend; snapend = t; /* now lets guess about the payload codepoint format */ proto = *b; /* start with a one-octet codepoint guess */ switch (proto) { case PPP_IP: ip_print(gndo, b+1, t - b - 1); goto cleanup;#ifdef INET6 case PPP_IPV6: ip6_print(b+1, t - b - 1); goto cleanup;#endif default: /* no luck - try next guess */ break; } proto = EXTRACT_16BITS(b); /* next guess - load two octets */ switch (proto) { case (PPP_ADDRESS << 8 | PPP_CONTROL): /* looks like a PPP frame */ proto = EXTRACT_16BITS(b+2); /* load the PPP proto-id */ handle_ppp(proto, b+4, t - b - 4); break; default: /* last guess - proto must be a PPP proto-id */ handle_ppp(proto, b+2, t - b - 2); break; }cleanup: snapend = se; free(b); return;}/* PPP */static voidhandle_ppp(u_int proto, const u_char *p, int length){ if ((proto & 0xff00) == 0x7e00) {/* is this an escape code ? */ ppp_hdlc(p-1, length); return; } switch (proto) { case PPP_LCP: /* fall through */ case PPP_IPCP: case PPP_OSICP: case PPP_MPLSCP: case PPP_IPV6CP: case PPP_CCP: case PPP_BACP: handle_ctrl_proto(proto, p, length); break; case PPP_ML: handle_mlppp(p, length); break; case PPP_CHAP: handle_chap(p, length); break; case PPP_PAP: handle_pap(p, length); break; case PPP_BAP: /* XXX: not yet completed */ handle_bap(p, length); break; case ETHERTYPE_IP: /*XXX*/ case PPP_VJNC: case PPP_IP: ip_print(gndo, p, length); break;#ifdef INET6 case ETHERTYPE_IPV6: /*XXX*/ case PPP_IPV6: ip6_print(p, length); break;#endif case ETHERTYPE_IPX: /*XXX*/ case PPP_IPX: ipx_print(p, length); break; case PPP_OSI: isoclns_print(p, length, length); break; case PPP_MPLS_UCAST: case PPP_MPLS_MCAST: mpls_print(p, length); break; case PPP_COMP: printf("compressed PPP data"); break; default: printf("%s ", tok2str(ppptype2str, "unknown PPP protocol (0x%04x)", proto)); print_unknown_data(p,"\n\t",length); break; }}/* Standard PPP printer */u_intppp_print(register const u_char *p, u_int length){ u_int proto,ppp_header; u_int olen = length; /* _o_riginal length */ u_int hdr_len = 0; /* * Here, we assume that p points to the Address and Control * field (if they present). */ if (length < 2) goto trunc; TCHECK2(*p, 2); ppp_header = EXTRACT_16BITS(p); switch(ppp_header) { case (PPP_WITHDIRECTION_IN << 8 | PPP_CONTROL): if (eflag) printf("In "); p += 2; length -= 2; hdr_len += 2; break; case (PPP_WITHDIRECTION_OUT << 8 | PPP_CONTROL): if (eflag) printf("Out "); p += 2; length -= 2; hdr_len += 2; break; case (PPP_ADDRESS << 8 | PPP_CONTROL): p += 2; /* ACFC not used */ length -= 2; hdr_len += 2; break; default: break; } if (length < 2) goto trunc; TCHECK(*p); if (*p % 2) { proto = *p; /* PFC is used */ p++; length--; hdr_len++; } else { TCHECK2(*p, 2); proto = EXTRACT_16BITS(p); p += 2; length -= 2; hdr_len += 2; } if (eflag) printf("%s (0x%04x), length %u: ", tok2str(ppptype2str, "unknown", proto), proto, olen); handle_ppp(proto, p, length); return (hdr_len);trunc: printf("[|ppp]"); return (0);}/* PPP I/F printer */u_intppp_if_print(const struct pcap_pkthdr *h, register const u_char *p){ register u_int length = h->len; register u_int caplen = h->caplen; if (caplen < PPP_HDRLEN) { printf("[|ppp]"); return (caplen); }#if 0 /* * XXX: seems to assume that there are 2 octets prepended to an * actual PPP frame. The 1st octet looks like Input/Output flag * while 2nd octet is unknown, at least to me * (mshindo@mshindo.net). * * That was what the original tcpdump code did. * * FreeBSD's "if_ppp.c" *does* set the first octet to 1 for outbound * packets and 0 for inbound packets - but only if the * protocol field has the 0x8000 bit set (i.e., it's a network * control protocol); it does so before running the packet through * "bpf_filter" to see if it should be discarded, and to see * if we should update the time we sent the most recent packet... * * ...but it puts the original address field back after doing * so. * * NetBSD's "if_ppp.c" doesn't set the first octet in that fashion. * * I don't know if any PPP implementation handed up to a BPF * device packets with the first octet being 1 for outbound and * 0 for inbound packets, so I (guy@alum.mit.edu) don't know * whether that ever needs to be checked or not. * * Note that NetBSD has a DLT_PPP_SERIAL, which it uses for PPP, * and its tcpdump appears to assume that the frame always * begins with an address field and a control field, and that * the address field might be 0x0f or 0x8f, for Cisco * point-to-point with HDLC framing as per section 4.3.1 of RFC * 1547, as well as 0xff, for PPP in HDLC-like framing as per * RFC 1662. * * (Is the Cisco framing in question what DLT_C_HDLC, in * BSD/OS, is?) */ if (eflag) printf("%c %4d %02x ", p[0] ? 'O' : 'I', length, p[1]);#endif ppp_print(p, length); return (0);}/* * PPP I/F printer to use if we know that RFC 1662-style PPP in HDLC-like * framing, or Cisco PPP with HDLC framing as per section 4.3.1 of RFC 1547, * is being used (i.e., we don't check for PPP_ADDRESS and PPP_CONTROL, * discard them *if* those are the first two octets, and parse the remaining * packet as a PPP packet, as "ppp_print()" does). * * This handles, for example, DLT_PPP_SERIAL in NetBSD. */u_intppp_hdlc_if_print(const struct pcap_pkthdr *h, register const u_char *p){ register u_int length = h->len; register u_int caplen = h->caplen; u_int proto; u_int hdrlen = 0; if (caplen < 2) { printf("[|ppp]"); return (caplen); } switch (p[0]) { case PPP_ADDRESS: if (caplen < 4) { printf("[|ppp]"); return (caplen); } if (eflag) printf("%02x %02x %d ", p[0], p[1], length); p += 2; length -= 2; hdrlen += 2; proto = EXTRACT_16BITS(p); p += 2; length -= 2; hdrlen += 2; printf("%s: ", tok2str(ppptype2str, "unknown PPP protocol (0x%04x)", proto)); handle_ppp(proto, p, length); break; case CHDLC_UNICAST: case CHDLC_BCAST: return (chdlc_if_print(h, p)); default: if (eflag) printf("%02x %02x %d ", p[0], p[1], length); p += 2; length -= 2; hdrlen += 2; /* * XXX - NetBSD's "ppp_netbsd_serial_if_print()" treats * the next two octets as an Ethernet type; does that * ever happen? */ printf("unknown addr %02x; ctrl %02x", p[0], p[1]); break; } return (hdrlen);}#define PPP_BSDI_HDRLEN 24/* BSD/OS specific PPP printer */u_intppp_bsdos_if_print(const struct pcap_pkthdr *h _U_, register const u_char *p _U_){ register int hdrlength;#ifdef __bsdi__ register u_int length = h->len; register u_int caplen = h->caplen; u_int16_t ptype; const u_char *q; int i; if (caplen < PPP_BSDI_HDRLEN) { printf("[|ppp]"); return (caplen) } hdrlength = 0;#if 0 if (p[0] == PPP_ADDRESS && p[1] == PPP_CONTROL) { if (eflag) printf("%02x %02x ", p[0], p[1]); p += 2; hdrlength = 2; } if (eflag) printf("%d ", length); /* Retrieve the protocol type */ if (*p & 01) { /* Compressed protocol field */ ptype = *p; if (eflag) printf("%02x ", ptype); p++; hdrlength += 1; } else { /* Un-compressed protocol field */ ptype = ntohs(*(u_int16_t *)p); if (eflag) printf("%04x ", ptype); p += 2; hdrlength += 2; }#else ptype = 0; /*XXX*/ if (eflag) printf("%c ", p[SLC_DIR] ? 'O' : 'I'); if (p[SLC_LLHL]) { /* link level header */ struct ppp_header *ph; q = p + SLC_BPFHDRLEN; ph = (struct ppp_header *)q; if (ph->phdr_addr == PPP_ADDRESS && ph->phdr_ctl == PPP_CONTROL) { if (eflag) printf("%02x %02x ", q[0], q[1]); ptype = ntohs(ph->phdr_type); if (eflag && (ptype == PPP_VJC || ptype == PPP_VJNC)) { printf("%s ", tok2str(ppptype2str, "proto-#%d", ptype)); } } else { if (eflag) { printf("LLH=["); for (i = 0; i < p[SLC_LLHL]; i++) printf("%02x", q[i]); printf("] "); } } } if (eflag) printf("%d ", length); if (p[SLC_CHL]) { q = p + SLC_BPFHDRLEN + p[SLC_LLHL]; switch (ptype) { case PPP_VJC: ptype = vjc_print(q, ptype); hdrlength = PPP_BSDI_HDRLEN; p += hdrlength; switch (ptype) { case PPP_IP: ip_print(p, length); break;#ifdef INET6 case PPP_IPV6: ip6_print(p, length); break;#endif case PPP_MPLS_UCAST: case PPP_MPLS_MCAST: mpls_print(p, length); break; } goto printx; case PPP_VJNC: ptype = vjc_print(q, ptype); hdrlength = PPP_BSDI_HDRLEN; p += hdrlength; switch (ptype) { case PPP_IP: ip_print(p, length); break;#ifdef INET6 case PPP_IPV6: ip6_print(p, length); break;#endif case PPP_MPLS_UCAST: case PPP_MPLS_MCAST: mpls_print(p, length); break; } goto printx; default: if (eflag) { printf("CH=["); for (i = 0; i < p[SLC_LLHL]; i++) printf("%02x", q[i]); printf("] "); } break; } } hdrlength = PPP_BSDI_HDRLEN;#endif length -= hdrlength; p += hdrlength; switch (ptype) { case PPP_IP: ip_print(p, length); break;#ifdef INET6 case PPP_IPV6: ip6_print(p, length); break;#endif case PPP_MPLS_UCAST: case PPP_MPLS_MCAST: mpls_print(p, length); break; default: printf("%s ", tok2str(ppptype2str, "unknown PPP protocol (0x%04x)", ptype)); }printx:#else /* __bsdi */ hdrlength = 0;#endif /* __bsdi__ */ return (hdrlength);}/* * Local Variables: * c-style: whitesmith * c-basic-offset: 8 * End: */
?? 快捷鍵說明
復制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號
Ctrl + =
減小字號
Ctrl + -