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