]> The Tcpdump Group git mirrors - tcpdump/blob - print-ppp.c
Add support for NetBSD DLT_PPP_SERIAL (PPP in HDLC-like framing, as per
[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 * Extensively modified by Motonori Shindo (mshindo@mshindo.net) for more
22 * complete PPP support.
23 */
24
25 /*
26 * TODO:
27 * o resolve XXX as much as possible
28 * o MP support
29 * o BAP support
30 */
31
32 #ifndef lint
33 static const char rcsid[] =
34 "@(#) $Header: /tcpdump/master/tcpdump/print-ppp.c,v 1.44 2000-09-18 05:11:44 guy Exp $ (LBL)";
35 #endif
36
37 #ifdef HAVE_CONFIG_H
38 #include "config.h"
39 #endif
40
41 #include <sys/param.h>
42 #include <sys/time.h>
43 #include <sys/socket.h>
44 #include <sys/file.h>
45 #include <sys/ioctl.h>
46
47 struct mbuf;
48 struct rtentry;
49 #include <net/if.h>
50
51 #include <netinet/in.h>
52 #include <netinet/in_systm.h>
53 #include <netinet/ip.h>
54 #include <netinet/if_ether.h>
55
56 #include <ctype.h>
57 #include <netdb.h>
58 #include <pcap.h>
59 #include <stdio.h>
60 #ifdef __bsdi__
61 #include <net/slcompress.h>
62 #include <net/if_ppp.h>
63 #endif
64
65 #include "interface.h"
66 #include "extract.h"
67 #include "addrtoname.h"
68 #include "ppp.h"
69 #include "chdlc.h"
70
71 /* XXX This goes somewhere else. */
72 #define PPP_HDRLEN 4
73
74 /*
75 * The following constatns are defined by IANA. Please refer to
76 * http://www.isi.edu/in-notes/iana/assignments/ppp-numbers
77 * for the up-to-date information.
78 */
79
80 /* Control Protocols (LCP/IPCP/CCP etc.) Codes */
81
82 #define CPCODES_VEXT 0 /* Vendor-Specific (RFC2153) */
83 #define CPCODES_CONF_REQ 1 /* Configure-Request */
84 #define CPCODES_CONF_ACK 2 /* Configure-Ack */
85 #define CPCODES_CONF_NAK 3 /* Configure-Nak */
86 #define CPCODES_CONF_REJ 4 /* Configure-Reject */
87 #define CPCODES_TERM_REQ 5 /* Terminate-Request */
88 #define CPCODES_TERM_ACK 6 /* Terminate-Ack */
89 #define CPCODES_CODE_REJ 7 /* Code-Reject */
90 #define CPCODES_PROT_REJ 8 /* Protocol-Reject (LCP only) */
91 #define CPCODES_ECHO_REQ 9 /* Echo-Request (LCP only) */
92 #define CPCODES_ECHO_RPL 10 /* Echo-Reply (LCP only) */
93 #define CPCODES_DISC_REQ 11 /* Discard-Request (LCP only) */
94 #define CPCODES_ID 12 /* Identification (LCP only) */
95 #define CPCODES_TIME_REM 13 /* Time-Remaining (LCP only) */
96 #define CPCODES_RESET_REQ 14 /* Reset-Request (CCP only) */
97 #define CPCODES_RESET_REP 15 /* Reset-Reply (CCP only) */
98
99 #define CPCODES_MIN CPCODES_VEXT
100 #define CPCODES_MAX CPCODES_RESET_REP
101
102 static const char *cpcodes[] = {
103 /*
104 * Control Protocol code values (RFC1661)
105 */
106 "Vend-Ext", /* (0) RFC2153 */
107 "Conf-Req", /* (1) */
108 "Conf-Ack", /* (2) */
109 "Conf-Nak", /* (3) */
110 "Conf-Rej", /* (4) */
111 "Term-Req", /* (5) */
112 "Term-Ack", /* (6) */
113 "Code-Rej", /* (7) */
114 "Prot-Rej", /* (8) */
115 "Echo-Req", /* (9) */
116 "Echo-Rep", /* (10) */
117 "Disc-Req", /* (11) */
118 "Ident", /* (12) RFC1570 */
119 "Time-Rem", /* (13) RFC1570 */
120 "Reset-Req", /* (14) RFC1962 */
121 "Reset-Ack", /* (15) RFC1962 */
122 };
123
124 /* LCP Config Options */
125
126 #define LCPOPT_VEXT 0
127 #define LCPOPT_MRU 1
128 #define LCPOPT_ACCM 2
129 #define LCPOPT_AP 3
130 #define LCPOPT_QP 4
131 #define LCPOPT_MN 5
132 #define LCPOPT_DEP6 6
133 #define LCPOPT_PFC 7
134 #define LCPOPT_ACFC 8
135 #define LCPOPT_FCSALT 9
136 #define LCPOPT_SDP 10
137 #define LCPOPT_NUMMODE 11
138 #define LCPOPT_DEP12 12
139 #define LCPOPT_CBACK 13
140 #define LCPOPT_DEP14 14
141 #define LCPOPT_DEP15 15
142 #define LCPOPT_DEP16 16
143 #define LCPOPT_MLMRRU 17
144 #define LCPOPT_MLSSNHF 18
145 #define LCPOPT_MLED 19
146 #define LCPOPT_PROP 20
147 #define LCPOPT_DCEID 21
148 #define LCPOPT_MPP 22
149 #define LCPOPT_LD 23
150 #define LCPOPT_LCPAOPT 24
151 #define LCPOPT_COBS 25
152 #define LCPOPT_PE 26
153 #define LCPOPT_MLHF 27
154 #define LCPOPT_I18N 28
155 #define LCPOPT_SDLOS 29
156 #define LCPOPT_PPPMUX 30
157
158 #define LCPOPT_MIN LCPOPT_VEXT
159 #define LCPOPT_MAX LCPOPT_PPPMUX
160
161 static const char *lcpconfopts[] = {
162 "Vend-Ext", /* (0) */
163 "MRU", /* (1) */
164 "ACCM", /* (2) */
165 "Auth-Prot", /* (3) */
166 "Qual-Prot", /* (4) */
167 "Magic-Num", /* (5) */
168 "deprecated(6)", /* used to be a Quality Protocol */
169 "PFC", /* (7) */
170 "ACFC", /* (8) */
171 "FCS-Alt", /* (9) */
172 "SDP", /* (10) */
173 "Num-Mode", /* (11) */
174 "deprecated(12)", /* used to be a Multi-Link-Procedure*/
175 "Call-Back", /* (13) */
176 "deprecated(14)", /* used to be a Connect-Time */
177 "deprecated(15)", /* used to be a Compund-Frames */
178 "deprecated(16)", /* used to be a Nominal-Data-Encap */
179 "MRRU", /* (17) */
180 "SSNHF", /* (18) */
181 "End-Disc", /* (19) */
182 "Proprietary", /* (20) */
183 "DCE-Id", /* (21) */
184 "MP+", /* (22) */
185 "Link-Disc", /* (23) */
186 "LCP-Auth-Opt", /* (24) */
187 "COBS", /* (25) */
188 "Prefix-elision", /* (26) */
189 "Multilink-header-Form",/* (27) */
190 "I18N", /* (28) */
191 "SDL-over-SONET/SDH", /* (29) */
192 "PPP-Muxing", /* (30) */
193 };
194
195 /* IPV6CP - to be supported */
196 /* ECP - to be supported */
197
198 /* CCP Config Options */
199
200 #define CCPOPT_OUI 0 /* RFC1962 */
201 #define CCPOPT_PRED1 1 /* RFC1962 */
202 #define CCPOPT_PRED2 2 /* RFC1962 */
203 #define CCPOPT_PJUMP 3 /* RFC1962 */
204 /* 4-15 unassigned */
205 #define CCPOPT_HPPPC 16 /* RFC1962 */
206 #define CCPOPT_STACLZS 17 /* RFC1974 */
207 #define CCPOPT_MPPC 18 /* RFC2118 */
208 #define CCPOPT_GFZA 19 /* RFC1962 */
209 #define CCPOPT_V42BIS 20 /* RFC1962 */
210 #define CCPOPT_BSDCOMP 21 /* RFC1977 */
211 /* 22 unassigned */
212 #define CCPOPT_LZSDCP 23 /* RFC1967 */
213 #define CCPOPT_MVRCA 24 /* RFC1975 */
214 #define CCPOPT_DEC 25 /* RFC1976 */
215 #define CCPOPT_DEFLATE 26 /* RFC1979 */
216 /* 27-254 unassigned */
217 #define CCPOPT_RESV 255 /* RFC1962 */
218
219 #define CCPOPT_MIN CCPOPT_OUI
220 #define CCPOPT_MAX CCPOPT_DEFLATE /* XXX: should be CCPOPT_RESV but... */
221
222 static const char *ccpconfopts[] = {
223 "OUI", /* (0) */
224 "Pred-1", /* (1) */
225 "Pred-2", /* (2) */
226 "Puddle", /* (3) */
227 "unassigned(4)", /* (4) */
228 "unassigned(5)", /* (5) */
229 "unassigned(6)", /* (6) */
230 "unassigned(7)", /* (7) */
231 "unassigned(8)", /* (8) */
232 "unassigned(9)", /* (9) */
233 "unassigned(10)", /* (10) */
234 "unassigned(11)", /* (11) */
235 "unassigned(12)", /* (12) */
236 "unassigned(13)", /* (13) */
237 "unassigned(14)", /* (14) */
238 "unassigned(15)", /* (15) */
239 "HP-PPC", /* (16) */
240 "Stac-LZS", /* (17) */
241 "MPPC", /* (18) */
242 "Gand-FZA", /* (19) */
243 "V.42bis", /* (20) */
244 "BSD-Comp", /* (21) */
245 "unassigned(22)", /* (22) */
246 "LZS-DCP", /* (23) */
247 "MVRCA", /* (24) */
248 "DEC", /* (25) */
249 "Deflate", /* (26) */
250 };
251
252 /* BACP Config Options */
253
254 #define BACPOPT_FPEER 1 /* RFC2125 */
255
256 /* SDCP - to be supported */
257
258 /* IPCP Config Options */
259
260 #define IPCPOPT_2ADDR 1 /* RFC1172, RFC1332 (deprecated) */
261 #define IPCPOPT_IPCOMP 2 /* RFC1332 */
262 #define IPCPOPT_ADDR 3 /* RFC1332 */
263 #define IPCPOPT_MOBILE4 4 /* RFC2290 */
264
265 #define IPCPOPT_PRIDNS 129 /* RFC1877 */
266 #define IPCPOPT_PRINBNS 130 /* RFC1877 */
267 #define IPCPOPT_SECDNS 131 /* RFC1877 */
268 #define IPCPOPT_SECNBNS 132 /* RFC1877 */
269
270 /* ATCP - to be supported */
271 /* OSINLCP - to be supported */
272 /* BVCP - to be supported */
273 /* BCP - to be supported */
274 /* IPXCP - to be supported */
275
276 /* Auth Algorithms */
277
278 /* 0-4 Reserved (RFC1994) */
279 #define AUTHALG_CHAPMD5 5 /* RFC1994 */
280 #define AUTHALG_MSCHAP1 128 /* RFC2433 */
281 #define AUTHALG_MSCHAP2 129 /* RFC2795 */
282
283 /* FCS Alternatives - to be supported */
284
285 /* Multilink Endpoint Discriminator (RFC1717) */
286 #define MEDCLASS_NULL 0 /* Null Class */
287 #define MEDCLASS_LOCAL 1 /* Locally Assigned */
288 #define MEDCLASS_IPV4 2 /* Internet Protocol (IPv4) */
289 #define MEDCLASS_MAC 3 /* IEEE 802.1 global MAC address */
290 #define MEDCLASS_MNB 4 /* PPP Magic Number Block */
291 #define MEDCLASS_PSNDN 5 /* Public Switched Network Director Number */
292
293 /* PPP LCP Callback */
294 #define CALLBACK_AUTH 0 /* Location determined by user auth */
295 #define CALLBACK_DSTR 1 /* Dialing string */
296 #define CALLBACK_LID 2 /* Location identifier */
297 #define CALLBACK_E164 3 /* E.164 number */
298 #define CALLBACK_X500 4 /* X.500 distinguished name */
299 #define CALLBACK_CBCP 6 /* Location is determined during CBCP nego */
300
301 /* CHAP */
302
303 #define CHAP_CHAL 1
304 #define CHAP_RESP 2
305 #define CHAP_SUCC 3
306 #define CHAP_FAIL 4
307
308 #define CHAP_CODEMIN CHAP_CHAL
309 #define CHAP_CODEMAX CHAP_FAIL
310
311 static const char *chapcode[] = {
312 "Chal", /* (1) */
313 "Resp", /* (2) */
314 "Succ", /* (3) */
315 "Fail", /* (4) */
316 };
317
318 /* PAP */
319
320 #define PAP_AREQ 1
321 #define PAP_AACK 2
322 #define PAP_ANAK 3
323
324 #define PAP_CODEMIN PAP_AREQ
325 #define PAP_CODEMAX PAP_ANAK
326
327 static const char *papcode[] = {
328 "Auth-Req", /* (1) */
329 "Auth-Ack", /* (2) */
330 "Auth-Nak", /* (3) */
331 };
332
333 /* BAP */
334 #define BAP_CALLREQ 1
335 #define BAP_CALLRES 2
336 #define BAP_CBREQ 3
337 #define BAP_CBRES 4
338 #define BAP_LDQREQ 5
339 #define BAP_LDQRES 6
340 #define BAP_CSIND 7
341 #define BAP_CSRES 8
342
343 static const char *ppp_protoname __P((u_int proto));
344 static void handle_ctrl_proto __P((u_int proto,const u_char *p, int length));
345 static void handle_chap __P((const u_char *p, int length));
346 static void handle_pap __P((const u_char *p, int length));
347 static void handle_bap __P((const u_char *p, int length));
348 static int print_lcp_config_options __P((const u_char *p, int));
349 static int print_ipcp_config_options __P((const u_char *p, int));
350 static int print_ccp_config_options __P((const u_char *p, int));
351 static int print_bacp_config_options __P((const u_char *p, int));
352 static void handle_ppp __P((u_int proto, const u_char *p, int length));
353
354 static const char *
355 ppp_protoname(u_int proto)
356 {
357 static char buf[20];
358
359 switch (proto) {
360 case PPP_IP: return "IP";
361 #ifdef PPP_XNS
362 case PPP_XNS: return "XNS";
363 #endif
364 #ifdef PPP_IPX
365 case PPP_IPX: return "IPX";
366 #endif
367 #ifdef PPP_COMP
368 case PPP_COMP: return "COMP";
369 #endif
370 #ifdef PPP_IPCP
371 case PPP_IPCP: return "IPCP";
372 #endif
373 #ifdef PPP_IPV6CP
374 case PPP_IPV6CP: return "IPV6CP";
375 #endif
376 #ifdef PPP_IPXCP
377 case PPP_IPXCP: return "IPXCP";
378 #endif
379 #ifdef PPP_CCP
380 case PPP_CCP: return "CCP";
381 #endif
382 #ifdef PPP_LCP
383 case PPP_LCP: return "LCP";
384 #endif
385 #ifdef PPP_PAP
386 case PPP_PAP: return "PAP";
387 #endif
388 #ifdef PPP_LQR
389 case PPP_LQR: return "LQR";
390 #endif
391 #ifdef PPP_CHAP
392 case PPP_CHAP: return "CHAP";
393 #endif
394 #ifdef PPP_BACP
395 case PPP_BACP: return "BACP";
396 #endif
397 #ifdef PPP_BAP
398 case PPP_BAP: return "BAP";
399 #endif
400 default:
401 snprintf(buf, sizeof(buf), "unknown-0x%04x", proto);
402 return buf;
403 }
404 }
405
406 /* generic Control Protocol (e.g. LCP, IPCP, CCP, etc.) handler */
407 static void
408 handle_ctrl_proto(u_int proto, const u_char *p, int length)
409 {
410 u_int code, len;
411 int (*pfunc)(const u_char *, int);
412 int x, j;
413
414 if (length < 1) {
415 printf("[|%s]", ppp_protoname(proto));
416 return;
417 } else if (length < 4) {
418 printf("[|%s 0x%02x]", ppp_protoname(proto), *p);
419 return;
420 }
421
422 code = *p;
423 if ((code >= CPCODES_MIN) && (code <= CPCODES_MAX))
424 printf("%s", cpcodes[code]);
425 else {
426 printf("0x%02x", code);
427 return;
428 }
429 p++;
430
431 printf("(%u)", *p); /* ID */
432 p++;
433
434 len = EXTRACT_16BITS(p);
435 p += 2;
436
437 if (length <= 4)
438 return; /* there may be a NULL confreq etc. */
439
440 switch (code) {
441 case CPCODES_VEXT:
442 if (length < 11)
443 break;
444 printf(", Magic-Num=%08x", EXTRACT_32BITS(p));
445 p += 4;
446 printf(" OUI=%02x%02x%02x", p[0], p[1], p[2]);
447 /* XXX: need to decode Kind and Value(s)? */
448 break;
449 case CPCODES_CONF_REQ:
450 case CPCODES_CONF_ACK:
451 case CPCODES_CONF_NAK:
452 case CPCODES_CONF_REJ:
453 x = len - 4; /* Code(1), Identifier(1) and Length(2) */
454 do {
455 switch (proto) {
456 case PPP_LCP:
457 pfunc = print_lcp_config_options;
458 break;
459 case PPP_IPCP:
460 pfunc = print_ipcp_config_options;
461 break;
462 case PPP_CCP:
463 pfunc = print_ccp_config_options;
464 break;
465 case PPP_BACP:
466 pfunc = print_bacp_config_options;
467 break;
468 }
469 if ((j = (*pfunc)(p, len)) == 0)
470 break;
471 x -= j;
472 p += j;
473 } while (x > 0);
474 break;
475
476 case CPCODES_TERM_REQ:
477 case CPCODES_TERM_ACK:
478 /* XXX: need to decode Data? */
479 break;
480 case CPCODES_CODE_REJ:
481 /* XXX: need to decode Rejected-Packet? */
482 break;
483 case CPCODES_PROT_REJ:
484 if (length < 6)
485 break;
486 printf(", Rejected-Protocol=%04x", EXTRACT_16BITS(p));
487 /* XXX: need to decode Rejected-Information? */
488 break;
489 case CPCODES_ECHO_REQ:
490 case CPCODES_ECHO_RPL:
491 case CPCODES_DISC_REQ:
492 case CPCODES_ID:
493 if (length < 8)
494 break;
495 printf(", Magic-Num=%08x", EXTRACT_32BITS(p));
496 /* XXX: need to decode Data? */
497 break;
498 case CPCODES_TIME_REM:
499 if (length < 12)
500 break;
501 printf(", Magic-Num=%08x", EXTRACT_32BITS(p));
502 printf(" Seconds-Remaining=%u", EXTRACT_32BITS(p + 4));
503 /* XXX: need to decode Message? */
504 break;
505 default:
506 printf(", unknown-Codes-0x%02x", code);
507 break;
508 }
509 }
510
511 /* LCP config options */
512 static int
513 print_lcp_config_options(const u_char *p, int length)
514 {
515 int len, opt;
516 int i;
517
518 if (length < 2)
519 return 0;
520 len = p[1];
521 opt = p[0];
522 if (length < len)
523 return 0;
524 if ((opt >= LCPOPT_MIN) && (opt <= LCPOPT_MAX))
525 printf(", %s", lcpconfopts[opt]);
526 else {
527 printf(", unknwhown-%d", opt);
528 return len;
529 }
530
531 switch (opt) {
532 case LCPOPT_VEXT:
533 if (len >= 6) {
534 printf(" OUI=%02x%02x%02x", p[2], p[3], p[4]);
535 #if 0
536 printf(" kind=%02x", p[5]);
537 printf(" val=")
538 for (i = 0; i < len - 6; i++) {
539 printf("%02x", p[6 + i]);
540 }
541 #endif
542 }
543 break;
544 case LCPOPT_MRU:
545 if (len == 4)
546 printf("=%u", EXTRACT_16BITS(p + 2));
547 break;
548 case LCPOPT_ACCM:
549 if (len == 6)
550 printf("=%08x", EXTRACT_32BITS(p + 2));
551 break;
552 case LCPOPT_AP:
553 if (len >= 4) {
554 if (p[2] == 0xc0 && p[3] == 0x23)
555 printf(" PAP");
556 else if (p[2] == 0xc2 && p[3] == 0x23) {
557 printf(" CHAP/");
558 switch (p[4]) {
559 default:
560 printf("unknown-algorithm-%u", p[4]);
561 break;
562 case AUTHALG_CHAPMD5:
563 printf("MD5");
564 break;
565 case AUTHALG_MSCHAP1:
566 printf("MSCHAPv1");
567 break;
568 case AUTHALG_MSCHAP2:
569 printf("MSCHAPv2");
570 break;
571 }
572 }
573 else if (p[2] == 0xc2 && p[3] == 0x27)
574 printf(" EAP");
575 else if (p[2] == 0xc0 && p[3] == 0x27)
576 printf(" SPAP");
577 else if (p[2] == 0xc1 && p[3] == 0x23)
578 printf(" Old-SPAP");
579 else
580 printf("unknown");
581 }
582 break;
583 case LCPOPT_QP:
584 if (len >= 4) {
585 if (p[2] == 0xc0 && p[3] == 0x25)
586 printf(" LQR");
587 else
588 printf(" unknown");
589 }
590 break;
591 case LCPOPT_MN:
592 if (len == 6)
593 printf("=%08x", EXTRACT_32BITS(p + 2));
594 break;
595 case LCPOPT_PFC:
596 break;
597 case LCPOPT_ACFC:
598 break;
599 case LCPOPT_LD:
600 if (len == 4)
601 printf("=%04x", EXTRACT_16BITS(p + 2));
602 break;
603 case LCPOPT_CBACK:
604 if (len < 3)
605 break;
606 switch (p[2]) { /* Operation */
607 case CALLBACK_AUTH:
608 printf(" UserAuth");
609 break;
610 case CALLBACK_DSTR:
611 printf(" DialString");
612 break;
613 case CALLBACK_LID:
614 printf(" LocalID");
615 break;
616 case CALLBACK_E164:
617 printf(" E.164");
618 break;
619 case CALLBACK_X500:
620 printf(" X.500");
621 break;
622 case CALLBACK_CBCP:
623 printf(" CBCP");
624 break;
625 default:
626 printf(" unknown-operation=%u", p[2]);
627 break;
628 }
629 break;
630 case LCPOPT_MLMRRU:
631 if (len == 4)
632 printf("=%u", EXTRACT_16BITS(p + 2));
633 break;
634 case LCPOPT_MLED:
635 if (len < 3)
636 break;
637 switch (p[2]) { /* class */
638 case MEDCLASS_NULL:
639 printf(" Null");
640 break;
641 case MEDCLASS_LOCAL:
642 printf(" Local"); /* XXX */
643 break;
644 case MEDCLASS_IPV4:
645 if (len != 7)
646 break;
647 printf(" IPv4=%s", ipaddr_string(p + 3));
648 break;
649 case MEDCLASS_MAC:
650 if (len != 9)
651 break;
652 printf(" MAC=%02x:%02x:%02x:%02x:%02x:%02x",
653 p[3], p[4], p[5], p[6], p[7], p[8]);
654 break;
655 case MEDCLASS_MNB:
656 printf(" Magic-Num-Block"); /* XXX */
657 break;
658 case MEDCLASS_PSNDN:
659 printf(" PSNDN"); /* XXX */
660 break;
661 }
662 break;
663
664 /* XXX: to be supported */
665 #if 0
666 case LCPOPT_DEP6:
667 case LCPOPT_FCSALT:
668 case LCPOPT_SDP:
669 case LCPOPT_NUMMODE:
670 case LCPOPT_DEP12:
671 case LCPOPT_DEP14:
672 case LCPOPT_DEP15:
673 case LCPOPT_DEP16:
674 case LCPOPT_MLSSNHF:
675 case LCPOPT_PROP:
676 case LCPOPT_DCEID:
677 case LCPOPT_MPP:
678 case LCPOPT_LCPAOPT:
679 case LCPOPT_COBS:
680 case LCPOPT_PE:
681 case LCPOPT_MLHF:
682 case LCPOPT_I18N:
683 case LCPOPT_SDLOS:
684 case LCPOPT_PPPMUX:
685 break;
686 #endif
687 }
688 return len;
689 }
690
691 /* CHAP */
692 static void
693 handle_chap(const u_char *p, int length)
694 {
695 u_int code, len;
696 int val_size, name_size, msg_size;
697 const u_char *p0;
698 int i;
699
700 p0 = p;
701 if (length < 1) {
702 printf("[|chap]");
703 return;
704 } else if (length < 4) {
705 printf("[|chap 0x%02x]", *p);
706 return;
707 }
708
709 code = *p;
710 if ((code >= CHAP_CODEMIN) && (code <= CHAP_CODEMAX))
711 printf("%s", chapcode[code - 1]);
712 else {
713 printf("0x%02x", code);
714 return;
715 }
716 p++;
717
718 printf("(%u)", *p); /* ID */
719 p++;
720
721 len = EXTRACT_16BITS(p);
722 p += 2;
723
724 /*
725 * Note that this is a generic CHAP decoding routine. Since we
726 * don't know which flavor of CHAP (i.e. CHAP-MD5, MS-CHAPv1,
727 * MS-CHAPv2) is used at this point, we can't decode packet
728 * specifically to each algorithms. Instead, we simply decode
729 * the GCD (Gratest Common Denominator) for all algorithms.
730 */
731 switch (code) {
732 case CHAP_CHAL:
733 case CHAP_RESP:
734 if (length - (p - p0) < 1)
735 return;
736 val_size = *p; /* value size */
737 p++;
738 if (length - (p - p0) < val_size)
739 return;
740 printf(", Value=");
741 for (i = 0; i < val_size; i++)
742 printf("%02x", *p++);
743 name_size = len - (p - p0);
744 printf(", Name=");
745 for (i = 0; i < name_size; i++)
746 safeputchar(*p++);
747 break;
748 case CHAP_SUCC:
749 case CHAP_FAIL:
750 msg_size = len - (p - p0);
751 printf(", Msg=");
752 for (i = 0; i< msg_size; i++)
753 safeputchar(*p++);
754 break;
755 }
756 }
757
758 /* PAP */
759 static void
760 handle_pap(const u_char *p, int length)
761 {
762 u_int code, len;
763 int peerid_len, passwd_len, msg_len;
764 const u_char *p0;
765 int i;
766
767 p0 = p;
768 if (length < 1) {
769 printf("[|pap]");
770 return;
771 } else if (length < 4) {
772 printf("[|pap 0x%02x]", *p);
773 return;
774 }
775
776 code = *p;
777 if (length < 4)
778 if ((code >= PAP_CODEMIN) && (code <= PAP_CODEMAX))
779 printf("%s", papcode[code - 1]);
780 else {
781 printf("0x%02x", code);
782 return;
783 }
784 p++;
785
786 printf("(%u)", *p); /* ID */
787 p++;
788
789 len = EXTRACT_16BITS(p);
790 p += 2;
791
792 switch (code) {
793 case PAP_AREQ:
794 if (length - (p - p0) < 1)
795 return;
796 peerid_len = *p; /* Peer-ID Length */
797 p++;
798 if (length - (p - p0) < peerid_len)
799 return;
800 printf(", Peer=");
801 for (i = 0; i < peerid_len; i++)
802 safeputchar(*p++);
803
804 if (length - (p - p0) < 1)
805 return;
806 passwd_len = *p; /* Password Length */
807 p++;
808 if (length - (p - p0) < passwd_len)
809 return;
810 printf(", Name=");
811 for (i = 0; i < passwd_len; i++)
812 safeputchar(*p++);
813 break;
814 case PAP_AACK:
815 case PAP_ANAK:
816 if (length - (p - p0) < 1)
817 return;
818 msg_len = *p; /* Msg-Length */
819 p++;
820 if (length - (p - p0) < passwd_len)
821 return;
822 printf(", Msg=");
823 for (i = 0; i< msg_len; i++)
824 safeputchar(*p++);
825 break;
826 }
827 return;
828 }
829
830 /* BAP */
831 static void
832 handle_bap(const u_char *p, int length)
833 {
834 /* XXX: to be supported!! */
835 }
836
837
838 /* IPCP config options */
839 static int
840 print_ipcp_config_options(const u_char *p, int length)
841 {
842 int len, opt;
843
844 if (length < 2)
845 return 0;
846 len = p[1];
847 opt = p[0];
848 if (length < len)
849 return 0;
850 switch (opt) {
851 case IPCPOPT_2ADDR: /* deprecated */
852 if (len != 10)
853 goto invlen;
854 printf(", IP-Addrs src=%s dst=%s",
855 ipaddr_string(p + 2),
856 ipaddr_string(p + 6));
857 break;
858 case IPCPOPT_IPCOMP:
859 if (len != 4)
860 goto invlen;
861 printf(", IP-Comp");
862 if (EXTRACT_16BITS(p + 2) == PPP_VJC) {
863 printf(" VJ-Comp");
864 /* XXX: VJ-Comp parameters should be decoded */
865 } else
866 printf(" unknown-comp-proto=%04x", EXTRACT_16BITS(p + 2));
867 break;
868 case IPCPOPT_ADDR:
869 if (len != 6)
870 goto invlen;
871 printf(", IP-Addr=%s", ipaddr_string(p + 2));
872 break;
873 case IPCPOPT_MOBILE4:
874 if (len != 6)
875 goto invlen;
876 printf(", Home-Addr=%s", ipaddr_string(p + 2));
877 break;
878 case IPCPOPT_PRIDNS:
879 if (len != 6)
880 goto invlen;
881 printf(", Pri-DNS=%s", ipaddr_string(p + 2));
882 break;
883 case IPCPOPT_PRINBNS:
884 if (len != 6)
885 goto invlen;
886 printf(", Pri-NBNS=%s", ipaddr_string(p + 2));
887 break;
888 case IPCPOPT_SECDNS:
889 if (len != 6)
890 goto invlen;
891 printf(", Sec-DNS=%s", ipaddr_string(p + 2));
892 break;
893 case IPCPOPT_SECNBNS:
894 if (len != 6)
895 goto invlen;
896 printf(", Sec-NBNS=%s", ipaddr_string(p + 2));
897 break;
898 default:
899 printf(", unknown-%d", opt);
900 break;
901 }
902 return len;
903
904 invlen:
905 printf(", invalid-length-%d", opt);
906 return 0;
907 }
908
909 /* CCP config options */
910 static int
911 print_ccp_config_options(const u_char *p, int length)
912 {
913 int len, opt;
914
915 if (length < 2)
916 return 0;
917 len = p[1];
918 opt = p[0];
919 if (length < len)
920 return 0;
921 if ((opt >= CCPOPT_MIN) && (opt <= CCPOPT_MAX))
922 printf(", %s", ccpconfopts[opt]);
923 #if 0 /* XXX */
924 switch (opt) {
925 case CCPOPT_OUI:
926 case CCPOPT_PRED1:
927 case CCPOPT_PRED2:
928 case CCPOPT_PJUMP:
929 case CCPOPT_HPPPC:
930 case CCPOPT_STACLZS:
931 case CCPOPT_MPPC:
932 case CCPOPT_GFZA:
933 case CCPOPT_V42BIS:
934 case CCPOPT_BSDCOMP:
935 case CCPOPT_LZSDCP:
936 case CCPOPT_MVRCA:
937 case CCPOPT_DEC:
938 case CCPOPT_DEFLATE:
939 case CCPOPT_RESV:
940 break;
941
942 default:
943 printf(", unknown-%d", opt);
944 break;
945 }
946 #endif
947 return len;
948 }
949
950 /* BACP config options */
951 static int
952 print_bacp_config_options(const u_char *p, int length)
953 {
954 int len, opt;
955
956 if (length < 2)
957 return 0;
958 len = p[1];
959 opt = p[0];
960 if (length < len)
961 return 0;
962 if (opt == BACPOPT_FPEER) {
963 printf(", Favored-Peer");
964 printf(" Magic-Num=%08x", EXTRACT_32BITS(p + 2));
965 } else {
966 printf(", unknown-option-%d", opt);
967 }
968 return len;
969 }
970
971
972 /* PPP */
973 static void
974 handle_ppp(u_int proto, const u_char *p, int length)
975 {
976 switch (proto) {
977 case PPP_LCP:
978 case PPP_IPCP:
979 case PPP_CCP:
980 case PPP_BACP:
981 handle_ctrl_proto(proto, p, length);
982 break;
983 case PPP_CHAP:
984 handle_chap(p, length);
985 break;
986 case PPP_PAP:
987 handle_pap(p, length);
988 break;
989 case PPP_BAP: /* XXX: not yet completed */
990 handle_bap(p, length);
991 break;
992 case ETHERTYPE_IP: /*XXX*/
993 case PPP_IP:
994 ip_print(p, length);
995 break;
996 #ifdef INET6
997 case ETHERTYPE_IPV6: /*XXX*/
998 case PPP_IPV6:
999 ip6_print(p, length);
1000 break;
1001 #endif
1002 }
1003 }
1004
1005 /* Standard PPP printer */
1006 void
1007 ppp_print(register const u_char *p, u_int length)
1008 {
1009 u_int proto;
1010
1011 /*
1012 * Here, we assume that p points to the Address and Control
1013 * field (if they present).
1014 */
1015 if (length < 2)
1016 goto trunc;
1017 if (*p == PPP_ADDRESS && *(p + 1) == PPP_CONTROL) {
1018 p += 2; /* ACFC not used */
1019 length -= 2;
1020 }
1021
1022 if (length < 2)
1023 goto trunc;
1024 if (*p % 2) {
1025 proto = *p; /* PFC is used */
1026 p++;
1027 length--;
1028 } else {
1029 proto = EXTRACT_16BITS(p);
1030 p += 2;
1031 length -= 2;
1032 }
1033
1034 printf("%s: ", ppp_protoname(proto));
1035
1036 handle_ppp(proto, p, length);
1037 return;
1038 trunc:
1039 printf("[|ppp]");
1040 }
1041
1042
1043 /* PPP I/F printer */
1044 void
1045 ppp_if_print(u_char *user, const struct pcap_pkthdr *h,
1046 register const u_char *p)
1047 {
1048 register u_int length = h->len;
1049 register u_int caplen = h->caplen;
1050 const struct ip *ip;
1051 u_int proto;
1052
1053 ts_print(&h->ts);
1054
1055 if (caplen < PPP_HDRLEN) {
1056 printf("[|ppp]");
1057 goto out;
1058 }
1059
1060 /*
1061 * Some printers want to get back at the link level addresses,
1062 * and/or check that they're not walking off the end of the packet.
1063 * Rather than pass them all the way down, we set these globals. */
1064
1065 packetp = p;
1066 snapend = p + caplen;
1067
1068 #if 0
1069 /*
1070 * XXX: seems to assume that there are 2 octets prepended to an
1071 * actual PPP frame. The 1st octet looks like Input/Output flag
1072 * while 2nd octet is unknown, at least to me
1073 * (mshindo@mshindo.net).
1074 *
1075 * That was what the original tcpdump code did.
1076 *
1077 * FreeBSD's "if_ppp.c" *does* set the first octet to 1 for outbound
1078 * packets and 0 for inbound packets - but only if the
1079 * protocol field has the 0x8000 bit set (i.e., it's a network
1080 * control protocol); it does so before running the packet through
1081 * "bpf_filter" to see if it should be discarded, and to see
1082 * if we should update the time we sent the most recent packet...
1083 *
1084 * ...but it puts the original address field back after doing
1085 * so.
1086 *
1087 * NetBSD's "if_ppp.c" doesn't set the first octet in that fashion.
1088 *
1089 * I don't know if any PPP implementation handed up to a BPF
1090 * device packets with the first octet being 1 for outbound and
1091 * 0 for inbound packets, so I (guy@alum.mit.edu) don't know
1092 * whether that ever needs to be checked or not.
1093 *
1094 * Note that NetBSD has a DLT_PPP_SERIAL, which it uses for PPP,
1095 * and its tcpdump appears to assume that the frame always
1096 * begins with an address field and a control field, and that
1097 * the address field might be 0x0f or 0x8f, for Cisco
1098 * point-to-point with HDLC framing as per section 4.3.1 of RFC
1099 * 1547, as well as 0xff, for PPP in HDLC-like framing as per
1100 * RFC 1662.
1101 *
1102 * (Is the Cisco framing in question what DLT_C_HDLC, in
1103 * BSD/OS, is?)
1104 */
1105 if (eflag)
1106 printf("%c %4d %02x ", p[0] ? 'O' : 'I', length, p[1]);
1107 #endif
1108
1109 ppp_print(p, length);
1110
1111 if (xflag)
1112 default_print(p, caplen);
1113 out:
1114 putchar('\n');
1115 }
1116
1117 /*
1118 * PPP I/F printer to use if we know that RFC 1662-style PPP in HDLC-like
1119 * framing, or Cisco PPP with HDLC framing as per section 4.3.1 of RFC 1547,
1120 * is being used (i.e., we don't check for PPP_ADDRESS and PPP_CONTROL,
1121 * discard them *if* those are the first two octets, and parse the remaining
1122 * packet as a PPP packet, as "ppp_print()" does).
1123 *
1124 * This handles, for example, DLT_PPP_SERIAL in NetBSD.
1125 */
1126 void
1127 ppp_hdlc_if_print(u_char *user, const struct pcap_pkthdr *h,
1128 register const u_char *p)
1129 {
1130 register u_int length = h->len;
1131 register u_int caplen = h->caplen;
1132 u_int proto;
1133
1134 if (caplen < 2) {
1135 printf("[|ppp]");
1136 goto out;
1137 }
1138
1139 /*
1140 * Some printers want to get back at the link level addresses,
1141 * and/or check that they're not walking off the end of the packet.
1142 * Rather than pass them all the way down, we set these globals.
1143 */
1144 packetp = p;
1145 snapend = p + caplen;
1146
1147 switch (p[0]) {
1148
1149 case PPP_ADDRESS:
1150 if (caplen < 4) {
1151 printf("[|ppp]");
1152 goto out;
1153 }
1154
1155 ts_print(&h->ts);
1156 if (eflag)
1157 printf("%02x %02x %d ", p[0], p[1], length);
1158 p += 2;
1159 length -= 2;
1160
1161 proto = EXTRACT_16BITS(p);
1162 p += 2;
1163 length -= 2;
1164 printf("%s: ", ppp_protoname(proto));
1165
1166 handle_ppp(proto, p, length);
1167 break;
1168
1169 case CHDLC_UNICAST:
1170 case CHDLC_BCAST:
1171 /*
1172 * Have the Cisco HDLC print routine do all the work.
1173 */
1174 chdlc_if_print(user, h, p);
1175 return;
1176
1177 default:
1178 ts_print(&h->ts);
1179 if (eflag)
1180 printf("%02x %02x %d ", p[0], p[1], length);
1181 p += 2;
1182 length -= 2;
1183
1184 /*
1185 * XXX - NetBSD's "ppp_netbsd_serial_if_print()" treats
1186 * the next two octets as an Ethernet type; does that
1187 * ever happen?
1188 */
1189 printf("unknown addr %02x; ctrl %02x", p[0], p[1]);
1190 break;
1191 }
1192
1193 if (xflag)
1194 default_print(p, caplen);
1195 out:
1196 putchar('\n');
1197 }
1198
1199
1200
1201 struct tok ppptype2str[] = {
1202 { PPP_IP, "IP" },
1203 { PPP_OSI, "OSI" },
1204 { PPP_NS, "NS" },
1205 { PPP_DECNET, "DECNET" },
1206 { PPP_APPLE, "APPLE" },
1207 { PPP_IPX, "IPX" },
1208 { PPP_VJC, "VJC" },
1209 { PPP_VJNC, "VJNC" },
1210 { PPP_BRPDU, "BRPDU" },
1211 { PPP_STII, "STII" },
1212 { PPP_VINES, "VINES" },
1213
1214 { PPP_HELLO, "HELLO" },
1215 { PPP_LUXCOM, "LUXCOM" },
1216 { PPP_SNS, "SNS" },
1217 { PPP_IPCP, "IPCP" },
1218 { PPP_OSICP, "OSICP" },
1219 { PPP_NSCP, "NSCP" },
1220 { PPP_DECNETCP, "DECNETCP" },
1221 { PPP_APPLECP, "APPLECP" },
1222 { PPP_IPXCP, "IPXCP" },
1223 { PPP_STIICP, "STIICP" },
1224 { PPP_VINESCP, "VINESCP" },
1225
1226 { PPP_LCP, "LCP" },
1227 { PPP_PAP, "PAP" },
1228 { PPP_LQM, "LQM" },
1229 { PPP_CHAP, "CHAP" },
1230 { PPP_BACP, "BACP" },
1231 { PPP_BAP, "BAP" },
1232 { PPP_MP, "MP" },
1233 { 0, NULL }
1234 };
1235
1236 #define PPP_BSDI_HDRLEN 24
1237
1238 /* BSD/OS specific PPP printer */
1239 void
1240 ppp_bsdos_if_print(u_char *user, const struct pcap_pkthdr *h,
1241 register const u_char *p)
1242 {
1243 #ifdef __bsdi__
1244 register u_int length = h->len;
1245 register u_int caplen = h->caplen;
1246 register int hdrlength;
1247 u_int16_t ptype;
1248 const u_char *q;
1249 int i;
1250
1251 ts_print(&h->ts);
1252
1253 if (caplen < PPP_BSDI_HDRLEN) {
1254 printf("[|ppp]");
1255 goto out;
1256 }
1257
1258 /*
1259 * Some printers want to get back at the link level addresses,
1260 * and/or check that they're not walking off the end of the packet.
1261 * Rather than pass them all the way down, we set these globals.
1262 */
1263 packetp = p;
1264 snapend = p + caplen;
1265 hdrlength = 0;
1266
1267 #if 0
1268 if (p[0] == PPP_ADDRESS && p[1] == PPP_CONTROL) {
1269 if (eflag)
1270 printf("%02x %02x ", p[0], p[1]);
1271 p += 2;
1272 hdrlength = 2;
1273 }
1274
1275 if (eflag)
1276 printf("%d ", length);
1277 /* Retrieve the protocol type */
1278 if (*p & 01) {
1279 /* Compressed protocol field */
1280 ptype = *p;
1281 if (eflag)
1282 printf("%02x ", ptype);
1283 p++;
1284 hdrlength += 1;
1285 } else {
1286 /* Un-compressed protocol field */
1287 ptype = ntohs(*(u_int16_t *)p);
1288 if (eflag)
1289 printf("%04x ", ptype);
1290 p += 2;
1291 hdrlength += 2;
1292 }
1293 #else
1294 ptype = 0; /*XXX*/
1295 if (eflag)
1296 printf("%c ", p[SLC_DIR] ? 'O' : 'I');
1297 if (p[SLC_LLHL]) {
1298 /* link level header */
1299 struct ppp_header *ph;
1300
1301 q = p + SLC_BPFHDRLEN;
1302 ph = (struct ppp_header *)q;
1303 if (ph->phdr_addr == PPP_ADDRESS
1304 && ph->phdr_ctl == PPP_CONTROL) {
1305 if (eflag)
1306 printf("%02x %02x ", q[0], q[1]);
1307 ptype = ntohs(ph->phdr_type);
1308 if (eflag && (ptype == PPP_VJC || ptype == PPP_VJNC)) {
1309 printf("%s ", tok2str(ppptype2str,
1310 "proto-#%d", ptype));
1311 }
1312 } else {
1313 if (eflag) {
1314 printf("LLH=[");
1315 for (i = 0; i < p[SLC_LLHL]; i++)
1316 printf("%02x", q[i]);
1317 printf("] ");
1318 }
1319 }
1320 if (eflag)
1321 printf("%d ", length);
1322 }
1323 if (p[SLC_CHL]) {
1324 q = p + SLC_BPFHDRLEN + p[SLC_LLHL];
1325
1326 switch (ptype) {
1327 case PPP_VJC:
1328 ptype = vjc_print(q, length - (q - p), ptype);
1329 hdrlength = PPP_BSDI_HDRLEN;
1330 p += hdrlength;
1331 switch (ptype) {
1332 case PPP_IP:
1333 ip_print(p, length);
1334 break;
1335 #ifdef INET6
1336 case PPP_IPV6:
1337 ip6_print(p, length);
1338 break;
1339 #endif
1340 }
1341 goto printx;
1342 case PPP_VJNC:
1343 ptype = vjc_print(q, length - (q - p), ptype);
1344 hdrlength = PPP_BSDI_HDRLEN;
1345 p += hdrlength;
1346 switch (ptype) {
1347 case PPP_IP:
1348 ip_print(p, length);
1349 break;
1350 #ifdef INET6
1351 case PPP_IPV6:
1352 ip6_print(p, length);
1353 break;
1354 #endif
1355 }
1356 goto printx;
1357 default:
1358 if (eflag) {
1359 printf("CH=[");
1360 for (i = 0; i < p[SLC_LLHL]; i++)
1361 printf("%02x", q[i]);
1362 printf("] ");
1363 }
1364 break;
1365 }
1366 }
1367
1368 hdrlength = PPP_BSDI_HDRLEN;
1369 #endif
1370
1371 length -= hdrlength;
1372 p += hdrlength;
1373
1374 switch (ptype) {
1375 case PPP_IP:
1376 ip_print(p, length);
1377 break;
1378 #ifdef INET6
1379 case PPP_IPV6:
1380 ip6_print(p, length);
1381 break;
1382 #endif
1383 default:
1384 printf("%s ", tok2str(ppptype2str, "proto-#%d", ptype));
1385 }
1386
1387 printx:
1388 if (xflag)
1389 default_print((const u_char *)p, caplen - hdrlength);
1390 out:
1391 putchar('\n');
1392 #endif /* __bsdi__ */
1393 }