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