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