xref: /freebsd/contrib/tcpdump/print-l2tp.c (revision b0453382235492c8e30b09659b52d784128ca7d0)
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  *
21b0453382SBill Fenner  * L2TP support contributed by Motonori Shindo (mshindo@ascend.co.jp)
22b0453382SBill Fenner  */
23b0453382SBill Fenner 
24b0453382SBill Fenner #ifndef lint
25b0453382SBill Fenner static const char rcsid[] =
26b0453382SBill Fenner     "@(#) $Header: /tcpdump/master/tcpdump/print-l2tp.c,v 1.6 1999/12/22 06:27:21 itojun 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"
41b0453382SBill Fenner 
42b0453382SBill Fenner static char tstr[] = " [|l2tp]";
43b0453382SBill Fenner 
44b0453382SBill Fenner #ifndef TRUE
45b0453382SBill Fenner #define TRUE 1
46b0453382SBill Fenner #endif
47b0453382SBill Fenner 
48b0453382SBill Fenner #ifndef FALSE
49b0453382SBill Fenner #define FALSE 0
50b0453382SBill Fenner #endif
51b0453382SBill Fenner 
52b0453382SBill Fenner static char *l2tp_message_type_string[] = {
53b0453382SBill Fenner 	"RESERVED_0",		/* 0  Reserved */
54b0453382SBill Fenner 	"SCCRQ",		/* 1  Start-Control-Connection-Request */
55b0453382SBill Fenner 	"SCCRP",		/* 2  Start-Control-Connection-Reply */
56b0453382SBill Fenner 	"SCCCN",		/* 3  Start-Control-Connection-Connected */
57b0453382SBill Fenner 	"StopCCN",		/* 4  Stop-Control-Connection-Notification */
58b0453382SBill Fenner 	"RESERVED_5",		/* 5  Reserved */
59b0453382SBill Fenner 	"HELLO",		/* 6  Hello */
60b0453382SBill Fenner 	"OCRQ",			/* 7  Outgoing-Call-Request */
61b0453382SBill Fenner 	"OCRP",			/* 8  Outgoing-Call-Reply */
62b0453382SBill Fenner 	"OCCN",			/* 9  Outgoing-Call-Connected */
63b0453382SBill Fenner 	"ICRQ",			/* 10 Incoming-Call-Request */
64b0453382SBill Fenner 	"ICRP",			/* 11 Incoming-Call-Reply */
65b0453382SBill Fenner 	"ICCN",			/* 12 Incoming-Call-Connected */
66b0453382SBill Fenner 	"RESERVED_13",		/* 13 Reserved */
67b0453382SBill Fenner 	"CDN",			/* 14 Call-Disconnect-Notify */
68b0453382SBill Fenner 	"WEN",			/* 15 WAN-Error-Notify */
69b0453382SBill Fenner 	"SLI"			/* 16 Set-Link-Info */
70b0453382SBill Fenner #define L2TP_MAX_MSGTYPE_INDEX	17
71b0453382SBill Fenner };
72b0453382SBill Fenner 
73b0453382SBill Fenner static void l2tp_msgtype_print(const u_char *dat, u_int length);
74b0453382SBill Fenner static void l2tp_result_code_print(const u_char *dat, u_int length);
75b0453382SBill Fenner static void l2tp_proto_ver_print(const u_char *dat, u_int length);
76b0453382SBill Fenner static void l2tp_framing_cap_print(const u_char *dat, u_int length);
77b0453382SBill Fenner static void l2tp_bearer_cap_print(const u_char *dat, u_int length);
78b0453382SBill Fenner static void l2tp_tie_breaker_print(const u_char *dat, u_int length);
79b0453382SBill Fenner static void l2tp_firm_ver_print(const u_char *dat, u_int length);
80b0453382SBill Fenner static void l2tp_host_name_print(const u_char *dat, u_int length);
81b0453382SBill Fenner static void l2tp_vendor_name_print(const u_char *dat, u_int length);
82b0453382SBill Fenner static void l2tp_assnd_tun_id_print(const u_char *dat, u_int length);
83b0453382SBill Fenner static void l2tp_recv_win_size_print(const u_char *dat, u_int length);
84b0453382SBill Fenner static void l2tp_challenge_print(const u_char *dat, u_int length);
85b0453382SBill Fenner static void l2tp_q931_cc_print(const u_char *dat, u_int length);
86b0453382SBill Fenner static void l2tp_challenge_resp_print(const u_char *dat, u_int length);
87b0453382SBill Fenner static void l2tp_assnd_sess_id_print(const u_char *dat, u_int length);
88b0453382SBill Fenner static void l2tp_call_ser_num_print(const u_char *dat, u_int length);
89b0453382SBill Fenner static void l2tp_minimum_bps_print(const u_char *dat, u_int length);
90b0453382SBill Fenner static void l2tp_maximum_bps_print(const u_char *dat, u_int length);
91b0453382SBill Fenner static void l2tp_bearer_type_print(const u_char *dat, u_int length);
92b0453382SBill Fenner static void l2tp_framing_type_print(const u_char *dat, u_int length);
93b0453382SBill Fenner static void l2tp_packet_proc_delay_print(const u_char *dat, u_int length);
94b0453382SBill Fenner static void l2tp_called_number_print(const u_char *dat, u_int length);
95b0453382SBill Fenner static void l2tp_calling_number_print(const u_char *dat, u_int length);
96b0453382SBill Fenner static void l2tp_sub_address_print(const u_char *dat, u_int length);
97b0453382SBill Fenner static void l2tp_tx_conn_speed_print(const u_char *dat, u_int length);
98b0453382SBill Fenner static void l2tp_phy_channel_id_print(const u_char *dat, u_int length);
99b0453382SBill Fenner static void l2tp_ini_recv_lcp_print(const u_char *dat, u_int length);
100b0453382SBill Fenner static void l2tp_last_sent_lcp_print(const u_char *dat, u_int length);
101b0453382SBill Fenner static void l2tp_last_recv_lcp_print(const u_char *dat, u_int length);
102b0453382SBill Fenner static void l2tp_proxy_auth_type_print(const u_char *dat, u_int length);
103b0453382SBill Fenner static void l2tp_proxy_auth_name_print(const u_char *dat, u_int length);
104b0453382SBill Fenner static void l2tp_proxy_auth_chal_print(const u_char *dat, u_int length);
105b0453382SBill Fenner static void l2tp_proxy_auth_id_print(const u_char *dat, u_int length);
106b0453382SBill Fenner static void l2tp_proxy_auth_resp_print(const u_char *dat, u_int length);
107b0453382SBill Fenner static void l2tp_call_errors_print(const u_char *dat, u_int length);
108b0453382SBill Fenner static void l2tp_accm_print(const u_char *dat, u_int length);
109b0453382SBill Fenner static void l2tp_random_vector_print(const u_char *dat, u_int length);
110b0453382SBill Fenner static void l2tp_private_grp_id_print(const u_char *dat, u_int length);
111b0453382SBill Fenner static void l2tp_rx_conn_speed_print(const u_char *dat, u_int length);
112b0453382SBill Fenner static void l2tp_seq_required_print(const u_char *dat, u_int length);
113b0453382SBill Fenner static void l2tp_avp_print(const u_char *dat, u_int length);
114b0453382SBill Fenner 
115b0453382SBill Fenner static struct l2tp_avp_vec l2tp_avp[] = {
116b0453382SBill Fenner   {"MSGTYPE", l2tp_msgtype_print}, 		/* 0  Message Type */
117b0453382SBill Fenner   {"RESULT_CODE", l2tp_result_code_print},	/* 1  Result Code */
118b0453382SBill Fenner   {"PROTO_VER", l2tp_proto_ver_print},		/* 2  Protocol Version */
119b0453382SBill Fenner   {"FRAMING_CAP", l2tp_framing_cap_print},	/* 3  Framing Capabilities */
120b0453382SBill Fenner   {"BEARER_CAP", l2tp_bearer_cap_print},	/* 4  Bearer Capabilities */
121b0453382SBill Fenner   {"TIE_BREAKER", l2tp_tie_breaker_print},	/* 5  Tie Breaker */
122b0453382SBill Fenner   {"FIRM_VER", l2tp_firm_ver_print},		/* 6  Firmware Revision */
123b0453382SBill Fenner   {"HOST_NAME", l2tp_host_name_print},		/* 7  Host Name */
124b0453382SBill Fenner   {"VENDOR_NAME", l2tp_vendor_name_print},	/* 8  Vendor Name */
125b0453382SBill Fenner   {"ASSND_TUN_ID", l2tp_assnd_tun_id_print}, 	/* 9  Assigned Tunnel ID */
126b0453382SBill Fenner   {"RECV_WIN_SIZE", l2tp_recv_win_size_print},	/* 10 Receive Window Size */
127b0453382SBill Fenner   {"CHALLENGE", l2tp_challenge_print},		/* 11 Challenge */
128b0453382SBill Fenner   {"Q931_CC", l2tp_q931_cc_print},		/* 12 Q.931 Cause Code */
129b0453382SBill Fenner   {"CHALLENGE_RESP", l2tp_challenge_resp_print},/* 13 Challenge Response */
130b0453382SBill Fenner   {"ASSND_SESS_ID", l2tp_assnd_sess_id_print},  /* 14 Assigned Session ID */
131b0453382SBill Fenner   {"CALL_SER_NUM", l2tp_call_ser_num_print}, 	/* 15 Call Serial Number */
132b0453382SBill Fenner   {"MINIMUM_BPS",	l2tp_minimum_bps_print},/* 16 Minimum BPS */
133b0453382SBill Fenner   {"MAXIMUM_BPS", l2tp_maximum_bps_print},	/* 17 Maximum BPS */
134b0453382SBill Fenner   {"BEARER_TYPE",	l2tp_bearer_type_print},/* 18 Bearer Type */
135b0453382SBill Fenner   {"FRAMING_TYPE", l2tp_framing_type_print}, 	/* 19 Framing Type */
136b0453382SBill Fenner   {"PACKET_PROC_DELAY", l2tp_packet_proc_delay_print}, /* 20 Packet Processing Delay (OBSOLETE) */
137b0453382SBill Fenner   {"CALLED_NUMBER", l2tp_called_number_print},	/* 21 Called Number */
138b0453382SBill Fenner   {"CALLING_NUMBER", l2tp_calling_number_print},/* 22 Calling Number */
139b0453382SBill Fenner   {"SUB_ADDRESS",	l2tp_sub_address_print},/* 23 Sub-Address */
140b0453382SBill Fenner   {"TX_CONN_SPEED", l2tp_tx_conn_speed_print},	/* 24 (Tx) Connect Speed */
141b0453382SBill Fenner   {"PHY_CHANNEL_ID", l2tp_phy_channel_id_print},/* 25 Physical Channel ID */
142b0453382SBill Fenner   {"INI_RECV_LCP", l2tp_ini_recv_lcp_print}, 	/* 26 Initial Received LCP CONFREQ */
143b0453382SBill Fenner   {"LAST_SENT_LCP", l2tp_last_sent_lcp_print},	/* 27 Last Sent LCP CONFREQ */
144b0453382SBill Fenner   {"LAST_RECV_LCP", l2tp_last_recv_lcp_print},	/* 28 Last Received LCP CONFREQ */
145b0453382SBill Fenner   {"PROXY_AUTH_TYPE", l2tp_proxy_auth_type_print},/* 29 Proxy Authen Type */
146b0453382SBill Fenner   {"PROXY_AUTH_NAME", l2tp_proxy_auth_name_print},/* 30 Proxy Authen Name */
147b0453382SBill Fenner   {"PROXY_AUTH_CHAL", l2tp_proxy_auth_chal_print},/* 31 Proxy Authen Challenge */
148b0453382SBill Fenner   {"PROXY_AUTH_ID", l2tp_proxy_auth_id_print},	/* 32 Proxy Authen ID */
149b0453382SBill Fenner   {"PROXY_AUTH_RESP", l2tp_proxy_auth_resp_print},/* 33 Proxy Authen Response */
150b0453382SBill Fenner   {"CALL_ERRORS", l2tp_call_errors_print},	/* 34 Call Errors */
151b0453382SBill Fenner   {"ACCM", l2tp_accm_print},			/* 35 ACCM */
152b0453382SBill Fenner   {"RANDOM_VECTOR", l2tp_random_vector_print},	/* 36 Random Vector */
153b0453382SBill Fenner   {"PRIVATE_GRP_ID", l2tp_private_grp_id_print},/* 37 Private Group ID */
154b0453382SBill Fenner   {"RX_CONN_SPEED", l2tp_rx_conn_speed_print},	/* 38 (Rx) Connect Speed */
155b0453382SBill Fenner   {"SEQ_REQUIRED", l2tp_seq_required_print}, 	/* 39 Sequencing Required */
156b0453382SBill Fenner #define L2TP_MAX_AVP_INDEX	40
157b0453382SBill Fenner };
158b0453382SBill Fenner 
159b0453382SBill Fenner #if 0
160b0453382SBill Fenner static char *l2tp_result_code_StopCCN[] = {
161b0453382SBill Fenner          "Reserved",
162b0453382SBill Fenner          "General request to clear control connection",
163b0453382SBill Fenner          "General error--Error Code indicates the problem",
164b0453382SBill Fenner          "Control channel already exists",
165b0453382SBill Fenner          "Requester is not authorized to establish a control channel",
166b0453382SBill Fenner          "The protocol version of the requester is not supported",
167b0453382SBill Fenner          "Requester is being shut down",
168b0453382SBill Fenner          "Finite State Machine error"
169b0453382SBill Fenner #define L2TP_MAX_RESULT_CODE_STOPCC_INDEX	8
170b0453382SBill Fenner };
171b0453382SBill Fenner #endif
172b0453382SBill Fenner 
173b0453382SBill Fenner #if 0
174b0453382SBill Fenner static char *l2tp_result_code_CDN[] = {
175b0453382SBill Fenner 	"Reserved",
176b0453382SBill Fenner 	"Call disconnected due to loss of carrier",
177b0453382SBill Fenner 	"Call disconnected for the reason indicated in error code",
178b0453382SBill Fenner 	"Call disconnected for administrative reasons",
179b0453382SBill Fenner 	"Call failed due to lack of appropriate facilities being " \
180b0453382SBill Fenner 	"available (temporary condition)",
181b0453382SBill Fenner 	"Call failed due to lack of appropriate facilities being " \
182b0453382SBill Fenner 	"available (permanent condition)",
183b0453382SBill Fenner 	"Invalid destination",
184b0453382SBill Fenner 	"Call failed due to no carrier detected",
185b0453382SBill Fenner 	"Call failed due to detection of a busy signal",
186b0453382SBill Fenner 	"Call failed due to lack of a dial tone",
187b0453382SBill Fenner 	"Call was not established within time allotted by LAC",
188b0453382SBill Fenner 	"Call was connected but no appropriate framing was detected"
189b0453382SBill Fenner #define L2TP_MAX_RESULT_CODE_CDN_INDEX	12
190b0453382SBill Fenner };
191b0453382SBill Fenner #endif
192b0453382SBill Fenner 
193b0453382SBill Fenner #if 0
194b0453382SBill Fenner static char *l2tp_error_code_general[] = {
195b0453382SBill Fenner 	"No general error",
196b0453382SBill Fenner 	"No control connection exists yet for this LAC-LNS pair",
197b0453382SBill Fenner 	"Length is wrong",
198b0453382SBill Fenner 	"One of the field values was out of range or " \
199b0453382SBill Fenner 	"reserved field was non-zero"
200b0453382SBill Fenner 	"Insufficient resources to handle this operation now",
201b0453382SBill Fenner 	"The Session ID is invalid in this context",
202b0453382SBill Fenner 	"A generic vendor-specific error occurred in the LAC",
203b0453382SBill Fenner 	"Try another"
204b0453382SBill Fenner #define L2TP_MAX_ERROR_CODE_GENERAL_INDEX	8
205b0453382SBill Fenner };
206b0453382SBill Fenner #endif
207b0453382SBill Fenner 
208b0453382SBill Fenner /******************************/
209b0453382SBill Fenner /* generic print out routines */
210b0453382SBill Fenner /******************************/
211b0453382SBill Fenner static void
212b0453382SBill Fenner print_string(const u_char *dat, u_int length)
213b0453382SBill Fenner {
214b0453382SBill Fenner 	int i;
215b0453382SBill Fenner 	for (i=0; i<length; i++) {
216b0453382SBill Fenner 		printf("%c", *dat++);
217b0453382SBill Fenner 	}
218b0453382SBill Fenner }
219b0453382SBill Fenner 
220b0453382SBill Fenner static void
221b0453382SBill Fenner print_octets(const u_char *dat, u_int length)
222b0453382SBill Fenner {
223b0453382SBill Fenner 	int i;
224b0453382SBill Fenner 	for (i=0; i<length; i++) {
225b0453382SBill Fenner 		printf("%02x", *dat++);
226b0453382SBill Fenner 	}
227b0453382SBill Fenner }
228b0453382SBill Fenner 
229b0453382SBill Fenner static void
230b0453382SBill Fenner print_short(const u_short *dat)
231b0453382SBill Fenner {
232b0453382SBill Fenner 	printf("%u", ntohs(*dat));
233b0453382SBill Fenner }
234b0453382SBill Fenner 
235b0453382SBill Fenner static void
236b0453382SBill Fenner print_int(const u_int *dat)
237b0453382SBill Fenner {
238b0453382SBill Fenner 	printf("%lu", (u_long)ntohl(*dat));
239b0453382SBill Fenner }
240b0453382SBill Fenner 
241b0453382SBill Fenner /**********************************/
242b0453382SBill Fenner /* AVP-specific print out routines*/
243b0453382SBill Fenner /**********************************/
244b0453382SBill Fenner static void
245b0453382SBill Fenner l2tp_msgtype_print(const u_char *dat, u_int length)
246b0453382SBill Fenner {
247b0453382SBill Fenner 	u_short *ptr = (u_short *)dat;
248b0453382SBill Fenner 
249b0453382SBill Fenner 	if (ntohs(*ptr) < L2TP_MAX_MSGTYPE_INDEX) {
250b0453382SBill Fenner 		printf("%s", l2tp_message_type_string[ntohs(*ptr)]);
251b0453382SBill Fenner 	}
252b0453382SBill Fenner }
253b0453382SBill Fenner 
254b0453382SBill Fenner static void
255b0453382SBill Fenner l2tp_result_code_print(const u_char *dat, u_int length)
256b0453382SBill Fenner {
257b0453382SBill Fenner 	/* we just print out the result and error code number */
258b0453382SBill Fenner 	u_short *ptr = (u_short *)dat;
259b0453382SBill Fenner 
260b0453382SBill Fenner 	if (length == 2) {		/* result code */
261b0453382SBill Fenner 		printf("%u", ntohs(*ptr));
262b0453382SBill Fenner 	} else if (length == 4) { 	/* result & error code */
263b0453382SBill Fenner 		printf("%u/%u", ntohs(*ptr), ntohs(*(ptr+1)));
264b0453382SBill Fenner 	} else if (length > 4) {	/* result & error code & msg */
265b0453382SBill Fenner 		printf("%u/%u ", ntohs(*ptr), ntohs(*(ptr+1)));
266b0453382SBill Fenner 		print_string((u_char *)(ptr+2), length - 4);
267b0453382SBill Fenner 	}
268b0453382SBill Fenner }
269b0453382SBill Fenner 
270b0453382SBill Fenner static void
271b0453382SBill Fenner l2tp_proto_ver_print(const u_char *dat, u_int length)
272b0453382SBill Fenner {
273b0453382SBill Fenner 	printf("%d.%d", *dat, *(dat+1));
274b0453382SBill Fenner }
275b0453382SBill Fenner 
276b0453382SBill Fenner 
277b0453382SBill Fenner static void
278b0453382SBill Fenner l2tp_framing_cap_print(const u_char *dat, u_int length)
279b0453382SBill Fenner {
280b0453382SBill Fenner 	u_int *ptr = (u_int *)dat;
281b0453382SBill Fenner 
282b0453382SBill Fenner 	if (ntohl(*ptr) &  L2TP_FRAMING_CAP_ASYNC_MASK) {
283b0453382SBill Fenner 		printf("A");
284b0453382SBill Fenner 	}
285b0453382SBill Fenner 	if (ntohl(*ptr) &  L2TP_FRAMING_CAP_SYNC_MASK) {
286b0453382SBill Fenner 		printf("S");
287b0453382SBill Fenner 	}
288b0453382SBill Fenner }
289b0453382SBill Fenner 
290b0453382SBill Fenner static void
291b0453382SBill Fenner l2tp_bearer_cap_print(const u_char *dat, u_int length)
292b0453382SBill Fenner {
293b0453382SBill Fenner 	u_int *ptr = (u_int *)dat;
294b0453382SBill Fenner 
295b0453382SBill Fenner 	if (ntohl(*ptr) &  L2TP_BEARER_CAP_ANALOG_MASK) {
296b0453382SBill Fenner 		printf("A");
297b0453382SBill Fenner 	}
298b0453382SBill Fenner 	if (ntohl(*ptr) &  L2TP_BEARER_CAP_DIGITAL_MASK) {
299b0453382SBill Fenner 		printf("D");
300b0453382SBill Fenner 	}
301b0453382SBill Fenner }
302b0453382SBill Fenner 
303b0453382SBill Fenner static void
304b0453382SBill Fenner l2tp_tie_breaker_print(const u_char *dat, u_int length)
305b0453382SBill Fenner {
306b0453382SBill Fenner 	printf("%lx", *(u_long *)dat);	/* XXX */
307b0453382SBill Fenner }
308b0453382SBill Fenner 
309b0453382SBill Fenner static void
310b0453382SBill Fenner l2tp_firm_ver_print(const u_char *dat, u_int length)
311b0453382SBill Fenner {
312b0453382SBill Fenner 	print_short((u_short *)dat);
313b0453382SBill Fenner }
314b0453382SBill Fenner 
315b0453382SBill Fenner static void
316b0453382SBill Fenner l2tp_host_name_print(const u_char *dat, u_int length)
317b0453382SBill Fenner {
318b0453382SBill Fenner 	print_string(dat, length);
319b0453382SBill Fenner }
320b0453382SBill Fenner 
321b0453382SBill Fenner static void
322b0453382SBill Fenner l2tp_vendor_name_print(const u_char *dat, u_int length)
323b0453382SBill Fenner {
324b0453382SBill Fenner 	print_string(dat, length);
325b0453382SBill Fenner }
326b0453382SBill Fenner 
327b0453382SBill Fenner static void
328b0453382SBill Fenner l2tp_assnd_tun_id_print(const u_char *dat, u_int length)
329b0453382SBill Fenner {
330b0453382SBill Fenner 	print_short((u_short *)dat);
331b0453382SBill Fenner }
332b0453382SBill Fenner 
333b0453382SBill Fenner static void
334b0453382SBill Fenner l2tp_recv_win_size_print(const u_char *dat, u_int length)
335b0453382SBill Fenner {
336b0453382SBill Fenner 	print_short((u_short *)dat);
337b0453382SBill Fenner }
338b0453382SBill Fenner 
339b0453382SBill Fenner static void
340b0453382SBill Fenner l2tp_challenge_print(const u_char *dat, u_int length)
341b0453382SBill Fenner {
342b0453382SBill Fenner 	print_octets(dat, length);
343b0453382SBill Fenner }
344b0453382SBill Fenner 
345b0453382SBill Fenner static void
346b0453382SBill Fenner l2tp_q931_cc_print(const u_char *dat, u_int length)
347b0453382SBill Fenner {
348b0453382SBill Fenner 	print_short((u_short *)dat);
349b0453382SBill Fenner 	printf(", %02x", dat[2]);
350b0453382SBill Fenner 	if (length > 3) {
351b0453382SBill Fenner 		printf(" ");
352b0453382SBill Fenner 		print_string(dat+3, length-3);
353b0453382SBill Fenner 	}
354b0453382SBill Fenner }
355b0453382SBill Fenner 
356b0453382SBill Fenner static void
357b0453382SBill Fenner l2tp_challenge_resp_print(const u_char *dat, u_int length)
358b0453382SBill Fenner {
359b0453382SBill Fenner 	print_octets(dat, 16);		/* XXX length should be 16? */
360b0453382SBill Fenner }
361b0453382SBill Fenner 
362b0453382SBill Fenner static void
363b0453382SBill Fenner l2tp_assnd_sess_id_print(const u_char *dat, u_int length)
364b0453382SBill Fenner {
365b0453382SBill Fenner 	print_short((u_short *)dat);
366b0453382SBill Fenner }
367b0453382SBill Fenner 
368b0453382SBill Fenner static void
369b0453382SBill Fenner l2tp_call_ser_num_print(const u_char *dat, u_int length)
370b0453382SBill Fenner {
371b0453382SBill Fenner 	print_int((u_int *)dat);
372b0453382SBill Fenner }
373b0453382SBill Fenner 
374b0453382SBill Fenner static void
375b0453382SBill Fenner l2tp_minimum_bps_print(const u_char *dat, u_int length)
376b0453382SBill Fenner {
377b0453382SBill Fenner 	print_int((u_int *)dat);
378b0453382SBill Fenner }
379b0453382SBill Fenner 
380b0453382SBill Fenner static void
381b0453382SBill Fenner l2tp_maximum_bps_print(const u_char *dat, u_int length)
382b0453382SBill Fenner {
383b0453382SBill Fenner 	print_int((u_int *)dat);
384b0453382SBill Fenner }
385b0453382SBill Fenner 
386b0453382SBill Fenner static void
387b0453382SBill Fenner l2tp_bearer_type_print(const u_char *dat, u_int length)
388b0453382SBill Fenner {
389b0453382SBill Fenner 	u_int *ptr = (u_int *)dat;
390b0453382SBill Fenner 
391b0453382SBill Fenner 	if (ntohl(*ptr) &  L2TP_BEARER_TYPE_ANALOG_MASK) {
392b0453382SBill Fenner 		printf("A");
393b0453382SBill Fenner 	}
394b0453382SBill Fenner 	if (ntohl(*ptr) &  L2TP_BEARER_TYPE_DIGITAL_MASK) {
395b0453382SBill Fenner 		printf("D");
396b0453382SBill Fenner 	}
397b0453382SBill Fenner }
398b0453382SBill Fenner 
399b0453382SBill Fenner static void
400b0453382SBill Fenner l2tp_framing_type_print(const u_char *dat, u_int length)
401b0453382SBill Fenner {
402b0453382SBill Fenner 	u_int *ptr = (u_int *)dat;
403b0453382SBill Fenner 
404b0453382SBill Fenner 	if (ntohl(*ptr) &  L2TP_FRAMING_TYPE_ASYNC_MASK) {
405b0453382SBill Fenner 		printf("A");
406b0453382SBill Fenner 	}
407b0453382SBill Fenner 	if (ntohl(*ptr) &  L2TP_FRAMING_TYPE_SYNC_MASK) {
408b0453382SBill Fenner 		printf("S");
409b0453382SBill Fenner 	}
410b0453382SBill Fenner }
411b0453382SBill Fenner 
412b0453382SBill Fenner static void
413b0453382SBill Fenner l2tp_packet_proc_delay_print(const u_char *dat, u_int length)
414b0453382SBill Fenner {
415b0453382SBill Fenner 	printf("obsolete");
416b0453382SBill Fenner }
417b0453382SBill Fenner 
418b0453382SBill Fenner static void
419b0453382SBill Fenner l2tp_called_number_print(const u_char *dat, u_int length)
420b0453382SBill Fenner {
421b0453382SBill Fenner 	print_string(dat, length);
422b0453382SBill Fenner }
423b0453382SBill Fenner 
424b0453382SBill Fenner static void
425b0453382SBill Fenner l2tp_calling_number_print(const u_char *dat, u_int length)
426b0453382SBill Fenner {
427b0453382SBill Fenner 	print_string(dat, length);
428b0453382SBill Fenner }
429b0453382SBill Fenner 
430b0453382SBill Fenner static void
431b0453382SBill Fenner l2tp_sub_address_print(const u_char *dat, u_int length)
432b0453382SBill Fenner {
433b0453382SBill Fenner 	print_string(dat, length);
434b0453382SBill Fenner }
435b0453382SBill Fenner 
436b0453382SBill Fenner static void
437b0453382SBill Fenner l2tp_tx_conn_speed_print(const u_char *dat, u_int length)
438b0453382SBill Fenner {
439b0453382SBill Fenner 	print_int((u_int *)dat);
440b0453382SBill Fenner }
441b0453382SBill Fenner 
442b0453382SBill Fenner static void
443b0453382SBill Fenner l2tp_phy_channel_id_print(const u_char *dat, u_int length)
444b0453382SBill Fenner {
445b0453382SBill Fenner 	print_int((u_int *)dat);
446b0453382SBill Fenner }
447b0453382SBill Fenner 
448b0453382SBill Fenner static void
449b0453382SBill Fenner l2tp_ini_recv_lcp_print(const u_char *dat, u_int length)
450b0453382SBill Fenner {
451b0453382SBill Fenner 	print_octets(dat, length);
452b0453382SBill Fenner }
453b0453382SBill Fenner 
454b0453382SBill Fenner static void
455b0453382SBill Fenner l2tp_last_sent_lcp_print(const u_char *dat, u_int length)
456b0453382SBill Fenner {
457b0453382SBill Fenner 	print_octets(dat, length);
458b0453382SBill Fenner }
459b0453382SBill Fenner 
460b0453382SBill Fenner static void
461b0453382SBill Fenner l2tp_last_recv_lcp_print(const u_char *dat, u_int length)
462b0453382SBill Fenner {
463b0453382SBill Fenner 	print_octets(dat, length);
464b0453382SBill Fenner }
465b0453382SBill Fenner 
466b0453382SBill Fenner static void
467b0453382SBill Fenner l2tp_proxy_auth_type_print(const u_char *dat, u_int length)
468b0453382SBill Fenner {
469b0453382SBill Fenner 	u_short *ptr = (u_short *)dat;
470b0453382SBill Fenner 
471b0453382SBill Fenner 	switch (ntohs(*ptr)) {
472b0453382SBill Fenner 	case L2TP_AUTHEN_TYPE_RESERVED:
473b0453382SBill Fenner 		printf("Reserved");
474b0453382SBill Fenner 		break;
475b0453382SBill Fenner 	case L2TP_AUTHEN_TYPE_TEXTUAL:
476b0453382SBill Fenner 		printf("Textual");
477b0453382SBill Fenner 		break;
478b0453382SBill Fenner 	case L2TP_AUTHEN_TYPE_CHAP:
479b0453382SBill Fenner 		printf("CHAP");
480b0453382SBill Fenner 		break;
481b0453382SBill Fenner 	case L2TP_AUTHEN_TYPE_PAP:
482b0453382SBill Fenner 		printf("PAP");
483b0453382SBill Fenner 		break;
484b0453382SBill Fenner 	case L2TP_AUTHEN_TYPE_NO_AUTH:
485b0453382SBill Fenner 		printf("No Auth");
486b0453382SBill Fenner 		break;
487b0453382SBill Fenner 	case L2TP_AUTHEN_TYPE_MSCHAP:
488b0453382SBill Fenner 		printf("MS-CHAP");
489b0453382SBill Fenner 		break;
490b0453382SBill Fenner 	default:
491b0453382SBill Fenner 		printf("unknown");
492b0453382SBill Fenner 	}
493b0453382SBill Fenner }
494b0453382SBill Fenner 
495b0453382SBill Fenner static void
496b0453382SBill Fenner l2tp_proxy_auth_name_print(const u_char *dat, u_int length)
497b0453382SBill Fenner {
498b0453382SBill Fenner 	print_octets(dat, length);
499b0453382SBill Fenner }
500b0453382SBill Fenner 
501b0453382SBill Fenner static void
502b0453382SBill Fenner l2tp_proxy_auth_chal_print(const u_char *dat, u_int length)
503b0453382SBill Fenner {
504b0453382SBill Fenner 	print_octets(dat, length);
505b0453382SBill Fenner }
506b0453382SBill Fenner 
507b0453382SBill Fenner static void
508b0453382SBill Fenner l2tp_proxy_auth_id_print(const u_char *dat, u_int length)
509b0453382SBill Fenner {
510b0453382SBill Fenner 	u_short *ptr = (u_short *)dat;
511b0453382SBill Fenner 
512b0453382SBill Fenner 	printf("%u", ntohs(*ptr) & L2TP_PROXY_AUTH_ID_MASK);
513b0453382SBill Fenner }
514b0453382SBill Fenner 
515b0453382SBill Fenner static void
516b0453382SBill Fenner l2tp_proxy_auth_resp_print(const u_char *dat, u_int length)
517b0453382SBill Fenner {
518b0453382SBill Fenner 	print_octets(dat, length);
519b0453382SBill Fenner }
520b0453382SBill Fenner 
521b0453382SBill Fenner static void
522b0453382SBill Fenner l2tp_call_errors_print(const u_char *dat, u_int length)
523b0453382SBill Fenner {
524b0453382SBill Fenner 	struct l2tp_call_errors *ptr = (struct l2tp_call_errors *)dat;
525b0453382SBill Fenner 
526b0453382SBill Fenner 	printf("CRCErr=%d FrameErr=%d HardOver=%d BufOver=%d ",
527b0453382SBill Fenner 	       ptr->crc_errs,
528b0453382SBill Fenner 	       ptr->framing_errs,
529b0453382SBill Fenner 	       ptr->hardware_overruns,
530b0453382SBill Fenner 	       ptr->buffer_overruns);
531b0453382SBill Fenner 	printf("Timeout=%d AlingErr=%d",
532b0453382SBill Fenner 	       ptr->timeout_errs,
533b0453382SBill Fenner 	       ptr->alignment_errs);
534b0453382SBill Fenner }
535b0453382SBill Fenner 
536b0453382SBill Fenner static void
537b0453382SBill Fenner l2tp_accm_print(const u_char *dat, u_int length)
538b0453382SBill Fenner {
539b0453382SBill Fenner 	struct l2tp_accm *ptr = (struct l2tp_accm *)dat;
540b0453382SBill Fenner 
541b0453382SBill Fenner 	printf("send=%x recv=%x", ptr->send_accm, ptr->recv_accm);
542b0453382SBill Fenner }
543b0453382SBill Fenner 
544b0453382SBill Fenner static void
545b0453382SBill Fenner l2tp_random_vector_print(const u_char *dat, u_int length)
546b0453382SBill Fenner {
547b0453382SBill Fenner 	print_octets(dat, length);
548b0453382SBill Fenner }
549b0453382SBill Fenner 
550b0453382SBill Fenner static void
551b0453382SBill Fenner l2tp_private_grp_id_print(const u_char *dat, u_int length)
552b0453382SBill Fenner {
553b0453382SBill Fenner 	print_string(dat, length);
554b0453382SBill Fenner 	/* XXX print_octets is more appropriate?? */
555b0453382SBill Fenner }
556b0453382SBill Fenner 
557b0453382SBill Fenner static void
558b0453382SBill Fenner l2tp_rx_conn_speed_print(const u_char *dat, u_int length)
559b0453382SBill Fenner {
560b0453382SBill Fenner 	print_int((u_int *)dat);
561b0453382SBill Fenner }
562b0453382SBill Fenner 
563b0453382SBill Fenner static void
564b0453382SBill Fenner l2tp_seq_required_print(const u_char *dat, u_int length)
565b0453382SBill Fenner {
566b0453382SBill Fenner 	return;
567b0453382SBill Fenner }
568b0453382SBill Fenner 
569b0453382SBill Fenner static void
570b0453382SBill Fenner l2tp_avp_print(const u_char *dat, u_int length)
571b0453382SBill Fenner {
572b0453382SBill Fenner 	u_int len;
573b0453382SBill Fenner 	const u_short *ptr = (u_short *)dat;
574b0453382SBill Fenner 	int hidden = FALSE;
575b0453382SBill Fenner 
576b0453382SBill Fenner 	printf(" ");
577b0453382SBill Fenner 	if (length > 0 && (snapend - dat) >= 2) {
578b0453382SBill Fenner 		/* there must be at least two octets for the length
579b0453382SBill Fenner 		   to be decoded */
580b0453382SBill Fenner 		if ((len = (ntohs(*ptr) & L2TP_AVP_HDR_LEN_MASK)) <=
581b0453382SBill Fenner 		    (snapend - dat)) {
582b0453382SBill Fenner 			if (ntohs(*ptr) & L2TP_AVP_HDR_FLAG_MANDATORY) {
583b0453382SBill Fenner 				printf("*");
584b0453382SBill Fenner 			}
585b0453382SBill Fenner 			if (ntohs(*ptr) & L2TP_AVP_HDR_FLAG_HIDDEN) {
586b0453382SBill Fenner 				hidden = TRUE;
587b0453382SBill Fenner 				printf("?");
588b0453382SBill Fenner 			}
589b0453382SBill Fenner 		} else {
590b0453382SBill Fenner 			printf("|...");
591b0453382SBill Fenner 			return;
592b0453382SBill Fenner 		}
593b0453382SBill Fenner 		ptr++;
594b0453382SBill Fenner 
595b0453382SBill Fenner 		if (ntohs(*ptr)) {	/* IETF == 0 */
596b0453382SBill Fenner 			printf("vendor=%04x", ntohs(*ptr));
597b0453382SBill Fenner 		}
598b0453382SBill Fenner 		ptr++;
599b0453382SBill Fenner 
600b0453382SBill Fenner 		if (ntohs(*ptr) < L2TP_MAX_AVP_INDEX) {
601b0453382SBill Fenner 			printf("%s", l2tp_avp[ntohs(*ptr)].name);
602b0453382SBill Fenner 			printf("(");
603b0453382SBill Fenner 			if (!hidden) {
604b0453382SBill Fenner 				(l2tp_avp[ntohs(*ptr)].print)
605b0453382SBill Fenner 					((u_char *)ptr+2, len-6);
606b0453382SBill Fenner 			} else {
607b0453382SBill Fenner 				printf("???");
608b0453382SBill Fenner 			}
609b0453382SBill Fenner 			printf(")");
610b0453382SBill Fenner 		} else {
611b0453382SBill Fenner 			printf(" invalid AVP %u", ntohs(*ptr));
612b0453382SBill Fenner 		}
613b0453382SBill Fenner 
614b0453382SBill Fenner 		l2tp_avp_print(dat + len, length - len);
615b0453382SBill Fenner 	} else if (length == 0) {
616b0453382SBill Fenner 		return;
617b0453382SBill Fenner 	} else {
618b0453382SBill Fenner 		printf("|...");
619b0453382SBill Fenner 	}
620b0453382SBill Fenner }
621b0453382SBill Fenner 
622b0453382SBill Fenner 
623b0453382SBill Fenner void
624b0453382SBill Fenner l2tp_print(const u_char *dat, u_int length)
625b0453382SBill Fenner {
626b0453382SBill Fenner 	const u_short *ptr = (u_short *)dat;
627b0453382SBill Fenner 	u_int cnt = 0;			/* total octets consumed */
628b0453382SBill Fenner 	u_short pad;
629b0453382SBill Fenner 	int flag_t, flag_l, flag_s, flag_o, flag_p;
630b0453382SBill Fenner 	u_short l2tp_len;
631b0453382SBill Fenner 
632b0453382SBill Fenner 	flag_t = flag_l = flag_s = flag_o = flag_p = FALSE;
633b0453382SBill Fenner 
634b0453382SBill Fenner 	if (min(length, snapend - dat) - 6 < 0) {
635b0453382SBill Fenner 		/* flag/ver, tunnel_id, session_id must be present for
636b0453382SBill Fenner 		   this packet to be properly decoded */
637b0453382SBill Fenner 		printf("%s", tstr);
638b0453382SBill Fenner 		return;
639b0453382SBill Fenner 	}
640b0453382SBill Fenner 
641b0453382SBill Fenner 	if ((ntohs(*ptr) & L2TP_VERSION_MASK) == L2TP_VERSION_L2TP) {
642b0453382SBill Fenner 		printf(" l2tp:");
643b0453382SBill Fenner 	} else if ((ntohs(*ptr) & L2TP_VERSION_MASK) == L2TP_VERSION_L2F) {
644b0453382SBill Fenner 		printf(" l2f:");
645b0453382SBill Fenner 		return;		/* nothing to do */
646b0453382SBill Fenner 	} else {
647b0453382SBill Fenner 		printf(" Unknown Version, neither L2F(1) nor L2TP(2)");
648b0453382SBill Fenner 		return;		/* nothing we can do */
649b0453382SBill Fenner 	}
650b0453382SBill Fenner 
651b0453382SBill Fenner 	printf("[");
652b0453382SBill Fenner 	if (ntohs(*ptr) & L2TP_FLAG_TYPE) {
653b0453382SBill Fenner 		flag_t = TRUE;
654b0453382SBill Fenner 		printf("T");
655b0453382SBill Fenner 	}
656b0453382SBill Fenner 	if (ntohs(*ptr) & L2TP_FLAG_LENGTH) {
657b0453382SBill Fenner 		flag_l = TRUE;
658b0453382SBill Fenner 		printf("L");
659b0453382SBill Fenner 	}
660b0453382SBill Fenner 	if (ntohs(*ptr) & L2TP_FLAG_SEQUENCE) {
661b0453382SBill Fenner 		flag_s = TRUE;
662b0453382SBill Fenner 		printf("S");
663b0453382SBill Fenner 	}
664b0453382SBill Fenner 	if (ntohs(*ptr) & L2TP_FLAG_OFFSET) {
665b0453382SBill Fenner 		flag_o = TRUE;
666b0453382SBill Fenner 		printf("O");
667b0453382SBill Fenner 	}
668b0453382SBill Fenner 	if (ntohs(*ptr) & L2TP_FLAG_PRIORITY) {
669b0453382SBill Fenner 		flag_p = TRUE;
670b0453382SBill Fenner 		printf("P");
671b0453382SBill Fenner 	}
672b0453382SBill Fenner 	printf("]");
673b0453382SBill Fenner 
674b0453382SBill Fenner 	ptr++;
675b0453382SBill Fenner 	cnt += 2;
676b0453382SBill Fenner 
677b0453382SBill Fenner 	if (flag_l) {
678b0453382SBill Fenner 		l2tp_len = ntohs(*ptr++);	/* XXX need to consider
679b0453382SBill Fenner 						   truncation ?? */
680b0453382SBill Fenner 		cnt += 2;
681b0453382SBill Fenner 	} else {
682b0453382SBill Fenner 		l2tp_len = 0;
683b0453382SBill Fenner 	}
684b0453382SBill Fenner 
685b0453382SBill Fenner 	printf("(%u/", ntohs(*ptr++));		/* Tunnel ID */
686b0453382SBill Fenner 	printf("%u)",  ntohs(*ptr++));		/* Session ID */
687b0453382SBill Fenner 	cnt += 4;
688b0453382SBill Fenner 
689b0453382SBill Fenner 	if (flag_s) {
690b0453382SBill Fenner 		printf("Ns=%u,", ntohs(*ptr++));
691b0453382SBill Fenner 		printf("Nr=%u",  ntohs(*ptr++));
692b0453382SBill Fenner 		cnt += 4;
693b0453382SBill Fenner 	}
694b0453382SBill Fenner 
695b0453382SBill Fenner 	if (flag_o) {
696b0453382SBill Fenner 		pad =  ntohs(*ptr++);
697b0453382SBill Fenner 		ptr += pad / sizeof(*ptr);
698b0453382SBill Fenner 		cnt += (2 + pad);
699b0453382SBill Fenner 	}
700b0453382SBill Fenner 
701b0453382SBill Fenner 	if (flag_t) {
702b0453382SBill Fenner 		if (length - cnt == 0) {
703b0453382SBill Fenner 			printf(" ZLB");
704b0453382SBill Fenner 		} else {
705b0453382SBill Fenner 			l2tp_avp_print((u_char *)ptr, length - cnt);
706b0453382SBill Fenner 		}
707b0453382SBill Fenner 	} else {
708b0453382SBill Fenner #if 0
709b0453382SBill Fenner 		printf(" {");
710b0453382SBill Fenner 		ppp_hdlc_print((u_char *)ptr, length - cnt);
711b0453382SBill Fenner 		printf("}");
712b0453382SBill Fenner #else
713b0453382SBill Fenner 		printf("[hdlc|]");
714b0453382SBill Fenner #endif
715b0453382SBill Fenner 	}
716b0453382SBill Fenner }
717