]>
The Tcpdump Group git mirrors - tcpdump/blob - print-ppp.c
2 * Copyright (c) 1990, 1991, 1993, 1994, 1995, 1996, 1997
3 * The Regents of the University of California. All rights reserved.
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that: (1) source code distributions
7 * retain the above copyright notice and this paragraph in its entirety, (2)
8 * distributions including binary code include the above copyright notice and
9 * this paragraph in its entirety in the documentation or other materials
10 * provided with the distribution, and (3) all advertising materials mentioning
11 * features or use of this software display the following acknowledgement:
12 * ``This product includes software developed by the University of California,
13 * Lawrence Berkeley Laboratory and its contributors.'' Neither the name of
14 * the University nor the names of its contributors may be used to endorse
15 * or promote products derived from this software without specific prior
17 * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR IMPLIED
18 * WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF
19 * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
23 static const char rcsid
[] =
24 "@(#) $Header: /tcpdump/master/tcpdump/print-ppp.c,v 1.36 2000-04-28 11:14:48 itojun Exp $ (LBL)";
31 #include <sys/param.h>
33 #include <sys/socket.h>
35 #include <sys/ioctl.h>
43 #include <netinet/in.h>
44 #include <netinet/in_systm.h>
45 #include <netinet/ip.h>
46 #include <netinet/if_ether.h>
53 #include <net/slcompress.h>
54 #include <net/if_ppp.h>
57 #include "interface.h"
59 #include "addrtoname.h"
62 /* XXX This goes somewhere else. */
67 #define LCP_CONF_REQ 1
68 #define LCP_CONF_ACK 2
69 #define LCP_CONF_NAK 3
70 #define LCP_CONF_REJ 4
71 #define LCP_TERM_REQ 5
72 #define LCP_TERM_ACK 6
73 #define LCP_CODE_REJ 7
74 #define LCP_PROT_REJ 8
75 #define LCP_ECHO_REQ 9
76 #define LCP_ECHO_RPL 10
77 #define LCP_DISC_REQ 11
79 #define LCP_MIN LCP_CONF_REQ
80 #define LCP_MAX LCP_DISC_REQ
82 static char *lcpcodes
[] = {
84 * LCP code values (RFC1661, pp26)
101 #define LCPOPT_ACCM 2
106 #define LCPOPT_ACFC 8
109 #define LCPOPT_MAX 24
111 static char *lcpconfopts
[] = {
114 "Async-Ctrl-Char-Map",
120 "Add-Ctrl-Field-Compr",
122 "Self-Describing-Pad",
124 "Multi-Link-Procedure",
128 "Nominal-Data-Encap",
134 "Multilink-Plus-Proc",
135 "Link-Discriminator",
146 #define CHAP_CODEMIN 1
147 #define CHAP_CODEMAX 4
149 static char *chapcode
[] = {
162 #define PAP_CODEMIN 1
163 #define PAP_CODEMAX 3
165 static char *papcode
[] = {
166 "Authenticate-Request",
177 static const char *ppp_protoname
__P((int proto
));
178 static void handle_lcp
__P((const u_char
*p
, int length
));
179 static int print_lcp_config_options
__P((const u_char
*p
));
180 static void handle_chap
__P((const u_char
*p
, int length
));
181 static void handle_ipcp
__P((const u_char
*p
, int length
));
182 static void handle_pap
__P((const u_char
*p
, int length
));
185 ppp_protoname(int proto
)
190 case PPP_IP
: return "IP";
192 case PPP_XNS
: return "XNS";
195 case PPP_IPX
: return "IPX";
198 case PPP_COMP
: return "COMP";
201 case PPP_IPCP
: return "IPCP";
204 case PPP_IPV6CP
: return "IPV6CP";
207 case PPP_IPXCP
: return "IPXCP";
210 case PPP_CCP
: return "CCP";
213 case PPP_LCP
: return "LCP";
216 case PPP_PAP
: return "PAP";
219 case PPP_LQR
: return "LQR";
222 case PPP_CHAP
: return "CHAP";
225 snprintf(buf
, sizeof(buf
), "unknown-0x%04x\n", proto
);
230 /* print LCP frame */
232 handle_lcp(const u_char
*p
, int length
)
239 if ((x
>= LCP_MIN
) && (x
<= LCP_MAX
))
240 printf("%s", lcpcodes
[x
- 1]);
256 if ((j
= print_lcp_config_options(ptr
)) == 0)
265 printf(", Magic-Number=%u",
266 EXTRACT_32BITS(p
+8));
278 /* LCP config options */
280 print_lcp_config_options(const u_char
*p
)
285 if ((opt
>= LCPOPT_MIN
) && (opt
<= LCPOPT_MAX
))
286 printf(", %s", lcpconfopts
[opt
]);
291 printf("=%d", (*(p
+2) << 8) + *(p
+3));
295 if (p
[2] == 0xc0 && p
[3] == 0x23)
297 else if (p
[2] == 0xc2 && p
[3] == 0x23) {
301 printf("unknown-algorithm-%u", p
[4]);
311 else if (p
[2] == 0xc2 && p
[3] == 0x27)
313 else if (p
[2] == 0xc0 && p
[3] == 0x27)
315 else if (p
[2] == 0xc1 && p
[3] == 0x23)
323 if (p
[2] == 0xc0 && p
[3] == 0x25)
331 printf("=%u", EXTRACT_32BITS(p
+2));
345 handle_chap(const u_char
*p
, int length
)
352 if ((x
>= CHAP_CODEMIN
) && (x
<= CHAP_CODEMAX
))
353 printf("%s", chapcode
[x
- 1]);
365 x
= p
[8]; /* value size */
368 printf("%02x", *ptr
++);
369 x
= length
- p
[8] - 1;
375 printf("\\%03o", *ptr
);
384 handle_pap(const u_char
*p
, int length
)
391 if ((x
>= PAP_CODEMIN
) && (x
<= PAP_CODEMAX
))
392 printf("%s", papcode
[x
- 1]);
402 printf(", Peer-Id=");
403 x
= p
[8]; /* peerid size */
409 printf("\\%03o", *ptr
);
418 printf("\\%03o", *ptr
);
430 handle_ipcp(const u_char
*p
, int length
)
436 printf("IP-Addresses");
437 printf(", src=%s", ipaddr_string(p
+ 10));
438 printf(", drc=%s", ipaddr_string(p
+ 14));
442 printf("IP-Compression-Protocol");
446 printf("IP-Address=%s", ipaddr_string(p
+ 10));
451 /* Standard PPP printer */
453 ppp_if_print(u_char
*user
, const struct pcap_pkthdr
*h
,
454 register const u_char
*p
)
456 register u_int length
= h
->len
;
457 register u_int caplen
= h
->caplen
;
463 if (caplen
< PPP_HDRLEN
) {
469 * Some printers want to get back at the link level addresses,
470 * and/or check that they're not walking off the end of the packet.
471 * Rather than pass them all the way down, we set these globals.
473 proto
= ntohs(*(u_int16_t
*)&p
[2]);
475 snapend
= p
+ caplen
;
478 printf("%c %4d %02x %s: ", p
[0] ? 'O' : 'I', length
,
479 p
[1], ppp_protoname(proto
));
481 length
-= PPP_HDRLEN
;
482 ip
= (struct ip
*)(p
+ PPP_HDRLEN
);
485 handle_lcp(p
, length
);
488 handle_chap(p
, length
);
491 handle_pap(p
, length
);
494 handle_ipcp(p
, length
);
496 case ETHERTYPE_IP
: /*XXX*/
498 ip_print((const u_char
*)ip
, length
);
501 case ETHERTYPE_IPV6
: /*XXX*/
505 ip6_print((const u_char
*)ip
, length
);
510 default_print((const u_char
*)ip
, caplen
- PPP_HDRLEN
);
515 struct tok ppptype2str
[] = {
519 { PPP_DECNET
, "DECNET" },
520 { PPP_APPLE
, "APPLE" },
523 { PPP_VJNC
, "VJNC" },
524 { PPP_BRPDU
, "BRPDU" },
525 { PPP_STII
, "STII" },
526 { PPP_VINES
, "VINES" },
528 { PPP_HELLO
, "HELLO" },
529 { PPP_LUXCOM
, "LUXCOM" },
531 { PPP_IPCP
, "IPCP" },
532 { PPP_OSICP
, "OSICP" },
533 { PPP_NSCP
, "NSCP" },
534 { PPP_DECNETCP
, "DECNETCP" },
535 { PPP_APPLECP
, "APPLECP" },
536 { PPP_IPXCP
, "IPXCP" },
537 { PPP_STIICP
, "STIICP" },
538 { PPP_VINESCP
, "VINESCP" },
543 { PPP_CHAP
, "CHAP" },
547 #define PPP_BSDI_HDRLEN 24
549 /* BSD/OS specific PPP printer */
551 ppp_bsdos_if_print(u_char
*user
, const struct pcap_pkthdr
*h
,
552 register const u_char
*p
)
555 register u_int length
= h
->len
;
556 register u_int caplen
= h
->caplen
;
557 register int hdrlength
;
564 if (caplen
< PPP_BSDI_HDRLEN
) {
570 * Some printers want to get back at the link level addresses,
571 * and/or check that they're not walking off the end of the packet.
572 * Rather than pass them all the way down, we set these globals.
575 snapend
= p
+ caplen
;
579 if (p
[0] == PPP_ADDRESS
&& p
[1] == PPP_CONTROL
) {
581 printf("%02x %02x ", p
[0], p
[1]);
587 printf("%d ", length
);
588 /* Retrieve the protocol type */
590 /* Compressed protocol field */
593 printf("%02x ", ptype
);
597 /* Un-compressed protocol field */
598 ptype
= ntohs(*(u_int16_t
*)p
);
600 printf("%04x ", ptype
);
607 printf("%c ", p
[SLC_DIR
] ? 'O' : 'I');
609 /* link level header */
610 struct ppp_header
*ph
;
612 q
= p
+ SLC_BPFHDRLEN
;
613 ph
= (struct ppp_header
*)q
;
614 if (ph
->phdr_addr
== PPP_ADDRESS
615 && ph
->phdr_ctl
== PPP_CONTROL
) {
617 printf("%02x %02x ", q
[0], q
[1]);
618 ptype
= ntohs(ph
->phdr_type
);
619 if (eflag
&& (ptype
== PPP_VJC
|| ptype
== PPP_VJNC
)) {
620 printf("%s ", tok2str(ppptype2str
,
621 "proto-#%d", ptype
));
626 for (i
= 0; i
< p
[SLC_LLHL
]; i
++)
627 printf("%02x", q
[i
]);
632 printf("%d ", length
);
635 q
= p
+ SLC_BPFHDRLEN
+ p
[SLC_LLHL
];
639 ptype
= vjc_print(q
, length
- (q
- p
), ptype
);
640 hdrlength
= PPP_BSDI_HDRLEN
;
646 ptype
= vjc_print(q
, length
- (q
- p
), ptype
);
647 hdrlength
= PPP_BSDI_HDRLEN
;
655 for (i
= 0; i
< p
[SLC_LLHL
]; i
++)
656 printf("%02x", q
[i
]);
663 hdrlength
= PPP_BSDI_HDRLEN
;
672 printf("%s ", tok2str(ppptype2str
, "proto-#%d", ptype
));
676 default_print((const u_char
*)p
, caplen
- hdrlength
);
679 #endif /* __bsdi__ */