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
25static 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
41static 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
58static const 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
118static const 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
163static const 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
177static const 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
185static 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
199static 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
219static 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/******************************/
236static void
237print_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
245static void
246print_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
254static void
255print_16bits_val(const u_int16_t *dat)
256{
257	printf("%u", EXTRACT_16BITS(dat));
258}
259
260static void
261print_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/***********************************/
269static void
270l2tp_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
278static void
279l2tp_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
293static void
294l2tp_proto_ver_print(const u_int16_t *dat)
295{
296	printf("%u.%u", (EXTRACT_16BITS(dat) >> 8),
297	    (EXTRACT_16BITS(dat) & 0xff));
298}
299
300static void
301l2tp_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
313static void
314l2tp_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
326static void
327l2tp_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
337static void
338l2tp_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
350static void
351l2tp_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
363static void
364l2tp_packet_proc_delay_print(void)
365{
366	printf("obsolete");
367}
368
369static void
370l2tp_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
378static void
379l2tp_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
386static void
387l2tp_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
419static void
420l2tp_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
436static void
437l2tp_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
452static void
453l2tp_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
606void
607l2tp_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