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/* \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
73
74#define	L2TP_MSGTYPE_SCCRQ	1  /* Start-Control-Connection-Request */
75#define	L2TP_MSGTYPE_SCCRP	2  /* Start-Control-Connection-Reply */
76#define	L2TP_MSGTYPE_SCCCN	3  /* Start-Control-Connection-Connected */
77#define	L2TP_MSGTYPE_STOPCCN	4  /* Stop-Control-Connection-Notification */
78#define	L2TP_MSGTYPE_HELLO	6  /* Hello */
79#define	L2TP_MSGTYPE_OCRQ	7  /* Outgoing-Call-Request */
80#define	L2TP_MSGTYPE_OCRP	8  /* Outgoing-Call-Reply */
81#define	L2TP_MSGTYPE_OCCN	9  /* Outgoing-Call-Connected */
82#define	L2TP_MSGTYPE_ICRQ	10 /* Incoming-Call-Request */
83#define	L2TP_MSGTYPE_ICRP	11 /* Incoming-Call-Reply */
84#define	L2TP_MSGTYPE_ICCN	12 /* Incoming-Call-Connected */
85#define	L2TP_MSGTYPE_CDN	14 /* Call-Disconnect-Notify */
86#define	L2TP_MSGTYPE_WEN	15 /* WAN-Error-Notify */
87#define	L2TP_MSGTYPE_SLI	16 /* Set-Link-Info */
88
89static const struct tok l2tp_msgtype2str[] = {
90	{ L2TP_MSGTYPE_SCCRQ,	"SCCRQ" },
91	{ L2TP_MSGTYPE_SCCRP,	"SCCRP" },
92	{ L2TP_MSGTYPE_SCCCN,	"SCCCN" },
93	{ L2TP_MSGTYPE_STOPCCN,	"StopCCN" },
94	{ L2TP_MSGTYPE_HELLO,	"HELLO" },
95	{ L2TP_MSGTYPE_OCRQ,	"OCRQ" },
96	{ L2TP_MSGTYPE_OCRP,	"OCRP" },
97	{ L2TP_MSGTYPE_OCCN,	"OCCN" },
98	{ L2TP_MSGTYPE_ICRQ,	"ICRQ" },
99	{ L2TP_MSGTYPE_ICRP,	"ICRP" },
100	{ L2TP_MSGTYPE_ICCN,	"ICCN" },
101	{ L2TP_MSGTYPE_CDN,	"CDN" },
102	{ L2TP_MSGTYPE_WEN,	"WEN" },
103	{ L2TP_MSGTYPE_SLI,	"SLI" },
104	{ 0,			NULL }
105};
106
107#define L2TP_AVP_MSGTYPE		0  /* Message Type */
108#define L2TP_AVP_RESULT_CODE		1  /* Result Code */
109#define L2TP_AVP_PROTO_VER		2  /* Protocol Version */
110#define L2TP_AVP_FRAMING_CAP		3  /* Framing Capabilities */
111#define L2TP_AVP_BEARER_CAP		4  /* Bearer Capabilities */
112#define L2TP_AVP_TIE_BREAKER		5  /* Tie Breaker */
113#define L2TP_AVP_FIRM_VER		6  /* Firmware Revision */
114#define L2TP_AVP_HOST_NAME		7  /* Host Name */
115#define L2TP_AVP_VENDOR_NAME		8  /* Vendor Name */
116#define L2TP_AVP_ASSND_TUN_ID		9  /* Assigned Tunnel ID */
117#define L2TP_AVP_RECV_WIN_SIZE		10 /* Receive Window Size */
118#define L2TP_AVP_CHALLENGE		11 /* Challenge */
119#define L2TP_AVP_Q931_CC		12 /* Q.931 Cause Code */
120#define L2TP_AVP_CHALLENGE_RESP		13 /* Challenge Response */
121#define L2TP_AVP_ASSND_SESS_ID		14 /* Assigned Session ID */
122#define L2TP_AVP_CALL_SER_NUM		15 /* Call Serial Number */
123#define L2TP_AVP_MINIMUM_BPS		16 /* Minimum BPS */
124#define L2TP_AVP_MAXIMUM_BPS		17 /* Maximum BPS */
125#define L2TP_AVP_BEARER_TYPE		18 /* Bearer Type */
126#define L2TP_AVP_FRAMING_TYPE		19 /* Framing Type */
127#define L2TP_AVP_PACKET_PROC_DELAY	20 /* Packet Processing Delay (OBSOLETE) */
128#define L2TP_AVP_CALLED_NUMBER		21 /* Called Number */
129#define L2TP_AVP_CALLING_NUMBER		22 /* Calling Number */
130#define L2TP_AVP_SUB_ADDRESS		23 /* Sub-Address */
131#define L2TP_AVP_TX_CONN_SPEED		24 /* (Tx) Connect Speed */
132#define L2TP_AVP_PHY_CHANNEL_ID		25 /* Physical Channel ID */
133#define L2TP_AVP_INI_RECV_LCP		26 /* Initial Received LCP CONFREQ */
134#define L2TP_AVP_LAST_SENT_LCP		27 /* Last Sent LCP CONFREQ */
135#define L2TP_AVP_LAST_RECV_LCP		28 /* Last Received LCP CONFREQ */
136#define L2TP_AVP_PROXY_AUTH_TYPE	29 /* Proxy Authen Type */
137#define L2TP_AVP_PROXY_AUTH_NAME	30 /* Proxy Authen Name */
138#define L2TP_AVP_PROXY_AUTH_CHAL	31 /* Proxy Authen Challenge */
139#define L2TP_AVP_PROXY_AUTH_ID		32 /* Proxy Authen ID */
140#define L2TP_AVP_PROXY_AUTH_RESP	33 /* Proxy Authen Response */
141#define L2TP_AVP_CALL_ERRORS		34 /* Call Errors */
142#define L2TP_AVP_ACCM			35 /* ACCM */
143#define L2TP_AVP_RANDOM_VECTOR		36 /* Random Vector */
144#define L2TP_AVP_PRIVATE_GRP_ID		37 /* Private Group ID */
145#define L2TP_AVP_RX_CONN_SPEED		38 /* (Rx) Connect Speed */
146#define L2TP_AVP_SEQ_REQUIRED		39 /* Sequencing Required */
147#define L2TP_AVP_PPP_DISCON_CC		46 /* PPP Disconnect Cause Code - RFC 3145 */
148
149static const struct tok l2tp_avp2str[] = {
150	{ L2TP_AVP_MSGTYPE,		"MSGTYPE" },
151	{ L2TP_AVP_RESULT_CODE,		"RESULT_CODE" },
152	{ L2TP_AVP_PROTO_VER,		"PROTO_VER" },
153	{ L2TP_AVP_FRAMING_CAP,		"FRAMING_CAP" },
154	{ L2TP_AVP_BEARER_CAP,		"BEARER_CAP" },
155	{ L2TP_AVP_TIE_BREAKER,		"TIE_BREAKER" },
156	{ L2TP_AVP_FIRM_VER,		"FIRM_VER" },
157	{ L2TP_AVP_HOST_NAME,		"HOST_NAME" },
158	{ L2TP_AVP_VENDOR_NAME,		"VENDOR_NAME" },
159	{ L2TP_AVP_ASSND_TUN_ID,	"ASSND_TUN_ID" },
160	{ L2TP_AVP_RECV_WIN_SIZE,	"RECV_WIN_SIZE" },
161	{ L2TP_AVP_CHALLENGE,		"CHALLENGE" },
162	{ L2TP_AVP_Q931_CC,		"Q931_CC", },
163	{ L2TP_AVP_CHALLENGE_RESP,	"CHALLENGE_RESP" },
164	{ L2TP_AVP_ASSND_SESS_ID,	"ASSND_SESS_ID" },
165	{ L2TP_AVP_CALL_SER_NUM,	"CALL_SER_NUM" },
166	{ L2TP_AVP_MINIMUM_BPS,		"MINIMUM_BPS" },
167	{ L2TP_AVP_MAXIMUM_BPS,		"MAXIMUM_BPS" },
168	{ L2TP_AVP_BEARER_TYPE,		"BEARER_TYPE" },
169	{ L2TP_AVP_FRAMING_TYPE,	"FRAMING_TYPE" },
170	{ L2TP_AVP_PACKET_PROC_DELAY,	"PACKET_PROC_DELAY" },
171	{ L2TP_AVP_CALLED_NUMBER,	"CALLED_NUMBER" },
172	{ L2TP_AVP_CALLING_NUMBER,	"CALLING_NUMBER" },
173	{ L2TP_AVP_SUB_ADDRESS,		"SUB_ADDRESS" },
174	{ L2TP_AVP_TX_CONN_SPEED,	"TX_CONN_SPEED" },
175	{ L2TP_AVP_PHY_CHANNEL_ID,	"PHY_CHANNEL_ID" },
176	{ L2TP_AVP_INI_RECV_LCP,	"INI_RECV_LCP" },
177	{ L2TP_AVP_LAST_SENT_LCP,	"LAST_SENT_LCP" },
178	{ L2TP_AVP_LAST_RECV_LCP,	"LAST_RECV_LCP" },
179	{ L2TP_AVP_PROXY_AUTH_TYPE,	"PROXY_AUTH_TYPE" },
180	{ L2TP_AVP_PROXY_AUTH_NAME,	"PROXY_AUTH_NAME" },
181	{ L2TP_AVP_PROXY_AUTH_CHAL,	"PROXY_AUTH_CHAL" },
182	{ L2TP_AVP_PROXY_AUTH_ID,	"PROXY_AUTH_ID" },
183	{ L2TP_AVP_PROXY_AUTH_RESP,	"PROXY_AUTH_RESP" },
184	{ L2TP_AVP_CALL_ERRORS,		"CALL_ERRORS" },
185	{ L2TP_AVP_ACCM,		"ACCM" },
186	{ L2TP_AVP_RANDOM_VECTOR,	"RANDOM_VECTOR" },
187	{ L2TP_AVP_PRIVATE_GRP_ID,	"PRIVATE_GRP_ID" },
188	{ L2TP_AVP_RX_CONN_SPEED,	"RX_CONN_SPEED" },
189	{ L2TP_AVP_SEQ_REQUIRED,	"SEQ_REQUIRED" },
190	{ L2TP_AVP_PPP_DISCON_CC,	"PPP_DISCON_CC" },
191	{ 0,				NULL }
192};
193
194static const struct tok l2tp_authentype2str[] = {
195	{ L2TP_AUTHEN_TYPE_RESERVED,	"Reserved" },
196	{ L2TP_AUTHEN_TYPE_TEXTUAL,	"Textual" },
197	{ L2TP_AUTHEN_TYPE_CHAP,	"CHAP" },
198	{ L2TP_AUTHEN_TYPE_PAP,		"PAP" },
199	{ L2TP_AUTHEN_TYPE_NO_AUTH,	"No Auth" },
200	{ L2TP_AUTHEN_TYPE_MSCHAPv1,	"MS-CHAPv1" },
201	{ 0,				NULL }
202};
203
204#define L2TP_PPP_DISCON_CC_DIRECTION_GLOBAL	0
205#define L2TP_PPP_DISCON_CC_DIRECTION_AT_PEER	1
206#define L2TP_PPP_DISCON_CC_DIRECTION_AT_LOCAL	2
207
208static const struct tok l2tp_cc_direction2str[] = {
209	{ L2TP_PPP_DISCON_CC_DIRECTION_GLOBAL,	"global error" },
210	{ L2TP_PPP_DISCON_CC_DIRECTION_AT_PEER,	"at peer" },
211	{ L2TP_PPP_DISCON_CC_DIRECTION_AT_LOCAL,"at local" },
212	{ 0,					NULL }
213};
214
215#if 0
216static char *l2tp_result_code_StopCCN[] = {
217         "Reserved",
218         "General request to clear control connection",
219         "General error--Error Code indicates the problem",
220         "Control channel already exists",
221         "Requester is not authorized to establish a control channel",
222         "The protocol version of the requester is not supported",
223         "Requester is being shut down",
224         "Finite State Machine error"
225#define L2TP_MAX_RESULT_CODE_STOPCC_INDEX	8
226};
227#endif
228
229#if 0
230static char *l2tp_result_code_CDN[] = {
231	"Reserved",
232	"Call disconnected due to loss of carrier",
233	"Call disconnected for the reason indicated in error code",
234	"Call disconnected for administrative reasons",
235	"Call failed due to lack of appropriate facilities being "
236	"available (temporary condition)",
237	"Call failed due to lack of appropriate facilities being "
238	"available (permanent condition)",
239	"Invalid destination",
240	"Call failed due to no carrier detected",
241	"Call failed due to detection of a busy signal",
242	"Call failed due to lack of a dial tone",
243	"Call was not established within time allotted by LAC",
244	"Call was connected but no appropriate framing was detected"
245#define L2TP_MAX_RESULT_CODE_CDN_INDEX	12
246};
247#endif
248
249#if 0
250static char *l2tp_error_code_general[] = {
251	"No general error",
252	"No control connection exists yet for this LAC-LNS pair",
253	"Length is wrong",
254	"One of the field values was out of range or "
255	"reserved field was non-zero"
256	"Insufficient resources to handle this operation now",
257	"The Session ID is invalid in this context",
258	"A generic vendor-specific error occurred in the LAC",
259	"Try another"
260#define L2TP_MAX_ERROR_CODE_GENERAL_INDEX	8
261};
262#endif
263
264/******************************/
265/* generic print out routines */
266/******************************/
267static void
268print_string(netdissect_options *ndo, const u_char *dat, u_int length)
269{
270	u_int i;
271	for (i=0; i<length; i++) {
272		fn_print_char(ndo, GET_U_1(dat));
273		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("%02x", GET_U_1(dat));
283		dat++;
284	}
285}
286
287static void
288print_16bits_val(netdissect_options *ndo, const uint8_t *dat)
289{
290	ND_PRINT("%u", GET_BE_U_2(dat));
291}
292
293static void
294print_32bits_val(netdissect_options *ndo, const uint8_t *dat)
295{
296	ND_PRINT("%u", GET_BE_U_4(dat));
297}
298
299/***********************************/
300/* AVP-specific print out routines */
301/***********************************/
302static void
303l2tp_msgtype_print(netdissect_options *ndo, const u_char *dat, u_int length)
304{
305	if (length < 2) {
306		ND_PRINT("AVP too short");
307		return;
308	}
309	ND_PRINT("%s", tok2str(l2tp_msgtype2str, "MSGTYPE-#%u",
310	    GET_BE_U_2(dat)));
311}
312
313static void
314l2tp_result_code_print(netdissect_options *ndo, const u_char *dat, u_int length)
315{
316	/* Result Code */
317	if (length < 2) {
318		ND_PRINT("AVP too short");
319		return;
320	}
321	ND_PRINT("%u", GET_BE_U_2(dat));
322	dat += 2;
323	length -= 2;
324
325	/* Error Code (opt) */
326	if (length == 0)
327		return;
328	if (length < 2) {
329		ND_PRINT(" AVP too short");
330		return;
331	}
332	ND_PRINT("/%u", GET_BE_U_2(dat));
333	dat += 2;
334	length -= 2;
335
336	/* Error Message (opt) */
337	if (length == 0)
338		return;
339	ND_PRINT(" ");
340	print_string(ndo, dat, length);
341}
342
343static void
344l2tp_proto_ver_print(netdissect_options *ndo, const u_char *dat, u_int length)
345{
346	if (length < 2) {
347		ND_PRINT("AVP too short");
348		return;
349	}
350	ND_PRINT("%u.%u", (GET_BE_U_2(dat) >> 8),
351		  (GET_BE_U_2(dat) & 0xff));
352}
353
354static void
355l2tp_framing_cap_print(netdissect_options *ndo, const u_char *dat, u_int length)
356{
357	if (length < 4) {
358		ND_PRINT("AVP too short");
359		return;
360	}
361	if (GET_BE_U_4(dat) &  L2TP_FRAMING_CAP_ASYNC_MASK) {
362		ND_PRINT("A");
363	}
364	if (GET_BE_U_4(dat) &  L2TP_FRAMING_CAP_SYNC_MASK) {
365		ND_PRINT("S");
366	}
367}
368
369static void
370l2tp_bearer_cap_print(netdissect_options *ndo, const u_char *dat, u_int length)
371{
372	if (length < 4) {
373		ND_PRINT("AVP too short");
374		return;
375	}
376	if (GET_BE_U_4(dat) &  L2TP_BEARER_CAP_ANALOG_MASK) {
377		ND_PRINT("A");
378	}
379	if (GET_BE_U_4(dat) &  L2TP_BEARER_CAP_DIGITAL_MASK) {
380		ND_PRINT("D");
381	}
382}
383
384static void
385l2tp_q931_cc_print(netdissect_options *ndo, const u_char *dat, u_int length)
386{
387	if (length < 3) {
388		ND_PRINT("AVP too short");
389		return;
390	}
391	print_16bits_val(ndo, dat);
392	ND_PRINT(", %02x", GET_U_1(dat + 2));
393	dat += 3;
394	length -= 3;
395	if (length != 0) {
396		ND_PRINT(" ");
397		print_string(ndo, dat, length);
398	}
399}
400
401static void
402l2tp_bearer_type_print(netdissect_options *ndo, const u_char *dat, u_int length)
403{
404	if (length < 4) {
405		ND_PRINT("AVP too short");
406		return;
407	}
408	if (GET_BE_U_4(dat) &  L2TP_BEARER_TYPE_ANALOG_MASK) {
409		ND_PRINT("A");
410	}
411	if (GET_BE_U_4(dat) &  L2TP_BEARER_TYPE_DIGITAL_MASK) {
412		ND_PRINT("D");
413	}
414}
415
416static void
417l2tp_framing_type_print(netdissect_options *ndo, const u_char *dat, u_int length)
418{
419	if (length < 4) {
420		ND_PRINT("AVP too short");
421		return;
422	}
423	if (GET_BE_U_4(dat) &  L2TP_FRAMING_TYPE_ASYNC_MASK) {
424		ND_PRINT("A");
425	}
426	if (GET_BE_U_4(dat) &  L2TP_FRAMING_TYPE_SYNC_MASK) {
427		ND_PRINT("S");
428	}
429}
430
431static void
432l2tp_packet_proc_delay_print(netdissect_options *ndo)
433{
434	ND_PRINT("obsolete");
435}
436
437static void
438l2tp_proxy_auth_type_print(netdissect_options *ndo, const u_char *dat, u_int length)
439{
440	if (length < 2) {
441		ND_PRINT("AVP too short");
442		return;
443	}
444	ND_PRINT("%s", tok2str(l2tp_authentype2str,
445			     "AuthType-#%u", GET_BE_U_2(dat)));
446}
447
448static void
449l2tp_proxy_auth_id_print(netdissect_options *ndo, const u_char *dat, u_int length)
450{
451	if (length < 2) {
452		ND_PRINT("AVP too short");
453		return;
454	}
455	ND_PRINT("%u", GET_BE_U_2(dat) & L2TP_PROXY_AUTH_ID_MASK);
456}
457
458static void
459l2tp_call_errors_print(netdissect_options *ndo, const u_char *dat, u_int length)
460{
461	uint32_t val;
462
463	if (length < 2) {
464		ND_PRINT("AVP too short");
465		return;
466	}
467	dat += 2;	/* skip "Reserved" */
468	length -= 2;
469
470	if (length < 4) {
471		ND_PRINT("AVP too short");
472		return;
473	}
474	val = GET_BE_U_4(dat); dat += 4; length -= 4;
475	ND_PRINT("CRCErr=%u ", val);
476
477	if (length < 4) {
478		ND_PRINT("AVP too short");
479		return;
480	}
481	val = GET_BE_U_4(dat); dat += 4; length -= 4;
482	ND_PRINT("FrameErr=%u ", val);
483
484	if (length < 4) {
485		ND_PRINT("AVP too short");
486		return;
487	}
488	val = GET_BE_U_4(dat); dat += 4; length -= 4;
489	ND_PRINT("HardOver=%u ", val);
490
491	if (length < 4) {
492		ND_PRINT("AVP too short");
493		return;
494	}
495	val = GET_BE_U_4(dat); dat += 4; length -= 4;
496	ND_PRINT("BufOver=%u ", val);
497
498	if (length < 4) {
499		ND_PRINT("AVP too short");
500		return;
501	}
502	val = GET_BE_U_4(dat); dat += 4; length -= 4;
503	ND_PRINT("Timeout=%u ", val);
504
505	if (length < 4) {
506		ND_PRINT("AVP too short");
507		return;
508	}
509	val = GET_BE_U_4(dat); dat += 4; length -= 4;
510	ND_PRINT("AlignErr=%u ", val);
511}
512
513static void
514l2tp_accm_print(netdissect_options *ndo, const u_char *dat, u_int length)
515{
516	uint32_t val;
517
518	if (length < 2) {
519		ND_PRINT("AVP too short");
520		return;
521	}
522	dat += 2;	/* skip "Reserved" */
523	length -= 2;
524
525	if (length < 4) {
526		ND_PRINT("AVP too short");
527		return;
528	}
529	val = GET_BE_U_4(dat); dat += 4; length -= 4;
530	ND_PRINT("send=%08x ", val);
531
532	if (length < 4) {
533		ND_PRINT("AVP too short");
534		return;
535	}
536	val = GET_BE_U_4(dat); dat += 4; length -= 4;
537	ND_PRINT("recv=%08x ", val);
538}
539
540static void
541l2tp_ppp_discon_cc_print(netdissect_options *ndo, const u_char *dat, u_int length)
542{
543	if (length < 5) {
544		ND_PRINT("AVP too short");
545		return;
546	}
547	/* Disconnect Code */
548	ND_PRINT("%04x, ", GET_BE_U_2(dat));
549	dat += 2;
550	length -= 2;
551	/* Control Protocol Number */
552	ND_PRINT("%04x ",  GET_BE_U_2(dat));
553	dat += 2;
554	length -= 2;
555	/* Direction */
556	ND_PRINT("%s", tok2str(l2tp_cc_direction2str,
557			     "Direction-#%u", GET_U_1(dat)));
558	dat++;
559	length--;
560
561	if (length != 0) {
562		ND_PRINT(" ");
563		print_string(ndo, (const u_char *)dat, length);
564	}
565}
566
567static u_int
568l2tp_avp_print(netdissect_options *ndo, const u_char *dat, u_int length)
569{
570	u_int len;
571	uint16_t attr_type;
572	int hidden = FALSE;
573
574	ND_PRINT(" ");
575	/* Flags & Length */
576	len = GET_BE_U_2(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_TCHECK_LEN(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 (GET_BE_U_2(dat) & L2TP_AVP_HDR_FLAG_MANDATORY) {
598		ND_PRINT("*");
599	}
600	if (GET_BE_U_2(dat) & L2TP_AVP_HDR_FLAG_HIDDEN) {
601		hidden = TRUE;
602		ND_PRINT("?");
603	}
604	dat += 2;
605
606	if (GET_BE_U_2(dat)) {
607		/* Vendor Specific Attribute */
608	        ND_PRINT("VENDOR%04x:", GET_BE_U_2(dat)); dat += 2;
609		ND_PRINT("ATTR%04x", GET_BE_U_2(dat)); dat += 2;
610		ND_PRINT("(");
611		print_octets(ndo, dat, len-6);
612		ND_PRINT(")");
613	} else {
614		/* IETF-defined Attributes */
615		dat += 2;
616		attr_type = GET_BE_U_2(dat); dat += 2;
617		ND_PRINT("%s", tok2str(l2tp_avp2str, "AVP-#%u", attr_type));
618		ND_PRINT("(");
619		if (hidden) {
620			ND_PRINT("???");
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("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("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("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("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(")");
726	}
727
728	return (len);
729
730 trunc:
731	nd_print_trunc(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	ndo->ndo_protocol = "l2tp";
746	flag_t = flag_l = flag_s = flag_o = FALSE;
747
748	if ((GET_BE_U_2(ptr) & L2TP_VERSION_MASK) == L2TP_VERSION_L2TP) {
749		ND_PRINT(" l2tp:");
750	} else if ((GET_BE_U_2(ptr) & L2TP_VERSION_MASK) == L2TP_VERSION_L2F) {
751		ND_PRINT(" l2f:");
752		return;		/* nothing to do */
753	} else {
754		ND_PRINT(" Unknown Version, neither L2F(1) nor L2TP(2)");
755		return;		/* nothing we can do */
756	}
757
758	ND_PRINT("[");
759	if (GET_BE_U_2(ptr) & L2TP_FLAG_TYPE) {
760		flag_t = TRUE;
761		ND_PRINT("T");
762	}
763	if (GET_BE_U_2(ptr) & L2TP_FLAG_LENGTH) {
764		flag_l = TRUE;
765		ND_PRINT("L");
766	}
767	if (GET_BE_U_2(ptr) & L2TP_FLAG_SEQUENCE) {
768		flag_s = TRUE;
769		ND_PRINT("S");
770	}
771	if (GET_BE_U_2(ptr) & L2TP_FLAG_OFFSET) {
772		flag_o = TRUE;
773		ND_PRINT("O");
774	}
775	if (GET_BE_U_2(ptr) & L2TP_FLAG_PRIORITY)
776		ND_PRINT("P");
777	ND_PRINT("]");
778
779	ptr += 2;
780	cnt += 2;
781
782	if (flag_l) {
783		l2tp_len = GET_BE_U_2(ptr);
784		ptr += 2;
785		cnt += 2;
786	} else {
787		l2tp_len = 0;
788	}
789	/* Tunnel ID */
790	ND_PRINT("(%u/", GET_BE_U_2(ptr));
791	ptr += 2;
792	cnt += 2;
793	/* Session ID */
794	ND_PRINT("%u)",  GET_BE_U_2(ptr));
795	ptr += 2;
796	cnt += 2;
797
798	if (flag_s) {
799		ND_PRINT("Ns=%u,", GET_BE_U_2(ptr));
800		ptr += 2;
801		cnt += 2;
802		ND_PRINT("Nr=%u",  GET_BE_U_2(ptr));
803		ptr += 2;
804		cnt += 2;
805	}
806
807	if (flag_o) {	/* Offset Size */
808		pad =  GET_BE_U_2(ptr);
809		/* Offset padding octets in packet buffer? */
810		ND_TCHECK_LEN(ptr + 2, pad);
811		ptr += (2 + pad);
812		cnt += (2 + pad);
813	}
814
815	if (flag_l) {
816		if (length < l2tp_len) {
817			ND_PRINT(" Length %u larger than packet", l2tp_len);
818			return;
819		}
820		length = l2tp_len;
821	}
822	if (length < cnt) {
823		ND_PRINT(" Length %u smaller than header length", length);
824		return;
825	}
826	if (flag_t) {
827		if (!flag_l) {
828			ND_PRINT(" No length");
829			return;
830		}
831		if (length - cnt == 0) {
832			ND_PRINT(" ZLB");
833		} else {
834			/*
835			 * Print AVPs.
836			 */
837			while (length - cnt != 0) {
838				u_int avp_length;
839
840				avp_length = l2tp_avp_print(ndo, ptr, length - cnt);
841				if (avp_length == 0) {
842					/*
843					 * Truncated.
844					 */
845					break;
846				}
847				cnt += avp_length;
848				ptr += avp_length;
849			}
850		}
851	} else {
852		ND_PRINT(" {");
853		ppp_print(ndo, ptr, length - cnt);
854		ND_PRINT("}");
855	}
856	return;
857trunc:
858	nd_print_trunc(ndo);
859}
860