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