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