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