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