📄 print-ppp.c
字号:
case CCPOPT_DEFLATE: case CCPOPT_RESV: break; default: printf(", unknown-%d", opt); break; }#endif return len;}/* BACP config options */static intprint_bacp_config_options(const u_char *p, int length){ int len, opt; if (length < 2) return 0; len = p[1]; opt = p[0]; if (length < len) return 0; if (opt == BACPOPT_FPEER) { printf(", Favored-Peer"); printf(" Magic-Num=%08x", EXTRACT_32BITS(p + 2)); } else { printf(", unknown-option-%d", opt); } return len;}/* PPP */static voidhandle_ppp(u_int proto, const u_char *p, int length){ switch (proto) { case PPP_LCP: case PPP_IPCP: case PPP_CCP: case PPP_BACP: handle_ctrl_proto(proto, 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_IP: ip_print(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; }}/* Standard PPP printer */voidppp_print(register const u_char *p, u_int length){ u_int proto; u_int full_length = length; /* * Here, we assume that p points to the Address and Control * field (if they present). */ if (length < 2) goto trunc; if (*p == PPP_ADDRESS && *(p + 1) == PPP_CONTROL) { p += 2; /* ACFC not used */ length -= 2; } if (length < 2) goto trunc; if (*p % 2) { proto = *p; /* PFC is used */ p++; length--; } else { proto = EXTRACT_16BITS(p); p += 2; length -= 2; } printf("%s %d: ", ppp_protoname(proto), full_length); handle_ppp(proto, p, length); return;trunc: printf("[|ppp]");}/* PPP I/F printer */voidppp_if_print(u_char *user, const struct pcap_pkthdr *h, register const u_char *p){ register u_int length = h->len; register u_int caplen = h->caplen; ts_print(&h->ts); if (caplen < PPP_HDRLEN) { printf("[|ppp]"); goto out; } /* * Some printers want to get back at the link level addresses, * and/or check that they're not walking off the end of the packet. * Rather than pass them all the way down, we set these globals. */ packetp = p; snapend = p + 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); if (xflag) default_print(p, caplen);out: putchar('\n');}/* * 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. */voidppp_hdlc_if_print(u_char *user, 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; if (caplen < 2) { printf("[|ppp]"); goto out; } /* * Some printers want to get back at the link level addresses, * and/or check that they're not walking off the end of the packet. * Rather than pass them all the way down, we set these globals. */ packetp = p; snapend = p + caplen; switch (p[0]) { case PPP_ADDRESS: if (caplen < 4) { printf("[|ppp]"); goto out; } ts_print(&h->ts); if (eflag) printf("%02x %02x %d ", p[0], p[1], length); p += 2; length -= 2; proto = EXTRACT_16BITS(p); p += 2; length -= 2; printf("%s: ", ppp_protoname(proto)); handle_ppp(proto, p, length); break; case CHDLC_UNICAST: case CHDLC_BCAST: /* * Have the Cisco HDLC print routine do all the work. */ chdlc_if_print(user, h, p); return; default: ts_print(&h->ts); if (eflag) printf("%02x %02x %d ", p[0], p[1], length); p += 2; length -= 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; } if (xflag) default_print(p, caplen);out: putchar('\n');}struct tok ppptype2str[] = { { PPP_IP, "IP" }, { PPP_OSI, "OSI" }, { PPP_NS, "NS" }, { PPP_DECNET, "DECNET" }, { PPP_APPLE, "APPLE" }, { PPP_IPX, "IPX" }, { PPP_VJC, "VJC" }, { PPP_VJNC, "VJNC" }, { PPP_BRPDU, "BRPDU" }, { PPP_STII, "STII" }, { PPP_VINES, "VINES" }, { PPP_HELLO, "HELLO" }, { PPP_LUXCOM, "LUXCOM" }, { PPP_SNS, "SNS" }, { PPP_IPCP, "IPCP" }, { PPP_OSICP, "OSICP" }, { PPP_NSCP, "NSCP" }, { PPP_DECNETCP, "DECNETCP" }, { PPP_APPLECP, "APPLECP" }, { PPP_IPXCP, "IPXCP" }, { PPP_STIICP, "STIICP" }, { PPP_VINESCP, "VINESCP" }, { PPP_LCP, "LCP" }, { PPP_PAP, "PAP" }, { PPP_LQM, "LQM" }, { PPP_CHAP, "CHAP" }, { PPP_BACP, "BACP" }, { PPP_BAP, "BAP" }, { PPP_MP, "MP" }, { 0, NULL }};#define PPP_BSDI_HDRLEN 24/* BSD/OS specific PPP printer */voidppp_bsdos_if_print(u_char *user, const struct pcap_pkthdr *h, register const u_char *p){#ifdef __bsdi__ register u_int length = h->len; register u_int caplen = h->caplen; register int hdrlength; u_int16_t ptype; const u_char *q; int i; ts_print(&h->ts); if (caplen < PPP_BSDI_HDRLEN) { printf("[|ppp]"); goto out; } /* * Some printers want to get back at the link level addresses, * and/or check that they're not walking off the end of the packet. * Rather than pass them all the way down, we set these globals. */ packetp = p; snapend = p + 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, length - (q - p), 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 } goto printx; case PPP_VJNC: ptype = vjc_print(q, length - (q - p), 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 } 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 default: printf("%s ", tok2str(ppptype2str, "proto-#%d", ptype)); }printx: if (xflag) default_print((const u_char *)p, caplen - hdrlength);out: putchar('\n');#endif /* __bsdi__ */}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -