]> The Tcpdump Group git mirrors - tcpdump/blob - print-ppp.c
add AC_REVISION
[tcpdump] / print-ppp.c
1 /*
2 * Copyright (c) 1990, 1991, 1993, 1994, 1995, 1996, 1997
3 * The Regents of the University of California. All rights reserved.
4 *
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
16 * written permission.
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.
20 */
21
22 #ifndef lint
23 static const char rcsid[] =
24 "@(#) $Header: /tcpdump/master/tcpdump/print-ppp.c,v 1.33 1999-12-22 06:27:22 itojun Exp $ (LBL)";
25 #endif
26
27 #ifdef HAVE_CONFIG_H
28 #include "config.h"
29 #endif
30
31 #include <sys/param.h>
32 #include <sys/time.h>
33 #include <sys/socket.h>
34 #include <sys/file.h>
35 #include <sys/ioctl.h>
36
37 #if __STDC__
38 struct mbuf;
39 struct rtentry;
40 #endif
41 #include <net/if.h>
42
43 #include <netinet/in.h>
44 #include <netinet/in_systm.h>
45 #include <netinet/ip.h>
46 #include <netinet/if_ether.h>
47
48 #include <ctype.h>
49 #include <netdb.h>
50 #include <pcap.h>
51 #include <stdio.h>
52 #ifdef __bsdi__
53 #include <net/slcompress.h>
54 #include <net/if_ppp.h>
55 #endif
56
57 #include "interface.h"
58 #include "addrtoname.h"
59 #include "ppp.h"
60
61 /* XXX This goes somewhere else. */
62 #define PPP_HDRLEN 4
63
64 /* LCP */
65
66 #define LCP_CONF_REQ 1
67 #define LCP_CONF_ACK 2
68 #define LCP_CONF_NAK 3
69 #define LCP_CONF_REJ 4
70 #define LCP_TERM_REQ 5
71 #define LCP_TERM_ACK 6
72 #define LCP_CODE_REJ 7
73 #define LCP_PROT_REJ 8
74 #define LCP_ECHO_REQ 9
75 #define LCP_ECHO_RPL 10
76 #define LCP_DISC_REQ 11
77
78 #define LCP_MIN LCP_CONF_REQ
79 #define LCP_MAX LCP_DISC_REQ
80
81 static char *lcpcodes[] = {
82 /*
83 * LCP code values (RFC1661, pp26)
84 */
85 "Configure-Request",
86 "Configure-Ack",
87 "Configure-Nak",
88 "Configure-Reject",
89 "Terminate-Request",
90 "Terminate-Ack",
91 "Code-Reject",
92 "Protocol-Reject",
93 "Echo-Request",
94 "Echo-Reply",
95 "Discard-Request",
96 };
97
98 #define LCPOPT_VEXT 0
99 #define LCPOPT_MRU 1
100 #define LCPOPT_ACCM 2
101 #define LCPOPT_AP 3
102 #define LCPOPT_QP 4
103 #define LCPOPT_MN 5
104 #define LCPOPT_PFC 7
105 #define LCPOPT_ACFC 8
106
107 #define LCPOPT_MIN 0
108 #define LCPOPT_MAX 24
109
110 static char *lcpconfopts[] = {
111 "Vendor-Ext",
112 "Max-Rx-Unit",
113 "Async-Ctrl-Char-Map",
114 "Auth-Prot",
115 "Quality-Prot",
116 "Magic-Number",
117 "unassigned (6)",
118 "Prot-Field-Compr",
119 "Add-Ctrl-Field-Compr",
120 "FCS-Alternatives",
121 "Self-Describing-Pad",
122 "Numbered-Mode",
123 "Multi-Link-Procedure",
124 "Call-Back",
125 "Connect-Time"
126 "Compund-Frames",
127 "Nominal-Data-Encap",
128 "Multilink-MRRU",
129 "Multilink-SSNHF",
130 "Multilink-ED",
131 "Proprietary",
132 "DCE-Identifier",
133 "Multilink-Plus-Proc",
134 "Link-Discriminator",
135 "LCP-Auth-Option",
136 };
137
138 /* CHAP */
139
140 #define CHAP_CHAL 1
141 #define CHAP_RESP 2
142 #define CHAP_SUCC 3
143 #define CHAP_FAIL 4
144
145 #define CHAP_CODEMIN 1
146 #define CHAP_CODEMAX 4
147
148 static char *chapcode[] = {
149 "Challenge",
150 "Response",
151 "Success",
152 "Failure",
153 };
154
155 /* PAP */
156
157 #define PAP_AREQ 1
158 #define PAP_AACK 2
159 #define PAP_ANAK 3
160
161 #define PAP_CODEMIN 1
162 #define PAP_CODEMAX 3
163
164 static char *papcode[] = {
165 "Authenticate-Request",
166 "Authenticate-Ack",
167 "Authenticate-Nak",
168 };
169
170 /* IPCP */
171
172 #define IPCP_2ADDR 1
173 #define IPCP_CP 2
174 #define IPCP_ADDR 3
175
176 static const char *ppp_protoname __P((int proto));
177 static void handle_lcp __P((const u_char *p, int length));
178 static int print_lcp_config_options __P((const u_char *p));
179 static void handle_chap __P((const u_char *p, int length));
180 static void handle_ipcp __P((const u_char *p, int length));
181 static void handle_pap __P((const u_char *p, int length));
182
183 static const char *
184 ppp_protoname(int proto)
185 {
186 static char buf[20];
187
188 switch (proto) {
189 case PPP_IP: return "IP";
190 #ifdef PPP_XNS
191 case PPP_XNS: return "XNS";
192 #endif
193 #ifdef PPP_IPX
194 case PPP_IPX: return "IPX";
195 #endif
196 #ifdef PPP_COMP
197 case PPP_COMP: return "COMP";
198 #endif
199 #ifdef PPP_IPCP
200 case PPP_IPCP: return "IPCP";
201 #endif
202 #ifdef PPP_IPV6CP
203 case PPP_IPV6CP: return "IPV6CP";
204 #endif
205 #ifdef PPP_IPXCP
206 case PPP_IPXCP: return "IPXCP";
207 #endif
208 #ifdef PPP_CCP
209 case PPP_CCP: return "CCP";
210 #endif
211 #ifdef PPP_LCP
212 case PPP_LCP: return "LCP";
213 #endif
214 #ifdef PPP_PAP
215 case PPP_PAP: return "PAP";
216 #endif
217 #ifdef PPP_LQR
218 case PPP_LQR: return "LQR";
219 #endif
220 #ifdef PPP_CHAP
221 case PPP_CHAP: return "CHAP";
222 #endif
223 default:
224 sprintf(buf, "unknown-0x%04x\n", proto);
225 return buf;
226 }
227 }
228
229 /* print LCP frame */
230 static void
231 handle_lcp(const u_char *p, int length)
232 {
233 int x, j;
234 const u_char *ptr;
235
236 x = p[4];
237
238 if ((x >= LCP_MIN) && (x <= LCP_MAX))
239 printf("%s", lcpcodes[x - 1]);
240 else {
241 printf("0x%02x", x);
242 return;
243 }
244
245 length -= 4;
246
247 switch (x) {
248 case LCP_CONF_REQ:
249 case LCP_CONF_ACK:
250 case LCP_CONF_NAK:
251 case LCP_CONF_REJ:
252 x = length;
253 ptr = p + 8;
254 do {
255 if ((j = print_lcp_config_options(ptr)) == 0)
256 break;
257 x -= j;
258 ptr += j;
259 } while (x > 0);
260 break;
261
262 case LCP_ECHO_REQ:
263 case LCP_ECHO_RPL:
264 printf(", Magic-Number=%u",
265 (u_int32_t)ntohl(*(u_int32_t *)(p + 8)));
266 break;
267 case LCP_TERM_REQ:
268 case LCP_TERM_ACK:
269 case LCP_CODE_REJ:
270 case LCP_PROT_REJ:
271 case LCP_DISC_REQ:
272 default:
273 break;
274 }
275 }
276
277 /* LCP config options */
278 static int
279 print_lcp_config_options(const u_char *p)
280 {
281 int len = p[1];
282 int opt = p[0];
283
284 if ((opt >= LCPOPT_MIN) && (opt <= LCPOPT_MAX))
285 printf(", %s", lcpconfopts[opt]);
286
287 switch (opt) {
288 case LCPOPT_MRU:
289 if (len == 4)
290 printf("=%d", (*(p+2) << 8) + *(p+3));
291 break;
292 case LCPOPT_AP:
293 if (len >= 4) {
294 if (p[2] == 0xc0 && p[3] == 0x23)
295 printf(" PAP");
296 else if (p[2] == 0xc2 && p[3] == 0x23) {
297 printf(" CHAP/");
298 switch (p[4]) {
299 default:
300 printf("unknown-algorithm-%u", p[4]);
301 break;
302 case 5:
303 printf("MD5");
304 break;
305 case 0x80:
306 printf("Microsoft");
307 break;
308 }
309 }
310 else if (p[2] == 0xc2 && p[3] == 0x27)
311 printf(" EAP");
312 else if (p[2] == 0xc0 && p[3] == 0x27)
313 printf(" SPAP");
314 else if (p[2] == 0xc1 && p[3] == 0x23)
315 printf(" Old-SPAP");
316 else
317 printf("unknown");
318 }
319 break;
320 case LCPOPT_QP:
321 if (len >= 4) {
322 if (p[2] == 0xc0 && p[3] == 0x25)
323 printf(" LQR");
324 else
325 printf(" unknown");
326 }
327 break;
328 case LCPOPT_MN:
329 if (len == 6)
330 printf("=%u", (u_int32_t)ntohl(*(u_int32_t *)(p + 2)));
331 break;
332 case LCPOPT_PFC:
333 printf(" PFC");
334 break;
335 case LCPOPT_ACFC:
336 printf(" ACFC");
337 break;
338 }
339 return len;
340 }
341
342 /* CHAP */
343 static void
344 handle_chap(const u_char *p, int length)
345 {
346 int x;
347 const u_char *ptr;
348
349 x = p[4];
350
351 if ((x >= CHAP_CODEMIN) && (x <= CHAP_CODEMAX))
352 printf("%s", chapcode[x - 1]);
353 else {
354 printf("0x%02x", x);
355 return;
356 }
357
358 length -= 4;
359
360 switch (p[4]) {
361 case CHAP_CHAL:
362 case CHAP_RESP:
363 printf(", Value=");
364 x = p[8]; /* value size */
365 ptr = p + 9;
366 while (--x >= 0)
367 printf("%02x", *ptr++);
368 x = length - p[8] - 1;
369 printf(", Name=");
370 while (--x >= 0) {
371 if (isprint(*ptr))
372 printf("%c", *ptr);
373 else
374 printf("\\%03o", *ptr);
375 ptr++;
376 }
377 break;
378 }
379 }
380
381 /* PAP */
382 static void
383 handle_pap(const u_char *p, int length)
384 {
385 int x;
386 const u_char *ptr;
387
388 x = p[4];
389
390 if ((x >= PAP_CODEMIN) && (x <= PAP_CODEMAX))
391 printf("%s", papcode[x - 1]);
392 else {
393 printf("0x%02x", x);
394 return;
395 }
396
397 length -= 4;
398
399 switch (x) {
400 case PAP_AREQ:
401 printf(", Peer-Id=");
402 x = p[8]; /* peerid size */
403 ptr = p + 9;
404 while (--x >= 0) {
405 if (isprint(*ptr))
406 printf("%c", *ptr);
407 else
408 printf("\\%03o", *ptr);
409 ptr++;
410 }
411 x = *ptr++;
412 printf(", Passwd=");
413 while (--x >= 0) {
414 if (isprint(*ptr))
415 printf("%c", *ptr);
416 else
417 printf("\\%03o", *ptr);
418 ptr++;
419 }
420 break;
421 case PAP_AACK:
422 case PAP_ANAK:
423 break;
424 }
425 }
426
427 /* IPCP */
428 static void
429 handle_ipcp(const u_char *p, int length)
430 {
431 length -= 4;
432
433 switch (p[8]) {
434 case IPCP_2ADDR:
435 printf("IP-Addresses");
436 printf(", src=%s", ipaddr_string(p + 10));
437 printf(", drc=%s", ipaddr_string(p + 14));
438 break;
439
440 case IPCP_CP:
441 printf("IP-Compression-Protocol");
442 break;
443
444 case IPCP_ADDR:
445 printf("IP-Address=%s", ipaddr_string(p + 10));
446 break;
447 }
448 }
449
450 /* Standard PPP printer */
451 void
452 ppp_if_print(u_char *user, const struct pcap_pkthdr *h,
453 register const u_char *p)
454 {
455 register u_int length = h->len;
456 register u_int caplen = h->caplen;
457 const struct ip *ip;
458 u_int proto;
459
460 ts_print(&h->ts);
461
462 if (caplen < PPP_HDRLEN) {
463 printf("[|ppp]");
464 goto out;
465 }
466
467 /*
468 * Some printers want to get back at the link level addresses,
469 * and/or check that they're not walking off the end of the packet.
470 * Rather than pass them all the way down, we set these globals.
471 */
472 proto = ntohs(*(u_short *)&p[2]);
473 packetp = p;
474 snapend = p + caplen;
475
476 if (eflag)
477 printf("%c %4d %02x %s: ", p[0] ? 'O' : 'I', length,
478 p[1], ppp_protoname(proto));
479
480 length -= PPP_HDRLEN;
481 ip = (struct ip *)(p + PPP_HDRLEN);
482 switch (proto) {
483 case PPP_LCP:
484 handle_lcp(p, length);
485 break;
486 case PPP_CHAP:
487 handle_chap(p, length);
488 break;
489 case PPP_PAP:
490 handle_pap(p, length);
491 break;
492 case PPP_IPCP:
493 handle_ipcp(p, length);
494 break;
495 case ETHERTYPE_IP: /*XXX*/
496 case PPP_IP:
497 ip_print((const u_char *)ip, length);
498 break;
499 #ifdef INET6
500 case ETHERTYPE_IPV6: /*XXX*/
501 #ifdef PPP_IPV6
502 case PPP_IPV6:
503 #endif
504 ip6_print((const u_char *)ip, length);
505 break;
506 #endif
507 }
508 if (xflag)
509 default_print((const u_char *)ip, caplen - PPP_HDRLEN);
510 out:
511 putchar('\n');
512 }
513
514 struct tok ppptype2str[] = {
515 { PPP_IP, "IP" },
516 { PPP_OSI, "OSI" },
517 { PPP_NS, "NS" },
518 { PPP_DECNET, "DECNET" },
519 { PPP_APPLE, "APPLE" },
520 { PPP_IPX, "IPX" },
521 { PPP_VJC, "VJC" },
522 { PPP_VJNC, "VJNC" },
523 { PPP_BRPDU, "BRPDU" },
524 { PPP_STII, "STII" },
525 { PPP_VINES, "VINES" },
526
527 { PPP_HELLO, "HELLO" },
528 { PPP_LUXCOM, "LUXCOM" },
529 { PPP_SNS, "SNS" },
530 { PPP_IPCP, "IPCP" },
531 { PPP_OSICP, "OSICP" },
532 { PPP_NSCP, "NSCP" },
533 { PPP_DECNETCP, "DECNETCP" },
534 { PPP_APPLECP, "APPLECP" },
535 { PPP_IPXCP, "IPXCP" },
536 { PPP_STIICP, "STIICP" },
537 { PPP_VINESCP, "VINESCP" },
538
539 { PPP_LCP, "LCP" },
540 { PPP_PAP, "PAP" },
541 { PPP_LQM, "LQM" },
542 { PPP_CHAP, "CHAP" },
543 { 0, NULL }
544 };
545
546 #define PPP_BSDI_HDRLEN 24
547
548 /* BSD/OS specific PPP printer */
549 void
550 ppp_bsdos_if_print(u_char *user, const struct pcap_pkthdr *h,
551 register const u_char *p)
552 {
553 #ifdef __bsdi__
554 register u_int length = h->len;
555 register u_int caplen = h->caplen;
556 register int hdrlength;
557 u_short ptype;
558 const u_char *q;
559 int i;
560
561 ts_print(&h->ts);
562
563 if (caplen < PPP_BSDI_HDRLEN) {
564 printf("[|ppp]");
565 goto out;
566 }
567
568 /*
569 * Some printers want to get back at the link level addresses,
570 * and/or check that they're not walking off the end of the packet.
571 * Rather than pass them all the way down, we set these globals.
572 */
573 packetp = p;
574 snapend = p + caplen;
575 hdrlength = 0;
576
577 #if 0
578 if (p[0] == PPP_ADDRESS && p[1] == PPP_CONTROL) {
579 if (eflag)
580 printf("%02x %02x ", p[0], p[1]);
581 p += 2;
582 hdrlength = 2;
583 }
584
585 if (eflag)
586 printf("%d ", length);
587 /* Retrieve the protocol type */
588 if (*p & 01) {
589 /* Compressed protocol field */
590 ptype = *p;
591 if (eflag)
592 printf("%02x ", ptype);
593 p++;
594 hdrlength += 1;
595 } else {
596 /* Un-compressed protocol field */
597 ptype = ntohs(*(u_short *)p);
598 if (eflag)
599 printf("%04x ", ptype);
600 p += 2;
601 hdrlength += 2;
602 }
603 #else
604 ptype = 0; /*XXX*/
605 if (eflag)
606 printf("%c ", p[SLC_DIR] ? 'O' : 'I');
607 if (p[SLC_LLHL]) {
608 /* link level header */
609 struct ppp_header *ph;
610
611 q = p + SLC_BPFHDRLEN;
612 ph = (struct ppp_header *)q;
613 if (ph->phdr_addr == PPP_ADDRESS
614 && ph->phdr_ctl == PPP_CONTROL) {
615 if (eflag)
616 printf("%02x %02x ", q[0], q[1]);
617 ptype = ntohs(ph->phdr_type);
618 if (eflag && (ptype == PPP_VJC || ptype == PPP_VJNC)) {
619 printf("%s ", tok2str(ppptype2str,
620 "proto-#%d", ptype));
621 }
622 } else {
623 if (eflag) {
624 printf("LLH=[");
625 for (i = 0; i < p[SLC_LLHL]; i++)
626 printf("%02x", q[i]);
627 printf("] ");
628 }
629 }
630 if (eflag)
631 printf("%d ", length);
632 }
633 if (p[SLC_CHL]) {
634 q = p + SLC_BPFHDRLEN + p[SLC_LLHL];
635
636 switch (ptype) {
637 case PPP_VJC:
638 ptype = vjc_print(q, length - (q - p), ptype);
639 hdrlength = PPP_BSDI_HDRLEN;
640 p += hdrlength;
641 if (ptype == PPP_IP)
642 ip_print(p, length);
643 goto printx;
644 case PPP_VJNC:
645 ptype = vjc_print(q, length - (q - p), ptype);
646 hdrlength = PPP_BSDI_HDRLEN;
647 p += hdrlength;
648 if (ptype == PPP_IP)
649 ip_print(p, length);
650 goto printx;
651 default:
652 if (eflag) {
653 printf("CH=[");
654 for (i = 0; i < p[SLC_LLHL]; i++)
655 printf("%02x", q[i]);
656 printf("] ");
657 }
658 break;
659 }
660 }
661
662 hdrlength = PPP_BSDI_HDRLEN;
663 #endif
664
665 length -= hdrlength;
666 p += hdrlength;
667
668 if (ptype == PPP_IP)
669 ip_print(p, length);
670 else
671 printf("%s ", tok2str(ppptype2str, "proto-#%d", ptype));
672
673 printx:
674 if (xflag)
675 default_print((const u_char *)p, caplen - hdrlength);
676 out:
677 putchar('\n');
678 #endif /* __bsdi__ */
679 }