xref: /freebsd/contrib/tcpdump/print-l2tp.c (revision 5b0fe478)
1b0453382SBill Fenner /*
2b0453382SBill Fenner  * Copyright (c) 1991, 1993, 1994, 1995, 1996, 1997
3b0453382SBill Fenner  *      The Regents of the University of California.  All rights reserved.
4b0453382SBill Fenner  *
5b0453382SBill Fenner  * Redistribution and use in source and binary forms, with or without
6b0453382SBill Fenner  * modification, are permitted provided that: (1) source code distributions
7b0453382SBill Fenner  * retain the above copyright notice and this paragraph in its entirety, (2)
8b0453382SBill Fenner  * distributions including binary code include the above copyright notice and
9b0453382SBill Fenner  * this paragraph in its entirety in the documentation or other materials
10b0453382SBill Fenner  * provided with the distribution, and (3) all advertising materials mentioning
11b0453382SBill Fenner  * features or use of this software display the following acknowledgement:
12b0453382SBill Fenner  * ``This product includes software developed by the University of California,
13b0453382SBill Fenner  * Lawrence Berkeley Laboratory and its contributors.'' Neither the name of
14b0453382SBill Fenner  * the University nor the names of its contributors may be used to endorse
15b0453382SBill Fenner  * or promote products derived from this software without specific prior
16b0453382SBill Fenner  * written permission.
17b0453382SBill Fenner  * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR IMPLIED
18b0453382SBill Fenner  * WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF
19b0453382SBill Fenner  * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
20b0453382SBill Fenner  *
21685295f4SBill Fenner  * L2TP support contributed by Motonori Shindo (mshindo@mshindo.net)
22b0453382SBill Fenner  */
23b0453382SBill Fenner 
24b0453382SBill Fenner #ifndef lint
255b0fe478SBruce M Simpson static const char rcsid[] _U_ =
265b0fe478SBruce M Simpson     "@(#) $Header: /tcpdump/master/tcpdump/print-l2tp.c,v 1.14.2.3 2003/12/26 23:21:42 guy Exp $";
27b0453382SBill Fenner #endif
28b0453382SBill Fenner 
29b0453382SBill Fenner #ifdef HAVE_CONFIG_H
30b0453382SBill Fenner #include "config.h"
31b0453382SBill Fenner #endif
32b0453382SBill Fenner 
335b0fe478SBruce M Simpson #include <tcpdump-stdinc.h>
345b0fe478SBruce M Simpson 
35b0453382SBill Fenner #include <stdio.h>
36b0453382SBill Fenner 
37b0453382SBill Fenner #include "l2tp.h"
38b0453382SBill Fenner #include "interface.h"
399afd0c29SBill Fenner #include "extract.h"
40b0453382SBill Fenner 
41b0453382SBill Fenner static char tstr[] = " [|l2tp]";
42b0453382SBill Fenner 
43b0453382SBill Fenner #ifndef TRUE
44b0453382SBill Fenner #define TRUE 1
45b0453382SBill Fenner #endif
46b0453382SBill Fenner 
47b0453382SBill Fenner #ifndef FALSE
48b0453382SBill Fenner #define FALSE 0
49b0453382SBill Fenner #endif
50b0453382SBill Fenner 
51a90e161bSBill Fenner #define	L2TP_MSGTYPE_SCCRQ	1  /* Start-Control-Connection-Request */
52a90e161bSBill Fenner #define	L2TP_MSGTYPE_SCCRP	2  /* Start-Control-Connection-Reply */
53a90e161bSBill Fenner #define	L2TP_MSGTYPE_SCCCN	3  /* Start-Control-Connection-Connected */
54a90e161bSBill Fenner #define	L2TP_MSGTYPE_STOPCCN	4  /* Stop-Control-Connection-Notification */
55a90e161bSBill Fenner #define	L2TP_MSGTYPE_HELLO	6  /* Hello */
56a90e161bSBill Fenner #define	L2TP_MSGTYPE_OCRQ	7  /* Outgoing-Call-Request */
57a90e161bSBill Fenner #define	L2TP_MSGTYPE_OCRP	8  /* Outgoing-Call-Reply */
58a90e161bSBill Fenner #define	L2TP_MSGTYPE_OCCN	9  /* Outgoing-Call-Connected */
59a90e161bSBill Fenner #define	L2TP_MSGTYPE_ICRQ	10 /* Incoming-Call-Request */
60a90e161bSBill Fenner #define	L2TP_MSGTYPE_ICRP	11 /* Incoming-Call-Reply */
61a90e161bSBill Fenner #define	L2TP_MSGTYPE_ICCN	12 /* Incoming-Call-Connected */
62a90e161bSBill Fenner #define	L2TP_MSGTYPE_CDN	14 /* Call-Disconnect-Notify */
63a90e161bSBill Fenner #define	L2TP_MSGTYPE_WEN	15 /* WAN-Error-Notify */
64a90e161bSBill Fenner #define	L2TP_MSGTYPE_SLI	16 /* Set-Link-Info */
65a90e161bSBill Fenner 
66a90e161bSBill Fenner static struct tok l2tp_msgtype2str[] = {
67a90e161bSBill Fenner 	{ L2TP_MSGTYPE_SCCRQ, 	"SCCRQ" },
68a90e161bSBill Fenner 	{ L2TP_MSGTYPE_SCCRP,	"SCCRP" },
69a90e161bSBill Fenner 	{ L2TP_MSGTYPE_SCCCN,	"SCCCN" },
70a90e161bSBill Fenner 	{ L2TP_MSGTYPE_STOPCCN,	"StopCCN" },
71a90e161bSBill Fenner 	{ L2TP_MSGTYPE_HELLO,	"HELLO" },
72a90e161bSBill Fenner 	{ L2TP_MSGTYPE_OCRQ,	"OCRQ" },
73a90e161bSBill Fenner 	{ L2TP_MSGTYPE_OCRP,	"OCRP" },
74a90e161bSBill Fenner 	{ L2TP_MSGTYPE_OCCN,	"OCCN" },
75a90e161bSBill Fenner 	{ L2TP_MSGTYPE_ICRQ,	"ICRQ" },
76a90e161bSBill Fenner 	{ L2TP_MSGTYPE_ICRP,	"ICRP" },
77a90e161bSBill Fenner 	{ L2TP_MSGTYPE_ICCN,	"ICCN" },
78a90e161bSBill Fenner 	{ L2TP_MSGTYPE_CDN,	"CDN" },
79a90e161bSBill Fenner 	{ L2TP_MSGTYPE_WEN,	"WEN" },
80a90e161bSBill Fenner 	{ L2TP_MSGTYPE_SLI,	"SLI" },
81a90e161bSBill Fenner 	{ 0,			NULL }
82b0453382SBill Fenner };
83b0453382SBill Fenner 
84a90e161bSBill Fenner #define L2TP_AVP_MSGTYPE		0  /* Message Type */
85a90e161bSBill Fenner #define L2TP_AVP_RESULT_CODE		1  /* Result Code */
86a90e161bSBill Fenner #define L2TP_AVP_PROTO_VER		2  /* Protocol Version */
87a90e161bSBill Fenner #define L2TP_AVP_FRAMING_CAP		3  /* Framing Capabilities */
88a90e161bSBill Fenner #define L2TP_AVP_BEARER_CAP		4  /* Bearer Capabilities */
89a90e161bSBill Fenner #define L2TP_AVP_TIE_BREAKER		5  /* Tie Breaker */
90a90e161bSBill Fenner #define L2TP_AVP_FIRM_VER		6  /* Firmware Revision */
91a90e161bSBill Fenner #define L2TP_AVP_HOST_NAME		7  /* Host Name */
92a90e161bSBill Fenner #define L2TP_AVP_VENDOR_NAME		8  /* Vendor Name */
93a90e161bSBill Fenner #define L2TP_AVP_ASSND_TUN_ID 		9  /* Assigned Tunnel ID */
94a90e161bSBill Fenner #define L2TP_AVP_RECV_WIN_SIZE		10 /* Receive Window Size */
95a90e161bSBill Fenner #define L2TP_AVP_CHALLENGE		11 /* Challenge */
96a90e161bSBill Fenner #define L2TP_AVP_Q931_CC		12 /* Q.931 Cause Code */
97a90e161bSBill Fenner #define L2TP_AVP_CHALLENGE_RESP		13 /* Challenge Response */
98a90e161bSBill Fenner #define L2TP_AVP_ASSND_SESS_ID  	14 /* Assigned Session ID */
99a90e161bSBill Fenner #define L2TP_AVP_CALL_SER_NUM 		15 /* Call Serial Number */
100a90e161bSBill Fenner #define L2TP_AVP_MINIMUM_BPS		16 /* Minimum BPS */
101a90e161bSBill Fenner #define L2TP_AVP_MAXIMUM_BPS		17 /* Maximum BPS */
102a90e161bSBill Fenner #define L2TP_AVP_BEARER_TYPE		18 /* Bearer Type */
103a90e161bSBill Fenner #define L2TP_AVP_FRAMING_TYPE 		19 /* Framing Type */
104a90e161bSBill Fenner #define L2TP_AVP_PACKET_PROC_DELAY	20 /* Packet Processing Delay (OBSOLETE) */
105a90e161bSBill Fenner #define L2TP_AVP_CALLED_NUMBER		21 /* Called Number */
106a90e161bSBill Fenner #define L2TP_AVP_CALLING_NUMBER		22 /* Calling Number */
107a90e161bSBill Fenner #define L2TP_AVP_SUB_ADDRESS		23 /* Sub-Address */
108a90e161bSBill Fenner #define L2TP_AVP_TX_CONN_SPEED		24 /* (Tx) Connect Speed */
109a90e161bSBill Fenner #define L2TP_AVP_PHY_CHANNEL_ID		25 /* Physical Channel ID */
110a90e161bSBill Fenner #define L2TP_AVP_INI_RECV_LCP		26 /* Initial Received LCP CONFREQ */
111a90e161bSBill Fenner #define L2TP_AVP_LAST_SENT_LCP		27 /* Last Sent LCP CONFREQ */
112a90e161bSBill Fenner #define L2TP_AVP_LAST_RECV_LCP		28 /* Last Received LCP CONFREQ */
113a90e161bSBill Fenner #define L2TP_AVP_PROXY_AUTH_TYPE	29 /* Proxy Authen Type */
114a90e161bSBill Fenner #define L2TP_AVP_PROXY_AUTH_NAME	30 /* Proxy Authen Name */
115a90e161bSBill Fenner #define L2TP_AVP_PROXY_AUTH_CHAL	31 /* Proxy Authen Challenge */
116a90e161bSBill Fenner #define L2TP_AVP_PROXY_AUTH_ID		32 /* Proxy Authen ID */
117a90e161bSBill Fenner #define L2TP_AVP_PROXY_AUTH_RESP	33 /* Proxy Authen Response */
118a90e161bSBill Fenner #define L2TP_AVP_CALL_ERRORS		34 /* Call Errors */
119a90e161bSBill Fenner #define L2TP_AVP_ACCM			35 /* ACCM */
120a90e161bSBill Fenner #define L2TP_AVP_RANDOM_VECTOR		36 /* Random Vector */
121a90e161bSBill Fenner #define L2TP_AVP_PRIVATE_GRP_ID		37 /* Private Group ID */
122a90e161bSBill Fenner #define L2TP_AVP_RX_CONN_SPEED		38 /* (Rx) Connect Speed */
123a90e161bSBill Fenner #define L2TP_AVP_SEQ_REQUIRED 		39 /* Sequencing Required */
124a90e161bSBill Fenner #define L2TP_AVP_PPP_DISCON_CC		46 /* PPP Disconnect Cause Code */
125b0453382SBill Fenner 
126a90e161bSBill Fenner static struct tok l2tp_avp2str[] = {
127a90e161bSBill Fenner 	{ L2TP_AVP_MSGTYPE,		"MSGTYPE" },
128a90e161bSBill Fenner 	{ L2TP_AVP_RESULT_CODE,		"RESULT_CODE" },
129a90e161bSBill Fenner 	{ L2TP_AVP_PROTO_VER,		"PROTO_VER" },
130a90e161bSBill Fenner 	{ L2TP_AVP_FRAMING_CAP,		"FRAMING_CAP" },
131a90e161bSBill Fenner 	{ L2TP_AVP_BEARER_CAP,		"BEARER_CAP" },
132a90e161bSBill Fenner 	{ L2TP_AVP_TIE_BREAKER,		"TIE_BREAKER" },
133a90e161bSBill Fenner 	{ L2TP_AVP_FIRM_VER,		"FIRM_VER" },
134a90e161bSBill Fenner 	{ L2TP_AVP_HOST_NAME,		"HOST_NAME" },
135a90e161bSBill Fenner 	{ L2TP_AVP_VENDOR_NAME,		"VENDOR_NAME" },
136a90e161bSBill Fenner 	{ L2TP_AVP_ASSND_TUN_ID,	"ASSND_TUN_ID" },
137a90e161bSBill Fenner 	{ L2TP_AVP_RECV_WIN_SIZE,	"RECV_WIN_SIZE" },
138a90e161bSBill Fenner 	{ L2TP_AVP_CHALLENGE,		"CHALLENGE" },
139a90e161bSBill Fenner 	{ L2TP_AVP_Q931_CC,		"Q931_CC", },
140a90e161bSBill Fenner 	{ L2TP_AVP_CHALLENGE_RESP,	"CHALLENGE_RESP" },
141a90e161bSBill Fenner 	{ L2TP_AVP_ASSND_SESS_ID,	"ASSND_SESS_ID" },
142a90e161bSBill Fenner 	{ L2TP_AVP_CALL_SER_NUM,	"CALL_SER_NUM" },
143a90e161bSBill Fenner 	{ L2TP_AVP_MINIMUM_BPS,		"MINIMUM_BPS" },
144a90e161bSBill Fenner 	{ L2TP_AVP_MAXIMUM_BPS,		"MAXIMUM_BPS" },
145a90e161bSBill Fenner 	{ L2TP_AVP_BEARER_TYPE,		"BEARER_TYPE" },
146a90e161bSBill Fenner 	{ L2TP_AVP_FRAMING_TYPE,	"FRAMING_TYPE" },
147a90e161bSBill Fenner 	{ L2TP_AVP_PACKET_PROC_DELAY,	"PACKET_PROC_DELAY" },
148a90e161bSBill Fenner 	{ L2TP_AVP_CALLED_NUMBER,	"CALLED_NUMBER" },
149a90e161bSBill Fenner 	{ L2TP_AVP_CALLING_NUMBER,	"CALLING_NUMBER" },
150a90e161bSBill Fenner 	{ L2TP_AVP_SUB_ADDRESS,		"SUB_ADDRESS" },
151a90e161bSBill Fenner 	{ L2TP_AVP_TX_CONN_SPEED,	"TX_CONN_SPEED" },
152a90e161bSBill Fenner 	{ L2TP_AVP_PHY_CHANNEL_ID,	"PHY_CHANNEL_ID" },
153a90e161bSBill Fenner 	{ L2TP_AVP_INI_RECV_LCP,	"INI_RECV_LCP" },
154a90e161bSBill Fenner 	{ L2TP_AVP_LAST_SENT_LCP,	"LAST_SENT_LCP" },
155a90e161bSBill Fenner 	{ L2TP_AVP_LAST_RECV_LCP,	"LAST_RECV_LCP" },
156a90e161bSBill Fenner 	{ L2TP_AVP_PROXY_AUTH_TYPE,	"PROXY_AUTH_TYPE" },
157a90e161bSBill Fenner 	{ L2TP_AVP_PROXY_AUTH_NAME,	"PROXY_AUTH_NAME" },
158a90e161bSBill Fenner 	{ L2TP_AVP_PROXY_AUTH_CHAL,	"PROXY_AUTH_CHAL" },
159a90e161bSBill Fenner 	{ L2TP_AVP_PROXY_AUTH_ID,	"PROXY_AUTH_ID" },
160a90e161bSBill Fenner 	{ L2TP_AVP_PROXY_AUTH_RESP,	"PROXY_AUTH_RESP" },
161a90e161bSBill Fenner 	{ L2TP_AVP_CALL_ERRORS,		"CALL_ERRORS" },
162a90e161bSBill Fenner 	{ L2TP_AVP_ACCM,		"ACCM" },
163a90e161bSBill Fenner 	{ L2TP_AVP_RANDOM_VECTOR,	"RANDOM_VECTOR" },
164a90e161bSBill Fenner 	{ L2TP_AVP_PRIVATE_GRP_ID,	"PRIVATE_GRP_ID" },
165a90e161bSBill Fenner 	{ L2TP_AVP_RX_CONN_SPEED,	"RX_CONN_SPEED" },
166a90e161bSBill Fenner 	{ L2TP_AVP_SEQ_REQUIRED,	"SEQ_REQUIRED" },
167a90e161bSBill Fenner 	{ L2TP_AVP_PPP_DISCON_CC,	"PPP_DISCON_CC" },
168a90e161bSBill Fenner 	{ 0,				NULL }
169a90e161bSBill Fenner };
170a90e161bSBill Fenner 
171a90e161bSBill Fenner static struct tok l2tp_authentype2str[] = {
172a90e161bSBill Fenner 	{ L2TP_AUTHEN_TYPE_RESERVED,	"Reserved" },
173a90e161bSBill Fenner 	{ L2TP_AUTHEN_TYPE_TEXTUAL,	"Textual" },
174a90e161bSBill Fenner 	{ L2TP_AUTHEN_TYPE_CHAP,	"CHAP" },
175a90e161bSBill Fenner 	{ L2TP_AUTHEN_TYPE_PAP,		"PAP" },
176a90e161bSBill Fenner 	{ L2TP_AUTHEN_TYPE_NO_AUTH,	"No Auth" },
177a90e161bSBill Fenner 	{ L2TP_AUTHEN_TYPE_MSCHAPv1,	"MS-CHAPv1" },
178a90e161bSBill Fenner 	{ 0,				NULL }
179a90e161bSBill Fenner };
180a90e161bSBill Fenner 
181a90e161bSBill Fenner #define L2TP_PPP_DISCON_CC_DIRECTION_GLOBAL	0
182a90e161bSBill Fenner #define L2TP_PPP_DISCON_CC_DIRECTION_AT_PEER	1
183a90e161bSBill Fenner #define L2TP_PPP_DISCON_CC_DIRECTION_AT_LOCAL	2
184a90e161bSBill Fenner 
185a90e161bSBill Fenner static struct tok l2tp_cc_direction2str[] = {
186a90e161bSBill Fenner 	{ L2TP_PPP_DISCON_CC_DIRECTION_GLOBAL,	"global error" },
187a90e161bSBill Fenner 	{ L2TP_PPP_DISCON_CC_DIRECTION_AT_PEER,	"at peer" },
188a90e161bSBill Fenner 	{ L2TP_PPP_DISCON_CC_DIRECTION_AT_LOCAL,"at local" },
189a90e161bSBill Fenner 	{ 0,					NULL }
190b0453382SBill Fenner };
191b0453382SBill Fenner 
192b0453382SBill Fenner #if 0
193b0453382SBill Fenner static char *l2tp_result_code_StopCCN[] = {
194b0453382SBill Fenner          "Reserved",
195b0453382SBill Fenner          "General request to clear control connection",
196b0453382SBill Fenner          "General error--Error Code indicates the problem",
197b0453382SBill Fenner          "Control channel already exists",
198b0453382SBill Fenner          "Requester is not authorized to establish a control channel",
199b0453382SBill Fenner          "The protocol version of the requester is not supported",
200b0453382SBill Fenner          "Requester is being shut down",
201b0453382SBill Fenner          "Finite State Machine error"
202b0453382SBill Fenner #define L2TP_MAX_RESULT_CODE_STOPCC_INDEX	8
203b0453382SBill Fenner };
204b0453382SBill Fenner #endif
205b0453382SBill Fenner 
206b0453382SBill Fenner #if 0
207b0453382SBill Fenner static char *l2tp_result_code_CDN[] = {
208b0453382SBill Fenner 	"Reserved",
209b0453382SBill Fenner 	"Call disconnected due to loss of carrier",
210b0453382SBill Fenner 	"Call disconnected for the reason indicated in error code",
211b0453382SBill Fenner 	"Call disconnected for administrative reasons",
212b0453382SBill Fenner 	"Call failed due to lack of appropriate facilities being " \
213b0453382SBill Fenner 	"available (temporary condition)",
214b0453382SBill Fenner 	"Call failed due to lack of appropriate facilities being " \
215b0453382SBill Fenner 	"available (permanent condition)",
216b0453382SBill Fenner 	"Invalid destination",
217b0453382SBill Fenner 	"Call failed due to no carrier detected",
218b0453382SBill Fenner 	"Call failed due to detection of a busy signal",
219b0453382SBill Fenner 	"Call failed due to lack of a dial tone",
220b0453382SBill Fenner 	"Call was not established within time allotted by LAC",
221b0453382SBill Fenner 	"Call was connected but no appropriate framing was detected"
222b0453382SBill Fenner #define L2TP_MAX_RESULT_CODE_CDN_INDEX	12
223b0453382SBill Fenner };
224b0453382SBill Fenner #endif
225b0453382SBill Fenner 
226b0453382SBill Fenner #if 0
227b0453382SBill Fenner static char *l2tp_error_code_general[] = {
228b0453382SBill Fenner 	"No general error",
229b0453382SBill Fenner 	"No control connection exists yet for this LAC-LNS pair",
230b0453382SBill Fenner 	"Length is wrong",
231b0453382SBill Fenner 	"One of the field values was out of range or " \
232b0453382SBill Fenner 	"reserved field was non-zero"
233b0453382SBill Fenner 	"Insufficient resources to handle this operation now",
234b0453382SBill Fenner 	"The Session ID is invalid in this context",
235b0453382SBill Fenner 	"A generic vendor-specific error occurred in the LAC",
236b0453382SBill Fenner 	"Try another"
237b0453382SBill Fenner #define L2TP_MAX_ERROR_CODE_GENERAL_INDEX	8
238b0453382SBill Fenner };
239b0453382SBill Fenner #endif
240b0453382SBill Fenner 
241b0453382SBill Fenner /******************************/
242b0453382SBill Fenner /* generic print out routines */
243b0453382SBill Fenner /******************************/
244b0453382SBill Fenner static void
245b0453382SBill Fenner print_string(const u_char *dat, u_int length)
246b0453382SBill Fenner {
2475b0fe478SBruce M Simpson 	u_int i;
248b0453382SBill Fenner 	for (i=0; i<length; i++) {
249b0453382SBill Fenner 		printf("%c", *dat++);
250b0453382SBill Fenner 	}
251b0453382SBill Fenner }
252b0453382SBill Fenner 
253b0453382SBill Fenner static void
254b0453382SBill Fenner print_octets(const u_char *dat, u_int length)
255b0453382SBill Fenner {
2565b0fe478SBruce M Simpson 	u_int i;
257b0453382SBill Fenner 	for (i=0; i<length; i++) {
258b0453382SBill Fenner 		printf("%02x", *dat++);
259b0453382SBill Fenner 	}
260b0453382SBill Fenner }
261b0453382SBill Fenner 
262b0453382SBill Fenner static void
263a90e161bSBill Fenner print_16bits_val(const u_int16_t *dat)
264b0453382SBill Fenner {
2659afd0c29SBill Fenner 	printf("%u", EXTRACT_16BITS(dat));
266b0453382SBill Fenner }
267b0453382SBill Fenner 
268b0453382SBill Fenner static void
269a90e161bSBill Fenner print_32bits_val(const u_int32_t *dat)
270b0453382SBill Fenner {
2719afd0c29SBill Fenner 	printf("%lu", (u_long)EXTRACT_32BITS(dat));
272b0453382SBill Fenner }
273b0453382SBill Fenner 
274a90e161bSBill Fenner /***********************************/
275b0453382SBill Fenner /* AVP-specific print out routines */
276a90e161bSBill Fenner /***********************************/
277b0453382SBill Fenner static void
278a90e161bSBill Fenner l2tp_msgtype_print(const u_char *dat)
279b0453382SBill Fenner {
280a90e161bSBill Fenner 	u_int16_t *ptr = (u_int16_t*)dat;
281b0453382SBill Fenner 
2829afd0c29SBill Fenner 	printf("%s", tok2str(l2tp_msgtype2str, "MSGTYPE-#%u",
2839afd0c29SBill Fenner 	    EXTRACT_16BITS(ptr)));
284b0453382SBill Fenner }
285b0453382SBill Fenner 
286b0453382SBill Fenner static void
287b0453382SBill Fenner l2tp_result_code_print(const u_char *dat, u_int length)
288b0453382SBill Fenner {
289a90e161bSBill Fenner 	u_int16_t *ptr = (u_int16_t *)dat;
290b0453382SBill Fenner 
2919afd0c29SBill Fenner 	printf("%u", EXTRACT_16BITS(ptr)); ptr++;	/* Result Code */
292a90e161bSBill Fenner 	if (length > 2) {				/* Error Code (opt) */
2939afd0c29SBill Fenner 	        printf("/%u", EXTRACT_16BITS(ptr)); ptr++;
294a90e161bSBill Fenner 	}
295a90e161bSBill Fenner 	if (length > 4) {				/* Error Message (opt) */
296a90e161bSBill Fenner 		printf(" ");
297a90e161bSBill Fenner 		print_string((u_char *)ptr, length - 4);
298b0453382SBill Fenner 	}
299b0453382SBill Fenner }
300b0453382SBill Fenner 
301b0453382SBill Fenner static void
302a90e161bSBill Fenner l2tp_proto_ver_print(const u_int16_t *dat)
303b0453382SBill Fenner {
3049afd0c29SBill Fenner 	printf("%u.%u", (EXTRACT_16BITS(dat) >> 8),
3059afd0c29SBill Fenner 	    (EXTRACT_16BITS(dat) & 0xff));
306b0453382SBill Fenner }
307b0453382SBill Fenner 
308b0453382SBill Fenner static void
309a90e161bSBill Fenner l2tp_framing_cap_print(const u_char *dat)
310b0453382SBill Fenner {
311a90e161bSBill Fenner 	u_int32_t *ptr = (u_int32_t *)dat;
312b0453382SBill Fenner 
3139afd0c29SBill Fenner 	if (EXTRACT_32BITS(ptr) &  L2TP_FRAMING_CAP_ASYNC_MASK) {
314b0453382SBill Fenner 		printf("A");
315b0453382SBill Fenner 	}
3169afd0c29SBill Fenner 	if (EXTRACT_32BITS(ptr) &  L2TP_FRAMING_CAP_SYNC_MASK) {
317b0453382SBill Fenner 		printf("S");
318b0453382SBill Fenner 	}
319b0453382SBill Fenner }
320b0453382SBill Fenner 
321b0453382SBill Fenner static void
322a90e161bSBill Fenner l2tp_bearer_cap_print(const u_char *dat)
323b0453382SBill Fenner {
324a90e161bSBill Fenner 	u_int32_t *ptr = (u_int32_t *)dat;
325b0453382SBill Fenner 
3269afd0c29SBill Fenner 	if (EXTRACT_32BITS(ptr) &  L2TP_BEARER_CAP_ANALOG_MASK) {
327b0453382SBill Fenner 		printf("A");
328b0453382SBill Fenner 	}
3299afd0c29SBill Fenner 	if (EXTRACT_32BITS(ptr) &  L2TP_BEARER_CAP_DIGITAL_MASK) {
330b0453382SBill Fenner 		printf("D");
331b0453382SBill Fenner 	}
332b0453382SBill Fenner }
333b0453382SBill Fenner 
334b0453382SBill Fenner static void
335b0453382SBill Fenner l2tp_q931_cc_print(const u_char *dat, u_int length)
336b0453382SBill Fenner {
337a90e161bSBill Fenner 	print_16bits_val((u_int16_t *)dat);
338b0453382SBill Fenner 	printf(", %02x", dat[2]);
339b0453382SBill Fenner 	if (length > 3) {
340b0453382SBill Fenner 		printf(" ");
341b0453382SBill Fenner 		print_string(dat+3, length-3);
342b0453382SBill Fenner 	}
343b0453382SBill Fenner }
344b0453382SBill Fenner 
345b0453382SBill Fenner static void
346a90e161bSBill Fenner l2tp_bearer_type_print(const u_char *dat)
347b0453382SBill Fenner {
348a90e161bSBill Fenner 	u_int32_t *ptr = (u_int32_t *)dat;
349b0453382SBill Fenner 
3509afd0c29SBill Fenner 	if (EXTRACT_32BITS(ptr) &  L2TP_BEARER_TYPE_ANALOG_MASK) {
351b0453382SBill Fenner 		printf("A");
352b0453382SBill Fenner 	}
3539afd0c29SBill Fenner 	if (EXTRACT_32BITS(ptr) &  L2TP_BEARER_TYPE_DIGITAL_MASK) {
354b0453382SBill Fenner 		printf("D");
355b0453382SBill Fenner 	}
356b0453382SBill Fenner }
357b0453382SBill Fenner 
358b0453382SBill Fenner static void
359a90e161bSBill Fenner l2tp_framing_type_print(const u_char *dat)
360b0453382SBill Fenner {
361a90e161bSBill Fenner 	u_int32_t *ptr = (u_int32_t *)dat;
362b0453382SBill Fenner 
3639afd0c29SBill Fenner 	if (EXTRACT_32BITS(ptr) &  L2TP_FRAMING_TYPE_ASYNC_MASK) {
364b0453382SBill Fenner 		printf("A");
365b0453382SBill Fenner 	}
3669afd0c29SBill Fenner 	if (EXTRACT_32BITS(ptr) &  L2TP_FRAMING_TYPE_SYNC_MASK) {
367b0453382SBill Fenner 		printf("S");
368b0453382SBill Fenner 	}
369b0453382SBill Fenner }
370b0453382SBill Fenner 
371b0453382SBill Fenner static void
372a90e161bSBill Fenner l2tp_packet_proc_delay_print(void)
373b0453382SBill Fenner {
374b0453382SBill Fenner 	printf("obsolete");
375b0453382SBill Fenner }
376b0453382SBill Fenner 
377b0453382SBill Fenner static void
378a90e161bSBill Fenner l2tp_proxy_auth_type_print(const u_char *dat)
379b0453382SBill Fenner {
380a90e161bSBill Fenner 	u_int16_t *ptr = (u_int16_t *)dat;
381a90e161bSBill Fenner 
382a90e161bSBill Fenner 	printf("%s", tok2str(l2tp_authentype2str,
3839afd0c29SBill Fenner 			     "AuthType-#%u", EXTRACT_16BITS(ptr)));
384b0453382SBill Fenner }
385b0453382SBill Fenner 
386b0453382SBill Fenner static void
387a90e161bSBill Fenner l2tp_proxy_auth_id_print(const u_char *dat)
388b0453382SBill Fenner {
389a90e161bSBill Fenner 	u_int16_t *ptr = (u_int16_t *)dat;
390b0453382SBill Fenner 
3919afd0c29SBill Fenner 	printf("%u", EXTRACT_16BITS(ptr) & L2TP_PROXY_AUTH_ID_MASK);
392b0453382SBill Fenner }
393b0453382SBill Fenner 
394b0453382SBill Fenner static void
395a90e161bSBill Fenner l2tp_call_errors_print(const u_char *dat)
396b0453382SBill Fenner {
397a90e161bSBill Fenner 	u_int16_t *ptr = (u_int16_t *)dat;
398a90e161bSBill Fenner 	u_int16_t val_h, val_l;
399a90e161bSBill Fenner 
400a90e161bSBill Fenner 	ptr++;		/* skip "Reserved" */
401a90e161bSBill Fenner 
4029afd0c29SBill Fenner 	val_h = EXTRACT_16BITS(ptr); ptr++;
4039afd0c29SBill Fenner 	val_l = EXTRACT_16BITS(ptr); ptr++;
404a90e161bSBill Fenner 	printf("CRCErr=%u ", (val_h<<16) + val_l);
405a90e161bSBill Fenner 
4069afd0c29SBill Fenner 	val_h = EXTRACT_16BITS(ptr); ptr++;
4079afd0c29SBill Fenner 	val_l = EXTRACT_16BITS(ptr); ptr++;
408a90e161bSBill Fenner 	printf("FrameErr=%u ", (val_h<<16) + val_l);
409a90e161bSBill Fenner 
4109afd0c29SBill Fenner 	val_h = EXTRACT_16BITS(ptr); ptr++;
4119afd0c29SBill Fenner 	val_l = EXTRACT_16BITS(ptr); ptr++;
412a90e161bSBill Fenner 	printf("HardOver=%u ", (val_h<<16) + val_l);
413a90e161bSBill Fenner 
4149afd0c29SBill Fenner 	val_h = EXTRACT_16BITS(ptr); ptr++;
4159afd0c29SBill Fenner 	val_l = EXTRACT_16BITS(ptr); ptr++;
416a90e161bSBill Fenner 	printf("BufOver=%u ", (val_h<<16) + val_l);
417a90e161bSBill Fenner 
4189afd0c29SBill Fenner 	val_h = EXTRACT_16BITS(ptr); ptr++;
4199afd0c29SBill Fenner 	val_l = EXTRACT_16BITS(ptr); ptr++;
420a90e161bSBill Fenner 	printf("Timeout=%u ", (val_h<<16) + val_l);
421a90e161bSBill Fenner 
4229afd0c29SBill Fenner 	val_h = EXTRACT_16BITS(ptr); ptr++;
4239afd0c29SBill Fenner 	val_l = EXTRACT_16BITS(ptr); ptr++;
424a90e161bSBill Fenner 	printf("AlignErr=%u ", (val_h<<16) + val_l);
425b0453382SBill Fenner }
426b0453382SBill Fenner 
427b0453382SBill Fenner static void
428a90e161bSBill Fenner l2tp_accm_print(const u_char *dat)
429b0453382SBill Fenner {
430a90e161bSBill Fenner 	u_int16_t *ptr = (u_int16_t *)dat;
431a90e161bSBill Fenner 	u_int16_t val_h, val_l;
432b0453382SBill Fenner 
433a90e161bSBill Fenner 	ptr++;		/* skip "Reserved" */
434a90e161bSBill Fenner 
4359afd0c29SBill Fenner 	val_h = EXTRACT_16BITS(ptr); ptr++;
4369afd0c29SBill Fenner 	val_l = EXTRACT_16BITS(ptr); ptr++;
437a90e161bSBill Fenner 	printf("send=%08x ", (val_h<<16) + val_l);
438a90e161bSBill Fenner 
4399afd0c29SBill Fenner 	val_h = EXTRACT_16BITS(ptr); ptr++;
4409afd0c29SBill Fenner 	val_l = EXTRACT_16BITS(ptr); ptr++;
441a90e161bSBill Fenner 	printf("recv=%08x ", (val_h<<16) + val_l);
442b0453382SBill Fenner }
443b0453382SBill Fenner 
444b0453382SBill Fenner static void
445a90e161bSBill Fenner l2tp_ppp_discon_cc_print(const u_char *dat, u_int length)
446b0453382SBill Fenner {
447a90e161bSBill Fenner 	u_int16_t *ptr = (u_int16_t *)dat;
448b0453382SBill Fenner 
4499afd0c29SBill Fenner 	printf("%04x, ", EXTRACT_16BITS(ptr)); ptr++;	/* Disconnect Code */
4509afd0c29SBill Fenner 	printf("%04x ",  EXTRACT_16BITS(ptr)); ptr++;	/* Control Protocol Number */
451a90e161bSBill Fenner 	printf("%s", tok2str(l2tp_cc_direction2str,
452a90e161bSBill Fenner 			     "Direction-#%u", *((u_char *)ptr++)));
453a90e161bSBill Fenner 
454a90e161bSBill Fenner 	if (length > 5) {
455a90e161bSBill Fenner 		printf(" ");
456a90e161bSBill Fenner 		print_string((const u_char *)ptr, length-5);
457a90e161bSBill Fenner 	}
458b0453382SBill Fenner }
459b0453382SBill Fenner 
460b0453382SBill Fenner static void
461a90e161bSBill Fenner l2tp_avp_print(const u_char *dat, int length)
462b0453382SBill Fenner {
463a90e161bSBill Fenner 	u_int len;
464a90e161bSBill Fenner 	const u_int16_t *ptr = (u_int16_t *)dat;
465a90e161bSBill Fenner 	u_int16_t attr_type;
466a90e161bSBill Fenner 	int hidden = FALSE;
467b0453382SBill Fenner 
468a90e161bSBill Fenner 	if (length <= 0) {
469b0453382SBill Fenner 		return;
470b0453382SBill Fenner 	}
471b0453382SBill Fenner 
472b0453382SBill Fenner 	printf(" ");
473a90e161bSBill Fenner 
474a90e161bSBill Fenner 	TCHECK(*ptr);	/* Flags & Length */
4759afd0c29SBill Fenner 	len = EXTRACT_16BITS(ptr) & L2TP_AVP_HDR_LEN_MASK;
476a90e161bSBill Fenner 
477b97c9af5SBill Fenner 	/* If it is not long enough to contain the header, we'll give up. */
478b97c9af5SBill Fenner 	if (len < 6)
479b97c9af5SBill Fenner 		goto trunc;
480b97c9af5SBill Fenner 
481b97c9af5SBill Fenner 	/* If it goes past the end of the remaining length of the packet,
482b97c9af5SBill Fenner 	   we'll give up. */
483b97c9af5SBill Fenner 	if (len > (u_int)length)
484b97c9af5SBill Fenner 		goto trunc;
485b97c9af5SBill Fenner 
486b97c9af5SBill Fenner 	/* If it goes past the end of the remaining length of the captured
487b97c9af5SBill Fenner 	   data, we'll give up. */
488a90e161bSBill Fenner 	TCHECK2(*ptr, len);
489a90e161bSBill Fenner 	/* After this point, no need to worry about truncation */
490a90e161bSBill Fenner 
4919afd0c29SBill Fenner 	if (EXTRACT_16BITS(ptr) & L2TP_AVP_HDR_FLAG_MANDATORY) {
492b0453382SBill Fenner 		printf("*");
493b0453382SBill Fenner 	}
4949afd0c29SBill Fenner 	if (EXTRACT_16BITS(ptr) & L2TP_AVP_HDR_FLAG_HIDDEN) {
495b0453382SBill Fenner 		hidden = TRUE;
496b0453382SBill Fenner 		printf("?");
497b0453382SBill Fenner 	}
498b0453382SBill Fenner 	ptr++;
499b0453382SBill Fenner 
5009afd0c29SBill Fenner 	if (EXTRACT_16BITS(ptr)) {
501685295f4SBill Fenner 		/* Vendor Specific Attribute */
5029afd0c29SBill Fenner 	        printf("VENDOR%04x:", EXTRACT_16BITS(ptr)); ptr++;
5039afd0c29SBill Fenner 		printf("ATTR%04x", EXTRACT_16BITS(ptr)); ptr++;
504685295f4SBill Fenner 		printf("(");
505a90e161bSBill Fenner 		print_octets((u_char *)ptr, len-6);
506685295f4SBill Fenner 		printf(")");
507685295f4SBill Fenner 	} else {
508a90e161bSBill Fenner 		/* IETF-defined Attributes */
509685295f4SBill Fenner 		ptr++;
5109afd0c29SBill Fenner 		attr_type = EXTRACT_16BITS(ptr); ptr++;
511a90e161bSBill Fenner 		printf("%s", tok2str(l2tp_avp2str, "AVP-#%u", attr_type));
512b0453382SBill Fenner 		printf("(");
513a90e161bSBill Fenner 		if (hidden) {
514b0453382SBill Fenner 			printf("???");
515a90e161bSBill Fenner 		} else {
516a90e161bSBill Fenner 			switch (attr_type) {
517a90e161bSBill Fenner 			case L2TP_AVP_MSGTYPE:
518a90e161bSBill Fenner 				l2tp_msgtype_print((u_char *)ptr);
519a90e161bSBill Fenner 				break;
520a90e161bSBill Fenner 			case L2TP_AVP_RESULT_CODE:
521a90e161bSBill Fenner 				l2tp_result_code_print((u_char *)ptr, len-6);
522a90e161bSBill Fenner 				break;
523a90e161bSBill Fenner 			case L2TP_AVP_PROTO_VER:
524a90e161bSBill Fenner 				l2tp_proto_ver_print(ptr);
525a90e161bSBill Fenner 				break;
526a90e161bSBill Fenner 			case L2TP_AVP_FRAMING_CAP:
527a90e161bSBill Fenner 				l2tp_framing_cap_print((u_char *)ptr);
528a90e161bSBill Fenner 				break;
529a90e161bSBill Fenner 			case L2TP_AVP_BEARER_CAP:
530a90e161bSBill Fenner 				l2tp_bearer_cap_print((u_char *)ptr);
531a90e161bSBill Fenner 				break;
532a90e161bSBill Fenner 			case L2TP_AVP_TIE_BREAKER:
533a90e161bSBill Fenner 				print_octets((u_char *)ptr, 8);
534a90e161bSBill Fenner 				break;
535a90e161bSBill Fenner 			case L2TP_AVP_FIRM_VER:
536a90e161bSBill Fenner 			case L2TP_AVP_ASSND_TUN_ID:
537a90e161bSBill Fenner 			case L2TP_AVP_RECV_WIN_SIZE:
538a90e161bSBill Fenner 			case L2TP_AVP_ASSND_SESS_ID:
539a90e161bSBill Fenner 				print_16bits_val(ptr);
540a90e161bSBill Fenner 				break;
541a90e161bSBill Fenner 			case L2TP_AVP_HOST_NAME:
542a90e161bSBill Fenner 			case L2TP_AVP_VENDOR_NAME:
543a90e161bSBill Fenner 			case L2TP_AVP_CALLING_NUMBER:
544a90e161bSBill Fenner 			case L2TP_AVP_CALLED_NUMBER:
545a90e161bSBill Fenner 			case L2TP_AVP_SUB_ADDRESS:
546a90e161bSBill Fenner 			case L2TP_AVP_PROXY_AUTH_NAME:
547a90e161bSBill Fenner 			case L2TP_AVP_PRIVATE_GRP_ID:
548a90e161bSBill Fenner 				print_string((u_char *)ptr, len-6);
549a90e161bSBill Fenner 				break;
550a90e161bSBill Fenner 			case L2TP_AVP_CHALLENGE:
551a90e161bSBill Fenner 			case L2TP_AVP_INI_RECV_LCP:
552a90e161bSBill Fenner 			case L2TP_AVP_LAST_SENT_LCP:
553a90e161bSBill Fenner 			case L2TP_AVP_LAST_RECV_LCP:
554a90e161bSBill Fenner 			case L2TP_AVP_PROXY_AUTH_CHAL:
555a90e161bSBill Fenner 			case L2TP_AVP_PROXY_AUTH_RESP:
556a90e161bSBill Fenner 			case L2TP_AVP_RANDOM_VECTOR:
557a90e161bSBill Fenner 				print_octets((u_char *)ptr, len-6);
558a90e161bSBill Fenner 				break;
559a90e161bSBill Fenner 			case L2TP_AVP_Q931_CC:
560a90e161bSBill Fenner 				l2tp_q931_cc_print((u_char *)ptr, len-6);
561a90e161bSBill Fenner 				break;
562a90e161bSBill Fenner 			case L2TP_AVP_CHALLENGE_RESP:
563a90e161bSBill Fenner 				print_octets((u_char *)ptr, 16);
564a90e161bSBill Fenner 				break;
565a90e161bSBill Fenner 			case L2TP_AVP_CALL_SER_NUM:
566a90e161bSBill Fenner 			case L2TP_AVP_MINIMUM_BPS:
567a90e161bSBill Fenner 			case L2TP_AVP_MAXIMUM_BPS:
568a90e161bSBill Fenner 			case L2TP_AVP_TX_CONN_SPEED:
569a90e161bSBill Fenner 			case L2TP_AVP_PHY_CHANNEL_ID:
570a90e161bSBill Fenner 			case L2TP_AVP_RX_CONN_SPEED:
571a90e161bSBill Fenner 				print_32bits_val((u_int32_t *)ptr);
572a90e161bSBill Fenner 				break;
573a90e161bSBill Fenner 			case L2TP_AVP_BEARER_TYPE:
574a90e161bSBill Fenner 				l2tp_bearer_type_print((u_char *)ptr);
575a90e161bSBill Fenner 				break;
576a90e161bSBill Fenner 			case L2TP_AVP_FRAMING_TYPE:
577a90e161bSBill Fenner 				l2tp_framing_type_print((u_char *)ptr);
578a90e161bSBill Fenner 				break;
579a90e161bSBill Fenner 			case L2TP_AVP_PACKET_PROC_DELAY:
580a90e161bSBill Fenner 				l2tp_packet_proc_delay_print();
581a90e161bSBill Fenner 				break;
582a90e161bSBill Fenner 			case L2TP_AVP_PROXY_AUTH_TYPE:
583a90e161bSBill Fenner 				l2tp_proxy_auth_type_print((u_char *)ptr);
584a90e161bSBill Fenner 				break;
585a90e161bSBill Fenner 			case L2TP_AVP_PROXY_AUTH_ID:
586a90e161bSBill Fenner 				l2tp_proxy_auth_id_print((u_char *)ptr);
587a90e161bSBill Fenner 				break;
588a90e161bSBill Fenner 			case L2TP_AVP_CALL_ERRORS:
589a90e161bSBill Fenner 				l2tp_call_errors_print((u_char *)ptr);
590a90e161bSBill Fenner 				break;
591a90e161bSBill Fenner 			case L2TP_AVP_ACCM:
592a90e161bSBill Fenner 				l2tp_accm_print((u_char *)ptr);
593a90e161bSBill Fenner 				break;
594a90e161bSBill Fenner 			case L2TP_AVP_SEQ_REQUIRED:
595a90e161bSBill Fenner 				break;	/* No Attribute Value */
596a90e161bSBill Fenner 			case L2TP_AVP_PPP_DISCON_CC:
597a90e161bSBill Fenner 				l2tp_ppp_discon_cc_print((u_char *)ptr, len-6);
598a90e161bSBill Fenner 				break;
599a90e161bSBill Fenner 			default:
600a90e161bSBill Fenner 				break;
601a90e161bSBill Fenner 			}
602b0453382SBill Fenner 		}
603b0453382SBill Fenner 		printf(")");
604685295f4SBill Fenner 	}
605b0453382SBill Fenner 
606b0453382SBill Fenner 	l2tp_avp_print(dat+len, length-len);
607b0453382SBill Fenner 	return;
608a90e161bSBill Fenner 
609a90e161bSBill Fenner  trunc:
610b0453382SBill Fenner 	printf("|...");
611b0453382SBill Fenner }
612b0453382SBill Fenner 
613b0453382SBill Fenner 
614b0453382SBill Fenner void
615b0453382SBill Fenner l2tp_print(const u_char *dat, u_int length)
616b0453382SBill Fenner {
617a90e161bSBill Fenner 	const u_int16_t *ptr = (u_int16_t *)dat;
618b0453382SBill Fenner 	u_int cnt = 0;			/* total octets consumed */
619a90e161bSBill Fenner 	u_int16_t pad;
620b0453382SBill Fenner 	int flag_t, flag_l, flag_s, flag_o, flag_p;
621a90e161bSBill Fenner 	u_int16_t l2tp_len;
622b0453382SBill Fenner 
623b0453382SBill Fenner 	flag_t = flag_l = flag_s = flag_o = flag_p = FALSE;
624b0453382SBill Fenner 
625a90e161bSBill Fenner 	TCHECK(*ptr);	/* Flags & Version */
6269afd0c29SBill Fenner 	if ((EXTRACT_16BITS(ptr) & L2TP_VERSION_MASK) == L2TP_VERSION_L2TP) {
627b0453382SBill Fenner 		printf(" l2tp:");
6289afd0c29SBill Fenner 	} else if ((EXTRACT_16BITS(ptr) & L2TP_VERSION_MASK) == L2TP_VERSION_L2F) {
629b0453382SBill Fenner 		printf(" l2f:");
630b0453382SBill Fenner 		return;		/* nothing to do */
631b0453382SBill Fenner 	} else {
632b0453382SBill Fenner 		printf(" Unknown Version, neither L2F(1) nor L2TP(2)");
633b0453382SBill Fenner 		return;		/* nothing we can do */
634b0453382SBill Fenner 	}
635b0453382SBill Fenner 
636b0453382SBill Fenner 	printf("[");
6379afd0c29SBill Fenner 	if (EXTRACT_16BITS(ptr) & L2TP_FLAG_TYPE) {
638b0453382SBill Fenner 		flag_t = TRUE;
639b0453382SBill Fenner 		printf("T");
640b0453382SBill Fenner 	}
6419afd0c29SBill Fenner 	if (EXTRACT_16BITS(ptr) & L2TP_FLAG_LENGTH) {
642b0453382SBill Fenner 		flag_l = TRUE;
643b0453382SBill Fenner 		printf("L");
644b0453382SBill Fenner 	}
6459afd0c29SBill Fenner 	if (EXTRACT_16BITS(ptr) & L2TP_FLAG_SEQUENCE) {
646b0453382SBill Fenner 		flag_s = TRUE;
647b0453382SBill Fenner 		printf("S");
648b0453382SBill Fenner 	}
6499afd0c29SBill Fenner 	if (EXTRACT_16BITS(ptr) & L2TP_FLAG_OFFSET) {
650b0453382SBill Fenner 		flag_o = TRUE;
651b0453382SBill Fenner 		printf("O");
652b0453382SBill Fenner 	}
6539afd0c29SBill Fenner 	if (EXTRACT_16BITS(ptr) & L2TP_FLAG_PRIORITY) {
654b0453382SBill Fenner 		flag_p = TRUE;
655b0453382SBill Fenner 		printf("P");
656b0453382SBill Fenner 	}
657b0453382SBill Fenner 	printf("]");
658b0453382SBill Fenner 
659b0453382SBill Fenner 	ptr++;
660b0453382SBill Fenner 	cnt += 2;
661b0453382SBill Fenner 
662b0453382SBill Fenner 	if (flag_l) {
663a90e161bSBill Fenner 		TCHECK(*ptr);	/* Length */
6649afd0c29SBill Fenner 		l2tp_len = EXTRACT_16BITS(ptr); ptr++;
665b0453382SBill Fenner 		cnt += 2;
666b0453382SBill Fenner 	} else {
667b0453382SBill Fenner 		l2tp_len = 0;
668b0453382SBill Fenner 	}
669b0453382SBill Fenner 
670a90e161bSBill Fenner 	TCHECK(*ptr);		/* Tunnel ID */
6719afd0c29SBill Fenner 	printf("(%u/", EXTRACT_16BITS(ptr)); ptr++;
672a90e161bSBill Fenner 	cnt += 2;
673a90e161bSBill Fenner 	TCHECK(*ptr);		/* Session ID */
6749afd0c29SBill Fenner 	printf("%u)",  EXTRACT_16BITS(ptr)); ptr++;
675a90e161bSBill Fenner 	cnt += 2;
676b0453382SBill Fenner 
677b0453382SBill Fenner 	if (flag_s) {
678a90e161bSBill Fenner 		TCHECK(*ptr);	/* Ns */
6799afd0c29SBill Fenner 		printf("Ns=%u,", EXTRACT_16BITS(ptr)); ptr++;
680a90e161bSBill Fenner 		cnt += 2;
681a90e161bSBill Fenner 		TCHECK(*ptr);	/* Nr */
6829afd0c29SBill Fenner 		printf("Nr=%u",  EXTRACT_16BITS(ptr)); ptr++;
683a90e161bSBill Fenner 		cnt += 2;
684b0453382SBill Fenner 	}
685b0453382SBill Fenner 
686b0453382SBill Fenner 	if (flag_o) {
687a90e161bSBill Fenner 		TCHECK(*ptr);	/* Offset Size */
6889afd0c29SBill Fenner 		pad =  EXTRACT_16BITS(ptr); ptr++;
689b0453382SBill Fenner 		ptr += pad / sizeof(*ptr);
690b0453382SBill Fenner 		cnt += (2 + pad);
691b0453382SBill Fenner 	}
692b0453382SBill Fenner 
693b0453382SBill Fenner 	if (flag_t) {
694b0453382SBill Fenner 		if (length - cnt == 0) {
695b0453382SBill Fenner 			printf(" ZLB");
696b0453382SBill Fenner 		} else {
697b0453382SBill Fenner 			l2tp_avp_print((u_char *)ptr, length - cnt);
698b0453382SBill Fenner 		}
699b0453382SBill Fenner 	} else {
700b0453382SBill Fenner 		printf(" {");
701685295f4SBill Fenner 		ppp_print((u_char *)ptr, length - cnt);
702b0453382SBill Fenner 		printf("}");
703b0453382SBill Fenner 	}
704a90e161bSBill Fenner 
705a90e161bSBill Fenner 	return;
706a90e161bSBill Fenner 
707a90e161bSBill Fenner  trunc:
708a90e161bSBill Fenner 	printf("%s", tstr);
709b0453382SBill Fenner }
710