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