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