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