]> The Tcpdump Group git mirrors - tcpdump/blob - print-ppp.c
avoid trigraph
[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.60 2001-03-17 04:41:49 itojun 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 case PPP_IPV6: return "IPv6";
351 #ifdef PPP_XNS
352 case PPP_XNS: return "XNS";
353 #endif
354 case PPP_IPX: return "IPX";
355 case PPP_VJC: return "VJC";
356 case PPP_VJNC: return "VJNC";
357 case PPP_COMP: return "COMP";
358 case PPP_IPCP: return "IPCP";
359 case PPP_IPV6CP: return "IPv6CP";
360 case PPP_IPXCP: return "IPXCP";
361 case PPP_CCP: return "CCP";
362 case PPP_LCP: return "LCP";
363 case PPP_PAP: return "PAP";
364 #ifdef PPP_LQR
365 case PPP_LQR: return "LQR";
366 #endif
367 case PPP_CHAP: return "CHAP";
368 case PPP_BACP: return "BACP";
369 case PPP_BAP: return "BAP";
370 default:
371 snprintf(buf, sizeof(buf), "unknown-0x%04x", proto);
372 return buf;
373 }
374 }
375
376 /* generic Control Protocol (e.g. LCP, IPCP, CCP, etc.) handler */
377 static void
378 handle_ctrl_proto(u_int proto, const u_char *p, int length)
379 {
380 u_int code, len;
381 int (*pfunc)(const u_char *, int);
382 int x, j;
383
384 if (length < 1) {
385 printf("[|%s]", ppp_protoname(proto));
386 return;
387 } else if (length < 4) {
388 printf("[|%s 0x%02x]", ppp_protoname(proto), *p);
389 return;
390 }
391
392 code = *p;
393 if ((code >= CPCODES_MIN) && (code <= CPCODES_MAX))
394 printf("%s", cpcodes[code]);
395 else {
396 printf("0x%02x", code);
397 return;
398 }
399 p++;
400
401 printf("(%u)", *p); /* ID */
402 p++;
403
404 len = EXTRACT_16BITS(p);
405 p += 2;
406
407 if (length <= 4)
408 return; /* there may be a NULL confreq etc. */
409
410 switch (code) {
411 case CPCODES_VEXT:
412 if (length < 11)
413 break;
414 printf(", Magic-Num=%08x", EXTRACT_32BITS(p));
415 p += 4;
416 printf(" OUI=%02x%02x%02x", p[0], p[1], p[2]);
417 /* XXX: need to decode Kind and Value(s)? */
418 break;
419 case CPCODES_CONF_REQ:
420 case CPCODES_CONF_ACK:
421 case CPCODES_CONF_NAK:
422 case CPCODES_CONF_REJ:
423 x = len - 4; /* Code(1), Identifier(1) and Length(2) */
424 do {
425 switch (proto) {
426 case PPP_LCP:
427 pfunc = print_lcp_config_options;
428 break;
429 case PPP_IPCP:
430 pfunc = print_ipcp_config_options;
431 break;
432 case PPP_CCP:
433 pfunc = print_ccp_config_options;
434 break;
435 case PPP_BACP:
436 pfunc = print_bacp_config_options;
437 break;
438 default:
439 /*
440 * This should never happen, but we set
441 * "pfunc" to squelch uninitialized
442 * variable warnings from compilers.
443 */
444 pfunc = NULL;
445 break;
446 }
447 if ((j = (*pfunc)(p, len)) == 0)
448 break;
449 x -= j;
450 p += j;
451 } while (x > 0);
452 break;
453
454 case CPCODES_TERM_REQ:
455 case CPCODES_TERM_ACK:
456 /* XXX: need to decode Data? */
457 break;
458 case CPCODES_CODE_REJ:
459 /* XXX: need to decode Rejected-Packet? */
460 break;
461 case CPCODES_PROT_REJ:
462 if (length < 6)
463 break;
464 printf(", Rejected-Protocol=%04x", EXTRACT_16BITS(p));
465 /* XXX: need to decode Rejected-Information? */
466 break;
467 case CPCODES_ECHO_REQ:
468 case CPCODES_ECHO_RPL:
469 case CPCODES_DISC_REQ:
470 case CPCODES_ID:
471 if (length < 8)
472 break;
473 printf(", Magic-Num=%08x", EXTRACT_32BITS(p));
474 /* XXX: need to decode Data? */
475 break;
476 case CPCODES_TIME_REM:
477 if (length < 12)
478 break;
479 printf(", Magic-Num=%08x", EXTRACT_32BITS(p));
480 printf(" Seconds-Remaining=%u", EXTRACT_32BITS(p + 4));
481 /* XXX: need to decode Message? */
482 break;
483 default:
484 printf(", unknown-Codes-0x%02x", code);
485 break;
486 }
487 }
488
489 /* LCP config options */
490 static int
491 print_lcp_config_options(const u_char *p, int length)
492 {
493 int len, opt;
494
495 if (length < 2)
496 return 0;
497 len = p[1];
498 opt = p[0];
499 if (length < len)
500 return 0;
501 if ((opt >= LCPOPT_MIN) && (opt <= LCPOPT_MAX))
502 printf(", %s", lcpconfopts[opt]);
503 else {
504 printf(", unknwhown-%d", opt);
505 return len;
506 }
507
508 switch (opt) {
509 case LCPOPT_VEXT:
510 if (len >= 6) {
511 printf(" OUI=%02x%02x%02x", p[2], p[3], p[4]);
512 #if 0
513 printf(" kind=%02x", p[5]);
514 printf(" val=")
515 for (i = 0; i < len - 6; i++) {
516 printf("%02x", p[6 + i]);
517 }
518 #endif
519 }
520 break;
521 case LCPOPT_MRU:
522 if (len == 4)
523 printf("=%u", EXTRACT_16BITS(p + 2));
524 break;
525 case LCPOPT_ACCM:
526 if (len == 6)
527 printf("=%08x", EXTRACT_32BITS(p + 2));
528 break;
529 case LCPOPT_AP:
530 if (len >= 4) {
531 if (p[2] == 0xc0 && p[3] == 0x23)
532 printf(" PAP");
533 else if (p[2] == 0xc2 && p[3] == 0x23) {
534 printf(" CHAP/");
535 switch (p[4]) {
536 default:
537 printf("unknown-algorithm-%u", p[4]);
538 break;
539 case AUTHALG_CHAPMD5:
540 printf("MD5");
541 break;
542 case AUTHALG_MSCHAP1:
543 printf("MSCHAPv1");
544 break;
545 case AUTHALG_MSCHAP2:
546 printf("MSCHAPv2");
547 break;
548 }
549 }
550 else if (p[2] == 0xc2 && p[3] == 0x27)
551 printf(" EAP");
552 else if (p[2] == 0xc0 && p[3] == 0x27)
553 printf(" SPAP");
554 else if (p[2] == 0xc1 && p[3] == 0x23)
555 printf(" Old-SPAP");
556 else
557 printf("unknown");
558 }
559 break;
560 case LCPOPT_QP:
561 if (len >= 4) {
562 if (p[2] == 0xc0 && p[3] == 0x25)
563 printf(" LQR");
564 else
565 printf(" unknown");
566 }
567 break;
568 case LCPOPT_MN:
569 if (len == 6)
570 printf("=%08x", EXTRACT_32BITS(p + 2));
571 break;
572 case LCPOPT_PFC:
573 break;
574 case LCPOPT_ACFC:
575 break;
576 case LCPOPT_LD:
577 if (len == 4)
578 printf("=%04x", EXTRACT_16BITS(p + 2));
579 break;
580 case LCPOPT_CBACK:
581 if (len < 3)
582 break;
583 switch (p[2]) { /* Operation */
584 case CALLBACK_AUTH:
585 printf(" UserAuth");
586 break;
587 case CALLBACK_DSTR:
588 printf(" DialString");
589 break;
590 case CALLBACK_LID:
591 printf(" LocalID");
592 break;
593 case CALLBACK_E164:
594 printf(" E.164");
595 break;
596 case CALLBACK_X500:
597 printf(" X.500");
598 break;
599 case CALLBACK_CBCP:
600 printf(" CBCP");
601 break;
602 default:
603 printf(" unknown-operation=%u", p[2]);
604 break;
605 }
606 break;
607 case LCPOPT_MLMRRU:
608 if (len == 4)
609 printf("=%u", EXTRACT_16BITS(p + 2));
610 break;
611 case LCPOPT_MLED:
612 if (len < 3)
613 break;
614 switch (p[2]) { /* class */
615 case MEDCLASS_NULL:
616 printf(" Null");
617 break;
618 case MEDCLASS_LOCAL:
619 printf(" Local"); /* XXX */
620 break;
621 case MEDCLASS_IPV4:
622 if (len != 7)
623 break;
624 printf(" IPv4=%s", ipaddr_string(p + 3));
625 break;
626 case MEDCLASS_MAC:
627 if (len != 9)
628 break;
629 printf(" MAC=%02x:%02x:%02x:%02x:%02x:%02x",
630 p[3], p[4], p[5], p[6], p[7], p[8]);
631 break;
632 case MEDCLASS_MNB:
633 printf(" Magic-Num-Block"); /* XXX */
634 break;
635 case MEDCLASS_PSNDN:
636 printf(" PSNDN"); /* XXX */
637 break;
638 }
639 break;
640
641 /* XXX: to be supported */
642 #if 0
643 case LCPOPT_DEP6:
644 case LCPOPT_FCSALT:
645 case LCPOPT_SDP:
646 case LCPOPT_NUMMODE:
647 case LCPOPT_DEP12:
648 case LCPOPT_DEP14:
649 case LCPOPT_DEP15:
650 case LCPOPT_DEP16:
651 case LCPOPT_MLSSNHF:
652 case LCPOPT_PROP:
653 case LCPOPT_DCEID:
654 case LCPOPT_MPP:
655 case LCPOPT_LCPAOPT:
656 case LCPOPT_COBS:
657 case LCPOPT_PE:
658 case LCPOPT_MLHF:
659 case LCPOPT_I18N:
660 case LCPOPT_SDLOS:
661 case LCPOPT_PPPMUX:
662 break;
663 #endif
664 }
665 return len;
666 }
667
668 /* CHAP */
669 static void
670 handle_chap(const u_char *p, int length)
671 {
672 u_int code, len;
673 int val_size, name_size, msg_size;
674 const u_char *p0;
675 int i;
676
677 p0 = p;
678 if (length < 1) {
679 printf("[|chap]");
680 return;
681 } else if (length < 4) {
682 printf("[|chap 0x%02x]", *p);
683 return;
684 }
685
686 code = *p;
687 if ((code >= CHAP_CODEMIN) && (code <= CHAP_CODEMAX))
688 printf("%s", chapcode[code - 1]);
689 else {
690 printf("0x%02x", code);
691 return;
692 }
693 p++;
694
695 printf("(%u)", *p); /* ID */
696 p++;
697
698 len = EXTRACT_16BITS(p);
699 p += 2;
700
701 /*
702 * Note that this is a generic CHAP decoding routine. Since we
703 * don't know which flavor of CHAP (i.e. CHAP-MD5, MS-CHAPv1,
704 * MS-CHAPv2) is used at this point, we can't decode packet
705 * specifically to each algorithms. Instead, we simply decode
706 * the GCD (Gratest Common Denominator) for all algorithms.
707 */
708 switch (code) {
709 case CHAP_CHAL:
710 case CHAP_RESP:
711 if (length - (p - p0) < 1)
712 return;
713 val_size = *p; /* value size */
714 p++;
715 if (length - (p - p0) < val_size)
716 return;
717 printf(", Value=");
718 for (i = 0; i < val_size; i++)
719 printf("%02x", *p++);
720 name_size = len - (p - p0);
721 printf(", Name=");
722 for (i = 0; i < name_size; i++)
723 safeputchar(*p++);
724 break;
725 case CHAP_SUCC:
726 case CHAP_FAIL:
727 msg_size = len - (p - p0);
728 printf(", Msg=");
729 for (i = 0; i< msg_size; i++)
730 safeputchar(*p++);
731 break;
732 }
733 }
734
735 /* PAP (see RFC 1334) */
736 static void
737 handle_pap(const u_char *p, int length)
738 {
739 u_int code, len;
740 int peerid_len, passwd_len, msg_len;
741 const u_char *p0;
742 int i;
743
744 p0 = p;
745 if (length < 1) {
746 printf("[|pap]");
747 return;
748 } else if (length < 4) {
749 printf("[|pap 0x%02x]", *p);
750 return;
751 }
752
753 code = *p;
754 if ((code >= PAP_CODEMIN) && (code <= PAP_CODEMAX))
755 printf("%s", papcode[code - 1]);
756 else {
757 printf("0x%02x", code);
758 return;
759 }
760 p++;
761
762 printf("(%u)", *p); /* ID */
763 p++;
764
765 len = EXTRACT_16BITS(p);
766 p += 2;
767
768 switch (code) {
769 case PAP_AREQ:
770 if (length - (p - p0) < 1)
771 return;
772 peerid_len = *p; /* Peer-ID Length */
773 p++;
774 if (length - (p - p0) < peerid_len)
775 return;
776 printf(", Peer=");
777 for (i = 0; i < peerid_len; i++)
778 safeputchar(*p++);
779
780 if (length - (p - p0) < 1)
781 return;
782 passwd_len = *p; /* Password Length */
783 p++;
784 if (length - (p - p0) < passwd_len)
785 return;
786 printf(", Name=");
787 for (i = 0; i < passwd_len; i++)
788 safeputchar(*p++);
789 break;
790 case PAP_AACK:
791 case PAP_ANAK:
792 if (length - (p - p0) < 1)
793 return;
794 msg_len = *p; /* Msg-Length */
795 p++;
796 if (length - (p - p0) < msg_len)
797 return;
798 printf(", Msg=");
799 for (i = 0; i< msg_len; i++)
800 safeputchar(*p++);
801 break;
802 }
803 return;
804 }
805
806 /* BAP */
807 static void
808 handle_bap(const u_char *p, int length)
809 {
810 /* XXX: to be supported!! */
811 }
812
813
814 /* IPCP config options */
815 static int
816 print_ipcp_config_options(const u_char *p, int length)
817 {
818 int len, opt;
819
820 if (length < 2)
821 return 0;
822 len = p[1];
823 opt = p[0];
824 if (length < len)
825 return 0;
826 switch (opt) {
827 case IPCPOPT_2ADDR: /* deprecated */
828 if (len != 10)
829 goto invlen;
830 printf(", IP-Addrs src=%s dst=%s",
831 ipaddr_string(p + 2),
832 ipaddr_string(p + 6));
833 break;
834 case IPCPOPT_IPCOMP:
835 if (len < 4)
836 goto invlen;
837 printf(", IP-Comp");
838 if (EXTRACT_16BITS(p + 2) == PPP_VJC) {
839 printf(" VJ-Comp");
840 /* XXX: VJ-Comp parameters should be decoded */
841 } else
842 printf(" unknown-comp-proto=%04x", EXTRACT_16BITS(p + 2));
843 break;
844 case IPCPOPT_ADDR:
845 if (len != 6)
846 goto invlen;
847 printf(", IP-Addr=%s", ipaddr_string(p + 2));
848 break;
849 case IPCPOPT_MOBILE4:
850 if (len != 6)
851 goto invlen;
852 printf(", Home-Addr=%s", ipaddr_string(p + 2));
853 break;
854 case IPCPOPT_PRIDNS:
855 if (len != 6)
856 goto invlen;
857 printf(", Pri-DNS=%s", ipaddr_string(p + 2));
858 break;
859 case IPCPOPT_PRINBNS:
860 if (len != 6)
861 goto invlen;
862 printf(", Pri-NBNS=%s", ipaddr_string(p + 2));
863 break;
864 case IPCPOPT_SECDNS:
865 if (len != 6)
866 goto invlen;
867 printf(", Sec-DNS=%s", ipaddr_string(p + 2));
868 break;
869 case IPCPOPT_SECNBNS:
870 if (len != 6)
871 goto invlen;
872 printf(", Sec-NBNS=%s", ipaddr_string(p + 2));
873 break;
874 default:
875 printf(", unknown-%d", opt);
876 break;
877 }
878 return len;
879
880 invlen:
881 printf(", invalid-length-%d", opt);
882 return 0;
883 }
884
885 /* CCP config options */
886 static int
887 print_ccp_config_options(const u_char *p, int length)
888 {
889 int len, opt;
890
891 if (length < 2)
892 return 0;
893 len = p[1];
894 opt = p[0];
895 if (length < len)
896 return 0;
897 if ((opt >= CCPOPT_MIN) && (opt <= CCPOPT_MAX))
898 printf(", %s", ccpconfopts[opt]);
899 #if 0 /* XXX */
900 switch (opt) {
901 case CCPOPT_OUI:
902 case CCPOPT_PRED1:
903 case CCPOPT_PRED2:
904 case CCPOPT_PJUMP:
905 case CCPOPT_HPPPC:
906 case CCPOPT_STACLZS:
907 case CCPOPT_MPPC:
908 case CCPOPT_GFZA:
909 case CCPOPT_V42BIS:
910 case CCPOPT_BSDCOMP:
911 case CCPOPT_LZSDCP:
912 case CCPOPT_MVRCA:
913 case CCPOPT_DEC:
914 case CCPOPT_DEFLATE:
915 case CCPOPT_RESV:
916 break;
917
918 default:
919 printf(", unknown-%d", opt);
920 break;
921 }
922 #endif
923 return len;
924 }
925
926 /* BACP config options */
927 static int
928 print_bacp_config_options(const u_char *p, int length)
929 {
930 int len, opt;
931
932 if (length < 2)
933 return 0;
934 len = p[1];
935 opt = p[0];
936 if (length < len)
937 return 0;
938 if (opt == BACPOPT_FPEER) {
939 printf(", Favored-Peer");
940 printf(" Magic-Num=%08x", EXTRACT_32BITS(p + 2));
941 } else {
942 printf(", unknown-option-%d", opt);
943 }
944 return len;
945 }
946
947
948 /* PPP */
949 static void
950 handle_ppp(u_int proto, const u_char *p, int length)
951 {
952 switch (proto) {
953 case PPP_LCP:
954 case PPP_IPCP:
955 case PPP_CCP:
956 case PPP_BACP:
957 handle_ctrl_proto(proto, p, length);
958 break;
959 case PPP_CHAP:
960 handle_chap(p, length);
961 break;
962 case PPP_PAP:
963 handle_pap(p, length);
964 break;
965 case PPP_BAP: /* XXX: not yet completed */
966 handle_bap(p, length);
967 break;
968 case ETHERTYPE_IP: /*XXX*/
969 case PPP_IP:
970 ip_print(p, length);
971 break;
972 #ifdef INET6
973 case ETHERTYPE_IPV6: /*XXX*/
974 case PPP_IPV6:
975 ip6_print(p, length);
976 break;
977 #endif
978 case ETHERTYPE_IPX: /*XXX*/
979 case PPP_IPX:
980 ipx_print(p, length);
981 break;
982 default:
983 break;
984 }
985 }
986
987 /* Standard PPP printer */
988 void
989 ppp_print(register const u_char *p, u_int length)
990 {
991 u_int proto;
992 u_int full_length = length;
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 }
1004
1005 if (length < 2)
1006 goto trunc;
1007 if (*p % 2) {
1008 proto = *p; /* PFC is used */
1009 p++;
1010 length--;
1011 } else {
1012 proto = EXTRACT_16BITS(p);
1013 p += 2;
1014 length -= 2;
1015 }
1016
1017 printf("%s %d: ", ppp_protoname(proto), full_length);
1018
1019 handle_ppp(proto, p, length);
1020 return;
1021 trunc:
1022 printf("[|ppp]");
1023 }
1024
1025
1026 /* PPP I/F printer */
1027 void
1028 ppp_if_print(u_char *user, const struct pcap_pkthdr *h,
1029 register const u_char *p)
1030 {
1031 register u_int length = h->len;
1032 register u_int caplen = h->caplen;
1033
1034 ts_print(&h->ts);
1035
1036 if (caplen < PPP_HDRLEN) {
1037 printf("[|ppp]");
1038 goto out;
1039 }
1040
1041 /*
1042 * Some printers want to get back at the link level addresses,
1043 * and/or check that they're not walking off the end of the packet.
1044 * Rather than pass them all the way down, we set these globals. */
1045
1046 packetp = p;
1047 snapend = p + caplen;
1048
1049 #if 0
1050 /*
1051 * XXX: seems to assume that there are 2 octets prepended to an
1052 * actual PPP frame. The 1st octet looks like Input/Output flag
1053 * while 2nd octet is unknown, at least to me
1054 * (mshindo@mshindo.net).
1055 *
1056 * That was what the original tcpdump code did.
1057 *
1058 * FreeBSD's "if_ppp.c" *does* set the first octet to 1 for outbound
1059 * packets and 0 for inbound packets - but only if the
1060 * protocol field has the 0x8000 bit set (i.e., it's a network
1061 * control protocol); it does so before running the packet through
1062 * "bpf_filter" to see if it should be discarded, and to see
1063 * if we should update the time we sent the most recent packet...
1064 *
1065 * ...but it puts the original address field back after doing
1066 * so.
1067 *
1068 * NetBSD's "if_ppp.c" doesn't set the first octet in that fashion.
1069 *
1070 * I don't know if any PPP implementation handed up to a BPF
1071 * device packets with the first octet being 1 for outbound and
1072 * 0 for inbound packets, so I (guy@alum.mit.edu) don't know
1073 * whether that ever needs to be checked or not.
1074 *
1075 * Note that NetBSD has a DLT_PPP_SERIAL, which it uses for PPP,
1076 * and its tcpdump appears to assume that the frame always
1077 * begins with an address field and a control field, and that
1078 * the address field might be 0x0f or 0x8f, for Cisco
1079 * point-to-point with HDLC framing as per section 4.3.1 of RFC
1080 * 1547, as well as 0xff, for PPP in HDLC-like framing as per
1081 * RFC 1662.
1082 *
1083 * (Is the Cisco framing in question what DLT_C_HDLC, in
1084 * BSD/OS, is?)
1085 */
1086 if (eflag)
1087 printf("%c %4d %02x ", p[0] ? 'O' : 'I', length, p[1]);
1088 #endif
1089
1090 ppp_print(p, length);
1091
1092 if (xflag)
1093 default_print(p, caplen);
1094 out:
1095 putchar('\n');
1096 }
1097
1098 /*
1099 * PPP I/F printer to use if we know that RFC 1662-style PPP in HDLC-like
1100 * framing, or Cisco PPP with HDLC framing as per section 4.3.1 of RFC 1547,
1101 * is being used (i.e., we don't check for PPP_ADDRESS and PPP_CONTROL,
1102 * discard them *if* those are the first two octets, and parse the remaining
1103 * packet as a PPP packet, as "ppp_print()" does).
1104 *
1105 * This handles, for example, DLT_PPP_SERIAL in NetBSD.
1106 */
1107 void
1108 ppp_hdlc_if_print(u_char *user, const struct pcap_pkthdr *h,
1109 register const u_char *p)
1110 {
1111 register u_int length = h->len;
1112 register u_int caplen = h->caplen;
1113 u_int proto;
1114
1115 if (caplen < 2) {
1116 printf("[|ppp]");
1117 goto out;
1118 }
1119
1120 /*
1121 * Some printers want to get back at the link level addresses,
1122 * and/or check that they're not walking off the end of the packet.
1123 * Rather than pass them all the way down, we set these globals.
1124 */
1125 packetp = p;
1126 snapend = p + caplen;
1127
1128 switch (p[0]) {
1129
1130 case PPP_ADDRESS:
1131 if (caplen < 4) {
1132 printf("[|ppp]");
1133 goto out;
1134 }
1135
1136 ts_print(&h->ts);
1137 if (eflag)
1138 printf("%02x %02x %d ", p[0], p[1], length);
1139 p += 2;
1140 length -= 2;
1141
1142 proto = EXTRACT_16BITS(p);
1143 p += 2;
1144 length -= 2;
1145 printf("%s: ", ppp_protoname(proto));
1146
1147 handle_ppp(proto, p, length);
1148 break;
1149
1150 case CHDLC_UNICAST:
1151 case CHDLC_BCAST:
1152 /*
1153 * Have the Cisco HDLC print routine do all the work.
1154 */
1155 chdlc_if_print(user, h, p);
1156 return;
1157
1158 default:
1159 ts_print(&h->ts);
1160 if (eflag)
1161 printf("%02x %02x %d ", p[0], p[1], length);
1162 p += 2;
1163 length -= 2;
1164
1165 /*
1166 * XXX - NetBSD's "ppp_netbsd_serial_if_print()" treats
1167 * the next two octets as an Ethernet type; does that
1168 * ever happen?
1169 */
1170 printf("unknown addr %02x; ctrl %02x", p[0], p[1]);
1171 break;
1172 }
1173
1174 if (xflag)
1175 default_print(p, caplen);
1176 out:
1177 putchar('\n');
1178 }
1179
1180
1181
1182 struct tok ppptype2str[] = {
1183 { PPP_IP, "IP" },
1184 { PPP_OSI, "OSI" },
1185 { PPP_NS, "NS" },
1186 { PPP_DECNET, "DECNET" },
1187 { PPP_APPLE, "APPLE" },
1188 { PPP_IPX, "IPX" },
1189 { PPP_VJC, "VJC" },
1190 { PPP_VJNC, "VJNC" },
1191 { PPP_BRPDU, "BRPDU" },
1192 { PPP_STII, "STII" },
1193 { PPP_VINES, "VINES" },
1194
1195 { PPP_HELLO, "HELLO" },
1196 { PPP_LUXCOM, "LUXCOM" },
1197 { PPP_SNS, "SNS" },
1198 { PPP_IPCP, "IPCP" },
1199 { PPP_OSICP, "OSICP" },
1200 { PPP_NSCP, "NSCP" },
1201 { PPP_DECNETCP, "DECNETCP" },
1202 { PPP_APPLECP, "APPLECP" },
1203 { PPP_IPXCP, "IPXCP" },
1204 { PPP_STIICP, "STIICP" },
1205 { PPP_VINESCP, "VINESCP" },
1206
1207 { PPP_LCP, "LCP" },
1208 { PPP_PAP, "PAP" },
1209 { PPP_LQM, "LQM" },
1210 { PPP_CHAP, "CHAP" },
1211 { PPP_BACP, "BACP" },
1212 { PPP_BAP, "BAP" },
1213 { PPP_MP, "MP" },
1214 { 0, NULL }
1215 };
1216
1217 #define PPP_BSDI_HDRLEN 24
1218
1219 /* BSD/OS specific PPP printer */
1220 void
1221 ppp_bsdos_if_print(u_char *user, const struct pcap_pkthdr *h,
1222 register const u_char *p)
1223 {
1224 #ifdef __bsdi__
1225 register u_int length = h->len;
1226 register u_int caplen = h->caplen;
1227 register int hdrlength;
1228 u_int16_t ptype;
1229 const u_char *q;
1230 int i;
1231
1232 ts_print(&h->ts);
1233
1234 if (caplen < PPP_BSDI_HDRLEN) {
1235 printf("[|ppp]");
1236 goto out;
1237 }
1238
1239 /*
1240 * Some printers want to get back at the link level addresses,
1241 * and/or check that they're not walking off the end of the packet.
1242 * Rather than pass them all the way down, we set these globals.
1243 */
1244 packetp = p;
1245 snapend = p + caplen;
1246 hdrlength = 0;
1247
1248 #if 0
1249 if (p[0] == PPP_ADDRESS && p[1] == PPP_CONTROL) {
1250 if (eflag)
1251 printf("%02x %02x ", p[0], p[1]);
1252 p += 2;
1253 hdrlength = 2;
1254 }
1255
1256 if (eflag)
1257 printf("%d ", length);
1258 /* Retrieve the protocol type */
1259 if (*p & 01) {
1260 /* Compressed protocol field */
1261 ptype = *p;
1262 if (eflag)
1263 printf("%02x ", ptype);
1264 p++;
1265 hdrlength += 1;
1266 } else {
1267 /* Un-compressed protocol field */
1268 ptype = ntohs(*(u_int16_t *)p);
1269 if (eflag)
1270 printf("%04x ", ptype);
1271 p += 2;
1272 hdrlength += 2;
1273 }
1274 #else
1275 ptype = 0; /*XXX*/
1276 if (eflag)
1277 printf("%c ", p[SLC_DIR] ? 'O' : 'I');
1278 if (p[SLC_LLHL]) {
1279 /* link level header */
1280 struct ppp_header *ph;
1281
1282 q = p + SLC_BPFHDRLEN;
1283 ph = (struct ppp_header *)q;
1284 if (ph->phdr_addr == PPP_ADDRESS
1285 && ph->phdr_ctl == PPP_CONTROL) {
1286 if (eflag)
1287 printf("%02x %02x ", q[0], q[1]);
1288 ptype = ntohs(ph->phdr_type);
1289 if (eflag && (ptype == PPP_VJC || ptype == PPP_VJNC)) {
1290 printf("%s ", tok2str(ppptype2str,
1291 "proto-#%d", ptype));
1292 }
1293 } else {
1294 if (eflag) {
1295 printf("LLH=[");
1296 for (i = 0; i < p[SLC_LLHL]; i++)
1297 printf("%02x", q[i]);
1298 printf("] ");
1299 }
1300 }
1301 }
1302 if (eflag)
1303 printf("%d ", length);
1304 if (p[SLC_CHL]) {
1305 q = p + SLC_BPFHDRLEN + p[SLC_LLHL];
1306
1307 switch (ptype) {
1308 case PPP_VJC:
1309 ptype = vjc_print(q, length - (q - p), ptype);
1310 hdrlength = PPP_BSDI_HDRLEN;
1311 p += hdrlength;
1312 switch (ptype) {
1313 case PPP_IP:
1314 ip_print(p, length);
1315 break;
1316 #ifdef INET6
1317 case PPP_IPV6:
1318 ip6_print(p, length);
1319 break;
1320 #endif
1321 }
1322 goto printx;
1323 case PPP_VJNC:
1324 ptype = vjc_print(q, length - (q - p), ptype);
1325 hdrlength = PPP_BSDI_HDRLEN;
1326 p += hdrlength;
1327 switch (ptype) {
1328 case PPP_IP:
1329 ip_print(p, length);
1330 break;
1331 #ifdef INET6
1332 case PPP_IPV6:
1333 ip6_print(p, length);
1334 break;
1335 #endif
1336 }
1337 goto printx;
1338 default:
1339 if (eflag) {
1340 printf("CH=[");
1341 for (i = 0; i < p[SLC_LLHL]; i++)
1342 printf("%02x", q[i]);
1343 printf("] ");
1344 }
1345 break;
1346 }
1347 }
1348
1349 hdrlength = PPP_BSDI_HDRLEN;
1350 #endif
1351
1352 length -= hdrlength;
1353 p += hdrlength;
1354
1355 switch (ptype) {
1356 case PPP_IP:
1357 ip_print(p, length);
1358 break;
1359 #ifdef INET6
1360 case PPP_IPV6:
1361 ip6_print(p, length);
1362 break;
1363 #endif
1364 default:
1365 printf("%s ", tok2str(ppptype2str, "proto-#%d", ptype));
1366 }
1367
1368 printx:
1369 if (xflag)
1370 default_print((const u_char *)p, caplen - hdrlength);
1371 out:
1372 putchar('\n');
1373 #endif /* __bsdi__ */
1374 }