]> The Tcpdump Group git mirrors - tcpdump/blob - print-ppp.c
f4ca3a82051910dac07a297735b3605c4033aec4
[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.113 2005-11-03 07:30:25 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 Rejected Packet");
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 if (length < 8)
529 break;
530 TCHECK2(*tptr, 4);
531 printf("\n\t Magic-Num 0x%08x", EXTRACT_32BITS(tptr));
532 /* XXX: need to decode Data? - hexdump for now */
533 if (len > 8) {
534 printf("\n\t -----trailing data-----");
535 TCHECK2(tptr[4], len-8);
536 print_unknown_data(tptr+4,"\n\t ",len-8);
537 }
538 break;
539 case CPCODES_ID:
540 if (length < 8)
541 break;
542 TCHECK2(*tptr, 4);
543 printf("\n\t Magic-Num 0x%08x", EXTRACT_32BITS(tptr));
544 /* RFC 1661 says this is intended to be human readable */
545 if (len > 8) {
546 printf("\n\t Message\n\t ");
547 fn_printn(tptr+4,len-4,snapend);
548 }
549 break;
550 case CPCODES_TIME_REM:
551 if (length < 12)
552 break;
553 TCHECK2(*tptr, 4);
554 printf("\n\t Magic-Num 0x%08x", EXTRACT_32BITS(tptr));
555 TCHECK2(*(tptr + 4), 4);
556 printf(", Seconds-Remaining %us", EXTRACT_32BITS(tptr + 4));
557 /* XXX: need to decode Message? */
558 break;
559 default:
560 /* XXX this is dirty but we do not get the
561 * original pointer passed to the begin
562 * the PPP packet */
563 if (vflag <= 1)
564 print_unknown_data(pptr-2,"\n\t ",length+2);
565 break;
566 }
567 return;
568
569 trunc:
570 printf("[|%s]", typestr);
571 }
572
573 /* LCP config options */
574 static int
575 print_lcp_config_options(const u_char *p, int length)
576 {
577 int len, opt;
578
579 if (length < 2)
580 return 0;
581 TCHECK2(*p, 2);
582 len = p[1];
583 opt = p[0];
584 if (length < len)
585 return 0;
586 if (len < 2) {
587 if ((opt >= LCPOPT_MIN) && (opt <= LCPOPT_MAX))
588 printf("\n\t %s Option (0x%02x), length %u (bogus, should be >= 2)", lcpconfopts[opt],opt,len);
589 else
590 printf("\n\tunknown LCP option 0x%02x", opt);
591 return 0;
592 }
593 if ((opt >= LCPOPT_MIN) && (opt <= LCPOPT_MAX))
594 printf("\n\t %s Option (0x%02x), length %u: ", lcpconfopts[opt],opt,len);
595 else {
596 printf("\n\tunknown LCP option 0x%02x", opt);
597 return len;
598 }
599
600 switch (opt) {
601 case LCPOPT_VEXT:
602 if (len >= 6) {
603 TCHECK2(*(p + 2), 3);
604 printf("Vendor: %s (%u)",
605 tok2str(oui_values,"Unknown",EXTRACT_24BITS(p+2)),
606 EXTRACT_24BITS(p+2));
607 #if 0
608 TCHECK(p[5]);
609 printf(", kind: 0x%02x", p[5]);
610 printf(", Value: 0x")
611 for (i = 0; i < len - 6; i++) {
612 TCHECK(p[6 + i]);
613 printf("%02x", p[6 + i]);
614 }
615 #endif
616 }
617 break;
618 case LCPOPT_MRU:
619 if (len == 4) {
620 TCHECK2(*(p + 2), 2);
621 printf("%u", EXTRACT_16BITS(p + 2));
622 }
623 break;
624 case LCPOPT_ACCM:
625 if (len == 6) {
626 TCHECK2(*(p + 2), 4);
627 printf("0x%08x", EXTRACT_32BITS(p + 2));
628 }
629 break;
630 case LCPOPT_AP:
631 if (len >= 4) {
632 TCHECK2(*(p + 2), 2);
633 printf("%s", tok2str(ppptype2str,"Unknown Auth Proto (0x04x)",EXTRACT_16BITS(p+2)));
634
635 switch (EXTRACT_16BITS(p+2)) {
636 case PPP_CHAP:
637 TCHECK(p[4]);
638 printf(", %s",tok2str(authalg_values,"Unknown Auth Alg %u",p[4]));
639 break;
640 case PPP_PAP: /* fall through */
641 case PPP_EAP:
642 case PPP_SPAP:
643 case PPP_SPAP_OLD:
644 break;
645 default:
646 print_unknown_data(p,"\n\t",len);
647 }
648 }
649 break;
650 case LCPOPT_QP:
651 if (len >= 4) {
652 TCHECK2(*(p + 2), 2);
653 if (EXTRACT_16BITS(p+2) == PPP_LQM)
654 printf(" LQR");
655 else
656 printf(" unknown");
657 }
658 break;
659 case LCPOPT_MN:
660 if (len == 6) {
661 TCHECK2(*(p + 2), 4);
662 printf("0x%08x", EXTRACT_32BITS(p + 2));
663 }
664 break;
665 case LCPOPT_PFC:
666 break;
667 case LCPOPT_ACFC:
668 break;
669 case LCPOPT_LD:
670 if (len == 4) {
671 TCHECK2(*(p + 2), 2);
672 printf("0x%04x", EXTRACT_16BITS(p + 2));
673 }
674 break;
675 case LCPOPT_CBACK:
676 if (len < 3)
677 break;
678 TCHECK(p[2]);
679 printf("Callback Operation %s (%u)",
680 tok2str(ppp_callback_values,"Unknown",p[2]),
681 p[2]);
682 break;
683 case LCPOPT_MLMRRU:
684 if (len == 4) {
685 TCHECK2(*(p + 2), 2);
686 printf("%u", EXTRACT_16BITS(p + 2));
687 }
688 break;
689 case LCPOPT_MLED:
690 if (len < 3)
691 break;
692 TCHECK(p[2]);
693 switch (p[2]) { /* class */
694 case MEDCLASS_NULL:
695 printf("Null");
696 break;
697 case MEDCLASS_LOCAL:
698 printf("Local"); /* XXX */
699 break;
700 case MEDCLASS_IPV4:
701 if (len != 7)
702 break;
703 TCHECK2(*(p + 3), 4);
704 printf("IPv4 %s", ipaddr_string(p + 3));
705 break;
706 case MEDCLASS_MAC:
707 if (len != 9)
708 break;
709 TCHECK(p[8]);
710 printf("MAC %02x:%02x:%02x:%02x:%02x:%02x",
711 p[3], p[4], p[5], p[6], p[7], p[8]);
712 break;
713 case MEDCLASS_MNB:
714 printf("Magic-Num-Block"); /* XXX */
715 break;
716 case MEDCLASS_PSNDN:
717 printf("PSNDN"); /* XXX */
718 break;
719 }
720 break;
721
722 /* XXX: to be supported */
723 #if 0
724 case LCPOPT_DEP6:
725 case LCPOPT_FCSALT:
726 case LCPOPT_SDP:
727 case LCPOPT_NUMMODE:
728 case LCPOPT_DEP12:
729 case LCPOPT_DEP14:
730 case LCPOPT_DEP15:
731 case LCPOPT_DEP16:
732 case LCPOPT_MLSSNHF:
733 case LCPOPT_PROP:
734 case LCPOPT_DCEID:
735 case LCPOPT_MPP:
736 case LCPOPT_LCPAOPT:
737 case LCPOPT_COBS:
738 case LCPOPT_PE:
739 case LCPOPT_MLHF:
740 case LCPOPT_I18N:
741 case LCPOPT_SDLOS:
742 case LCPOPT_PPPMUX:
743 break;
744 #endif
745 default:
746 if(vflag<2)
747 print_unknown_data(&p[2],"\n\t ",len-2);
748 break;
749 }
750
751 if (vflag>1)
752 print_unknown_data(&p[2],"\n\t ",len-2); /* exclude TLV header */
753
754 return len;
755
756 trunc:
757 printf("[|lcp]");
758 return 0;
759 }
760
761 /* ML-PPP*/
762 struct tok ppp_ml_flag_values[] = {
763 { 0x80, "begin" },
764 { 0x40, "end" },
765 { 0, NULL }
766 };
767
768 static void
769 handle_mlppp(const u_char *p, int length) {
770
771 if (!eflag)
772 printf("MLPPP, ");
773
774 printf("seq 0x%03x, Flags [%s], length %u",
775 (EXTRACT_16BITS(p))&0x0fff, /* only support 12-Bit sequence space for now */
776 bittok2str(ppp_ml_flag_values, "none", *p & 0xc0),
777 length);
778
779 return;
780 }
781
782 /* CHAP */
783 static void
784 handle_chap(const u_char *p, int length)
785 {
786 u_int code, len;
787 int val_size, name_size, msg_size;
788 const u_char *p0;
789 int i;
790
791 p0 = p;
792 if (length < 1) {
793 printf("[|chap]");
794 return;
795 } else if (length < 4) {
796 TCHECK(*p);
797 printf("[|chap 0x%02x]", *p);
798 return;
799 }
800
801 TCHECK(*p);
802 code = *p;
803 printf("CHAP, %s (0x%02x)",
804 tok2str(chapcode_values,"unknown",code),
805 code);
806 p++;
807
808 TCHECK(*p);
809 printf(", id %u", *p); /* ID */
810 p++;
811
812 TCHECK2(*p, 2);
813 len = EXTRACT_16BITS(p);
814 p += 2;
815
816 /*
817 * Note that this is a generic CHAP decoding routine. Since we
818 * don't know which flavor of CHAP (i.e. CHAP-MD5, MS-CHAPv1,
819 * MS-CHAPv2) is used at this point, we can't decode packet
820 * specifically to each algorithms. Instead, we simply decode
821 * the GCD (Gratest Common Denominator) for all algorithms.
822 */
823 switch (code) {
824 case CHAP_CHAL:
825 case CHAP_RESP:
826 if (length - (p - p0) < 1)
827 return;
828 TCHECK(*p);
829 val_size = *p; /* value size */
830 p++;
831 if (length - (p - p0) < val_size)
832 return;
833 printf(", Value ");
834 for (i = 0; i < val_size; i++) {
835 TCHECK(*p);
836 printf("%02x", *p++);
837 }
838 name_size = len - (p - p0);
839 printf(", Name ");
840 for (i = 0; i < name_size; i++) {
841 TCHECK(*p);
842 safeputchar(*p++);
843 }
844 break;
845 case CHAP_SUCC:
846 case CHAP_FAIL:
847 msg_size = len - (p - p0);
848 printf(", Msg ");
849 for (i = 0; i< msg_size; i++) {
850 TCHECK(*p);
851 safeputchar(*p++);
852 }
853 break;
854 }
855 return;
856
857 trunc:
858 printf("[|chap]");
859 }
860
861 /* PAP (see RFC 1334) */
862 static void
863 handle_pap(const u_char *p, int length)
864 {
865 u_int code, len;
866 int peerid_len, passwd_len, msg_len;
867 const u_char *p0;
868 int i;
869
870 p0 = p;
871 if (length < 1) {
872 printf("[|pap]");
873 return;
874 } else if (length < 4) {
875 TCHECK(*p);
876 printf("[|pap 0x%02x]", *p);
877 return;
878 }
879
880 TCHECK(*p);
881 code = *p;
882 printf("PAP, %s (0x%02x)",
883 tok2str(papcode_values,"unknown",code),
884 code);
885 p++;
886
887 TCHECK(*p);
888 printf(", id %u", *p); /* ID */
889 p++;
890
891 TCHECK2(*p, 2);
892 len = EXTRACT_16BITS(p);
893 p += 2;
894
895 if ((int)len > length) {
896 printf(", length %u > packet size", len);
897 return;
898 }
899 length = len;
900 if (length < (p - p0)) {
901 printf(", length %u < PAP header length", length);
902 return;
903 }
904
905 switch (code) {
906 case PAP_AREQ:
907 if (length - (p - p0) < 1)
908 return;
909 TCHECK(*p);
910 peerid_len = *p; /* Peer-ID Length */
911 p++;
912 if (length - (p - p0) < peerid_len)
913 return;
914 printf(", Peer ");
915 for (i = 0; i < peerid_len; i++) {
916 TCHECK(*p);
917 safeputchar(*p++);
918 }
919
920 if (length - (p - p0) < 1)
921 return;
922 TCHECK(*p);
923 passwd_len = *p; /* Password Length */
924 p++;
925 if (length - (p - p0) < passwd_len)
926 return;
927 printf(", Name ");
928 for (i = 0; i < passwd_len; i++) {
929 TCHECK(*p);
930 safeputchar(*p++);
931 }
932 break;
933 case PAP_AACK:
934 case PAP_ANAK:
935 if (length - (p - p0) < 1)
936 return;
937 TCHECK(*p);
938 msg_len = *p; /* Msg-Length */
939 p++;
940 if (length - (p - p0) < msg_len)
941 return;
942 printf(", Msg ");
943 for (i = 0; i< msg_len; i++) {
944 TCHECK(*p);
945 safeputchar(*p++);
946 }
947 break;
948 }
949 return;
950
951 trunc:
952 printf("[|pap]");
953 }
954
955 /* BAP */
956 static void
957 handle_bap(const u_char *p _U_, int length _U_)
958 {
959 /* XXX: to be supported!! */
960 }
961
962
963 /* IPCP config options */
964 static int
965 print_ipcp_config_options(const u_char *p, int length)
966 {
967 int len, opt;
968
969 if (length < 2)
970 return 0;
971 TCHECK2(*p, 2);
972 len = p[1];
973 opt = p[0];
974 if (length < len)
975 return 0;
976 if (len < 2) {
977 printf("\n\t %s Option (0x%02x), length %u (bogus, should be >= 2)",
978 tok2str(ipcpopt_values,"unknown",opt),
979 opt,
980 len);
981 return 0;
982 }
983
984 printf("\n\t %s Option (0x%02x), length %u: ",
985 tok2str(ipcpopt_values,"unknown",opt),
986 opt,
987 len);
988
989 switch (opt) {
990 case IPCPOPT_2ADDR: /* deprecated */
991 if (len != 10)
992 goto invlen;
993 TCHECK2(*(p + 6), 4);
994 printf("src %s, dst %s",
995 ipaddr_string(p + 2),
996 ipaddr_string(p + 6));
997 break;
998 case IPCPOPT_IPCOMP:
999 if (len < 4)
1000 goto invlen;
1001 TCHECK2(*(p + 2), 2);
1002 if (EXTRACT_16BITS(p + 2) == PPP_VJC) {
1003 printf("VJ-Comp");
1004 /* XXX: VJ-Comp parameters should be decoded */
1005 } else
1006 printf("unknown-comp-proto %04x", EXTRACT_16BITS(p + 2));
1007 break;
1008
1009 case IPCPOPT_ADDR: /* those options share the same format - fall through */
1010 case IPCPOPT_MOBILE4:
1011 case IPCPOPT_PRIDNS:
1012 case IPCPOPT_PRINBNS:
1013 case IPCPOPT_SECDNS:
1014 case IPCPOPT_SECNBNS:
1015 if (len != 6)
1016 goto invlen;
1017 TCHECK2(*(p + 2), 4);
1018 printf("%s", ipaddr_string(p + 2));
1019 break;
1020 default:
1021 if(vflag<2)
1022 print_unknown_data(&p[2],"\n\t ",len-2);
1023 break;
1024 }
1025 if (vflag>1)
1026 print_unknown_data(&p[2],"\n\t ",len-2); /* exclude TLV header */
1027 return len;
1028
1029 invlen:
1030 printf(", invalid-length-%d", opt);
1031 return 0;
1032
1033 trunc:
1034 printf("[|ipcp]");
1035 return 0;
1036 }
1037
1038 /* IP6CP config options */
1039 static int
1040 print_ip6cp_config_options(const u_char *p, int length)
1041 {
1042 int len, opt;
1043
1044 if (length < 2)
1045 return 0;
1046 TCHECK2(*p, 2);
1047 len = p[1];
1048 opt = p[0];
1049 if (length < len)
1050 return 0;
1051 if (len < 2) {
1052 printf("\n\t %s Option (0x%02x), length %u (bogus, should be >= 2)",
1053 tok2str(ip6cpopt_values,"unknown",opt),
1054 opt,
1055 len);
1056 return 0;
1057 }
1058
1059 printf("\n\t %s Option (0x%02x), length %u: ",
1060 tok2str(ip6cpopt_values,"unknown",opt),
1061 opt,
1062 len);
1063
1064 switch (opt) {
1065 case IP6CP_IFID:
1066 if (len != 10)
1067 goto invlen;
1068 TCHECK2(*(p + 2), 8);
1069 printf("%04x:%04x:%04x:%04x",
1070 EXTRACT_16BITS(p + 2),
1071 EXTRACT_16BITS(p + 4),
1072 EXTRACT_16BITS(p + 6),
1073 EXTRACT_16BITS(p + 8));
1074 break;
1075 default:
1076 if(vflag<2)
1077 print_unknown_data(&p[2],"\n\t ",len-2);
1078 break;
1079 }
1080 if (vflag>1)
1081 print_unknown_data(&p[2],"\n\t ",len-2); /* exclude TLV header */
1082
1083 return len;
1084
1085 invlen:
1086 printf(", invalid-length-%d", opt);
1087 return 0;
1088
1089 trunc:
1090 printf("[|ip6cp]");
1091 return 0;
1092 }
1093
1094
1095 /* CCP config options */
1096 static int
1097 print_ccp_config_options(const u_char *p, int length)
1098 {
1099 int len, opt;
1100
1101 if (length < 2)
1102 return 0;
1103 TCHECK2(*p, 2);
1104 len = p[1];
1105 opt = p[0];
1106 if (length < len)
1107 return 0;
1108 if (len < 2) {
1109 printf("\n\t %s Option (0x%02x), length %u (bogus, should be >= 2)",
1110 tok2str(ccpconfopts_values, "Unknown", opt),
1111 opt,
1112 len);
1113 return 0;
1114 }
1115
1116 printf("\n\t %s Option (0x%02x), length %u:",
1117 tok2str(ccpconfopts_values, "Unknown", opt),
1118 opt,
1119 len);
1120
1121 switch (opt) {
1122 /* fall through --> default: nothing supported yet */
1123 case CCPOPT_OUI:
1124 case CCPOPT_PRED1:
1125 case CCPOPT_PRED2:
1126 case CCPOPT_PJUMP:
1127 case CCPOPT_HPPPC:
1128 case CCPOPT_STACLZS:
1129 case CCPOPT_MPPC:
1130 case CCPOPT_GFZA:
1131 case CCPOPT_V42BIS:
1132 case CCPOPT_BSDCOMP:
1133 case CCPOPT_LZSDCP:
1134 case CCPOPT_MVRCA:
1135 case CCPOPT_DEC:
1136 case CCPOPT_DEFLATE:
1137 case CCPOPT_RESV:
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("[|ccp]");
1150 return 0;
1151 }
1152
1153 /* BACP config options */
1154 static int
1155 print_bacp_config_options(const u_char *p, int length)
1156 {
1157 int len, opt;
1158
1159 if (length < 2)
1160 return 0;
1161 TCHECK2(*p, 2);
1162 len = p[1];
1163 opt = p[0];
1164 if (length < len)
1165 return 0;
1166 if (len < 2) {
1167 printf("\n\t %s Option (0x%02x), length %u (bogus, should be >= 2)",
1168 tok2str(bacconfopts_values, "Unknown", opt),
1169 opt,
1170 len);
1171 return 0;
1172 }
1173
1174 printf("\n\t %s Option (0x%02x), length %u:",
1175 tok2str(bacconfopts_values, "Unknown", opt),
1176 opt,
1177 len);
1178
1179 switch (opt) {
1180 case BACPOPT_FPEER:
1181 TCHECK2(*(p + 2), 4);
1182 printf(", Magic-Num 0x%08x", EXTRACT_32BITS(p + 2));
1183 break;
1184 default:
1185 if(vflag<2)
1186 print_unknown_data(&p[2],"\n\t ",len-2);
1187 break;
1188 }
1189 if (vflag>1)
1190 print_unknown_data(&p[2],"\n\t ",len-2); /* exclude TLV header */
1191
1192 return len;
1193
1194 trunc:
1195 printf("[|bacp]");
1196 return 0;
1197 }
1198
1199
1200 static void
1201 ppp_hdlc(const u_char *p, int length)
1202 {
1203 u_char *b, *s, *t, c;
1204 int i, proto;
1205 const void *se;
1206
1207 b = (u_int8_t *)malloc(length);
1208 if (b == NULL)
1209 return;
1210
1211 /*
1212 * Unescape all the data into a temporary, private, buffer.
1213 * Do this so that we dont overwrite the original packet
1214 * contents.
1215 */
1216 for (s = (u_char *)p, t = b, i = length; i > 0; i--) {
1217 c = *s++;
1218 if (c == 0x7d) {
1219 if (i > 1) {
1220 i--;
1221 c = *s++ ^ 0x20;
1222 } else
1223 continue;
1224 }
1225 *t++ = c;
1226 }
1227
1228 se = snapend;
1229 snapend = t;
1230
1231 /* now lets guess about the payload codepoint format */
1232 proto = *b; /* start with a one-octet codepoint guess */
1233
1234 switch (proto) {
1235 case PPP_IP:
1236 ip_print(gndo, b+1, t - b - 1);
1237 goto cleanup;
1238 #ifdef INET6
1239 case PPP_IPV6:
1240 ip6_print(b+1, t - b - 1);
1241 goto cleanup;
1242 #endif
1243 default: /* no luck - try next guess */
1244 break;
1245 }
1246
1247 proto = EXTRACT_16BITS(b); /* next guess - load two octets */
1248
1249 switch (proto) {
1250 case (PPP_ADDRESS << 8 | PPP_CONTROL): /* looks like a PPP frame */
1251 proto = EXTRACT_16BITS(b+2); /* load the PPP proto-id */
1252 handle_ppp(proto, b+4, t - b - 4);
1253 break;
1254 default: /* last guess - proto must be a PPP proto-id */
1255 handle_ppp(proto, b+2, t - b - 2);
1256 break;
1257 }
1258
1259 cleanup:
1260 snapend = se;
1261 free(b);
1262 return;
1263 }
1264
1265
1266 /* PPP */
1267 static void
1268 handle_ppp(u_int proto, const u_char *p, int length)
1269 {
1270 if ((proto & 0xff00) == 0x7e00) {/* is this an escape code ? */
1271 ppp_hdlc(p-1, length);
1272 return;
1273 }
1274
1275 switch (proto) {
1276 case PPP_LCP: /* fall through */
1277 case PPP_IPCP:
1278 case PPP_OSICP:
1279 case PPP_MPLSCP:
1280 case PPP_IPV6CP:
1281 case PPP_CCP:
1282 case PPP_BACP:
1283 handle_ctrl_proto(proto, p, length);
1284 break;
1285 case PPP_ML:
1286 handle_mlppp(p, length);
1287 break;
1288 case PPP_CHAP:
1289 handle_chap(p, length);
1290 break;
1291 case PPP_PAP:
1292 handle_pap(p, length);
1293 break;
1294 case PPP_BAP: /* XXX: not yet completed */
1295 handle_bap(p, length);
1296 break;
1297 case ETHERTYPE_IP: /*XXX*/
1298 case PPP_VJNC:
1299 case PPP_IP:
1300 ip_print(gndo, p, length);
1301 break;
1302 #ifdef INET6
1303 case ETHERTYPE_IPV6: /*XXX*/
1304 case PPP_IPV6:
1305 ip6_print(p, length);
1306 break;
1307 #endif
1308 case ETHERTYPE_IPX: /*XXX*/
1309 case PPP_IPX:
1310 ipx_print(p, length);
1311 break;
1312 case PPP_OSI:
1313 isoclns_print(p, length, length);
1314 break;
1315 case PPP_MPLS_UCAST:
1316 case PPP_MPLS_MCAST:
1317 mpls_print(p, length);
1318 break;
1319 case PPP_COMP:
1320 printf("compressed PPP data");
1321 break;
1322 default:
1323 printf("%s ", tok2str(ppptype2str, "unknown PPP protocol (0x%04x)", proto));
1324 print_unknown_data(p,"\n\t",length);
1325 break;
1326 }
1327 }
1328
1329 /* Standard PPP printer */
1330 u_int
1331 ppp_print(register const u_char *p, u_int length)
1332 {
1333 u_int proto,ppp_header;
1334 u_int olen = length; /* _o_riginal length */
1335 u_int hdr_len = 0;
1336
1337 /*
1338 * Here, we assume that p points to the Address and Control
1339 * field (if they present).
1340 */
1341 if (length < 2)
1342 goto trunc;
1343 TCHECK2(*p, 2);
1344 ppp_header = EXTRACT_16BITS(p);
1345
1346 switch(ppp_header) {
1347 case (PPP_WITHDIRECTION_IN << 8 | PPP_CONTROL):
1348 if (eflag) printf("In ");
1349 p += 2;
1350 length -= 2;
1351 hdr_len += 2;
1352 break;
1353 case (PPP_WITHDIRECTION_OUT << 8 | PPP_CONTROL):
1354 if (eflag) printf("Out ");
1355 p += 2;
1356 length -= 2;
1357 hdr_len += 2;
1358 break;
1359 case (PPP_ADDRESS << 8 | PPP_CONTROL):
1360 p += 2; /* ACFC not used */
1361 length -= 2;
1362 hdr_len += 2;
1363 break;
1364
1365 default:
1366 break;
1367 }
1368
1369 if (length < 2)
1370 goto trunc;
1371 TCHECK(*p);
1372 if (*p % 2) {
1373 proto = *p; /* PFC is used */
1374 p++;
1375 length--;
1376 hdr_len++;
1377 } else {
1378 TCHECK2(*p, 2);
1379 proto = EXTRACT_16BITS(p);
1380 p += 2;
1381 length -= 2;
1382 hdr_len += 2;
1383 }
1384
1385 if (eflag)
1386 printf("%s (0x%04x), length %u: ",
1387 tok2str(ppptype2str, "unknown", proto),
1388 proto,
1389 olen);
1390
1391 handle_ppp(proto, p, length);
1392 return (hdr_len);
1393 trunc:
1394 printf("[|ppp]");
1395 return (0);
1396 }
1397
1398
1399 /* PPP I/F printer */
1400 u_int
1401 ppp_if_print(const struct pcap_pkthdr *h, register const u_char *p)
1402 {
1403 register u_int length = h->len;
1404 register u_int caplen = h->caplen;
1405
1406 if (caplen < PPP_HDRLEN) {
1407 printf("[|ppp]");
1408 return (caplen);
1409 }
1410
1411 #if 0
1412 /*
1413 * XXX: seems to assume that there are 2 octets prepended to an
1414 * actual PPP frame. The 1st octet looks like Input/Output flag
1415 * while 2nd octet is unknown, at least to me
1416 * (mshindo@mshindo.net).
1417 *
1418 * That was what the original tcpdump code did.
1419 *
1420 * FreeBSD's "if_ppp.c" *does* set the first octet to 1 for outbound
1421 * packets and 0 for inbound packets - but only if the
1422 * protocol field has the 0x8000 bit set (i.e., it's a network
1423 * control protocol); it does so before running the packet through
1424 * "bpf_filter" to see if it should be discarded, and to see
1425 * if we should update the time we sent the most recent packet...
1426 *
1427 * ...but it puts the original address field back after doing
1428 * so.
1429 *
1430 * NetBSD's "if_ppp.c" doesn't set the first octet in that fashion.
1431 *
1432 * I don't know if any PPP implementation handed up to a BPF
1433 * device packets with the first octet being 1 for outbound and
1434 * 0 for inbound packets, so I (guy@alum.mit.edu) don't know
1435 * whether that ever needs to be checked or not.
1436 *
1437 * Note that NetBSD has a DLT_PPP_SERIAL, which it uses for PPP,
1438 * and its tcpdump appears to assume that the frame always
1439 * begins with an address field and a control field, and that
1440 * the address field might be 0x0f or 0x8f, for Cisco
1441 * point-to-point with HDLC framing as per section 4.3.1 of RFC
1442 * 1547, as well as 0xff, for PPP in HDLC-like framing as per
1443 * RFC 1662.
1444 *
1445 * (Is the Cisco framing in question what DLT_C_HDLC, in
1446 * BSD/OS, is?)
1447 */
1448 if (eflag)
1449 printf("%c %4d %02x ", p[0] ? 'O' : 'I', length, p[1]);
1450 #endif
1451
1452 ppp_print(p, length);
1453
1454 return (0);
1455 }
1456
1457 /*
1458 * PPP I/F printer to use if we know that RFC 1662-style PPP in HDLC-like
1459 * framing, or Cisco PPP with HDLC framing as per section 4.3.1 of RFC 1547,
1460 * is being used (i.e., we don't check for PPP_ADDRESS and PPP_CONTROL,
1461 * discard them *if* those are the first two octets, and parse the remaining
1462 * packet as a PPP packet, as "ppp_print()" does).
1463 *
1464 * This handles, for example, DLT_PPP_SERIAL in NetBSD.
1465 */
1466 u_int
1467 ppp_hdlc_if_print(const struct pcap_pkthdr *h, register const u_char *p)
1468 {
1469 register u_int length = h->len;
1470 register u_int caplen = h->caplen;
1471 u_int proto;
1472 u_int hdrlen = 0;
1473
1474 if (caplen < 2) {
1475 printf("[|ppp]");
1476 return (caplen);
1477 }
1478
1479 switch (p[0]) {
1480
1481 case PPP_ADDRESS:
1482 if (caplen < 4) {
1483 printf("[|ppp]");
1484 return (caplen);
1485 }
1486
1487 if (eflag)
1488 printf("%02x %02x %d ", p[0], p[1], length);
1489 p += 2;
1490 length -= 2;
1491 hdrlen += 2;
1492
1493 proto = EXTRACT_16BITS(p);
1494 p += 2;
1495 length -= 2;
1496 hdrlen += 2;
1497 printf("%s: ", tok2str(ppptype2str, "unknown PPP protocol (0x%04x)", proto));
1498
1499 handle_ppp(proto, p, length);
1500 break;
1501
1502 case CHDLC_UNICAST:
1503 case CHDLC_BCAST:
1504 return (chdlc_if_print(h, p));
1505
1506 default:
1507 if (eflag)
1508 printf("%02x %02x %d ", p[0], p[1], length);
1509 p += 2;
1510 length -= 2;
1511 hdrlen += 2;
1512
1513 /*
1514 * XXX - NetBSD's "ppp_netbsd_serial_if_print()" treats
1515 * the next two octets as an Ethernet type; does that
1516 * ever happen?
1517 */
1518 printf("unknown addr %02x; ctrl %02x", p[0], p[1]);
1519 break;
1520 }
1521
1522 return (hdrlen);
1523 }
1524
1525 #define PPP_BSDI_HDRLEN 24
1526
1527 /* BSD/OS specific PPP printer */
1528 u_int
1529 ppp_bsdos_if_print(const struct pcap_pkthdr *h _U_, register const u_char *p _U_)
1530 {
1531 register int hdrlength;
1532 #ifdef __bsdi__
1533 register u_int length = h->len;
1534 register u_int caplen = h->caplen;
1535 u_int16_t ptype;
1536 const u_char *q;
1537 int i;
1538
1539 if (caplen < PPP_BSDI_HDRLEN) {
1540 printf("[|ppp]");
1541 return (caplen)
1542 }
1543
1544 hdrlength = 0;
1545
1546 #if 0
1547 if (p[0] == PPP_ADDRESS && p[1] == PPP_CONTROL) {
1548 if (eflag)
1549 printf("%02x %02x ", p[0], p[1]);
1550 p += 2;
1551 hdrlength = 2;
1552 }
1553
1554 if (eflag)
1555 printf("%d ", length);
1556 /* Retrieve the protocol type */
1557 if (*p & 01) {
1558 /* Compressed protocol field */
1559 ptype = *p;
1560 if (eflag)
1561 printf("%02x ", ptype);
1562 p++;
1563 hdrlength += 1;
1564 } else {
1565 /* Un-compressed protocol field */
1566 ptype = ntohs(*(u_int16_t *)p);
1567 if (eflag)
1568 printf("%04x ", ptype);
1569 p += 2;
1570 hdrlength += 2;
1571 }
1572 #else
1573 ptype = 0; /*XXX*/
1574 if (eflag)
1575 printf("%c ", p[SLC_DIR] ? 'O' : 'I');
1576 if (p[SLC_LLHL]) {
1577 /* link level header */
1578 struct ppp_header *ph;
1579
1580 q = p + SLC_BPFHDRLEN;
1581 ph = (struct ppp_header *)q;
1582 if (ph->phdr_addr == PPP_ADDRESS
1583 && ph->phdr_ctl == PPP_CONTROL) {
1584 if (eflag)
1585 printf("%02x %02x ", q[0], q[1]);
1586 ptype = ntohs(ph->phdr_type);
1587 if (eflag && (ptype == PPP_VJC || ptype == PPP_VJNC)) {
1588 printf("%s ", tok2str(ppptype2str,
1589 "proto-#%d", ptype));
1590 }
1591 } else {
1592 if (eflag) {
1593 printf("LLH=[");
1594 for (i = 0; i < p[SLC_LLHL]; i++)
1595 printf("%02x", q[i]);
1596 printf("] ");
1597 }
1598 }
1599 }
1600 if (eflag)
1601 printf("%d ", length);
1602 if (p[SLC_CHL]) {
1603 q = p + SLC_BPFHDRLEN + p[SLC_LLHL];
1604
1605 switch (ptype) {
1606 case PPP_VJC:
1607 ptype = vjc_print(q, ptype);
1608 hdrlength = PPP_BSDI_HDRLEN;
1609 p += hdrlength;
1610 switch (ptype) {
1611 case PPP_IP:
1612 ip_print(p, length);
1613 break;
1614 #ifdef INET6
1615 case PPP_IPV6:
1616 ip6_print(p, length);
1617 break;
1618 #endif
1619 case PPP_MPLS_UCAST:
1620 case PPP_MPLS_MCAST:
1621 mpls_print(p, length);
1622 break;
1623 }
1624 goto printx;
1625 case PPP_VJNC:
1626 ptype = vjc_print(q, ptype);
1627 hdrlength = PPP_BSDI_HDRLEN;
1628 p += hdrlength;
1629 switch (ptype) {
1630 case PPP_IP:
1631 ip_print(p, length);
1632 break;
1633 #ifdef INET6
1634 case PPP_IPV6:
1635 ip6_print(p, length);
1636 break;
1637 #endif
1638 case PPP_MPLS_UCAST:
1639 case PPP_MPLS_MCAST:
1640 mpls_print(p, length);
1641 break;
1642 }
1643 goto printx;
1644 default:
1645 if (eflag) {
1646 printf("CH=[");
1647 for (i = 0; i < p[SLC_LLHL]; i++)
1648 printf("%02x", q[i]);
1649 printf("] ");
1650 }
1651 break;
1652 }
1653 }
1654
1655 hdrlength = PPP_BSDI_HDRLEN;
1656 #endif
1657
1658 length -= hdrlength;
1659 p += hdrlength;
1660
1661 switch (ptype) {
1662 case PPP_IP:
1663 ip_print(p, length);
1664 break;
1665 #ifdef INET6
1666 case PPP_IPV6:
1667 ip6_print(p, length);
1668 break;
1669 #endif
1670 case PPP_MPLS_UCAST:
1671 case PPP_MPLS_MCAST:
1672 mpls_print(p, length);
1673 break;
1674 default:
1675 printf("%s ", tok2str(ppptype2str, "unknown PPP protocol (0x%04x)", ptype));
1676 }
1677
1678 printx:
1679 #else /* __bsdi */
1680 hdrlength = 0;
1681 #endif /* __bsdi__ */
1682 return (hdrlength);
1683 }
1684
1685
1686 /*
1687 * Local Variables:
1688 * c-style: whitesmith
1689 * c-basic-offset: 8
1690 * End:
1691 */