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