print-l2tp.c revision 356341
116Salm/*
216Salm * Copyright (c) 1991, 1993, 1994, 1995, 1996, 1997
316Salm *      The Regents of the University of California.  All rights reserved.
416Salm *
516Salm * Redistribution and use in source and binary forms, with or without
616Salm * modification, are permitted provided that: (1) source code distributions
716Salm * retain the above copyright notice and this paragraph in its entirety, (2)
816Salm * distributions including binary code include the above copyright notice and
916Salm * this paragraph in its entirety in the documentation or other materials
1016Salm * provided with the distribution, and (3) all advertising materials mentioning
1116Salm * features or use of this software display the following acknowledgement:
1216Salm * ``This product includes software developed by the University of California,
1316Salm * Lawrence Berkeley Laboratory and its contributors.'' Neither the name of
1416Salm * the University nor the names of its contributors may be used to endorse
1516Salm * or promote products derived from this software without specific prior
1616Salm * 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/* \summary: Layer Two Tunneling Protocol (L2TP) printer */
25
26/* specification: RFC 2661 */
27
28#ifdef HAVE_CONFIG_H
29#include "config.h"
30#endif
31
32#include <netdissect-stdinc.h>
33
34#include "netdissect.h"
35#include "extract.h"
36
37#define L2TP_FLAG_TYPE		0x8000	/* Type (0=Data, 1=Control) */
38#define L2TP_FLAG_LENGTH	0x4000	/* Length */
39#define L2TP_FLAG_SEQUENCE	0x0800	/* Sequence */
40#define L2TP_FLAG_OFFSET	0x0200	/* Offset */
41#define L2TP_FLAG_PRIORITY	0x0100	/* Priority */
42
43#define L2TP_VERSION_MASK	0x000f	/* Version Mask */
44#define L2TP_VERSION_L2F	0x0001	/* L2F */
45#define L2TP_VERSION_L2TP	0x0002	/* L2TP */
46
47#define L2TP_AVP_HDR_FLAG_MANDATORY	0x8000	/* Mandatory Flag */
48#define L2TP_AVP_HDR_FLAG_HIDDEN	0x4000	/* Hidden Flag */
49#define L2TP_AVP_HDR_LEN_MASK		0x03ff	/* Length Mask */
50
51#define L2TP_FRAMING_CAP_SYNC_MASK	0x00000001	/* Synchronous */
52#define L2TP_FRAMING_CAP_ASYNC_MASK	0x00000002	/* Asynchronous */
53
54#define L2TP_FRAMING_TYPE_SYNC_MASK	0x00000001	/* Synchronous */
55#define L2TP_FRAMING_TYPE_ASYNC_MASK	0x00000002	/* Asynchronous */
56
57#define L2TP_BEARER_CAP_DIGITAL_MASK	0x00000001	/* Digital */
58#define L2TP_BEARER_CAP_ANALOG_MASK	0x00000002	/* Analog */
59
60#define L2TP_BEARER_TYPE_DIGITAL_MASK	0x00000001	/* Digital */
61#define L2TP_BEARER_TYPE_ANALOG_MASK	0x00000002	/* Analog */
62
63/* Authen Type */
64#define L2TP_AUTHEN_TYPE_RESERVED	0x0000	/* Reserved */
65#define L2TP_AUTHEN_TYPE_TEXTUAL	0x0001	/* Textual username/password exchange */
66#define L2TP_AUTHEN_TYPE_CHAP		0x0002	/* PPP CHAP */
67#define L2TP_AUTHEN_TYPE_PAP		0x0003	/* PPP PAP */
68#define L2TP_AUTHEN_TYPE_NO_AUTH	0x0004	/* No Authentication */
69#define L2TP_AUTHEN_TYPE_MSCHAPv1	0x0005	/* MSCHAPv1 */
70
71#define L2TP_PROXY_AUTH_ID_MASK		0x00ff
72
73static const char tstr[] = " [|l2tp]";
74
75#define	L2TP_MSGTYPE_SCCRQ	1  /* Start-Control-Connection-Request */
76#define	L2TP_MSGTYPE_SCCRP	2  /* Start-Control-Connection-Reply */
77#define	L2TP_MSGTYPE_SCCCN	3  /* Start-Control-Connection-Connected */
78#define	L2TP_MSGTYPE_STOPCCN	4  /* Stop-Control-Connection-Notification */
79#define	L2TP_MSGTYPE_HELLO	6  /* Hello */
80#define	L2TP_MSGTYPE_OCRQ	7  /* Outgoing-Call-Request */
81#define	L2TP_MSGTYPE_OCRP	8  /* Outgoing-Call-Reply */
82#define	L2TP_MSGTYPE_OCCN	9  /* Outgoing-Call-Connected */
83#define	L2TP_MSGTYPE_ICRQ	10 /* Incoming-Call-Request */
84#define	L2TP_MSGTYPE_ICRP	11 /* Incoming-Call-Reply */
85#define	L2TP_MSGTYPE_ICCN	12 /* Incoming-Call-Connected */
86#define	L2TP_MSGTYPE_CDN	14 /* Call-Disconnect-Notify */
87#define	L2TP_MSGTYPE_WEN	15 /* WAN-Error-Notify */
88#define	L2TP_MSGTYPE_SLI	16 /* Set-Link-Info */
89
90static const struct tok l2tp_msgtype2str[] = {
91	{ L2TP_MSGTYPE_SCCRQ, 	"SCCRQ" },
92	{ L2TP_MSGTYPE_SCCRP,	"SCCRP" },
93	{ L2TP_MSGTYPE_SCCCN,	"SCCCN" },
94	{ L2TP_MSGTYPE_STOPCCN,	"StopCCN" },
95	{ L2TP_MSGTYPE_HELLO,	"HELLO" },
96	{ L2TP_MSGTYPE_OCRQ,	"OCRQ" },
97	{ L2TP_MSGTYPE_OCRP,	"OCRP" },
98	{ L2TP_MSGTYPE_OCCN,	"OCCN" },
99	{ L2TP_MSGTYPE_ICRQ,	"ICRQ" },
100	{ L2TP_MSGTYPE_ICRP,	"ICRP" },
101	{ L2TP_MSGTYPE_ICCN,	"ICCN" },
102	{ L2TP_MSGTYPE_CDN,	"CDN" },
103	{ L2TP_MSGTYPE_WEN,	"WEN" },
104	{ L2TP_MSGTYPE_SLI,	"SLI" },
105	{ 0,			NULL }
106};
107
108#define L2TP_AVP_MSGTYPE		0  /* Message Type */
109#define L2TP_AVP_RESULT_CODE		1  /* Result Code */
110#define L2TP_AVP_PROTO_VER		2  /* Protocol Version */
111#define L2TP_AVP_FRAMING_CAP		3  /* Framing Capabilities */
112#define L2TP_AVP_BEARER_CAP		4  /* Bearer Capabilities */
113#define L2TP_AVP_TIE_BREAKER		5  /* Tie Breaker */
114#define L2TP_AVP_FIRM_VER		6  /* Firmware Revision */
115#define L2TP_AVP_HOST_NAME		7  /* Host Name */
116#define L2TP_AVP_VENDOR_NAME		8  /* Vendor Name */
117#define L2TP_AVP_ASSND_TUN_ID 		9  /* Assigned Tunnel ID */
118#define L2TP_AVP_RECV_WIN_SIZE		10 /* Receive Window Size */
119#define L2TP_AVP_CHALLENGE		11 /* Challenge */
120#define L2TP_AVP_Q931_CC		12 /* Q.931 Cause Code */
121#define L2TP_AVP_CHALLENGE_RESP		13 /* Challenge Response */
122#define L2TP_AVP_ASSND_SESS_ID  	14 /* Assigned Session ID */
123#define L2TP_AVP_CALL_SER_NUM 		15 /* Call Serial Number */
124#define L2TP_AVP_MINIMUM_BPS		16 /* Minimum BPS */
125#define L2TP_AVP_MAXIMUM_BPS		17 /* Maximum BPS */
126#define L2TP_AVP_BEARER_TYPE		18 /* Bearer Type */
127#define L2TP_AVP_FRAMING_TYPE 		19 /* Framing Type */
128#define L2TP_AVP_PACKET_PROC_DELAY	20 /* Packet Processing Delay (OBSOLETE) */
129#define L2TP_AVP_CALLED_NUMBER		21 /* Called Number */
130#define L2TP_AVP_CALLING_NUMBER		22 /* Calling Number */
131#define L2TP_AVP_SUB_ADDRESS		23 /* Sub-Address */
132#define L2TP_AVP_TX_CONN_SPEED		24 /* (Tx) Connect Speed */
133#define L2TP_AVP_PHY_CHANNEL_ID		25 /* Physical Channel ID */
134#define L2TP_AVP_INI_RECV_LCP		26 /* Initial Received LCP CONFREQ */
135#define L2TP_AVP_LAST_SENT_LCP		27 /* Last Sent LCP CONFREQ */
136#define L2TP_AVP_LAST_RECV_LCP		28 /* Last Received LCP CONFREQ */
137#define L2TP_AVP_PROXY_AUTH_TYPE	29 /* Proxy Authen Type */
138#define L2TP_AVP_PROXY_AUTH_NAME	30 /* Proxy Authen Name */
139#define L2TP_AVP_PROXY_AUTH_CHAL	31 /* Proxy Authen Challenge */
140#define L2TP_AVP_PROXY_AUTH_ID		32 /* Proxy Authen ID */
141#define L2TP_AVP_PROXY_AUTH_RESP	33 /* Proxy Authen Response */
142#define L2TP_AVP_CALL_ERRORS		34 /* Call Errors */
143#define L2TP_AVP_ACCM			35 /* ACCM */
144#define L2TP_AVP_RANDOM_VECTOR		36 /* Random Vector */
145#define L2TP_AVP_PRIVATE_GRP_ID		37 /* Private Group ID */
146#define L2TP_AVP_RX_CONN_SPEED		38 /* (Rx) Connect Speed */
147#define L2TP_AVP_SEQ_REQUIRED 		39 /* Sequencing Required */
148#define L2TP_AVP_PPP_DISCON_CC		46 /* PPP Disconnect Cause Code - RFC 3145 */
149
150static const struct tok l2tp_avp2str[] = {
151	{ L2TP_AVP_MSGTYPE,		"MSGTYPE" },
152	{ L2TP_AVP_RESULT_CODE,		"RESULT_CODE" },
153	{ L2TP_AVP_PROTO_VER,		"PROTO_VER" },
154	{ L2TP_AVP_FRAMING_CAP,		"FRAMING_CAP" },
155	{ L2TP_AVP_BEARER_CAP,		"BEARER_CAP" },
156	{ L2TP_AVP_TIE_BREAKER,		"TIE_BREAKER" },
157	{ L2TP_AVP_FIRM_VER,		"FIRM_VER" },
158	{ L2TP_AVP_HOST_NAME,		"HOST_NAME" },
159	{ L2TP_AVP_VENDOR_NAME,		"VENDOR_NAME" },
160	{ L2TP_AVP_ASSND_TUN_ID,	"ASSND_TUN_ID" },
161	{ L2TP_AVP_RECV_WIN_SIZE,	"RECV_WIN_SIZE" },
162	{ L2TP_AVP_CHALLENGE,		"CHALLENGE" },
163	{ L2TP_AVP_Q931_CC,		"Q931_CC", },
164	{ L2TP_AVP_CHALLENGE_RESP,	"CHALLENGE_RESP" },
165	{ L2TP_AVP_ASSND_SESS_ID,	"ASSND_SESS_ID" },
166	{ L2TP_AVP_CALL_SER_NUM,	"CALL_SER_NUM" },
167	{ L2TP_AVP_MINIMUM_BPS,		"MINIMUM_BPS" },
168	{ L2TP_AVP_MAXIMUM_BPS,		"MAXIMUM_BPS" },
169	{ L2TP_AVP_BEARER_TYPE,		"BEARER_TYPE" },
170	{ L2TP_AVP_FRAMING_TYPE,	"FRAMING_TYPE" },
171	{ L2TP_AVP_PACKET_PROC_DELAY,	"PACKET_PROC_DELAY" },
172	{ L2TP_AVP_CALLED_NUMBER,	"CALLED_NUMBER" },
173	{ L2TP_AVP_CALLING_NUMBER,	"CALLING_NUMBER" },
174	{ L2TP_AVP_SUB_ADDRESS,		"SUB_ADDRESS" },
175	{ L2TP_AVP_TX_CONN_SPEED,	"TX_CONN_SPEED" },
176	{ L2TP_AVP_PHY_CHANNEL_ID,	"PHY_CHANNEL_ID" },
177	{ L2TP_AVP_INI_RECV_LCP,	"INI_RECV_LCP" },
178	{ L2TP_AVP_LAST_SENT_LCP,	"LAST_SENT_LCP" },
179	{ L2TP_AVP_LAST_RECV_LCP,	"LAST_RECV_LCP" },
180	{ L2TP_AVP_PROXY_AUTH_TYPE,	"PROXY_AUTH_TYPE" },
181	{ L2TP_AVP_PROXY_AUTH_NAME,	"PROXY_AUTH_NAME" },
182	{ L2TP_AVP_PROXY_AUTH_CHAL,	"PROXY_AUTH_CHAL" },
183	{ L2TP_AVP_PROXY_AUTH_ID,	"PROXY_AUTH_ID" },
184	{ L2TP_AVP_PROXY_AUTH_RESP,	"PROXY_AUTH_RESP" },
185	{ L2TP_AVP_CALL_ERRORS,		"CALL_ERRORS" },
186	{ L2TP_AVP_ACCM,		"ACCM" },
187	{ L2TP_AVP_RANDOM_VECTOR,	"RANDOM_VECTOR" },
188	{ L2TP_AVP_PRIVATE_GRP_ID,	"PRIVATE_GRP_ID" },
189	{ L2TP_AVP_RX_CONN_SPEED,	"RX_CONN_SPEED" },
190	{ L2TP_AVP_SEQ_REQUIRED,	"SEQ_REQUIRED" },
191	{ L2TP_AVP_PPP_DISCON_CC,	"PPP_DISCON_CC" },
192	{ 0,				NULL }
193};
194
195static const struct tok l2tp_authentype2str[] = {
196	{ L2TP_AUTHEN_TYPE_RESERVED,	"Reserved" },
197	{ L2TP_AUTHEN_TYPE_TEXTUAL,	"Textual" },
198	{ L2TP_AUTHEN_TYPE_CHAP,	"CHAP" },
199	{ L2TP_AUTHEN_TYPE_PAP,		"PAP" },
200	{ L2TP_AUTHEN_TYPE_NO_AUTH,	"No Auth" },
201	{ L2TP_AUTHEN_TYPE_MSCHAPv1,	"MS-CHAPv1" },
202	{ 0,				NULL }
203};
204
205#define L2TP_PPP_DISCON_CC_DIRECTION_GLOBAL	0
206#define L2TP_PPP_DISCON_CC_DIRECTION_AT_PEER	1
207#define L2TP_PPP_DISCON_CC_DIRECTION_AT_LOCAL	2
208
209static const struct tok l2tp_cc_direction2str[] = {
210	{ L2TP_PPP_DISCON_CC_DIRECTION_GLOBAL,	"global error" },
211	{ L2TP_PPP_DISCON_CC_DIRECTION_AT_PEER,	"at peer" },
212	{ L2TP_PPP_DISCON_CC_DIRECTION_AT_LOCAL,"at local" },
213	{ 0,					NULL }
214};
215
216#if 0
217static char *l2tp_result_code_StopCCN[] = {
218         "Reserved",
219         "General request to clear control connection",
220         "General error--Error Code indicates the problem",
221         "Control channel already exists",
222         "Requester is not authorized to establish a control channel",
223         "The protocol version of the requester is not supported",
224         "Requester is being shut down",
225         "Finite State Machine error"
226#define L2TP_MAX_RESULT_CODE_STOPCC_INDEX	8
227};
228#endif
229
230#if 0
231static char *l2tp_result_code_CDN[] = {
232	"Reserved",
233	"Call disconnected due to loss of carrier",
234	"Call disconnected for the reason indicated in error code",
235	"Call disconnected for administrative reasons",
236	"Call failed due to lack of appropriate facilities being " \
237	"available (temporary condition)",
238	"Call failed due to lack of appropriate facilities being " \
239	"available (permanent condition)",
240	"Invalid destination",
241	"Call failed due to no carrier detected",
242	"Call failed due to detection of a busy signal",
243	"Call failed due to lack of a dial tone",
244	"Call was not established within time allotted by LAC",
245	"Call was connected but no appropriate framing was detected"
246#define L2TP_MAX_RESULT_CODE_CDN_INDEX	12
247};
248#endif
249
250#if 0
251static char *l2tp_error_code_general[] = {
252	"No general error",
253	"No control connection exists yet for this LAC-LNS pair",
254	"Length is wrong",
255	"One of the field values was out of range or " \
256	"reserved field was non-zero"
257	"Insufficient resources to handle this operation now",
258	"The Session ID is invalid in this context",
259	"A generic vendor-specific error occurred in the LAC",
260	"Try another"
261#define L2TP_MAX_ERROR_CODE_GENERAL_INDEX	8
262};
263#endif
264
265/******************************/
266/* generic print out routines */
267/******************************/
268static void
269print_string(netdissect_options *ndo, const u_char *dat, u_int length)
270{
271	u_int i;
272	for (i=0; i<length; i++) {
273		ND_PRINT((ndo, "%c", *dat++));
274	}
275}
276
277static void
278print_octets(netdissect_options *ndo, const u_char *dat, u_int length)
279{
280	u_int i;
281	for (i=0; i<length; i++) {
282		ND_PRINT((ndo, "%02x", *dat++));
283	}
284}
285
286static void
287print_16bits_val(netdissect_options *ndo, const uint8_t *dat)
288{
289	ND_PRINT((ndo, "%u", EXTRACT_16BITS(dat)));
290}
291
292static void
293print_32bits_val(netdissect_options *ndo, const uint8_t *dat)
294{
295	ND_PRINT((ndo, "%u", EXTRACT_32BITS(dat)));
296}
297
298/***********************************/
299/* AVP-specific print out routines */
300/***********************************/
301static void
302l2tp_msgtype_print(netdissect_options *ndo, const u_char *dat, u_int length)
303{
304	if (length < 2) {
305		ND_PRINT((ndo, "AVP too short"));
306		return;
307	}
308	ND_PRINT((ndo, "%s", tok2str(l2tp_msgtype2str, "MSGTYPE-#%u",
309	    EXTRACT_16BITS(dat))));
310}
311
312static void
313l2tp_result_code_print(netdissect_options *ndo, const u_char *dat, u_int length)
314{
315	/* Result Code */
316	if (length < 2) {
317		ND_PRINT((ndo, "AVP too short"));
318		return;
319	}
320	ND_PRINT((ndo, "%u", EXTRACT_16BITS(dat)));
321	dat += 2;
322	length -= 2;
323
324	/* Error Code (opt) */
325	if (length == 0)
326		return;
327	if (length < 2) {
328		ND_PRINT((ndo, " AVP too short"));
329		return;
330	}
331	ND_PRINT((ndo, "/%u", EXTRACT_16BITS(dat)));
332	dat += 2;
333	length -= 2;
334
335	/* Error Message (opt) */
336	if (length == 0)
337		return;
338	ND_PRINT((ndo, " "));
339	print_string(ndo, dat, length);
340}
341
342static void
343l2tp_proto_ver_print(netdissect_options *ndo, const u_char *dat, u_int length)
344{
345	if (length < 2) {
346		ND_PRINT((ndo, "AVP too short"));
347		return;
348	}
349	ND_PRINT((ndo, "%u.%u", (EXTRACT_16BITS(dat) >> 8),
350	    (EXTRACT_16BITS(dat) & 0xff)));
351}
352
353static void
354l2tp_framing_cap_print(netdissect_options *ndo, const u_char *dat, u_int length)
355{
356	if (length < 4) {
357		ND_PRINT((ndo, "AVP too short"));
358		return;
359	}
360	if (EXTRACT_32BITS(dat) &  L2TP_FRAMING_CAP_ASYNC_MASK) {
361		ND_PRINT((ndo, "A"));
362	}
363	if (EXTRACT_32BITS(dat) &  L2TP_FRAMING_CAP_SYNC_MASK) {
364		ND_PRINT((ndo, "S"));
365	}
366}
367
368static void
369l2tp_bearer_cap_print(netdissect_options *ndo, const u_char *dat, u_int length)
370{
371	if (length < 4) {
372		ND_PRINT((ndo, "AVP too short"));
373		return;
374	}
375	if (EXTRACT_32BITS(dat) &  L2TP_BEARER_CAP_ANALOG_MASK) {
376		ND_PRINT((ndo, "A"));
377	}
378	if (EXTRACT_32BITS(dat) &  L2TP_BEARER_CAP_DIGITAL_MASK) {
379		ND_PRINT((ndo, "D"));
380	}
381}
382
383static void
384l2tp_q931_cc_print(netdissect_options *ndo, const u_char *dat, u_int length)
385{
386	if (length < 3) {
387		ND_PRINT((ndo, "AVP too short"));
388		return;
389	}
390	print_16bits_val(ndo, dat);
391	ND_PRINT((ndo, ", %02x", EXTRACT_8BITS(dat + 2)));
392	dat += 3;
393	length -= 3;
394	if (length != 0) {
395		ND_PRINT((ndo, " "));
396		print_string(ndo, dat, length);
397	}
398}
399
400static void
401l2tp_bearer_type_print(netdissect_options *ndo, const u_char *dat, u_int length)
402{
403	if (length < 4) {
404		ND_PRINT((ndo, "AVP too short"));
405		return;
406	}
407	if (EXTRACT_32BITS(dat) &  L2TP_BEARER_TYPE_ANALOG_MASK) {
408		ND_PRINT((ndo, "A"));
409	}
410	if (EXTRACT_32BITS(dat) &  L2TP_BEARER_TYPE_DIGITAL_MASK) {
411		ND_PRINT((ndo, "D"));
412	}
413}
414
415static void
416l2tp_framing_type_print(netdissect_options *ndo, const u_char *dat, u_int length)
417{
418	if (length < 4) {
419		ND_PRINT((ndo, "AVP too short"));
420		return;
421	}
422	if (EXTRACT_32BITS(dat) &  L2TP_FRAMING_TYPE_ASYNC_MASK) {
423		ND_PRINT((ndo, "A"));
424	}
425	if (EXTRACT_32BITS(dat) &  L2TP_FRAMING_TYPE_SYNC_MASK) {
426		ND_PRINT((ndo, "S"));
427	}
428}
429
430static void
431l2tp_packet_proc_delay_print(netdissect_options *ndo)
432{
433	ND_PRINT((ndo, "obsolete"));
434}
435
436static void
437l2tp_proxy_auth_type_print(netdissect_options *ndo, const u_char *dat, u_int length)
438{
439	if (length < 2) {
440		ND_PRINT((ndo, "AVP too short"));
441		return;
442	}
443	ND_PRINT((ndo, "%s", tok2str(l2tp_authentype2str,
444			     "AuthType-#%u", EXTRACT_16BITS(dat))));
445}
446
447static void
448l2tp_proxy_auth_id_print(netdissect_options *ndo, const u_char *dat, u_int length)
449{
450	if (length < 2) {
451		ND_PRINT((ndo, "AVP too short"));
452		return;
453	}
454	ND_PRINT((ndo, "%u", EXTRACT_16BITS(dat) & L2TP_PROXY_AUTH_ID_MASK));
455}
456
457static void
458l2tp_call_errors_print(netdissect_options *ndo, const u_char *dat, u_int length)
459{
460	uint32_t val;
461
462	if (length < 2) {
463		ND_PRINT((ndo, "AVP too short"));
464		return;
465	}
466	dat += 2;	/* skip "Reserved" */
467	length -= 2;
468
469	if (length < 4) {
470		ND_PRINT((ndo, "AVP too short"));
471		return;
472	}
473	val = EXTRACT_32BITS(dat); dat += 4; length -= 4;
474	ND_PRINT((ndo, "CRCErr=%u ", val));
475
476	if (length < 4) {
477		ND_PRINT((ndo, "AVP too short"));
478		return;
479	}
480	val = EXTRACT_32BITS(dat); dat += 4; length -= 4;
481	ND_PRINT((ndo, "FrameErr=%u ", val));
482
483	if (length < 4) {
484		ND_PRINT((ndo, "AVP too short"));
485		return;
486	}
487	val = EXTRACT_32BITS(dat); dat += 4; length -= 4;
488	ND_PRINT((ndo, "HardOver=%u ", val));
489
490	if (length < 4) {
491		ND_PRINT((ndo, "AVP too short"));
492		return;
493	}
494	val = EXTRACT_32BITS(dat); dat += 4; length -= 4;
495	ND_PRINT((ndo, "BufOver=%u ", val));
496
497	if (length < 4) {
498		ND_PRINT((ndo, "AVP too short"));
499		return;
500	}
501	val = EXTRACT_32BITS(dat); dat += 4; length -= 4;
502	ND_PRINT((ndo, "Timeout=%u ", val));
503
504	if (length < 4) {
505		ND_PRINT((ndo, "AVP too short"));
506		return;
507	}
508	val = EXTRACT_32BITS(dat); dat += 4; length -= 4;
509	ND_PRINT((ndo, "AlignErr=%u ", val));
510}
511
512static void
513l2tp_accm_print(netdissect_options *ndo, const u_char *dat, u_int length)
514{
515	uint32_t val;
516
517	if (length < 2) {
518		ND_PRINT((ndo, "AVP too short"));
519		return;
520	}
521	dat += 2;	/* skip "Reserved" */
522	length -= 2;
523
524	if (length < 4) {
525		ND_PRINT((ndo, "AVP too short"));
526		return;
527	}
528	val = EXTRACT_32BITS(dat); dat += 4; length -= 4;
529	ND_PRINT((ndo, "send=%08x ", val));
530
531	if (length < 4) {
532		ND_PRINT((ndo, "AVP too short"));
533		return;
534	}
535	val = EXTRACT_32BITS(dat); dat += 4; length -= 4;
536	ND_PRINT((ndo, "recv=%08x ", val));
537}
538
539static void
540l2tp_ppp_discon_cc_print(netdissect_options *ndo, const u_char *dat, u_int length)
541{
542	if (length < 5) {
543		ND_PRINT((ndo, "AVP too short"));
544		return;
545	}
546	/* Disconnect Code */
547	ND_PRINT((ndo, "%04x, ", EXTRACT_16BITS(dat)));
548	dat += 2;
549	length -= 2;
550	/* Control Protocol Number */
551	ND_PRINT((ndo, "%04x ",  EXTRACT_16BITS(dat)));
552	dat += 2;
553	length -= 2;
554	/* Direction */
555	ND_PRINT((ndo, "%s", tok2str(l2tp_cc_direction2str,
556			     "Direction-#%u", EXTRACT_8BITS(dat))));
557	dat++;
558	length--;
559
560	if (length != 0) {
561		ND_PRINT((ndo, " "));
562		print_string(ndo, (const u_char *)dat, length);
563	}
564}
565
566static u_int
567l2tp_avp_print(netdissect_options *ndo, const u_char *dat, u_int length)
568{
569	u_int len;
570	uint16_t attr_type;
571	int hidden = FALSE;
572
573	ND_PRINT((ndo, " "));
574
575	ND_TCHECK_16BITS(dat);	/* Flags & Length */
576	len = EXTRACT_16BITS(dat) & L2TP_AVP_HDR_LEN_MASK;
577
578	/* If it is not long enough to contain the header, we'll give up. */
579	if (len < 6)
580		goto trunc;
581
582	/* If it goes past the end of the remaining length of the packet,
583	   we'll give up. */
584	if (len > (u_int)length)
585		goto trunc;
586
587	/* If it goes past the end of the remaining length of the captured
588	   data, we'll give up. */
589	ND_TCHECK2(*dat, len);
590
591	/*
592	 * After this point, we don't need to check whether we go past
593	 * the length of the captured data; however, we *do* need to
594	 * check whether we go past the end of the AVP.
595	 */
596
597	if (EXTRACT_16BITS(dat) & L2TP_AVP_HDR_FLAG_MANDATORY) {
598		ND_PRINT((ndo, "*"));
599	}
600	if (EXTRACT_16BITS(dat) & L2TP_AVP_HDR_FLAG_HIDDEN) {
601		hidden = TRUE;
602		ND_PRINT((ndo, "?"));
603	}
604	dat += 2;
605
606	if (EXTRACT_16BITS(dat)) {
607		/* Vendor Specific Attribute */
608	        ND_PRINT((ndo, "VENDOR%04x:", EXTRACT_16BITS(dat))); dat += 2;
609		ND_PRINT((ndo, "ATTR%04x", EXTRACT_16BITS(dat))); dat += 2;
610		ND_PRINT((ndo, "("));
611		print_octets(ndo, dat, len-6);
612		ND_PRINT((ndo, ")"));
613	} else {
614		/* IETF-defined Attributes */
615		dat += 2;
616		attr_type = EXTRACT_16BITS(dat); dat += 2;
617		ND_PRINT((ndo, "%s", tok2str(l2tp_avp2str, "AVP-#%u", attr_type)));
618		ND_PRINT((ndo, "("));
619		if (hidden) {
620			ND_PRINT((ndo, "???"));
621		} else {
622			switch (attr_type) {
623			case L2TP_AVP_MSGTYPE:
624				l2tp_msgtype_print(ndo, dat, len-6);
625				break;
626			case L2TP_AVP_RESULT_CODE:
627				l2tp_result_code_print(ndo, dat, len-6);
628				break;
629			case L2TP_AVP_PROTO_VER:
630				l2tp_proto_ver_print(ndo, dat, len-6);
631				break;
632			case L2TP_AVP_FRAMING_CAP:
633				l2tp_framing_cap_print(ndo, dat, len-6);
634				break;
635			case L2TP_AVP_BEARER_CAP:
636				l2tp_bearer_cap_print(ndo, dat, len-6);
637				break;
638			case L2TP_AVP_TIE_BREAKER:
639				if (len-6 < 8) {
640					ND_PRINT((ndo, "AVP too short"));
641					break;
642				}
643				print_octets(ndo, dat, 8);
644				break;
645			case L2TP_AVP_FIRM_VER:
646			case L2TP_AVP_ASSND_TUN_ID:
647			case L2TP_AVP_RECV_WIN_SIZE:
648			case L2TP_AVP_ASSND_SESS_ID:
649				if (len-6 < 2) {
650					ND_PRINT((ndo, "AVP too short"));
651					break;
652				}
653				print_16bits_val(ndo, dat);
654				break;
655			case L2TP_AVP_HOST_NAME:
656			case L2TP_AVP_VENDOR_NAME:
657			case L2TP_AVP_CALLING_NUMBER:
658			case L2TP_AVP_CALLED_NUMBER:
659			case L2TP_AVP_SUB_ADDRESS:
660			case L2TP_AVP_PROXY_AUTH_NAME:
661			case L2TP_AVP_PRIVATE_GRP_ID:
662				print_string(ndo, dat, len-6);
663				break;
664			case L2TP_AVP_CHALLENGE:
665			case L2TP_AVP_INI_RECV_LCP:
666			case L2TP_AVP_LAST_SENT_LCP:
667			case L2TP_AVP_LAST_RECV_LCP:
668			case L2TP_AVP_PROXY_AUTH_CHAL:
669			case L2TP_AVP_PROXY_AUTH_RESP:
670			case L2TP_AVP_RANDOM_VECTOR:
671				print_octets(ndo, dat, len-6);
672				break;
673			case L2TP_AVP_Q931_CC:
674				l2tp_q931_cc_print(ndo, dat, len-6);
675				break;
676			case L2TP_AVP_CHALLENGE_RESP:
677				if (len-6 < 16) {
678					ND_PRINT((ndo, "AVP too short"));
679					break;
680				}
681				print_octets(ndo, dat, 16);
682				break;
683			case L2TP_AVP_CALL_SER_NUM:
684			case L2TP_AVP_MINIMUM_BPS:
685			case L2TP_AVP_MAXIMUM_BPS:
686			case L2TP_AVP_TX_CONN_SPEED:
687			case L2TP_AVP_PHY_CHANNEL_ID:
688			case L2TP_AVP_RX_CONN_SPEED:
689				if (len-6 < 4) {
690					ND_PRINT((ndo, "AVP too short"));
691					break;
692				}
693				print_32bits_val(ndo, dat);
694				break;
695			case L2TP_AVP_BEARER_TYPE:
696				l2tp_bearer_type_print(ndo, dat, len-6);
697				break;
698			case L2TP_AVP_FRAMING_TYPE:
699				l2tp_framing_type_print(ndo, dat, len-6);
700				break;
701			case L2TP_AVP_PACKET_PROC_DELAY:
702				l2tp_packet_proc_delay_print(ndo);
703				break;
704			case L2TP_AVP_PROXY_AUTH_TYPE:
705				l2tp_proxy_auth_type_print(ndo, dat, len-6);
706				break;
707			case L2TP_AVP_PROXY_AUTH_ID:
708				l2tp_proxy_auth_id_print(ndo, dat, len-6);
709				break;
710			case L2TP_AVP_CALL_ERRORS:
711				l2tp_call_errors_print(ndo, dat, len-6);
712				break;
713			case L2TP_AVP_ACCM:
714				l2tp_accm_print(ndo, dat, len-6);
715				break;
716			case L2TP_AVP_SEQ_REQUIRED:
717				break;	/* No Attribute Value */
718			case L2TP_AVP_PPP_DISCON_CC:
719				l2tp_ppp_discon_cc_print(ndo, dat, len-6);
720				break;
721			default:
722				break;
723			}
724		}
725		ND_PRINT((ndo, ")"));
726	}
727
728	return (len);
729
730 trunc:
731	ND_PRINT((ndo, "|..."));
732	return (0);
733}
734
735
736void
737l2tp_print(netdissect_options *ndo, const u_char *dat, u_int length)
738{
739	const u_char *ptr = dat;
740	u_int cnt = 0;			/* total octets consumed */
741	uint16_t pad;
742	int flag_t, flag_l, flag_s, flag_o;
743	uint16_t l2tp_len;
744
745	flag_t = flag_l = flag_s = flag_o = FALSE;
746
747	ND_TCHECK2(*ptr, 2);	/* Flags & Version */
748	if ((EXTRACT_16BITS(ptr) & L2TP_VERSION_MASK) == L2TP_VERSION_L2TP) {
749		ND_PRINT((ndo, " l2tp:"));
750	} else if ((EXTRACT_16BITS(ptr) & L2TP_VERSION_MASK) == L2TP_VERSION_L2F) {
751		ND_PRINT((ndo, " l2f:"));
752		return;		/* nothing to do */
753	} else {
754		ND_PRINT((ndo, " Unknown Version, neither L2F(1) nor L2TP(2)"));
755		return;		/* nothing we can do */
756	}
757
758	ND_PRINT((ndo, "["));
759	if (EXTRACT_16BITS(ptr) & L2TP_FLAG_TYPE) {
760		flag_t = TRUE;
761		ND_PRINT((ndo, "T"));
762	}
763	if (EXTRACT_16BITS(ptr) & L2TP_FLAG_LENGTH) {
764		flag_l = TRUE;
765		ND_PRINT((ndo, "L"));
766	}
767	if (EXTRACT_16BITS(ptr) & L2TP_FLAG_SEQUENCE) {
768		flag_s = TRUE;
769		ND_PRINT((ndo, "S"));
770	}
771	if (EXTRACT_16BITS(ptr) & L2TP_FLAG_OFFSET) {
772		flag_o = TRUE;
773		ND_PRINT((ndo, "O"));
774	}
775	if (EXTRACT_16BITS(ptr) & L2TP_FLAG_PRIORITY)
776		ND_PRINT((ndo, "P"));
777	ND_PRINT((ndo, "]"));
778
779	ptr += 2;
780	cnt += 2;
781
782	if (flag_l) {
783		ND_TCHECK2(*ptr, 2);	/* Length */
784		l2tp_len = EXTRACT_16BITS(ptr);
785		ptr += 2;
786		cnt += 2;
787	} else {
788		l2tp_len = 0;
789	}
790
791	ND_TCHECK2(*ptr, 2);		/* Tunnel ID */
792	ND_PRINT((ndo, "(%u/", EXTRACT_16BITS(ptr)));
793	ptr += 2;
794	cnt += 2;
795	ND_TCHECK2(*ptr, 2);		/* Session ID */
796	ND_PRINT((ndo, "%u)",  EXTRACT_16BITS(ptr)));
797	ptr += 2;
798	cnt += 2;
799
800	if (flag_s) {
801		ND_TCHECK2(*ptr, 2);	/* Ns */
802		ND_PRINT((ndo, "Ns=%u,", EXTRACT_16BITS(ptr)));
803		ptr += 2;
804		cnt += 2;
805		ND_TCHECK2(*ptr, 2);	/* Nr */
806		ND_PRINT((ndo, "Nr=%u",  EXTRACT_16BITS(ptr)));
807		ptr += 2;
808		cnt += 2;
809	}
810
811	if (flag_o) {
812		ND_TCHECK2(*ptr, 2);	/* Offset Size */
813		pad =  EXTRACT_16BITS(ptr);
814		ptr += (2 + pad);
815		cnt += (2 + pad);
816	}
817
818	if (flag_l) {
819		if (length < l2tp_len) {
820			ND_PRINT((ndo, " Length %u larger than packet", l2tp_len));
821			return;
822		}
823		length = l2tp_len;
824	}
825	if (length < cnt) {
826		ND_PRINT((ndo, " Length %u smaller than header length", length));
827		return;
828	}
829	if (flag_t) {
830		if (!flag_l) {
831			ND_PRINT((ndo, " No length"));
832			return;
833		}
834		if (length - cnt == 0) {
835			ND_PRINT((ndo, " ZLB"));
836		} else {
837			/*
838			 * Print AVPs.
839			 */
840			while (length - cnt != 0) {
841				u_int avp_length;
842
843				avp_length = l2tp_avp_print(ndo, ptr, length - cnt);
844				if (avp_length == 0) {
845					/*
846					 * Truncated.
847					 */
848					break;
849				}
850				cnt += avp_length;
851				ptr += avp_length;
852			}
853		}
854	} else {
855		ND_PRINT((ndo, " {"));
856		ppp_print(ndo, ptr, length - cnt);
857		ND_PRINT((ndo, "}"));
858	}
859
860	return;
861
862 trunc:
863	ND_PRINT((ndo, "%s", tstr));
864}
865