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