xref: /freebsd/contrib/tcpdump/print-l2tp.c (revision b97c9af58ad5902b91f3e97c12ac18b76954b8e2)
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
25b0453382SBill Fenner static const char rcsid[] =
269afd0c29SBill Fenner     "@(#) $Header: /tcpdump/master/tcpdump/print-l2tp.c,v 1.10.2.1 2002/05/25 09:47:07 guy Exp $";
27b0453382SBill Fenner #endif
28b0453382SBill Fenner 
29b0453382SBill Fenner #ifdef HAVE_CONFIG_H
30b0453382SBill Fenner #include "config.h"
31b0453382SBill Fenner #endif
32b0453382SBill Fenner 
33b0453382SBill Fenner #include <stdio.h>
34b0453382SBill Fenner #include <sys/types.h>
35b0453382SBill Fenner #include <sys/param.h>
36b0453382SBill Fenner #include <netinet/in.h>
37b0453382SBill Fenner #include <arpa/inet.h>
38b0453382SBill Fenner 
39b0453382SBill Fenner #include "l2tp.h"
40b0453382SBill Fenner #include "interface.h"
419afd0c29SBill Fenner #include "extract.h"
42b0453382SBill Fenner 
43b0453382SBill Fenner static char tstr[] = " [|l2tp]";
44b0453382SBill Fenner 
45b0453382SBill Fenner #ifndef TRUE
46b0453382SBill Fenner #define TRUE 1
47b0453382SBill Fenner #endif
48b0453382SBill Fenner 
49b0453382SBill Fenner #ifndef FALSE
50b0453382SBill Fenner #define FALSE 0
51b0453382SBill Fenner #endif
52b0453382SBill Fenner 
53a90e161bSBill Fenner #define	L2TP_MSGTYPE_SCCRQ	1  /* Start-Control-Connection-Request */
54a90e161bSBill Fenner #define	L2TP_MSGTYPE_SCCRP	2  /* Start-Control-Connection-Reply */
55a90e161bSBill Fenner #define	L2TP_MSGTYPE_SCCCN	3  /* Start-Control-Connection-Connected */
56a90e161bSBill Fenner #define	L2TP_MSGTYPE_STOPCCN	4  /* Stop-Control-Connection-Notification */
57a90e161bSBill Fenner #define	L2TP_MSGTYPE_HELLO	6  /* Hello */
58a90e161bSBill Fenner #define	L2TP_MSGTYPE_OCRQ	7  /* Outgoing-Call-Request */
59a90e161bSBill Fenner #define	L2TP_MSGTYPE_OCRP	8  /* Outgoing-Call-Reply */
60a90e161bSBill Fenner #define	L2TP_MSGTYPE_OCCN	9  /* Outgoing-Call-Connected */
61a90e161bSBill Fenner #define	L2TP_MSGTYPE_ICRQ	10 /* Incoming-Call-Request */
62a90e161bSBill Fenner #define	L2TP_MSGTYPE_ICRP	11 /* Incoming-Call-Reply */
63a90e161bSBill Fenner #define	L2TP_MSGTYPE_ICCN	12 /* Incoming-Call-Connected */
64a90e161bSBill Fenner #define	L2TP_MSGTYPE_CDN	14 /* Call-Disconnect-Notify */
65a90e161bSBill Fenner #define	L2TP_MSGTYPE_WEN	15 /* WAN-Error-Notify */
66a90e161bSBill Fenner #define	L2TP_MSGTYPE_SLI	16 /* Set-Link-Info */
67a90e161bSBill Fenner 
68a90e161bSBill Fenner static struct tok l2tp_msgtype2str[] = {
69a90e161bSBill Fenner 	{ L2TP_MSGTYPE_SCCRQ, 	"SCCRQ" },
70a90e161bSBill Fenner 	{ L2TP_MSGTYPE_SCCRP,	"SCCRP" },
71a90e161bSBill Fenner 	{ L2TP_MSGTYPE_SCCCN,	"SCCCN" },
72a90e161bSBill Fenner 	{ L2TP_MSGTYPE_STOPCCN,	"StopCCN" },
73a90e161bSBill Fenner 	{ L2TP_MSGTYPE_HELLO,	"HELLO" },
74a90e161bSBill Fenner 	{ L2TP_MSGTYPE_OCRQ,	"OCRQ" },
75a90e161bSBill Fenner 	{ L2TP_MSGTYPE_OCRP,	"OCRP" },
76a90e161bSBill Fenner 	{ L2TP_MSGTYPE_OCCN,	"OCCN" },
77a90e161bSBill Fenner 	{ L2TP_MSGTYPE_ICRQ,	"ICRQ" },
78a90e161bSBill Fenner 	{ L2TP_MSGTYPE_ICRP,	"ICRP" },
79a90e161bSBill Fenner 	{ L2TP_MSGTYPE_ICCN,	"ICCN" },
80a90e161bSBill Fenner 	{ L2TP_MSGTYPE_CDN,	"CDN" },
81a90e161bSBill Fenner 	{ L2TP_MSGTYPE_WEN,	"WEN" },
82a90e161bSBill Fenner 	{ L2TP_MSGTYPE_SLI,	"SLI" },
83a90e161bSBill Fenner 	{ 0,			NULL }
84b0453382SBill Fenner };
85b0453382SBill Fenner 
86a90e161bSBill Fenner #define L2TP_AVP_MSGTYPE		0  /* Message Type */
87a90e161bSBill Fenner #define L2TP_AVP_RESULT_CODE		1  /* Result Code */
88a90e161bSBill Fenner #define L2TP_AVP_PROTO_VER		2  /* Protocol Version */
89a90e161bSBill Fenner #define L2TP_AVP_FRAMING_CAP		3  /* Framing Capabilities */
90a90e161bSBill Fenner #define L2TP_AVP_BEARER_CAP		4  /* Bearer Capabilities */
91a90e161bSBill Fenner #define L2TP_AVP_TIE_BREAKER		5  /* Tie Breaker */
92a90e161bSBill Fenner #define L2TP_AVP_FIRM_VER		6  /* Firmware Revision */
93a90e161bSBill Fenner #define L2TP_AVP_HOST_NAME		7  /* Host Name */
94a90e161bSBill Fenner #define L2TP_AVP_VENDOR_NAME		8  /* Vendor Name */
95a90e161bSBill Fenner #define L2TP_AVP_ASSND_TUN_ID 		9  /* Assigned Tunnel ID */
96a90e161bSBill Fenner #define L2TP_AVP_RECV_WIN_SIZE		10 /* Receive Window Size */
97a90e161bSBill Fenner #define L2TP_AVP_CHALLENGE		11 /* Challenge */
98a90e161bSBill Fenner #define L2TP_AVP_Q931_CC		12 /* Q.931 Cause Code */
99a90e161bSBill Fenner #define L2TP_AVP_CHALLENGE_RESP		13 /* Challenge Response */
100a90e161bSBill Fenner #define L2TP_AVP_ASSND_SESS_ID  	14 /* Assigned Session ID */
101a90e161bSBill Fenner #define L2TP_AVP_CALL_SER_NUM 		15 /* Call Serial Number */
102a90e161bSBill Fenner #define L2TP_AVP_MINIMUM_BPS		16 /* Minimum BPS */
103a90e161bSBill Fenner #define L2TP_AVP_MAXIMUM_BPS		17 /* Maximum BPS */
104a90e161bSBill Fenner #define L2TP_AVP_BEARER_TYPE		18 /* Bearer Type */
105a90e161bSBill Fenner #define L2TP_AVP_FRAMING_TYPE 		19 /* Framing Type */
106a90e161bSBill Fenner #define L2TP_AVP_PACKET_PROC_DELAY	20 /* Packet Processing Delay (OBSOLETE) */
107a90e161bSBill Fenner #define L2TP_AVP_CALLED_NUMBER		21 /* Called Number */
108a90e161bSBill Fenner #define L2TP_AVP_CALLING_NUMBER		22 /* Calling Number */
109a90e161bSBill Fenner #define L2TP_AVP_SUB_ADDRESS		23 /* Sub-Address */
110a90e161bSBill Fenner #define L2TP_AVP_TX_CONN_SPEED		24 /* (Tx) Connect Speed */
111a90e161bSBill Fenner #define L2TP_AVP_PHY_CHANNEL_ID		25 /* Physical Channel ID */
112a90e161bSBill Fenner #define L2TP_AVP_INI_RECV_LCP		26 /* Initial Received LCP CONFREQ */
113a90e161bSBill Fenner #define L2TP_AVP_LAST_SENT_LCP		27 /* Last Sent LCP CONFREQ */
114a90e161bSBill Fenner #define L2TP_AVP_LAST_RECV_LCP		28 /* Last Received LCP CONFREQ */
115a90e161bSBill Fenner #define L2TP_AVP_PROXY_AUTH_TYPE	29 /* Proxy Authen Type */
116a90e161bSBill Fenner #define L2TP_AVP_PROXY_AUTH_NAME	30 /* Proxy Authen Name */
117a90e161bSBill Fenner #define L2TP_AVP_PROXY_AUTH_CHAL	31 /* Proxy Authen Challenge */
118a90e161bSBill Fenner #define L2TP_AVP_PROXY_AUTH_ID		32 /* Proxy Authen ID */
119a90e161bSBill Fenner #define L2TP_AVP_PROXY_AUTH_RESP	33 /* Proxy Authen Response */
120a90e161bSBill Fenner #define L2TP_AVP_CALL_ERRORS		34 /* Call Errors */
121a90e161bSBill Fenner #define L2TP_AVP_ACCM			35 /* ACCM */
122a90e161bSBill Fenner #define L2TP_AVP_RANDOM_VECTOR		36 /* Random Vector */
123a90e161bSBill Fenner #define L2TP_AVP_PRIVATE_GRP_ID		37 /* Private Group ID */
124a90e161bSBill Fenner #define L2TP_AVP_RX_CONN_SPEED		38 /* (Rx) Connect Speed */
125a90e161bSBill Fenner #define L2TP_AVP_SEQ_REQUIRED 		39 /* Sequencing Required */
126a90e161bSBill Fenner #define L2TP_AVP_PPP_DISCON_CC		46 /* PPP Disconnect Cause Code */
127b0453382SBill Fenner 
128a90e161bSBill Fenner static struct tok l2tp_avp2str[] = {
129a90e161bSBill Fenner 	{ L2TP_AVP_MSGTYPE,		"MSGTYPE" },
130a90e161bSBill Fenner 	{ L2TP_AVP_RESULT_CODE,		"RESULT_CODE" },
131a90e161bSBill Fenner 	{ L2TP_AVP_PROTO_VER,		"PROTO_VER" },
132a90e161bSBill Fenner 	{ L2TP_AVP_FRAMING_CAP,		"FRAMING_CAP" },
133a90e161bSBill Fenner 	{ L2TP_AVP_BEARER_CAP,		"BEARER_CAP" },
134a90e161bSBill Fenner 	{ L2TP_AVP_TIE_BREAKER,		"TIE_BREAKER" },
135a90e161bSBill Fenner 	{ L2TP_AVP_FIRM_VER,		"FIRM_VER" },
136a90e161bSBill Fenner 	{ L2TP_AVP_HOST_NAME,		"HOST_NAME" },
137a90e161bSBill Fenner 	{ L2TP_AVP_VENDOR_NAME,		"VENDOR_NAME" },
138a90e161bSBill Fenner 	{ L2TP_AVP_ASSND_TUN_ID,	"ASSND_TUN_ID" },
139a90e161bSBill Fenner 	{ L2TP_AVP_RECV_WIN_SIZE,	"RECV_WIN_SIZE" },
140a90e161bSBill Fenner 	{ L2TP_AVP_CHALLENGE,		"CHALLENGE" },
141a90e161bSBill Fenner 	{ L2TP_AVP_Q931_CC,		"Q931_CC", },
142a90e161bSBill Fenner 	{ L2TP_AVP_CHALLENGE_RESP,	"CHALLENGE_RESP" },
143a90e161bSBill Fenner 	{ L2TP_AVP_ASSND_SESS_ID,	"ASSND_SESS_ID" },
144a90e161bSBill Fenner 	{ L2TP_AVP_CALL_SER_NUM,	"CALL_SER_NUM" },
145a90e161bSBill Fenner 	{ L2TP_AVP_MINIMUM_BPS,		"MINIMUM_BPS" },
146a90e161bSBill Fenner 	{ L2TP_AVP_MAXIMUM_BPS,		"MAXIMUM_BPS" },
147a90e161bSBill Fenner 	{ L2TP_AVP_BEARER_TYPE,		"BEARER_TYPE" },
148a90e161bSBill Fenner 	{ L2TP_AVP_FRAMING_TYPE,	"FRAMING_TYPE" },
149a90e161bSBill Fenner 	{ L2TP_AVP_PACKET_PROC_DELAY,	"PACKET_PROC_DELAY" },
150a90e161bSBill Fenner 	{ L2TP_AVP_CALLED_NUMBER,	"CALLED_NUMBER" },
151a90e161bSBill Fenner 	{ L2TP_AVP_CALLING_NUMBER,	"CALLING_NUMBER" },
152a90e161bSBill Fenner 	{ L2TP_AVP_SUB_ADDRESS,		"SUB_ADDRESS" },
153a90e161bSBill Fenner 	{ L2TP_AVP_TX_CONN_SPEED,	"TX_CONN_SPEED" },
154a90e161bSBill Fenner 	{ L2TP_AVP_PHY_CHANNEL_ID,	"PHY_CHANNEL_ID" },
155a90e161bSBill Fenner 	{ L2TP_AVP_INI_RECV_LCP,	"INI_RECV_LCP" },
156a90e161bSBill Fenner 	{ L2TP_AVP_LAST_SENT_LCP,	"LAST_SENT_LCP" },
157a90e161bSBill Fenner 	{ L2TP_AVP_LAST_RECV_LCP,	"LAST_RECV_LCP" },
158a90e161bSBill Fenner 	{ L2TP_AVP_PROXY_AUTH_TYPE,	"PROXY_AUTH_TYPE" },
159a90e161bSBill Fenner 	{ L2TP_AVP_PROXY_AUTH_NAME,	"PROXY_AUTH_NAME" },
160a90e161bSBill Fenner 	{ L2TP_AVP_PROXY_AUTH_CHAL,	"PROXY_AUTH_CHAL" },
161a90e161bSBill Fenner 	{ L2TP_AVP_PROXY_AUTH_ID,	"PROXY_AUTH_ID" },
162a90e161bSBill Fenner 	{ L2TP_AVP_PROXY_AUTH_RESP,	"PROXY_AUTH_RESP" },
163a90e161bSBill Fenner 	{ L2TP_AVP_CALL_ERRORS,		"CALL_ERRORS" },
164a90e161bSBill Fenner 	{ L2TP_AVP_ACCM,		"ACCM" },
165a90e161bSBill Fenner 	{ L2TP_AVP_RANDOM_VECTOR,	"RANDOM_VECTOR" },
166a90e161bSBill Fenner 	{ L2TP_AVP_PRIVATE_GRP_ID,	"PRIVATE_GRP_ID" },
167a90e161bSBill Fenner 	{ L2TP_AVP_RX_CONN_SPEED,	"RX_CONN_SPEED" },
168a90e161bSBill Fenner 	{ L2TP_AVP_SEQ_REQUIRED,	"SEQ_REQUIRED" },
169a90e161bSBill Fenner 	{ L2TP_AVP_PPP_DISCON_CC,	"PPP_DISCON_CC" },
170a90e161bSBill Fenner 	{ 0,				NULL }
171a90e161bSBill Fenner };
172a90e161bSBill Fenner 
173a90e161bSBill Fenner static struct tok l2tp_authentype2str[] = {
174a90e161bSBill Fenner 	{ L2TP_AUTHEN_TYPE_RESERVED,	"Reserved" },
175a90e161bSBill Fenner 	{ L2TP_AUTHEN_TYPE_TEXTUAL,	"Textual" },
176a90e161bSBill Fenner 	{ L2TP_AUTHEN_TYPE_CHAP,	"CHAP" },
177a90e161bSBill Fenner 	{ L2TP_AUTHEN_TYPE_PAP,		"PAP" },
178a90e161bSBill Fenner 	{ L2TP_AUTHEN_TYPE_NO_AUTH,	"No Auth" },
179a90e161bSBill Fenner 	{ L2TP_AUTHEN_TYPE_MSCHAPv1,	"MS-CHAPv1" },
180a90e161bSBill Fenner 	{ 0,				NULL }
181a90e161bSBill Fenner };
182a90e161bSBill Fenner 
183a90e161bSBill Fenner #define L2TP_PPP_DISCON_CC_DIRECTION_GLOBAL	0
184a90e161bSBill Fenner #define L2TP_PPP_DISCON_CC_DIRECTION_AT_PEER	1
185a90e161bSBill Fenner #define L2TP_PPP_DISCON_CC_DIRECTION_AT_LOCAL	2
186a90e161bSBill Fenner 
187a90e161bSBill Fenner static struct tok l2tp_cc_direction2str[] = {
188a90e161bSBill Fenner 	{ L2TP_PPP_DISCON_CC_DIRECTION_GLOBAL,	"global error" },
189a90e161bSBill Fenner 	{ L2TP_PPP_DISCON_CC_DIRECTION_AT_PEER,	"at peer" },
190a90e161bSBill Fenner 	{ L2TP_PPP_DISCON_CC_DIRECTION_AT_LOCAL,"at local" },
191a90e161bSBill Fenner 	{ 0,					NULL }
192b0453382SBill Fenner };
193b0453382SBill Fenner 
194b0453382SBill Fenner #if 0
195b0453382SBill Fenner static char *l2tp_result_code_StopCCN[] = {
196b0453382SBill Fenner          "Reserved",
197b0453382SBill Fenner          "General request to clear control connection",
198b0453382SBill Fenner          "General error--Error Code indicates the problem",
199b0453382SBill Fenner          "Control channel already exists",
200b0453382SBill Fenner          "Requester is not authorized to establish a control channel",
201b0453382SBill Fenner          "The protocol version of the requester is not supported",
202b0453382SBill Fenner          "Requester is being shut down",
203b0453382SBill Fenner          "Finite State Machine error"
204b0453382SBill Fenner #define L2TP_MAX_RESULT_CODE_STOPCC_INDEX	8
205b0453382SBill Fenner };
206b0453382SBill Fenner #endif
207b0453382SBill Fenner 
208b0453382SBill Fenner #if 0
209b0453382SBill Fenner static char *l2tp_result_code_CDN[] = {
210b0453382SBill Fenner 	"Reserved",
211b0453382SBill Fenner 	"Call disconnected due to loss of carrier",
212b0453382SBill Fenner 	"Call disconnected for the reason indicated in error code",
213b0453382SBill Fenner 	"Call disconnected for administrative reasons",
214b0453382SBill Fenner 	"Call failed due to lack of appropriate facilities being " \
215b0453382SBill Fenner 	"available (temporary condition)",
216b0453382SBill Fenner 	"Call failed due to lack of appropriate facilities being " \
217b0453382SBill Fenner 	"available (permanent condition)",
218b0453382SBill Fenner 	"Invalid destination",
219b0453382SBill Fenner 	"Call failed due to no carrier detected",
220b0453382SBill Fenner 	"Call failed due to detection of a busy signal",
221b0453382SBill Fenner 	"Call failed due to lack of a dial tone",
222b0453382SBill Fenner 	"Call was not established within time allotted by LAC",
223b0453382SBill Fenner 	"Call was connected but no appropriate framing was detected"
224b0453382SBill Fenner #define L2TP_MAX_RESULT_CODE_CDN_INDEX	12
225b0453382SBill Fenner };
226b0453382SBill Fenner #endif
227b0453382SBill Fenner 
228b0453382SBill Fenner #if 0
229b0453382SBill Fenner static char *l2tp_error_code_general[] = {
230b0453382SBill Fenner 	"No general error",
231b0453382SBill Fenner 	"No control connection exists yet for this LAC-LNS pair",
232b0453382SBill Fenner 	"Length is wrong",
233b0453382SBill Fenner 	"One of the field values was out of range or " \
234b0453382SBill Fenner 	"reserved field was non-zero"
235b0453382SBill Fenner 	"Insufficient resources to handle this operation now",
236b0453382SBill Fenner 	"The Session ID is invalid in this context",
237b0453382SBill Fenner 	"A generic vendor-specific error occurred in the LAC",
238b0453382SBill Fenner 	"Try another"
239b0453382SBill Fenner #define L2TP_MAX_ERROR_CODE_GENERAL_INDEX	8
240b0453382SBill Fenner };
241b0453382SBill Fenner #endif
242b0453382SBill Fenner 
243b0453382SBill Fenner /******************************/
244b0453382SBill Fenner /* generic print out routines */
245b0453382SBill Fenner /******************************/
246b0453382SBill Fenner static void
247b0453382SBill Fenner print_string(const u_char *dat, u_int length)
248b0453382SBill Fenner {
249b0453382SBill Fenner 	int i;
250b0453382SBill Fenner 	for (i=0; i<length; i++) {
251b0453382SBill Fenner 		printf("%c", *dat++);
252b0453382SBill Fenner 	}
253b0453382SBill Fenner }
254b0453382SBill Fenner 
255b0453382SBill Fenner static void
256b0453382SBill Fenner print_octets(const u_char *dat, u_int length)
257b0453382SBill Fenner {
258b0453382SBill Fenner 	int i;
259b0453382SBill Fenner 	for (i=0; i<length; i++) {
260b0453382SBill Fenner 		printf("%02x", *dat++);
261b0453382SBill Fenner 	}
262b0453382SBill Fenner }
263b0453382SBill Fenner 
264b0453382SBill Fenner static void
265a90e161bSBill Fenner print_16bits_val(const u_int16_t *dat)
266b0453382SBill Fenner {
2679afd0c29SBill Fenner 	printf("%u", EXTRACT_16BITS(dat));
268b0453382SBill Fenner }
269b0453382SBill Fenner 
270b0453382SBill Fenner static void
271a90e161bSBill Fenner print_32bits_val(const u_int32_t *dat)
272b0453382SBill Fenner {
2739afd0c29SBill Fenner 	printf("%lu", (u_long)EXTRACT_32BITS(dat));
274b0453382SBill Fenner }
275b0453382SBill Fenner 
276a90e161bSBill Fenner /***********************************/
277b0453382SBill Fenner /* AVP-specific print out routines */
278a90e161bSBill Fenner /***********************************/
279b0453382SBill Fenner static void
280a90e161bSBill Fenner l2tp_msgtype_print(const u_char *dat)
281b0453382SBill Fenner {
282a90e161bSBill Fenner 	u_int16_t *ptr = (u_int16_t*)dat;
283b0453382SBill Fenner 
2849afd0c29SBill Fenner 	printf("%s", tok2str(l2tp_msgtype2str, "MSGTYPE-#%u",
2859afd0c29SBill Fenner 	    EXTRACT_16BITS(ptr)));
286b0453382SBill Fenner }
287b0453382SBill Fenner 
288b0453382SBill Fenner static void
289b0453382SBill Fenner l2tp_result_code_print(const u_char *dat, u_int length)
290b0453382SBill Fenner {
291a90e161bSBill Fenner 	u_int16_t *ptr = (u_int16_t *)dat;
292b0453382SBill Fenner 
2939afd0c29SBill Fenner 	printf("%u", EXTRACT_16BITS(ptr)); ptr++;	/* Result Code */
294a90e161bSBill Fenner 	if (length > 2) {				/* Error Code (opt) */
2959afd0c29SBill Fenner 	        printf("/%u", EXTRACT_16BITS(ptr)); ptr++;
296a90e161bSBill Fenner 	}
297a90e161bSBill Fenner 	if (length > 4) {				/* Error Message (opt) */
298a90e161bSBill Fenner 		printf(" ");
299a90e161bSBill Fenner 		print_string((u_char *)ptr, length - 4);
300b0453382SBill Fenner 	}
301b0453382SBill Fenner }
302b0453382SBill Fenner 
303b0453382SBill Fenner static void
304a90e161bSBill Fenner l2tp_proto_ver_print(const u_int16_t *dat)
305b0453382SBill Fenner {
3069afd0c29SBill Fenner 	printf("%u.%u", (EXTRACT_16BITS(dat) >> 8),
3079afd0c29SBill Fenner 	    (EXTRACT_16BITS(dat) & 0xff));
308b0453382SBill Fenner }
309b0453382SBill Fenner 
310b0453382SBill Fenner static void
311a90e161bSBill Fenner l2tp_framing_cap_print(const u_char *dat)
312b0453382SBill Fenner {
313a90e161bSBill Fenner 	u_int32_t *ptr = (u_int32_t *)dat;
314b0453382SBill Fenner 
3159afd0c29SBill Fenner 	if (EXTRACT_32BITS(ptr) &  L2TP_FRAMING_CAP_ASYNC_MASK) {
316b0453382SBill Fenner 		printf("A");
317b0453382SBill Fenner 	}
3189afd0c29SBill Fenner 	if (EXTRACT_32BITS(ptr) &  L2TP_FRAMING_CAP_SYNC_MASK) {
319b0453382SBill Fenner 		printf("S");
320b0453382SBill Fenner 	}
321b0453382SBill Fenner }
322b0453382SBill Fenner 
323b0453382SBill Fenner static void
324a90e161bSBill Fenner l2tp_bearer_cap_print(const u_char *dat)
325b0453382SBill Fenner {
326a90e161bSBill Fenner 	u_int32_t *ptr = (u_int32_t *)dat;
327b0453382SBill Fenner 
3289afd0c29SBill Fenner 	if (EXTRACT_32BITS(ptr) &  L2TP_BEARER_CAP_ANALOG_MASK) {
329b0453382SBill Fenner 		printf("A");
330b0453382SBill Fenner 	}
3319afd0c29SBill Fenner 	if (EXTRACT_32BITS(ptr) &  L2TP_BEARER_CAP_DIGITAL_MASK) {
332b0453382SBill Fenner 		printf("D");
333b0453382SBill Fenner 	}
334b0453382SBill Fenner }
335b0453382SBill Fenner 
336b0453382SBill Fenner static void
337b0453382SBill Fenner l2tp_q931_cc_print(const u_char *dat, u_int length)
338b0453382SBill Fenner {
339a90e161bSBill Fenner 	print_16bits_val((u_int16_t *)dat);
340b0453382SBill Fenner 	printf(", %02x", dat[2]);
341b0453382SBill Fenner 	if (length > 3) {
342b0453382SBill Fenner 		printf(" ");
343b0453382SBill Fenner 		print_string(dat+3, length-3);
344b0453382SBill Fenner 	}
345b0453382SBill Fenner }
346b0453382SBill Fenner 
347b0453382SBill Fenner static void
348a90e161bSBill Fenner l2tp_bearer_type_print(const u_char *dat)
349b0453382SBill Fenner {
350a90e161bSBill Fenner 	u_int32_t *ptr = (u_int32_t *)dat;
351b0453382SBill Fenner 
3529afd0c29SBill Fenner 	if (EXTRACT_32BITS(ptr) &  L2TP_BEARER_TYPE_ANALOG_MASK) {
353b0453382SBill Fenner 		printf("A");
354b0453382SBill Fenner 	}
3559afd0c29SBill Fenner 	if (EXTRACT_32BITS(ptr) &  L2TP_BEARER_TYPE_DIGITAL_MASK) {
356b0453382SBill Fenner 		printf("D");
357b0453382SBill Fenner 	}
358b0453382SBill Fenner }
359b0453382SBill Fenner 
360b0453382SBill Fenner static void
361a90e161bSBill Fenner l2tp_framing_type_print(const u_char *dat)
362b0453382SBill Fenner {
363a90e161bSBill Fenner 	u_int32_t *ptr = (u_int32_t *)dat;
364b0453382SBill Fenner 
3659afd0c29SBill Fenner 	if (EXTRACT_32BITS(ptr) &  L2TP_FRAMING_TYPE_ASYNC_MASK) {
366b0453382SBill Fenner 		printf("A");
367b0453382SBill Fenner 	}
3689afd0c29SBill Fenner 	if (EXTRACT_32BITS(ptr) &  L2TP_FRAMING_TYPE_SYNC_MASK) {
369b0453382SBill Fenner 		printf("S");
370b0453382SBill Fenner 	}
371b0453382SBill Fenner }
372b0453382SBill Fenner 
373b0453382SBill Fenner static void
374a90e161bSBill Fenner l2tp_packet_proc_delay_print(void)
375b0453382SBill Fenner {
376b0453382SBill Fenner 	printf("obsolete");
377b0453382SBill Fenner }
378b0453382SBill Fenner 
379b0453382SBill Fenner static void
380a90e161bSBill Fenner l2tp_proxy_auth_type_print(const u_char *dat)
381b0453382SBill Fenner {
382a90e161bSBill Fenner 	u_int16_t *ptr = (u_int16_t *)dat;
383a90e161bSBill Fenner 
384a90e161bSBill Fenner 	printf("%s", tok2str(l2tp_authentype2str,
3859afd0c29SBill Fenner 			     "AuthType-#%u", EXTRACT_16BITS(ptr)));
386b0453382SBill Fenner }
387b0453382SBill Fenner 
388b0453382SBill Fenner static void
389a90e161bSBill Fenner l2tp_proxy_auth_id_print(const u_char *dat)
390b0453382SBill Fenner {
391a90e161bSBill Fenner 	u_int16_t *ptr = (u_int16_t *)dat;
392b0453382SBill Fenner 
3939afd0c29SBill Fenner 	printf("%u", EXTRACT_16BITS(ptr) & L2TP_PROXY_AUTH_ID_MASK);
394b0453382SBill Fenner }
395b0453382SBill Fenner 
396b0453382SBill Fenner static void
397a90e161bSBill Fenner l2tp_call_errors_print(const u_char *dat)
398b0453382SBill Fenner {
399a90e161bSBill Fenner 	u_int16_t *ptr = (u_int16_t *)dat;
400a90e161bSBill Fenner 	u_int16_t val_h, val_l;
401a90e161bSBill Fenner 
402a90e161bSBill Fenner 	ptr++;		/* skip "Reserved" */
403a90e161bSBill Fenner 
4049afd0c29SBill Fenner 	val_h = EXTRACT_16BITS(ptr); ptr++;
4059afd0c29SBill Fenner 	val_l = EXTRACT_16BITS(ptr); ptr++;
406a90e161bSBill Fenner 	printf("CRCErr=%u ", (val_h<<16) + val_l);
407a90e161bSBill Fenner 
4089afd0c29SBill Fenner 	val_h = EXTRACT_16BITS(ptr); ptr++;
4099afd0c29SBill Fenner 	val_l = EXTRACT_16BITS(ptr); ptr++;
410a90e161bSBill Fenner 	printf("FrameErr=%u ", (val_h<<16) + val_l);
411a90e161bSBill Fenner 
4129afd0c29SBill Fenner 	val_h = EXTRACT_16BITS(ptr); ptr++;
4139afd0c29SBill Fenner 	val_l = EXTRACT_16BITS(ptr); ptr++;
414a90e161bSBill Fenner 	printf("HardOver=%u ", (val_h<<16) + val_l);
415a90e161bSBill Fenner 
4169afd0c29SBill Fenner 	val_h = EXTRACT_16BITS(ptr); ptr++;
4179afd0c29SBill Fenner 	val_l = EXTRACT_16BITS(ptr); ptr++;
418a90e161bSBill Fenner 	printf("BufOver=%u ", (val_h<<16) + val_l);
419a90e161bSBill Fenner 
4209afd0c29SBill Fenner 	val_h = EXTRACT_16BITS(ptr); ptr++;
4219afd0c29SBill Fenner 	val_l = EXTRACT_16BITS(ptr); ptr++;
422a90e161bSBill Fenner 	printf("Timeout=%u ", (val_h<<16) + val_l);
423a90e161bSBill Fenner 
4249afd0c29SBill Fenner 	val_h = EXTRACT_16BITS(ptr); ptr++;
4259afd0c29SBill Fenner 	val_l = EXTRACT_16BITS(ptr); ptr++;
426a90e161bSBill Fenner 	printf("AlignErr=%u ", (val_h<<16) + val_l);
427b0453382SBill Fenner }
428b0453382SBill Fenner 
429b0453382SBill Fenner static void
430a90e161bSBill Fenner l2tp_accm_print(const u_char *dat)
431b0453382SBill Fenner {
432a90e161bSBill Fenner 	u_int16_t *ptr = (u_int16_t *)dat;
433a90e161bSBill Fenner 	u_int16_t val_h, val_l;
434b0453382SBill Fenner 
435a90e161bSBill Fenner 	ptr++;		/* skip "Reserved" */
436a90e161bSBill Fenner 
4379afd0c29SBill Fenner 	val_h = EXTRACT_16BITS(ptr); ptr++;
4389afd0c29SBill Fenner 	val_l = EXTRACT_16BITS(ptr); ptr++;
439a90e161bSBill Fenner 	printf("send=%08x ", (val_h<<16) + val_l);
440a90e161bSBill Fenner 
4419afd0c29SBill Fenner 	val_h = EXTRACT_16BITS(ptr); ptr++;
4429afd0c29SBill Fenner 	val_l = EXTRACT_16BITS(ptr); ptr++;
443a90e161bSBill Fenner 	printf("recv=%08x ", (val_h<<16) + val_l);
444b0453382SBill Fenner }
445b0453382SBill Fenner 
446b0453382SBill Fenner static void
447a90e161bSBill Fenner l2tp_ppp_discon_cc_print(const u_char *dat, u_int length)
448b0453382SBill Fenner {
449a90e161bSBill Fenner 	u_int16_t *ptr = (u_int16_t *)dat;
450b0453382SBill Fenner 
4519afd0c29SBill Fenner 	printf("%04x, ", EXTRACT_16BITS(ptr)); ptr++;	/* Disconnect Code */
4529afd0c29SBill Fenner 	printf("%04x ",  EXTRACT_16BITS(ptr)); ptr++;	/* Control Protocol Number */
453a90e161bSBill Fenner 	printf("%s", tok2str(l2tp_cc_direction2str,
454a90e161bSBill Fenner 			     "Direction-#%u", *((u_char *)ptr++)));
455a90e161bSBill Fenner 
456a90e161bSBill Fenner 	if (length > 5) {
457a90e161bSBill Fenner 		printf(" ");
458a90e161bSBill Fenner 		print_string((const u_char *)ptr, length-5);
459a90e161bSBill Fenner 	}
460b0453382SBill Fenner }
461b0453382SBill Fenner 
462b0453382SBill Fenner static void
463a90e161bSBill Fenner l2tp_avp_print(const u_char *dat, int length)
464b0453382SBill Fenner {
465a90e161bSBill Fenner 	u_int len;
466a90e161bSBill Fenner 	const u_int16_t *ptr = (u_int16_t *)dat;
467a90e161bSBill Fenner 	u_int16_t attr_type;
468a90e161bSBill Fenner 	int hidden = FALSE;
469b0453382SBill Fenner 
470a90e161bSBill Fenner 	if (length <= 0) {
471b0453382SBill Fenner 		return;
472b0453382SBill Fenner 	}
473b0453382SBill Fenner 
474b0453382SBill Fenner 	printf(" ");
475a90e161bSBill Fenner 
476a90e161bSBill Fenner 	TCHECK(*ptr);	/* Flags & Length */
4779afd0c29SBill Fenner 	len = EXTRACT_16BITS(ptr) & L2TP_AVP_HDR_LEN_MASK;
478a90e161bSBill Fenner 
479b97c9af5SBill Fenner 	/* If it is not long enough to contain the header, we'll give up. */
480b97c9af5SBill Fenner 	if (len < 6)
481b97c9af5SBill Fenner 		goto trunc;
482b97c9af5SBill Fenner 
483b97c9af5SBill Fenner 	/* If it goes past the end of the remaining length of the packet,
484b97c9af5SBill Fenner 	   we'll give up. */
485b97c9af5SBill Fenner 	if (len > (u_int)length)
486b97c9af5SBill Fenner 		goto trunc;
487b97c9af5SBill Fenner 
488b97c9af5SBill Fenner 	/* If it goes past the end of the remaining length of the captured
489b97c9af5SBill Fenner 	   data, we'll give up. */
490a90e161bSBill Fenner 	TCHECK2(*ptr, len);
491a90e161bSBill Fenner 	/* After this point, no need to worry about truncation */
492a90e161bSBill Fenner 
4939afd0c29SBill Fenner 	if (EXTRACT_16BITS(ptr) & L2TP_AVP_HDR_FLAG_MANDATORY) {
494b0453382SBill Fenner 		printf("*");
495b0453382SBill Fenner 	}
4969afd0c29SBill Fenner 	if (EXTRACT_16BITS(ptr) & L2TP_AVP_HDR_FLAG_HIDDEN) {
497b0453382SBill Fenner 		hidden = TRUE;
498b0453382SBill Fenner 		printf("?");
499b0453382SBill Fenner 	}
500b0453382SBill Fenner 	ptr++;
501b0453382SBill Fenner 
5029afd0c29SBill Fenner 	if (EXTRACT_16BITS(ptr)) {
503685295f4SBill Fenner 		/* Vendor Specific Attribute */
5049afd0c29SBill Fenner 	        printf("VENDOR%04x:", EXTRACT_16BITS(ptr)); ptr++;
5059afd0c29SBill Fenner 		printf("ATTR%04x", EXTRACT_16BITS(ptr)); ptr++;
506685295f4SBill Fenner 		printf("(");
507a90e161bSBill Fenner 		print_octets((u_char *)ptr, len-6);
508685295f4SBill Fenner 		printf(")");
509685295f4SBill Fenner 	} else {
510a90e161bSBill Fenner 		/* IETF-defined Attributes */
511685295f4SBill Fenner 		ptr++;
5129afd0c29SBill Fenner 		attr_type = EXTRACT_16BITS(ptr); ptr++;
513a90e161bSBill Fenner 		printf("%s", tok2str(l2tp_avp2str, "AVP-#%u", attr_type));
514b0453382SBill Fenner 		printf("(");
515a90e161bSBill Fenner 		if (hidden) {
516b0453382SBill Fenner 			printf("???");
517a90e161bSBill Fenner 		} else {
518a90e161bSBill Fenner 			switch (attr_type) {
519a90e161bSBill Fenner 			case L2TP_AVP_MSGTYPE:
520a90e161bSBill Fenner 				l2tp_msgtype_print((u_char *)ptr);
521a90e161bSBill Fenner 				break;
522a90e161bSBill Fenner 			case L2TP_AVP_RESULT_CODE:
523a90e161bSBill Fenner 				l2tp_result_code_print((u_char *)ptr, len-6);
524a90e161bSBill Fenner 				break;
525a90e161bSBill Fenner 			case L2TP_AVP_PROTO_VER:
526a90e161bSBill Fenner 				l2tp_proto_ver_print(ptr);
527a90e161bSBill Fenner 				break;
528a90e161bSBill Fenner 			case L2TP_AVP_FRAMING_CAP:
529a90e161bSBill Fenner 				l2tp_framing_cap_print((u_char *)ptr);
530a90e161bSBill Fenner 				break;
531a90e161bSBill Fenner 			case L2TP_AVP_BEARER_CAP:
532a90e161bSBill Fenner 				l2tp_bearer_cap_print((u_char *)ptr);
533a90e161bSBill Fenner 				break;
534a90e161bSBill Fenner 			case L2TP_AVP_TIE_BREAKER:
535a90e161bSBill Fenner 				print_octets((u_char *)ptr, 8);
536a90e161bSBill Fenner 				break;
537a90e161bSBill Fenner 			case L2TP_AVP_FIRM_VER:
538a90e161bSBill Fenner 			case L2TP_AVP_ASSND_TUN_ID:
539a90e161bSBill Fenner 			case L2TP_AVP_RECV_WIN_SIZE:
540a90e161bSBill Fenner 			case L2TP_AVP_ASSND_SESS_ID:
541a90e161bSBill Fenner 				print_16bits_val(ptr);
542a90e161bSBill Fenner 				break;
543a90e161bSBill Fenner 			case L2TP_AVP_HOST_NAME:
544a90e161bSBill Fenner 			case L2TP_AVP_VENDOR_NAME:
545a90e161bSBill Fenner 			case L2TP_AVP_CALLING_NUMBER:
546a90e161bSBill Fenner 			case L2TP_AVP_CALLED_NUMBER:
547a90e161bSBill Fenner 			case L2TP_AVP_SUB_ADDRESS:
548a90e161bSBill Fenner 			case L2TP_AVP_PROXY_AUTH_NAME:
549a90e161bSBill Fenner 			case L2TP_AVP_PRIVATE_GRP_ID:
550a90e161bSBill Fenner 				print_string((u_char *)ptr, len-6);
551a90e161bSBill Fenner 				break;
552a90e161bSBill Fenner 			case L2TP_AVP_CHALLENGE:
553a90e161bSBill Fenner 			case L2TP_AVP_INI_RECV_LCP:
554a90e161bSBill Fenner 			case L2TP_AVP_LAST_SENT_LCP:
555a90e161bSBill Fenner 			case L2TP_AVP_LAST_RECV_LCP:
556a90e161bSBill Fenner 			case L2TP_AVP_PROXY_AUTH_CHAL:
557a90e161bSBill Fenner 			case L2TP_AVP_PROXY_AUTH_RESP:
558a90e161bSBill Fenner 			case L2TP_AVP_RANDOM_VECTOR:
559a90e161bSBill Fenner 				print_octets((u_char *)ptr, len-6);
560a90e161bSBill Fenner 				break;
561a90e161bSBill Fenner 			case L2TP_AVP_Q931_CC:
562a90e161bSBill Fenner 				l2tp_q931_cc_print((u_char *)ptr, len-6);
563a90e161bSBill Fenner 				break;
564a90e161bSBill Fenner 			case L2TP_AVP_CHALLENGE_RESP:
565a90e161bSBill Fenner 				print_octets((u_char *)ptr, 16);
566a90e161bSBill Fenner 				break;
567a90e161bSBill Fenner 			case L2TP_AVP_CALL_SER_NUM:
568a90e161bSBill Fenner 			case L2TP_AVP_MINIMUM_BPS:
569a90e161bSBill Fenner 			case L2TP_AVP_MAXIMUM_BPS:
570a90e161bSBill Fenner 			case L2TP_AVP_TX_CONN_SPEED:
571a90e161bSBill Fenner 			case L2TP_AVP_PHY_CHANNEL_ID:
572a90e161bSBill Fenner 			case L2TP_AVP_RX_CONN_SPEED:
573a90e161bSBill Fenner 				print_32bits_val((u_int32_t *)ptr);
574a90e161bSBill Fenner 				break;
575a90e161bSBill Fenner 			case L2TP_AVP_BEARER_TYPE:
576a90e161bSBill Fenner 				l2tp_bearer_type_print((u_char *)ptr);
577a90e161bSBill Fenner 				break;
578a90e161bSBill Fenner 			case L2TP_AVP_FRAMING_TYPE:
579a90e161bSBill Fenner 				l2tp_framing_type_print((u_char *)ptr);
580a90e161bSBill Fenner 				break;
581a90e161bSBill Fenner 			case L2TP_AVP_PACKET_PROC_DELAY:
582a90e161bSBill Fenner 				l2tp_packet_proc_delay_print();
583a90e161bSBill Fenner 				break;
584a90e161bSBill Fenner 			case L2TP_AVP_PROXY_AUTH_TYPE:
585a90e161bSBill Fenner 				l2tp_proxy_auth_type_print((u_char *)ptr);
586a90e161bSBill Fenner 				break;
587a90e161bSBill Fenner 			case L2TP_AVP_PROXY_AUTH_ID:
588a90e161bSBill Fenner 				l2tp_proxy_auth_id_print((u_char *)ptr);
589a90e161bSBill Fenner 				break;
590a90e161bSBill Fenner 			case L2TP_AVP_CALL_ERRORS:
591a90e161bSBill Fenner 				l2tp_call_errors_print((u_char *)ptr);
592a90e161bSBill Fenner 				break;
593a90e161bSBill Fenner 			case L2TP_AVP_ACCM:
594a90e161bSBill Fenner 				l2tp_accm_print((u_char *)ptr);
595a90e161bSBill Fenner 				break;
596a90e161bSBill Fenner 			case L2TP_AVP_SEQ_REQUIRED:
597a90e161bSBill Fenner 				break;	/* No Attribute Value */
598a90e161bSBill Fenner 			case L2TP_AVP_PPP_DISCON_CC:
599a90e161bSBill Fenner 				l2tp_ppp_discon_cc_print((u_char *)ptr, len-6);
600a90e161bSBill Fenner 				break;
601a90e161bSBill Fenner 			default:
602a90e161bSBill Fenner 				break;
603a90e161bSBill Fenner 			}
604b0453382SBill Fenner 		}
605b0453382SBill Fenner 		printf(")");
606685295f4SBill Fenner 	}
607b0453382SBill Fenner 
608b0453382SBill Fenner 	l2tp_avp_print(dat+len, length-len);
609b0453382SBill Fenner 	return;
610a90e161bSBill Fenner 
611a90e161bSBill Fenner  trunc:
612b0453382SBill Fenner 	printf("|...");
613b0453382SBill Fenner }
614b0453382SBill Fenner 
615b0453382SBill Fenner 
616b0453382SBill Fenner void
617b0453382SBill Fenner l2tp_print(const u_char *dat, u_int length)
618b0453382SBill Fenner {
619a90e161bSBill Fenner 	const u_int16_t *ptr = (u_int16_t *)dat;
620b0453382SBill Fenner 	u_int cnt = 0;			/* total octets consumed */
621a90e161bSBill Fenner 	u_int16_t pad;
622b0453382SBill Fenner 	int flag_t, flag_l, flag_s, flag_o, flag_p;
623a90e161bSBill Fenner 	u_int16_t l2tp_len;
624b0453382SBill Fenner 
625b0453382SBill Fenner 	flag_t = flag_l = flag_s = flag_o = flag_p = FALSE;
626b0453382SBill Fenner 
627a90e161bSBill Fenner 	TCHECK(*ptr);	/* Flags & Version */
6289afd0c29SBill Fenner 	if ((EXTRACT_16BITS(ptr) & L2TP_VERSION_MASK) == L2TP_VERSION_L2TP) {
629b0453382SBill Fenner 		printf(" l2tp:");
6309afd0c29SBill Fenner 	} else if ((EXTRACT_16BITS(ptr) & L2TP_VERSION_MASK) == L2TP_VERSION_L2F) {
631b0453382SBill Fenner 		printf(" l2f:");
632b0453382SBill Fenner 		return;		/* nothing to do */
633b0453382SBill Fenner 	} else {
634b0453382SBill Fenner 		printf(" Unknown Version, neither L2F(1) nor L2TP(2)");
635b0453382SBill Fenner 		return;		/* nothing we can do */
636b0453382SBill Fenner 	}
637b0453382SBill Fenner 
638b0453382SBill Fenner 	printf("[");
6399afd0c29SBill Fenner 	if (EXTRACT_16BITS(ptr) & L2TP_FLAG_TYPE) {
640b0453382SBill Fenner 		flag_t = TRUE;
641b0453382SBill Fenner 		printf("T");
642b0453382SBill Fenner 	}
6439afd0c29SBill Fenner 	if (EXTRACT_16BITS(ptr) & L2TP_FLAG_LENGTH) {
644b0453382SBill Fenner 		flag_l = TRUE;
645b0453382SBill Fenner 		printf("L");
646b0453382SBill Fenner 	}
6479afd0c29SBill Fenner 	if (EXTRACT_16BITS(ptr) & L2TP_FLAG_SEQUENCE) {
648b0453382SBill Fenner 		flag_s = TRUE;
649b0453382SBill Fenner 		printf("S");
650b0453382SBill Fenner 	}
6519afd0c29SBill Fenner 	if (EXTRACT_16BITS(ptr) & L2TP_FLAG_OFFSET) {
652b0453382SBill Fenner 		flag_o = TRUE;
653b0453382SBill Fenner 		printf("O");
654b0453382SBill Fenner 	}
6559afd0c29SBill Fenner 	if (EXTRACT_16BITS(ptr) & L2TP_FLAG_PRIORITY) {
656b0453382SBill Fenner 		flag_p = TRUE;
657b0453382SBill Fenner 		printf("P");
658b0453382SBill Fenner 	}
659b0453382SBill Fenner 	printf("]");
660b0453382SBill Fenner 
661b0453382SBill Fenner 	ptr++;
662b0453382SBill Fenner 	cnt += 2;
663b0453382SBill Fenner 
664b0453382SBill Fenner 	if (flag_l) {
665a90e161bSBill Fenner 		TCHECK(*ptr);	/* Length */
6669afd0c29SBill Fenner 		l2tp_len = EXTRACT_16BITS(ptr); ptr++;
667b0453382SBill Fenner 		cnt += 2;
668b0453382SBill Fenner 	} else {
669b0453382SBill Fenner 		l2tp_len = 0;
670b0453382SBill Fenner 	}
671b0453382SBill Fenner 
672a90e161bSBill Fenner 	TCHECK(*ptr);		/* Tunnel ID */
6739afd0c29SBill Fenner 	printf("(%u/", EXTRACT_16BITS(ptr)); ptr++;
674a90e161bSBill Fenner 	cnt += 2;
675a90e161bSBill Fenner 	TCHECK(*ptr);		/* Session ID */
6769afd0c29SBill Fenner 	printf("%u)",  EXTRACT_16BITS(ptr)); ptr++;
677a90e161bSBill Fenner 	cnt += 2;
678b0453382SBill Fenner 
679b0453382SBill Fenner 	if (flag_s) {
680a90e161bSBill Fenner 		TCHECK(*ptr);	/* Ns */
6819afd0c29SBill Fenner 		printf("Ns=%u,", EXTRACT_16BITS(ptr)); ptr++;
682a90e161bSBill Fenner 		cnt += 2;
683a90e161bSBill Fenner 		TCHECK(*ptr);	/* Nr */
6849afd0c29SBill Fenner 		printf("Nr=%u",  EXTRACT_16BITS(ptr)); ptr++;
685a90e161bSBill Fenner 		cnt += 2;
686b0453382SBill Fenner 	}
687b0453382SBill Fenner 
688b0453382SBill Fenner 	if (flag_o) {
689a90e161bSBill Fenner 		TCHECK(*ptr);	/* Offset Size */
6909afd0c29SBill Fenner 		pad =  EXTRACT_16BITS(ptr); ptr++;
691b0453382SBill Fenner 		ptr += pad / sizeof(*ptr);
692b0453382SBill Fenner 		cnt += (2 + pad);
693b0453382SBill Fenner 	}
694b0453382SBill Fenner 
695b0453382SBill Fenner 	if (flag_t) {
696b0453382SBill Fenner 		if (length - cnt == 0) {
697b0453382SBill Fenner 			printf(" ZLB");
698b0453382SBill Fenner 		} else {
699b0453382SBill Fenner 			l2tp_avp_print((u_char *)ptr, length - cnt);
700b0453382SBill Fenner 		}
701b0453382SBill Fenner 	} else {
702b0453382SBill Fenner 		printf(" {");
703685295f4SBill Fenner 		ppp_print((u_char *)ptr, length - cnt);
704b0453382SBill Fenner 		printf("}");
705b0453382SBill Fenner 	}
706a90e161bSBill Fenner 
707a90e161bSBill Fenner 	return;
708a90e161bSBill Fenner 
709a90e161bSBill Fenner  trunc:
710a90e161bSBill Fenner 	printf("%s", tstr);
711b0453382SBill Fenner }
712