print-l2tp.c revision 111726
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 decode the entire AVP, we'll
480	   abandon. */
481	TCHECK2(*ptr, len);
482	/* After this point, no need to worry about truncation */
483
484	if (EXTRACT_16BITS(ptr) & L2TP_AVP_HDR_FLAG_MANDATORY) {
485		printf("*");
486	}
487	if (EXTRACT_16BITS(ptr) & L2TP_AVP_HDR_FLAG_HIDDEN) {
488		hidden = TRUE;
489		printf("?");
490	}
491	ptr++;
492
493	if (EXTRACT_16BITS(ptr)) {
494		/* Vendor Specific Attribute */
495	        printf("VENDOR%04x:", EXTRACT_16BITS(ptr)); ptr++;
496		printf("ATTR%04x", EXTRACT_16BITS(ptr)); ptr++;
497		printf("(");
498		print_octets((u_char *)ptr, len-6);
499		printf(")");
500	} else {
501		/* IETF-defined Attributes */
502		ptr++;
503		attr_type = EXTRACT_16BITS(ptr); ptr++;
504		printf("%s", tok2str(l2tp_avp2str, "AVP-#%u", attr_type));
505		printf("(");
506		if (hidden) {
507			printf("???");
508		} else {
509			switch (attr_type) {
510			case L2TP_AVP_MSGTYPE:
511				l2tp_msgtype_print((u_char *)ptr);
512				break;
513			case L2TP_AVP_RESULT_CODE:
514				l2tp_result_code_print((u_char *)ptr, len-6);
515				break;
516			case L2TP_AVP_PROTO_VER:
517				l2tp_proto_ver_print(ptr);
518				break;
519			case L2TP_AVP_FRAMING_CAP:
520				l2tp_framing_cap_print((u_char *)ptr);
521				break;
522			case L2TP_AVP_BEARER_CAP:
523				l2tp_bearer_cap_print((u_char *)ptr);
524				break;
525			case L2TP_AVP_TIE_BREAKER:
526				print_octets((u_char *)ptr, 8);
527				break;
528			case L2TP_AVP_FIRM_VER:
529			case L2TP_AVP_ASSND_TUN_ID:
530			case L2TP_AVP_RECV_WIN_SIZE:
531			case L2TP_AVP_ASSND_SESS_ID:
532				print_16bits_val(ptr);
533				break;
534			case L2TP_AVP_HOST_NAME:
535			case L2TP_AVP_VENDOR_NAME:
536			case L2TP_AVP_CALLING_NUMBER:
537			case L2TP_AVP_CALLED_NUMBER:
538			case L2TP_AVP_SUB_ADDRESS:
539			case L2TP_AVP_PROXY_AUTH_NAME:
540			case L2TP_AVP_PRIVATE_GRP_ID:
541				print_string((u_char *)ptr, len-6);
542				break;
543			case L2TP_AVP_CHALLENGE:
544			case L2TP_AVP_INI_RECV_LCP:
545			case L2TP_AVP_LAST_SENT_LCP:
546			case L2TP_AVP_LAST_RECV_LCP:
547			case L2TP_AVP_PROXY_AUTH_CHAL:
548			case L2TP_AVP_PROXY_AUTH_RESP:
549			case L2TP_AVP_RANDOM_VECTOR:
550				print_octets((u_char *)ptr, len-6);
551				break;
552			case L2TP_AVP_Q931_CC:
553				l2tp_q931_cc_print((u_char *)ptr, len-6);
554				break;
555			case L2TP_AVP_CHALLENGE_RESP:
556				print_octets((u_char *)ptr, 16);
557				break;
558			case L2TP_AVP_CALL_SER_NUM:
559			case L2TP_AVP_MINIMUM_BPS:
560			case L2TP_AVP_MAXIMUM_BPS:
561			case L2TP_AVP_TX_CONN_SPEED:
562			case L2TP_AVP_PHY_CHANNEL_ID:
563			case L2TP_AVP_RX_CONN_SPEED:
564				print_32bits_val((u_int32_t *)ptr);
565				break;
566			case L2TP_AVP_BEARER_TYPE:
567				l2tp_bearer_type_print((u_char *)ptr);
568				break;
569			case L2TP_AVP_FRAMING_TYPE:
570				l2tp_framing_type_print((u_char *)ptr);
571				break;
572			case L2TP_AVP_PACKET_PROC_DELAY:
573				l2tp_packet_proc_delay_print();
574				break;
575			case L2TP_AVP_PROXY_AUTH_TYPE:
576				l2tp_proxy_auth_type_print((u_char *)ptr);
577				break;
578			case L2TP_AVP_PROXY_AUTH_ID:
579				l2tp_proxy_auth_id_print((u_char *)ptr);
580				break;
581			case L2TP_AVP_CALL_ERRORS:
582				l2tp_call_errors_print((u_char *)ptr);
583				break;
584			case L2TP_AVP_ACCM:
585				l2tp_accm_print((u_char *)ptr);
586				break;
587			case L2TP_AVP_SEQ_REQUIRED:
588				break;	/* No Attribute Value */
589			case L2TP_AVP_PPP_DISCON_CC:
590				l2tp_ppp_discon_cc_print((u_char *)ptr, len-6);
591				break;
592			default:
593				break;
594			}
595		}
596		printf(")");
597	}
598
599	l2tp_avp_print(dat+len, length-len);
600	return;
601
602 trunc:
603	printf("|...");
604}
605
606
607void
608l2tp_print(const u_char *dat, u_int length)
609{
610	const u_int16_t *ptr = (u_int16_t *)dat;
611	u_int cnt = 0;			/* total octets consumed */
612	u_int16_t pad;
613	int flag_t, flag_l, flag_s, flag_o, flag_p;
614	u_int16_t l2tp_len;
615
616	flag_t = flag_l = flag_s = flag_o = flag_p = FALSE;
617
618	TCHECK(*ptr);	/* Flags & Version */
619	if ((EXTRACT_16BITS(ptr) & L2TP_VERSION_MASK) == L2TP_VERSION_L2TP) {
620		printf(" l2tp:");
621	} else if ((EXTRACT_16BITS(ptr) & L2TP_VERSION_MASK) == L2TP_VERSION_L2F) {
622		printf(" l2f:");
623		return;		/* nothing to do */
624	} else {
625		printf(" Unknown Version, neither L2F(1) nor L2TP(2)");
626		return;		/* nothing we can do */
627	}
628
629	printf("[");
630	if (EXTRACT_16BITS(ptr) & L2TP_FLAG_TYPE) {
631		flag_t = TRUE;
632		printf("T");
633	}
634	if (EXTRACT_16BITS(ptr) & L2TP_FLAG_LENGTH) {
635		flag_l = TRUE;
636		printf("L");
637	}
638	if (EXTRACT_16BITS(ptr) & L2TP_FLAG_SEQUENCE) {
639		flag_s = TRUE;
640		printf("S");
641	}
642	if (EXTRACT_16BITS(ptr) & L2TP_FLAG_OFFSET) {
643		flag_o = TRUE;
644		printf("O");
645	}
646	if (EXTRACT_16BITS(ptr) & L2TP_FLAG_PRIORITY) {
647		flag_p = TRUE;
648		printf("P");
649	}
650	printf("]");
651
652	ptr++;
653	cnt += 2;
654
655	if (flag_l) {
656		TCHECK(*ptr);	/* Length */
657		l2tp_len = EXTRACT_16BITS(ptr); ptr++;
658		cnt += 2;
659	} else {
660		l2tp_len = 0;
661	}
662
663	TCHECK(*ptr);		/* Tunnel ID */
664	printf("(%u/", EXTRACT_16BITS(ptr)); ptr++;
665	cnt += 2;
666	TCHECK(*ptr);		/* Session ID */
667	printf("%u)",  EXTRACT_16BITS(ptr)); ptr++;
668	cnt += 2;
669
670	if (flag_s) {
671		TCHECK(*ptr);	/* Ns */
672		printf("Ns=%u,", EXTRACT_16BITS(ptr)); ptr++;
673		cnt += 2;
674		TCHECK(*ptr);	/* Nr */
675		printf("Nr=%u",  EXTRACT_16BITS(ptr)); ptr++;
676		cnt += 2;
677	}
678
679	if (flag_o) {
680		TCHECK(*ptr);	/* Offset Size */
681		pad =  EXTRACT_16BITS(ptr); ptr++;
682		ptr += pad / sizeof(*ptr);
683		cnt += (2 + pad);
684	}
685
686	if (flag_t) {
687		if (length - cnt == 0) {
688			printf(" ZLB");
689		} else {
690			l2tp_avp_print((u_char *)ptr, length - cnt);
691		}
692	} else {
693		printf(" {");
694		ppp_print((u_char *)ptr, length - cnt);
695		printf("}");
696	}
697
698	return;
699
700 trunc:
701	printf("%s", tstr);
702}
703