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