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