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