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