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