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