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