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