xref: /netbsd-src/external/bsd/tcpdump/dist/print-l2tp.c (revision 3117ece4fc4a4ca4489ba793710b60b0d26bab6c)
1 /*
2  * Copyright (c) 1991, 1993, 1994, 1995, 1996, 1997
3  *      The Regents of the University of California.  All rights reserved.
4  *
5  * Redistribution and use in source and binary forms, with or without
6  * modification, are permitted provided that: (1) source code distributions
7  * retain the above copyright notice and this paragraph in its entirety, (2)
8  * distributions including binary code include the above copyright notice and
9  * this paragraph in its entirety in the documentation or other materials
10  * provided with the distribution, and (3) all advertising materials mentioning
11  * features or use of this software display the following acknowledgement:
12  * ``This product includes software developed by the University of California,
13  * Lawrence Berkeley Laboratory and its contributors.'' Neither the name of
14  * the University nor the names of its contributors may be used to endorse
15  * or promote products derived from this software without specific prior
16  * written permission.
17  * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR IMPLIED
18  * WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF
19  * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
20  *
21  * L2TP support contributed by Motonori Shindo (mshindo@mshindo.net)
22  */
23 
24 #include <sys/cdefs.h>
25 #ifndef lint
26 __RCSID("$NetBSD: print-l2tp.c,v 1.11 2024/09/02 16:15:31 christos Exp $");
27 #endif
28 
29 /* \summary: Layer Two Tunneling Protocol (L2TP) printer */
30 
31 /* specification: RFC 2661 */
32 
33 #include <config.h>
34 
35 #include "netdissect-stdinc.h"
36 
37 #include "netdissect.h"
38 #include "extract.h"
39 
40 #define L2TP_FLAG_TYPE		0x8000	/* Type (0=Data, 1=Control) */
41 #define L2TP_FLAG_LENGTH	0x4000	/* Length */
42 #define L2TP_FLAG_SEQUENCE	0x0800	/* Sequence */
43 #define L2TP_FLAG_OFFSET	0x0200	/* Offset */
44 #define L2TP_FLAG_PRIORITY	0x0100	/* Priority */
45 
46 #define L2TP_VERSION_MASK	0x000f	/* Version Mask */
47 #define L2TP_VERSION_L2F	0x0001	/* L2F */
48 #define L2TP_VERSION_L2TP	0x0002	/* L2TP */
49 
50 #define L2TP_AVP_HDR_FLAG_MANDATORY	0x8000	/* Mandatory Flag */
51 #define L2TP_AVP_HDR_FLAG_HIDDEN	0x4000	/* Hidden Flag */
52 #define L2TP_AVP_HDR_LEN_MASK		0x03ff	/* Length Mask */
53 
54 #define L2TP_FRAMING_CAP_SYNC_MASK	0x00000001	/* Synchronous */
55 #define L2TP_FRAMING_CAP_ASYNC_MASK	0x00000002	/* Asynchronous */
56 
57 #define L2TP_FRAMING_TYPE_SYNC_MASK	0x00000001	/* Synchronous */
58 #define L2TP_FRAMING_TYPE_ASYNC_MASK	0x00000002	/* Asynchronous */
59 
60 #define L2TP_BEARER_CAP_DIGITAL_MASK	0x00000001	/* Digital */
61 #define L2TP_BEARER_CAP_ANALOG_MASK	0x00000002	/* Analog */
62 
63 #define L2TP_BEARER_TYPE_DIGITAL_MASK	0x00000001	/* Digital */
64 #define L2TP_BEARER_TYPE_ANALOG_MASK	0x00000002	/* Analog */
65 
66 /* Authen Type */
67 #define L2TP_AUTHEN_TYPE_RESERVED	0x0000	/* Reserved */
68 #define L2TP_AUTHEN_TYPE_TEXTUAL	0x0001	/* Textual username/password exchange */
69 #define L2TP_AUTHEN_TYPE_CHAP		0x0002	/* PPP CHAP */
70 #define L2TP_AUTHEN_TYPE_PAP		0x0003	/* PPP PAP */
71 #define L2TP_AUTHEN_TYPE_NO_AUTH	0x0004	/* No Authentication */
72 #define L2TP_AUTHEN_TYPE_MSCHAPv1	0x0005	/* MSCHAPv1 */
73 
74 #define L2TP_PROXY_AUTH_ID_MASK		0x00ff
75 
76 
77 #define	L2TP_MSGTYPE_SCCRQ	1  /* Start-Control-Connection-Request */
78 #define	L2TP_MSGTYPE_SCCRP	2  /* Start-Control-Connection-Reply */
79 #define	L2TP_MSGTYPE_SCCCN	3  /* Start-Control-Connection-Connected */
80 #define	L2TP_MSGTYPE_STOPCCN	4  /* Stop-Control-Connection-Notification */
81 #define	L2TP_MSGTYPE_HELLO	6  /* Hello */
82 #define	L2TP_MSGTYPE_OCRQ	7  /* Outgoing-Call-Request */
83 #define	L2TP_MSGTYPE_OCRP	8  /* Outgoing-Call-Reply */
84 #define	L2TP_MSGTYPE_OCCN	9  /* Outgoing-Call-Connected */
85 #define	L2TP_MSGTYPE_ICRQ	10 /* Incoming-Call-Request */
86 #define	L2TP_MSGTYPE_ICRP	11 /* Incoming-Call-Reply */
87 #define	L2TP_MSGTYPE_ICCN	12 /* Incoming-Call-Connected */
88 #define	L2TP_MSGTYPE_CDN	14 /* Call-Disconnect-Notify */
89 #define	L2TP_MSGTYPE_WEN	15 /* WAN-Error-Notify */
90 #define	L2TP_MSGTYPE_SLI	16 /* Set-Link-Info */
91 
92 static const struct tok l2tp_msgtype2str[] = {
93 	{ L2TP_MSGTYPE_SCCRQ,	"SCCRQ" },
94 	{ L2TP_MSGTYPE_SCCRP,	"SCCRP" },
95 	{ L2TP_MSGTYPE_SCCCN,	"SCCCN" },
96 	{ L2TP_MSGTYPE_STOPCCN,	"StopCCN" },
97 	{ L2TP_MSGTYPE_HELLO,	"HELLO" },
98 	{ L2TP_MSGTYPE_OCRQ,	"OCRQ" },
99 	{ L2TP_MSGTYPE_OCRP,	"OCRP" },
100 	{ L2TP_MSGTYPE_OCCN,	"OCCN" },
101 	{ L2TP_MSGTYPE_ICRQ,	"ICRQ" },
102 	{ L2TP_MSGTYPE_ICRP,	"ICRP" },
103 	{ L2TP_MSGTYPE_ICCN,	"ICCN" },
104 	{ L2TP_MSGTYPE_CDN,	"CDN" },
105 	{ L2TP_MSGTYPE_WEN,	"WEN" },
106 	{ L2TP_MSGTYPE_SLI,	"SLI" },
107 	{ 0,			NULL }
108 };
109 
110 #define L2TP_AVP_MSGTYPE		0  /* Message Type */
111 #define L2TP_AVP_RESULT_CODE		1  /* Result Code */
112 #define L2TP_AVP_PROTO_VER		2  /* Protocol Version */
113 #define L2TP_AVP_FRAMING_CAP		3  /* Framing Capabilities */
114 #define L2TP_AVP_BEARER_CAP		4  /* Bearer Capabilities */
115 #define L2TP_AVP_TIE_BREAKER		5  /* Tie Breaker */
116 #define L2TP_AVP_FIRM_VER		6  /* Firmware Revision */
117 #define L2TP_AVP_HOST_NAME		7  /* Host Name */
118 #define L2TP_AVP_VENDOR_NAME		8  /* Vendor Name */
119 #define L2TP_AVP_ASSND_TUN_ID		9  /* Assigned Tunnel ID */
120 #define L2TP_AVP_RECV_WIN_SIZE		10 /* Receive Window Size */
121 #define L2TP_AVP_CHALLENGE		11 /* Challenge */
122 #define L2TP_AVP_Q931_CC		12 /* Q.931 Cause Code */
123 #define L2TP_AVP_CHALLENGE_RESP		13 /* Challenge Response */
124 #define L2TP_AVP_ASSND_SESS_ID		14 /* Assigned Session ID */
125 #define L2TP_AVP_CALL_SER_NUM		15 /* Call Serial Number */
126 #define L2TP_AVP_MINIMUM_BPS		16 /* Minimum BPS */
127 #define L2TP_AVP_MAXIMUM_BPS		17 /* Maximum BPS */
128 #define L2TP_AVP_BEARER_TYPE		18 /* Bearer Type */
129 #define L2TP_AVP_FRAMING_TYPE		19 /* Framing Type */
130 #define L2TP_AVP_PACKET_PROC_DELAY	20 /* Packet Processing Delay (OBSOLETE) */
131 #define L2TP_AVP_CALLED_NUMBER		21 /* Called Number */
132 #define L2TP_AVP_CALLING_NUMBER		22 /* Calling Number */
133 #define L2TP_AVP_SUB_ADDRESS		23 /* Sub-Address */
134 #define L2TP_AVP_TX_CONN_SPEED		24 /* (Tx) Connect Speed */
135 #define L2TP_AVP_PHY_CHANNEL_ID		25 /* Physical Channel ID */
136 #define L2TP_AVP_INI_RECV_LCP		26 /* Initial Received LCP CONFREQ */
137 #define L2TP_AVP_LAST_SENT_LCP		27 /* Last Sent LCP CONFREQ */
138 #define L2TP_AVP_LAST_RECV_LCP		28 /* Last Received LCP CONFREQ */
139 #define L2TP_AVP_PROXY_AUTH_TYPE	29 /* Proxy Authen Type */
140 #define L2TP_AVP_PROXY_AUTH_NAME	30 /* Proxy Authen Name */
141 #define L2TP_AVP_PROXY_AUTH_CHAL	31 /* Proxy Authen Challenge */
142 #define L2TP_AVP_PROXY_AUTH_ID		32 /* Proxy Authen ID */
143 #define L2TP_AVP_PROXY_AUTH_RESP	33 /* Proxy Authen Response */
144 #define L2TP_AVP_CALL_ERRORS		34 /* Call Errors */
145 #define L2TP_AVP_ACCM			35 /* ACCM */
146 #define L2TP_AVP_RANDOM_VECTOR		36 /* Random Vector */
147 #define L2TP_AVP_PRIVATE_GRP_ID		37 /* Private Group ID */
148 #define L2TP_AVP_RX_CONN_SPEED		38 /* (Rx) Connect Speed */
149 #define L2TP_AVP_SEQ_REQUIRED		39 /* Sequencing Required */
150 #define L2TP_AVP_PPP_DISCON_CC		46 /* PPP Disconnect Cause Code - RFC 3145 */
151 
152 static const struct tok l2tp_avp2str[] = {
153 	{ L2TP_AVP_MSGTYPE,		"MSGTYPE" },
154 	{ L2TP_AVP_RESULT_CODE,		"RESULT_CODE" },
155 	{ L2TP_AVP_PROTO_VER,		"PROTO_VER" },
156 	{ L2TP_AVP_FRAMING_CAP,		"FRAMING_CAP" },
157 	{ L2TP_AVP_BEARER_CAP,		"BEARER_CAP" },
158 	{ L2TP_AVP_TIE_BREAKER,		"TIE_BREAKER" },
159 	{ L2TP_AVP_FIRM_VER,		"FIRM_VER" },
160 	{ L2TP_AVP_HOST_NAME,		"HOST_NAME" },
161 	{ L2TP_AVP_VENDOR_NAME,		"VENDOR_NAME" },
162 	{ L2TP_AVP_ASSND_TUN_ID,	"ASSND_TUN_ID" },
163 	{ L2TP_AVP_RECV_WIN_SIZE,	"RECV_WIN_SIZE" },
164 	{ L2TP_AVP_CHALLENGE,		"CHALLENGE" },
165 	{ L2TP_AVP_Q931_CC,		"Q931_CC", },
166 	{ L2TP_AVP_CHALLENGE_RESP,	"CHALLENGE_RESP" },
167 	{ L2TP_AVP_ASSND_SESS_ID,	"ASSND_SESS_ID" },
168 	{ L2TP_AVP_CALL_SER_NUM,	"CALL_SER_NUM" },
169 	{ L2TP_AVP_MINIMUM_BPS,		"MINIMUM_BPS" },
170 	{ L2TP_AVP_MAXIMUM_BPS,		"MAXIMUM_BPS" },
171 	{ L2TP_AVP_BEARER_TYPE,		"BEARER_TYPE" },
172 	{ L2TP_AVP_FRAMING_TYPE,	"FRAMING_TYPE" },
173 	{ L2TP_AVP_PACKET_PROC_DELAY,	"PACKET_PROC_DELAY" },
174 	{ L2TP_AVP_CALLED_NUMBER,	"CALLED_NUMBER" },
175 	{ L2TP_AVP_CALLING_NUMBER,	"CALLING_NUMBER" },
176 	{ L2TP_AVP_SUB_ADDRESS,		"SUB_ADDRESS" },
177 	{ L2TP_AVP_TX_CONN_SPEED,	"TX_CONN_SPEED" },
178 	{ L2TP_AVP_PHY_CHANNEL_ID,	"PHY_CHANNEL_ID" },
179 	{ L2TP_AVP_INI_RECV_LCP,	"INI_RECV_LCP" },
180 	{ L2TP_AVP_LAST_SENT_LCP,	"LAST_SENT_LCP" },
181 	{ L2TP_AVP_LAST_RECV_LCP,	"LAST_RECV_LCP" },
182 	{ L2TP_AVP_PROXY_AUTH_TYPE,	"PROXY_AUTH_TYPE" },
183 	{ L2TP_AVP_PROXY_AUTH_NAME,	"PROXY_AUTH_NAME" },
184 	{ L2TP_AVP_PROXY_AUTH_CHAL,	"PROXY_AUTH_CHAL" },
185 	{ L2TP_AVP_PROXY_AUTH_ID,	"PROXY_AUTH_ID" },
186 	{ L2TP_AVP_PROXY_AUTH_RESP,	"PROXY_AUTH_RESP" },
187 	{ L2TP_AVP_CALL_ERRORS,		"CALL_ERRORS" },
188 	{ L2TP_AVP_ACCM,		"ACCM" },
189 	{ L2TP_AVP_RANDOM_VECTOR,	"RANDOM_VECTOR" },
190 	{ L2TP_AVP_PRIVATE_GRP_ID,	"PRIVATE_GRP_ID" },
191 	{ L2TP_AVP_RX_CONN_SPEED,	"RX_CONN_SPEED" },
192 	{ L2TP_AVP_SEQ_REQUIRED,	"SEQ_REQUIRED" },
193 	{ L2TP_AVP_PPP_DISCON_CC,	"PPP_DISCON_CC" },
194 	{ 0,				NULL }
195 };
196 
197 static const struct tok l2tp_authentype2str[] = {
198 	{ L2TP_AUTHEN_TYPE_RESERVED,	"Reserved" },
199 	{ L2TP_AUTHEN_TYPE_TEXTUAL,	"Textual" },
200 	{ L2TP_AUTHEN_TYPE_CHAP,	"CHAP" },
201 	{ L2TP_AUTHEN_TYPE_PAP,		"PAP" },
202 	{ L2TP_AUTHEN_TYPE_NO_AUTH,	"No Auth" },
203 	{ L2TP_AUTHEN_TYPE_MSCHAPv1,	"MS-CHAPv1" },
204 	{ 0,				NULL }
205 };
206 
207 #define L2TP_PPP_DISCON_CC_DIRECTION_GLOBAL	0
208 #define L2TP_PPP_DISCON_CC_DIRECTION_AT_PEER	1
209 #define L2TP_PPP_DISCON_CC_DIRECTION_AT_LOCAL	2
210 
211 static const struct tok l2tp_cc_direction2str[] = {
212 	{ L2TP_PPP_DISCON_CC_DIRECTION_GLOBAL,	"global error" },
213 	{ L2TP_PPP_DISCON_CC_DIRECTION_AT_PEER,	"at peer" },
214 	{ L2TP_PPP_DISCON_CC_DIRECTION_AT_LOCAL,"at local" },
215 	{ 0,					NULL }
216 };
217 
218 #if 0
219 static char *l2tp_result_code_StopCCN[] = {
220          "Reserved",
221          "General request to clear control connection",
222          "General error--Error Code indicates the problem",
223          "Control channel already exists",
224          "Requester is not authorized to establish a control channel",
225          "The protocol version of the requester is not supported",
226          "Requester is being shut down",
227          "Finite State Machine error"
228 #define L2TP_MAX_RESULT_CODE_STOPCC_INDEX	8
229 };
230 #endif
231 
232 #if 0
233 static char *l2tp_result_code_CDN[] = {
234 	"Reserved",
235 	"Call disconnected due to loss of carrier",
236 	"Call disconnected for the reason indicated in error code",
237 	"Call disconnected for administrative reasons",
238 	"Call failed due to lack of appropriate facilities being "
239 	"available (temporary condition)",
240 	"Call failed due to lack of appropriate facilities being "
241 	"available (permanent condition)",
242 	"Invalid destination",
243 	"Call failed due to no carrier detected",
244 	"Call failed due to detection of a busy signal",
245 	"Call failed due to lack of a dial tone",
246 	"Call was not established within time allotted by LAC",
247 	"Call was connected but no appropriate framing was detected"
248 #define L2TP_MAX_RESULT_CODE_CDN_INDEX	12
249 };
250 #endif
251 
252 #if 0
253 static char *l2tp_error_code_general[] = {
254 	"No general error",
255 	"No control connection exists yet for this LAC-LNS pair",
256 	"Length is wrong",
257 	"One of the field values was out of range or "
258 	"reserved field was non-zero"
259 	"Insufficient resources to handle this operation now",
260 	"The Session ID is invalid in this context",
261 	"A generic vendor-specific error occurred in the LAC",
262 	"Try another"
263 #define L2TP_MAX_ERROR_CODE_GENERAL_INDEX	8
264 };
265 #endif
266 
267 /******************************/
268 /* generic print out routines */
269 /******************************/
270 static void
271 print_string(netdissect_options *ndo, const u_char *dat, u_int length)
272 {
273 	u_int i;
274 	for (i=0; i<length; i++) {
275 		fn_print_char(ndo, GET_U_1(dat));
276 		dat++;
277 	}
278 }
279 
280 static void
281 print_octets(netdissect_options *ndo, const u_char *dat, u_int length)
282 {
283 	u_int i;
284 	for (i=0; i<length; i++) {
285 		ND_PRINT("%02x", GET_U_1(dat));
286 		dat++;
287 	}
288 }
289 
290 static void
291 print_16bits_val(netdissect_options *ndo, const uint8_t *dat)
292 {
293 	ND_PRINT("%u", GET_BE_U_2(dat));
294 }
295 
296 static void
297 print_32bits_val(netdissect_options *ndo, const uint8_t *dat)
298 {
299 	ND_PRINT("%u", GET_BE_U_4(dat));
300 }
301 
302 /***********************************/
303 /* AVP-specific print out routines */
304 /***********************************/
305 static void
306 l2tp_msgtype_print(netdissect_options *ndo, const u_char *dat, u_int length)
307 {
308 	if (length < 2) {
309 		ND_PRINT("AVP too short");
310 		return;
311 	}
312 	ND_PRINT("%s", tok2str(l2tp_msgtype2str, "MSGTYPE-#%u",
313 	    GET_BE_U_2(dat)));
314 }
315 
316 static void
317 l2tp_result_code_print(netdissect_options *ndo, const u_char *dat, u_int length)
318 {
319 	/* Result Code */
320 	if (length < 2) {
321 		ND_PRINT("AVP too short");
322 		return;
323 	}
324 	ND_PRINT("%u", GET_BE_U_2(dat));
325 	dat += 2;
326 	length -= 2;
327 
328 	/* Error Code (opt) */
329 	if (length == 0)
330 		return;
331 	if (length < 2) {
332 		ND_PRINT(" AVP too short");
333 		return;
334 	}
335 	ND_PRINT("/%u", GET_BE_U_2(dat));
336 	dat += 2;
337 	length -= 2;
338 
339 	/* Error Message (opt) */
340 	if (length == 0)
341 		return;
342 	ND_PRINT(" ");
343 	print_string(ndo, dat, length);
344 }
345 
346 static void
347 l2tp_proto_ver_print(netdissect_options *ndo, const u_char *dat, u_int length)
348 {
349 	if (length < 2) {
350 		ND_PRINT("AVP too short");
351 		return;
352 	}
353 	ND_PRINT("%u.%u", (GET_BE_U_2(dat) >> 8),
354 		  (GET_BE_U_2(dat) & 0xff));
355 }
356 
357 static void
358 l2tp_framing_cap_print(netdissect_options *ndo, const u_char *dat, u_int length)
359 {
360 	if (length < 4) {
361 		ND_PRINT("AVP too short");
362 		return;
363 	}
364 	if (GET_BE_U_4(dat) &  L2TP_FRAMING_CAP_ASYNC_MASK) {
365 		ND_PRINT("A");
366 	}
367 	if (GET_BE_U_4(dat) &  L2TP_FRAMING_CAP_SYNC_MASK) {
368 		ND_PRINT("S");
369 	}
370 }
371 
372 static void
373 l2tp_bearer_cap_print(netdissect_options *ndo, const u_char *dat, u_int length)
374 {
375 	if (length < 4) {
376 		ND_PRINT("AVP too short");
377 		return;
378 	}
379 	if (GET_BE_U_4(dat) &  L2TP_BEARER_CAP_ANALOG_MASK) {
380 		ND_PRINT("A");
381 	}
382 	if (GET_BE_U_4(dat) &  L2TP_BEARER_CAP_DIGITAL_MASK) {
383 		ND_PRINT("D");
384 	}
385 }
386 
387 static void
388 l2tp_q931_cc_print(netdissect_options *ndo, const u_char *dat, u_int length)
389 {
390 	if (length < 3) {
391 		ND_PRINT("AVP too short");
392 		return;
393 	}
394 	print_16bits_val(ndo, dat);
395 	ND_PRINT(", %02x", GET_U_1(dat + 2));
396 	dat += 3;
397 	length -= 3;
398 	if (length != 0) {
399 		ND_PRINT(" ");
400 		print_string(ndo, dat, length);
401 	}
402 }
403 
404 static void
405 l2tp_bearer_type_print(netdissect_options *ndo, const u_char *dat, u_int length)
406 {
407 	if (length < 4) {
408 		ND_PRINT("AVP too short");
409 		return;
410 	}
411 	if (GET_BE_U_4(dat) &  L2TP_BEARER_TYPE_ANALOG_MASK) {
412 		ND_PRINT("A");
413 	}
414 	if (GET_BE_U_4(dat) &  L2TP_BEARER_TYPE_DIGITAL_MASK) {
415 		ND_PRINT("D");
416 	}
417 }
418 
419 static void
420 l2tp_framing_type_print(netdissect_options *ndo, const u_char *dat, u_int length)
421 {
422 	if (length < 4) {
423 		ND_PRINT("AVP too short");
424 		return;
425 	}
426 	if (GET_BE_U_4(dat) &  L2TP_FRAMING_TYPE_ASYNC_MASK) {
427 		ND_PRINT("A");
428 	}
429 	if (GET_BE_U_4(dat) &  L2TP_FRAMING_TYPE_SYNC_MASK) {
430 		ND_PRINT("S");
431 	}
432 }
433 
434 static void
435 l2tp_packet_proc_delay_print(netdissect_options *ndo)
436 {
437 	ND_PRINT("obsolete");
438 }
439 
440 static void
441 l2tp_proxy_auth_type_print(netdissect_options *ndo, const u_char *dat, u_int length)
442 {
443 	if (length < 2) {
444 		ND_PRINT("AVP too short");
445 		return;
446 	}
447 	ND_PRINT("%s", tok2str(l2tp_authentype2str,
448 			     "AuthType-#%u", GET_BE_U_2(dat)));
449 }
450 
451 static void
452 l2tp_proxy_auth_id_print(netdissect_options *ndo, const u_char *dat, u_int length)
453 {
454 	if (length < 2) {
455 		ND_PRINT("AVP too short");
456 		return;
457 	}
458 	ND_PRINT("%u", GET_BE_U_2(dat) & L2TP_PROXY_AUTH_ID_MASK);
459 }
460 
461 static void
462 l2tp_call_errors_print(netdissect_options *ndo, const u_char *dat, u_int length)
463 {
464 	uint32_t val;
465 
466 	if (length < 2) {
467 		ND_PRINT("AVP too short");
468 		return;
469 	}
470 	dat += 2;	/* skip "Reserved" */
471 	length -= 2;
472 
473 	if (length < 4) {
474 		ND_PRINT("AVP too short");
475 		return;
476 	}
477 	val = GET_BE_U_4(dat); dat += 4; length -= 4;
478 	ND_PRINT("CRCErr=%u ", val);
479 
480 	if (length < 4) {
481 		ND_PRINT("AVP too short");
482 		return;
483 	}
484 	val = GET_BE_U_4(dat); dat += 4; length -= 4;
485 	ND_PRINT("FrameErr=%u ", val);
486 
487 	if (length < 4) {
488 		ND_PRINT("AVP too short");
489 		return;
490 	}
491 	val = GET_BE_U_4(dat); dat += 4; length -= 4;
492 	ND_PRINT("HardOver=%u ", val);
493 
494 	if (length < 4) {
495 		ND_PRINT("AVP too short");
496 		return;
497 	}
498 	val = GET_BE_U_4(dat); dat += 4; length -= 4;
499 	ND_PRINT("BufOver=%u ", val);
500 
501 	if (length < 4) {
502 		ND_PRINT("AVP too short");
503 		return;
504 	}
505 	val = GET_BE_U_4(dat); dat += 4; length -= 4;
506 	ND_PRINT("Timeout=%u ", val);
507 
508 	if (length < 4) {
509 		ND_PRINT("AVP too short");
510 		return;
511 	}
512 	val = GET_BE_U_4(dat); dat += 4; length -= 4;
513 	ND_PRINT("AlignErr=%u ", val);
514 }
515 
516 static void
517 l2tp_accm_print(netdissect_options *ndo, const u_char *dat, u_int length)
518 {
519 	uint32_t val;
520 
521 	if (length < 2) {
522 		ND_PRINT("AVP too short");
523 		return;
524 	}
525 	dat += 2;	/* skip "Reserved" */
526 	length -= 2;
527 
528 	if (length < 4) {
529 		ND_PRINT("AVP too short");
530 		return;
531 	}
532 	val = GET_BE_U_4(dat); dat += 4; length -= 4;
533 	ND_PRINT("send=%08x ", val);
534 
535 	if (length < 4) {
536 		ND_PRINT("AVP too short");
537 		return;
538 	}
539 	val = GET_BE_U_4(dat); dat += 4; length -= 4;
540 	ND_PRINT("recv=%08x ", val);
541 }
542 
543 static void
544 l2tp_ppp_discon_cc_print(netdissect_options *ndo, const u_char *dat, u_int length)
545 {
546 	if (length < 5) {
547 		ND_PRINT("AVP too short");
548 		return;
549 	}
550 	/* Disconnect Code */
551 	ND_PRINT("%04x, ", GET_BE_U_2(dat));
552 	dat += 2;
553 	length -= 2;
554 	/* Control Protocol Number */
555 	ND_PRINT("%04x ",  GET_BE_U_2(dat));
556 	dat += 2;
557 	length -= 2;
558 	/* Direction */
559 	ND_PRINT("%s", tok2str(l2tp_cc_direction2str,
560 			     "Direction-#%u", GET_U_1(dat)));
561 	dat++;
562 	length--;
563 
564 	if (length != 0) {
565 		ND_PRINT(" ");
566 		print_string(ndo, (const u_char *)dat, length);
567 	}
568 }
569 
570 static u_int
571 l2tp_avp_print(netdissect_options *ndo, const u_char *dat, u_int length)
572 {
573 	u_int len;
574 	uint16_t attr_type;
575 	int hidden = FALSE;
576 
577 	ND_PRINT(" ");
578 	/* Flags & Length */
579 	len = GET_BE_U_2(dat) & L2TP_AVP_HDR_LEN_MASK;
580 
581 	/* If it is not long enough to contain the header, we'll give up. */
582 	if (len < 6)
583 		goto trunc;
584 
585 	/* If it goes past the end of the remaining length of the packet,
586 	   we'll give up. */
587 	if (len > (u_int)length)
588 		goto trunc;
589 
590 	/* If it goes past the end of the remaining length of the captured
591 	   data, we'll give up. */
592 	ND_TCHECK_LEN(dat, len);
593 
594 	/*
595 	 * After this point, we don't need to check whether we go past
596 	 * the length of the captured data; however, we *do* need to
597 	 * check whether we go past the end of the AVP.
598 	 */
599 
600 	if (GET_BE_U_2(dat) & L2TP_AVP_HDR_FLAG_MANDATORY) {
601 		ND_PRINT("*");
602 	}
603 	if (GET_BE_U_2(dat) & L2TP_AVP_HDR_FLAG_HIDDEN) {
604 		hidden = TRUE;
605 		ND_PRINT("?");
606 	}
607 	dat += 2;
608 
609 	if (GET_BE_U_2(dat)) {
610 		/* Vendor Specific Attribute */
611 	        ND_PRINT("VENDOR%04x:", GET_BE_U_2(dat)); dat += 2;
612 		ND_PRINT("ATTR%04x", GET_BE_U_2(dat)); dat += 2;
613 		ND_PRINT("(");
614 		print_octets(ndo, dat, len-6);
615 		ND_PRINT(")");
616 	} else {
617 		/* IETF-defined Attributes */
618 		dat += 2;
619 		attr_type = GET_BE_U_2(dat); dat += 2;
620 		ND_PRINT("%s", tok2str(l2tp_avp2str, "AVP-#%u", attr_type));
621 		ND_PRINT("(");
622 		if (hidden) {
623 			ND_PRINT("???");
624 		} else {
625 			switch (attr_type) {
626 			case L2TP_AVP_MSGTYPE:
627 				l2tp_msgtype_print(ndo, dat, len-6);
628 				break;
629 			case L2TP_AVP_RESULT_CODE:
630 				l2tp_result_code_print(ndo, dat, len-6);
631 				break;
632 			case L2TP_AVP_PROTO_VER:
633 				l2tp_proto_ver_print(ndo, dat, len-6);
634 				break;
635 			case L2TP_AVP_FRAMING_CAP:
636 				l2tp_framing_cap_print(ndo, dat, len-6);
637 				break;
638 			case L2TP_AVP_BEARER_CAP:
639 				l2tp_bearer_cap_print(ndo, dat, len-6);
640 				break;
641 			case L2TP_AVP_TIE_BREAKER:
642 				if (len-6 < 8) {
643 					ND_PRINT("AVP too short");
644 					break;
645 				}
646 				print_octets(ndo, dat, 8);
647 				break;
648 			case L2TP_AVP_FIRM_VER:
649 			case L2TP_AVP_ASSND_TUN_ID:
650 			case L2TP_AVP_RECV_WIN_SIZE:
651 			case L2TP_AVP_ASSND_SESS_ID:
652 				if (len-6 < 2) {
653 					ND_PRINT("AVP too short");
654 					break;
655 				}
656 				print_16bits_val(ndo, dat);
657 				break;
658 			case L2TP_AVP_HOST_NAME:
659 			case L2TP_AVP_VENDOR_NAME:
660 			case L2TP_AVP_CALLING_NUMBER:
661 			case L2TP_AVP_CALLED_NUMBER:
662 			case L2TP_AVP_SUB_ADDRESS:
663 			case L2TP_AVP_PROXY_AUTH_NAME:
664 			case L2TP_AVP_PRIVATE_GRP_ID:
665 				print_string(ndo, dat, len-6);
666 				break;
667 			case L2TP_AVP_CHALLENGE:
668 			case L2TP_AVP_INI_RECV_LCP:
669 			case L2TP_AVP_LAST_SENT_LCP:
670 			case L2TP_AVP_LAST_RECV_LCP:
671 			case L2TP_AVP_PROXY_AUTH_CHAL:
672 			case L2TP_AVP_PROXY_AUTH_RESP:
673 			case L2TP_AVP_RANDOM_VECTOR:
674 				print_octets(ndo, dat, len-6);
675 				break;
676 			case L2TP_AVP_Q931_CC:
677 				l2tp_q931_cc_print(ndo, dat, len-6);
678 				break;
679 			case L2TP_AVP_CHALLENGE_RESP:
680 				if (len-6 < 16) {
681 					ND_PRINT("AVP too short");
682 					break;
683 				}
684 				print_octets(ndo, dat, 16);
685 				break;
686 			case L2TP_AVP_CALL_SER_NUM:
687 			case L2TP_AVP_MINIMUM_BPS:
688 			case L2TP_AVP_MAXIMUM_BPS:
689 			case L2TP_AVP_TX_CONN_SPEED:
690 			case L2TP_AVP_PHY_CHANNEL_ID:
691 			case L2TP_AVP_RX_CONN_SPEED:
692 				if (len-6 < 4) {
693 					ND_PRINT("AVP too short");
694 					break;
695 				}
696 				print_32bits_val(ndo, dat);
697 				break;
698 			case L2TP_AVP_BEARER_TYPE:
699 				l2tp_bearer_type_print(ndo, dat, len-6);
700 				break;
701 			case L2TP_AVP_FRAMING_TYPE:
702 				l2tp_framing_type_print(ndo, dat, len-6);
703 				break;
704 			case L2TP_AVP_PACKET_PROC_DELAY:
705 				l2tp_packet_proc_delay_print(ndo);
706 				break;
707 			case L2TP_AVP_PROXY_AUTH_TYPE:
708 				l2tp_proxy_auth_type_print(ndo, dat, len-6);
709 				break;
710 			case L2TP_AVP_PROXY_AUTH_ID:
711 				l2tp_proxy_auth_id_print(ndo, dat, len-6);
712 				break;
713 			case L2TP_AVP_CALL_ERRORS:
714 				l2tp_call_errors_print(ndo, dat, len-6);
715 				break;
716 			case L2TP_AVP_ACCM:
717 				l2tp_accm_print(ndo, dat, len-6);
718 				break;
719 			case L2TP_AVP_SEQ_REQUIRED:
720 				break;	/* No Attribute Value */
721 			case L2TP_AVP_PPP_DISCON_CC:
722 				l2tp_ppp_discon_cc_print(ndo, dat, len-6);
723 				break;
724 			default:
725 				break;
726 			}
727 		}
728 		ND_PRINT(")");
729 	}
730 
731 	return (len);
732 
733  trunc:
734 	nd_print_trunc(ndo);
735 	return (0);
736 }
737 
738 
739 void
740 l2tp_print(netdissect_options *ndo, const u_char *dat, u_int length)
741 {
742 	const u_char *ptr = dat;
743 	u_int cnt = 0;			/* total octets consumed */
744 	uint16_t pad;
745 	int flag_t, flag_l, flag_s, flag_o;
746 	uint16_t l2tp_len;
747 
748 	ndo->ndo_protocol = "l2tp";
749 	flag_t = flag_l = flag_s = flag_o = FALSE;
750 
751 	if ((GET_BE_U_2(ptr) & L2TP_VERSION_MASK) == L2TP_VERSION_L2TP) {
752 		ND_PRINT(" l2tp:");
753 	} else if ((GET_BE_U_2(ptr) & L2TP_VERSION_MASK) == L2TP_VERSION_L2F) {
754 		ND_PRINT(" l2f:");
755 		return;		/* nothing to do */
756 	} else {
757 		ND_PRINT(" Unknown Version, neither L2F(1) nor L2TP(2)");
758 		return;		/* nothing we can do */
759 	}
760 
761 	ND_PRINT("[");
762 	if (GET_BE_U_2(ptr) & L2TP_FLAG_TYPE) {
763 		flag_t = TRUE;
764 		ND_PRINT("T");
765 	}
766 	if (GET_BE_U_2(ptr) & L2TP_FLAG_LENGTH) {
767 		flag_l = TRUE;
768 		ND_PRINT("L");
769 	}
770 	if (GET_BE_U_2(ptr) & L2TP_FLAG_SEQUENCE) {
771 		flag_s = TRUE;
772 		ND_PRINT("S");
773 	}
774 	if (GET_BE_U_2(ptr) & L2TP_FLAG_OFFSET) {
775 		flag_o = TRUE;
776 		ND_PRINT("O");
777 	}
778 	if (GET_BE_U_2(ptr) & L2TP_FLAG_PRIORITY)
779 		ND_PRINT("P");
780 	ND_PRINT("]");
781 
782 	ptr += 2;
783 	cnt += 2;
784 
785 	if (flag_l) {
786 		l2tp_len = GET_BE_U_2(ptr);
787 		ptr += 2;
788 		cnt += 2;
789 	} else {
790 		l2tp_len = 0;
791 	}
792 	/* Tunnel ID */
793 	ND_PRINT("(%u/", GET_BE_U_2(ptr));
794 	ptr += 2;
795 	cnt += 2;
796 	/* Session ID */
797 	ND_PRINT("%u)",  GET_BE_U_2(ptr));
798 	ptr += 2;
799 	cnt += 2;
800 
801 	if (flag_s) {
802 		ND_PRINT("Ns=%u,", GET_BE_U_2(ptr));
803 		ptr += 2;
804 		cnt += 2;
805 		ND_PRINT("Nr=%u",  GET_BE_U_2(ptr));
806 		ptr += 2;
807 		cnt += 2;
808 	}
809 
810 	if (flag_o) {	/* Offset Size */
811 		pad =  GET_BE_U_2(ptr);
812 		/* Offset padding octets in packet buffer? */
813 		ND_TCHECK_LEN(ptr + 2, pad);
814 		ptr += (2 + pad);
815 		cnt += (2 + pad);
816 	}
817 
818 	if (flag_l) {
819 		if (length < l2tp_len) {
820 			ND_PRINT(" Length %u larger than packet", l2tp_len);
821 			return;
822 		}
823 		length = l2tp_len;
824 	}
825 	if (length < cnt) {
826 		ND_PRINT(" Length %u smaller than header length", length);
827 		return;
828 	}
829 	if (flag_t) {
830 		if (!flag_l) {
831 			ND_PRINT(" No length");
832 			return;
833 		}
834 		if (length - cnt == 0) {
835 			ND_PRINT(" ZLB");
836 		} else {
837 			/*
838 			 * Print AVPs.
839 			 */
840 			while (length - cnt != 0) {
841 				u_int avp_length;
842 
843 				avp_length = l2tp_avp_print(ndo, ptr, length - cnt);
844 				if (avp_length == 0) {
845 					/*
846 					 * Truncated.
847 					 */
848 					break;
849 				}
850 				cnt += avp_length;
851 				ptr += avp_length;
852 			}
853 		}
854 	} else {
855 		ND_PRINT(" {");
856 		ppp_print(ndo, ptr, length - cnt);
857 		ND_PRINT("}");
858 	}
859 	return;
860 trunc:
861 	nd_print_trunc(ndo);
862 }
863