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