print-l2tp.c revision 56893
1221512Stuexen/*
2221512Stuexen * Copyright (c) 1991, 1993, 1994, 1995, 1996, 1997
3235827Stuexen *      The Regents of the University of California.  All rights reserved.
4235827Stuexen *
5165242Srrs * Redistribution and use in source and binary forms, with or without
6165242Srrs * modification, are permitted provided that: (1) source code distributions
7221512Stuexen * retain the above copyright notice and this paragraph in its entirety, (2)
8165242Srrs * distributions including binary code include the above copyright notice and
9221512Stuexen * this paragraph in its entirety in the documentation or other materials
10221512Stuexen * provided with the distribution, and (3) all advertising materials mentioning
11221512Stuexen * features or use of this software display the following acknowledgement:
12221512Stuexen * ``This product includes software developed by the University of California,
13221512Stuexen * Lawrence Berkeley Laboratory and its contributors.'' Neither the name of
14221512Stuexen * the University nor the names of its contributors may be used to endorse
15221512Stuexen * or promote products derived from this software without specific prior
16221512Stuexen * written permission.
17221512Stuexen * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR IMPLIED
18221512Stuexen * WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF
19221512Stuexen * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
20221512Stuexen *
21221512Stuexen * L2TP support contributed by Motonori Shindo (mshindo@ascend.co.jp)
22221512Stuexen */
23221512Stuexen
24221512Stuexen#ifndef lint
25221512Stuexenstatic const char rcsid[] =
26221512Stuexen    "@(#) $Header: /tcpdump/master/tcpdump/print-l2tp.c,v 1.6 1999/12/22 06:27:21 itojun Exp $";
27221512Stuexen#endif
28221512Stuexen
29221512Stuexen#ifdef HAVE_CONFIG_H
30221512Stuexen#include "config.h"
31165242Srrs#endif
32221512Stuexen
33165242Srrs#include <stdio.h>
34165242Srrs#include <sys/types.h>
35235827Stuexen#include <sys/param.h>
36165242Srrs#include <netinet/in.h>
37165242Srrs#include <arpa/inet.h>
38165242Srrs
39165242Srrs#include "l2tp.h"
40165242Srrs#include "interface.h"
41165242Srrs
42165242Srrsstatic char tstr[] = " [|l2tp]";
43165242Srrs
44165242Srrs#ifndef TRUE
45165242Srrs#define TRUE 1
46165242Srrs#endif
47165242Srrs
48165242Srrs#ifndef FALSE
49165242Srrs#define FALSE 0
50165242Srrs#endif
51165242Srrs
52165242Srrsstatic char *l2tp_message_type_string[] = {
53209684Sbrucec	"RESERVED_0",		/* 0  Reserved */
54209684Sbrucec	"SCCRQ",		/* 1  Start-Control-Connection-Request */
55209684Sbrucec	"SCCRP",		/* 2  Start-Control-Connection-Reply */
56165242Srrs	"SCCCN",		/* 3  Start-Control-Connection-Connected */
57165242Srrs	"StopCCN",		/* 4  Stop-Control-Connection-Notification */
58165242Srrs	"RESERVED_5",		/* 5  Reserved */
59165242Srrs	"HELLO",		/* 6  Hello */
60166884Srrs	"OCRQ",			/* 7  Outgoing-Call-Request */
61165242Srrs	"OCRP",			/* 8  Outgoing-Call-Reply */
62165242Srrs	"OCCN",			/* 9  Outgoing-Call-Connected */
63165242Srrs	"ICRQ",			/* 10 Incoming-Call-Request */
64165242Srrs	"ICRP",			/* 11 Incoming-Call-Reply */
65165242Srrs	"ICCN",			/* 12 Incoming-Call-Connected */
66165242Srrs	"RESERVED_13",		/* 13 Reserved */
67165242Srrs	"CDN",			/* 14 Call-Disconnect-Notify */
68165242Srrs	"WEN",			/* 15 WAN-Error-Notify */
69165242Srrs	"SLI"			/* 16 Set-Link-Info */
70165242Srrs#define L2TP_MAX_MSGTYPE_INDEX	17
71165242Srrs};
72165242Srrs
73165242Srrsstatic void l2tp_msgtype_print(const u_char *dat, u_int length);
74223132Stuexenstatic void l2tp_result_code_print(const u_char *dat, u_int length);
75165242Srrsstatic void l2tp_proto_ver_print(const u_char *dat, u_int length);
76165242Srrsstatic void l2tp_framing_cap_print(const u_char *dat, u_int length);
77165242Srrsstatic void l2tp_bearer_cap_print(const u_char *dat, u_int length);
78165242Srrsstatic void l2tp_tie_breaker_print(const u_char *dat, u_int length);
79165242Srrsstatic void l2tp_firm_ver_print(const u_char *dat, u_int length);
80165242Srrsstatic void l2tp_host_name_print(const u_char *dat, u_int length);
81165242Srrsstatic void l2tp_vendor_name_print(const u_char *dat, u_int length);
82165242Srrsstatic void l2tp_assnd_tun_id_print(const u_char *dat, u_int length);
83165242Srrsstatic void l2tp_recv_win_size_print(const u_char *dat, u_int length);
84223132Stuexenstatic void l2tp_challenge_print(const u_char *dat, u_int length);
85223132Stuexenstatic void l2tp_q931_cc_print(const u_char *dat, u_int length);
86165242Srrsstatic void l2tp_challenge_resp_print(const u_char *dat, u_int length);
87165242Srrsstatic void l2tp_assnd_sess_id_print(const u_char *dat, u_int length);
88170993Srrsstatic void l2tp_call_ser_num_print(const u_char *dat, u_int length);
89165242Srrsstatic void l2tp_minimum_bps_print(const u_char *dat, u_int length);
90223132Stuexenstatic void l2tp_maximum_bps_print(const u_char *dat, u_int length);
91165242Srrsstatic void l2tp_bearer_type_print(const u_char *dat, u_int length);
92223132Stuexenstatic void l2tp_framing_type_print(const u_char *dat, u_int length);
93165242Srrsstatic void l2tp_packet_proc_delay_print(const u_char *dat, u_int length);
94165242Srrsstatic void l2tp_called_number_print(const u_char *dat, u_int length);
95170993Srrsstatic void l2tp_calling_number_print(const u_char *dat, u_int length);
96165242Srrsstatic void l2tp_sub_address_print(const u_char *dat, u_int length);
97165242Srrsstatic void l2tp_tx_conn_speed_print(const u_char *dat, u_int length);
98165242Srrsstatic void l2tp_phy_channel_id_print(const u_char *dat, u_int length);
99165242Srrsstatic void l2tp_ini_recv_lcp_print(const u_char *dat, u_int length);
100170580Srrsstatic void l2tp_last_sent_lcp_print(const u_char *dat, u_int length);
101170580Srrsstatic void l2tp_last_recv_lcp_print(const u_char *dat, u_int length);
102165242Srrsstatic void l2tp_proxy_auth_type_print(const u_char *dat, u_int length);
103249333Stuexenstatic void l2tp_proxy_auth_name_print(const u_char *dat, u_int length);
104255695Stuexenstatic void l2tp_proxy_auth_chal_print(const u_char *dat, u_int length);
105165242Srrsstatic void l2tp_proxy_auth_id_print(const u_char *dat, u_int length);
106165242Srrsstatic void l2tp_proxy_auth_resp_print(const u_char *dat, u_int length);
107255695Stuexenstatic void l2tp_call_errors_print(const u_char *dat, u_int length);
108165242Srrsstatic void l2tp_accm_print(const u_char *dat, u_int length);
109170580Srrsstatic void l2tp_random_vector_print(const u_char *dat, u_int length);
110170580Srrsstatic void l2tp_private_grp_id_print(const u_char *dat, u_int length);
111170580Srrsstatic void l2tp_rx_conn_speed_print(const u_char *dat, u_int length);
112170580Srrsstatic void l2tp_seq_required_print(const u_char *dat, u_int length);
113170580Srrsstatic void l2tp_avp_print(const u_char *dat, u_int length);
114249333Stuexen
115249333Stuexenstatic struct l2tp_avp_vec l2tp_avp[] = {
116249333Stuexen  {"MSGTYPE", l2tp_msgtype_print}, 		/* 0  Message Type */
117249333Stuexen  {"RESULT_CODE", l2tp_result_code_print},	/* 1  Result Code */
118255695Stuexen  {"PROTO_VER", l2tp_proto_ver_print},		/* 2  Protocol Version */
119165242Srrs  {"FRAMING_CAP", l2tp_framing_cap_print},	/* 3  Framing Capabilities */
120249333Stuexen  {"BEARER_CAP", l2tp_bearer_cap_print},	/* 4  Bearer Capabilities */
121165242Srrs  {"TIE_BREAKER", l2tp_tie_breaker_print},	/* 5  Tie Breaker */
122165242Srrs  {"FIRM_VER", l2tp_firm_ver_print},		/* 6  Firmware Revision */
123243302Stuexen  {"HOST_NAME", l2tp_host_name_print},		/* 7  Host Name */
124243302Stuexen  {"VENDOR_NAME", l2tp_vendor_name_print},	/* 8  Vendor Name */
125171031Srrs  {"ASSND_TUN_ID", l2tp_assnd_tun_id_print}, 	/* 9  Assigned Tunnel ID */
126249333Stuexen  {"RECV_WIN_SIZE", l2tp_recv_win_size_print},	/* 10 Receive Window Size */
127171031Srrs  {"CHALLENGE", l2tp_challenge_print},		/* 11 Challenge */
128171031Srrs  {"Q931_CC", l2tp_q931_cc_print},		/* 12 Q.931 Cause Code */
129171031Srrs  {"CHALLENGE_RESP", l2tp_challenge_resp_print},/* 13 Challenge Response */
130243302Stuexen  {"ASSND_SESS_ID", l2tp_assnd_sess_id_print},  /* 14 Assigned Session ID */
131243302Stuexen  {"CALL_SER_NUM", l2tp_call_ser_num_print}, 	/* 15 Call Serial Number */
132243302Stuexen  {"MINIMUM_BPS",	l2tp_minimum_bps_print},/* 16 Minimum BPS */
133243302Stuexen  {"MAXIMUM_BPS", l2tp_maximum_bps_print},	/* 17 Maximum BPS */
134243302Stuexen  {"BEARER_TYPE",	l2tp_bearer_type_print},/* 18 Bearer Type */
135171031Srrs  {"FRAMING_TYPE", l2tp_framing_type_print}, 	/* 19 Framing Type */
136249333Stuexen  {"PACKET_PROC_DELAY", l2tp_packet_proc_delay_print}, /* 20 Packet Processing Delay (OBSOLETE) */
137171031Srrs  {"CALLED_NUMBER", l2tp_called_number_print},	/* 21 Called Number */
138171031Srrs  {"CALLING_NUMBER", l2tp_calling_number_print},/* 22 Calling Number */
139171031Srrs  {"SUB_ADDRESS",	l2tp_sub_address_print},/* 23 Sub-Address */
140165242Srrs  {"TX_CONN_SPEED", l2tp_tx_conn_speed_print},	/* 24 (Tx) Connect Speed */
141165242Srrs  {"PHY_CHANNEL_ID", l2tp_phy_channel_id_print},/* 25 Physical Channel ID */
142165242Srrs  {"INI_RECV_LCP", l2tp_ini_recv_lcp_print}, 	/* 26 Initial Received LCP CONFREQ */
143165242Srrs  {"LAST_SENT_LCP", l2tp_last_sent_lcp_print},	/* 27 Last Sent LCP CONFREQ */
144165242Srrs  {"LAST_RECV_LCP", l2tp_last_recv_lcp_print},	/* 28 Last Received LCP CONFREQ */
145243302Stuexen  {"PROXY_AUTH_TYPE", l2tp_proxy_auth_type_print},/* 29 Proxy Authen Type */
146243302Stuexen  {"PROXY_AUTH_NAME", l2tp_proxy_auth_name_print},/* 30 Proxy Authen Name */
147243302Stuexen  {"PROXY_AUTH_CHAL", l2tp_proxy_auth_chal_print},/* 31 Proxy Authen Challenge */
148165242Srrs  {"PROXY_AUTH_ID", l2tp_proxy_auth_id_print},	/* 32 Proxy Authen ID */
149243302Stuexen  {"PROXY_AUTH_RESP", l2tp_proxy_auth_resp_print},/* 33 Proxy Authen Response */
150243302Stuexen  {"CALL_ERRORS", l2tp_call_errors_print},	/* 34 Call Errors */
151249333Stuexen  {"ACCM", l2tp_accm_print},			/* 35 ACCM */
152165242Srrs  {"RANDOM_VECTOR", l2tp_random_vector_print},	/* 36 Random Vector */
153165242Srrs  {"PRIVATE_GRP_ID", l2tp_private_grp_id_print},/* 37 Private Group ID */
154165242Srrs  {"RX_CONN_SPEED", l2tp_rx_conn_speed_print},	/* 38 (Rx) Connect Speed */
155249333Stuexen  {"SEQ_REQUIRED", l2tp_seq_required_print}, 	/* 39 Sequencing Required */
156165242Srrs#define L2TP_MAX_AVP_INDEX	40
157165242Srrs};
158249333Stuexen
159165242Srrs#if 0
160169623Srrsstatic char *l2tp_result_code_StopCCN[] = {
161249333Stuexen         "Reserved",
162249333Stuexen         "General request to clear control connection",
163167598Srrs         "General error--Error Code indicates the problem",
164255695Stuexen         "Control channel already exists",
165165242Srrs         "Requester is not authorized to establish a control channel",
166165242Srrs         "The protocol version of the requester is not supported",
167165242Srrs         "Requester is being shut down",
168165242Srrs         "Finite State Machine error"
169165242Srrs#define L2TP_MAX_RESULT_CODE_STOPCC_INDEX	8
170165242Srrs};
171165242Srrs#endif
172165242Srrs
173171572Srrs#if 0
174171572Srrsstatic char *l2tp_result_code_CDN[] = {
175228630Stuexen	"Reserved",
176228630Stuexen	"Call disconnected due to loss of carrier",
177171572Srrs	"Call disconnected for the reason indicated in error code",
178165242Srrs	"Call disconnected for administrative reasons",
179170580Srrs	"Call failed due to lack of appropriate facilities being " \
180165242Srrs	"available (temporary condition)",
181165242Srrs	"Call failed due to lack of appropriate facilities being " \
182165242Srrs	"available (permanent condition)",
183165242Srrs	"Invalid destination",
184165242Srrs	"Call failed due to no carrier detected",
185170580Srrs	"Call failed due to detection of a busy signal",
186170580Srrs	"Call failed due to lack of a dial tone",
187170580Srrs	"Call was not established within time allotted by LAC",
188170580Srrs	"Call was connected but no appropriate framing was detected"
189170580Srrs#define L2TP_MAX_RESULT_CODE_CDN_INDEX	12
190171572Srrs};
191165242Srrs#endif
192165242Srrs
193243302Stuexen#if 0
194243302Stuexenstatic char *l2tp_error_code_general[] = {
195243302Stuexen	"No general error",
196243302Stuexen	"No control connection exists yet for this LAC-LNS pair",
197243302Stuexen	"Length is wrong",
198243302Stuexen	"One of the field values was out of range or " \
199171572Srrs	"reserved field was non-zero"
200171572Srrs	"Insufficient resources to handle this operation now",
201171572Srrs	"The Session ID is invalid in this context",
202171572Srrs	"A generic vendor-specific error occurred in the LAC",
203171572Srrs	"Try another"
204171572Srrs#define L2TP_MAX_ERROR_CODE_GENERAL_INDEX	8
205243302Stuexen};
206243302Stuexen#endif
207171572Srrs
208171572Srrs/******************************/
209171572Srrs/* generic print out routines */
210171572Srrs/******************************/
211171572Srrsstatic void
212171572Srrsprint_string(const u_char *dat, u_int length)
213243302Stuexen{
214243302Stuexen	int i;
215243302Stuexen	for (i=0; i<length; i++) {
216243302Stuexen		printf("%c", *dat++);
217243302Stuexen	}
218243302Stuexen}
219171572Srrs
220171572Srrsstatic void
221171572Srrsprint_octets(const u_char *dat, u_int length)
222171572Srrs{
223171572Srrs	int i;
224171572Srrs	for (i=0; i<length; i++) {
225243302Stuexen		printf("%02x", *dat++);
226243302Stuexen	}
227171572Srrs}
228171572Srrs
229171572Srrsstatic void
230171572Srrsprint_short(const u_short *dat)
231171572Srrs{
232171572Srrs	printf("%u", ntohs(*dat));
233243302Stuexen}
234243302Stuexen
235243302Stuexenstatic void
236260428Stuexenprint_int(const u_int *dat)
237243302Stuexen{
238171572Srrs	printf("%lu", (u_long)ntohl(*dat));
239228630Stuexen}
240171572Srrs
241243302Stuexen/**********************************/
242243302Stuexen/* AVP-specific print out routines*/
243243302Stuexen/**********************************/
244243302Stuexenstatic void
245243302Stuexenl2tp_msgtype_print(const u_char *dat, u_int length)
246243302Stuexen{
247243302Stuexen	u_short *ptr = (u_short *)dat;
248171572Srrs
249171031Srrs	if (ntohs(*ptr) < L2TP_MAX_MSGTYPE_INDEX) {
250171031Srrs		printf("%s", l2tp_message_type_string[ntohs(*ptr)]);
251228630Stuexen	}
252260428Stuexen}
253260428Stuexen
254260428Stuexenstatic void
255260428Stuexenl2tp_result_code_print(const u_char *dat, u_int length)
256260428Stuexen{
257260428Stuexen	/* we just print out the result and error code number */
258260428Stuexen	u_short *ptr = (u_short *)dat;
259260428Stuexen
260260428Stuexen	if (length == 2) {		/* result code */
261260428Stuexen		printf("%u", ntohs(*ptr));
262260428Stuexen	} else if (length == 4) { 	/* result & error code */
263260428Stuexen		printf("%u/%u", ntohs(*ptr), ntohs(*(ptr+1)));
264260428Stuexen	} else if (length > 4) {	/* result & error code & msg */
265260428Stuexen		printf("%u/%u ", ntohs(*ptr), ntohs(*(ptr+1)));
266260428Stuexen		print_string((u_char *)(ptr+2), length - 4);
267260428Stuexen	}
268260428Stuexen}
269171031Srrs
270171031Srrsstatic void
271165242Srrsl2tp_proto_ver_print(const u_char *dat, u_int length)
272165242Srrs{
273165242Srrs	printf("%d.%d", *dat, *(dat+1));
274228630Stuexen}
275165242Srrs
276165242Srrs
277165242Srrsstatic void
278165242Srrsl2tp_framing_cap_print(const u_char *dat, u_int length)
279165242Srrs{
280165242Srrs	u_int *ptr = (u_int *)dat;
281165242Srrs
282165242Srrs	if (ntohl(*ptr) &  L2TP_FRAMING_CAP_ASYNC_MASK) {
283165242Srrs		printf("A");
284171152Srrs	}
285171152Srrs	if (ntohl(*ptr) &  L2TP_FRAMING_CAP_SYNC_MASK) {
286165242Srrs		printf("S");
287253105Stuexen	}
288253105Stuexen}
289253105Stuexen
290253105Stuexenstatic void
291253105Stuexenl2tp_bearer_cap_print(const u_char *dat, u_int length)
292171572Srrs{
293171572Srrs	u_int *ptr = (u_int *)dat;
294171572Srrs
295171572Srrs	if (ntohl(*ptr) &  L2TP_BEARER_CAP_ANALOG_MASK) {
296171572Srrs		printf("A");
297171572Srrs	}
298171572Srrs	if (ntohl(*ptr) &  L2TP_BEARER_CAP_DIGITAL_MASK) {
299171572Srrs		printf("D");
300171572Srrs	}
301171572Srrs}
302171572Srrs
303171572Srrsstatic void
304171572Srrsl2tp_tie_breaker_print(const u_char *dat, u_int length)
305171572Srrs{
306171572Srrs	printf("%lx", *(u_long *)dat);	/* XXX */
307171572Srrs}
308171572Srrs
309171572Srrsstatic void
310171572Srrsl2tp_firm_ver_print(const u_char *dat, u_int length)
311171572Srrs{
312171572Srrs	print_short((u_short *)dat);
313171572Srrs}
314171572Srrs
315171572Srrsstatic void
316171572Srrsl2tp_host_name_print(const u_char *dat, u_int length)
317171572Srrs{
318171572Srrs	print_string(dat, length);
319171572Srrs}
320171572Srrs
321171572Srrsstatic void
322171572Srrsl2tp_vendor_name_print(const u_char *dat, u_int length)
323171572Srrs{
324171572Srrs	print_string(dat, length);
325171572Srrs}
326171572Srrs
327171572Srrsstatic void
328171572Srrsl2tp_assnd_tun_id_print(const u_char *dat, u_int length)
329171572Srrs{
330171572Srrs	print_short((u_short *)dat);
331171572Srrs}
332171572Srrs
333171572Srrsstatic void
334171572Srrsl2tp_recv_win_size_print(const u_char *dat, u_int length)
335221512Stuexen{
336221512Stuexen	print_short((u_short *)dat);
337221512Stuexen}
338223132Stuexen
339223132Stuexenstatic void
340223132Stuexenl2tp_challenge_print(const u_char *dat, u_int length)
341223178Stuexen{
342223178Stuexen	print_octets(dat, length);
343223178Stuexen}
344223178Stuexen
345223178Stuexenstatic void
346223178Stuexenl2tp_q931_cc_print(const u_char *dat, u_int length)
347224641Stuexen{
348224641Stuexen	print_short((u_short *)dat);
349224641Stuexen	printf(", %02x", dat[2]);
350227755Stuexen	if (length > 3) {
351227755Stuexen		printf(" ");
352227755Stuexen		print_string(dat+3, length-3);
353270356Stuexen	}
354270356Stuexen}
355270356Stuexen
356270357Stuexenstatic void
357270357Stuexenl2tp_challenge_resp_print(const u_char *dat, u_int length)
358270357Stuexen{
359270362Stuexen	print_octets(dat, 16);		/* XXX length should be 16? */
360270362Stuexen}
361270362Stuexen
362270362Stuexenstatic void
363270362Stuexenl2tp_assnd_sess_id_print(const u_char *dat, u_int length)
364270362Stuexen{
365270361Stuexen	print_short((u_short *)dat);
366270361Stuexen}
367270361Stuexen
368270359Stuexenstatic void
369270359Stuexenl2tp_call_ser_num_print(const u_char *dat, u_int length)
370270359Stuexen{
371270360Stuexen	print_int((u_int *)dat);
372270360Stuexen}
373270360Stuexen
374223180Stuexenstatic void
375223180Stuexenl2tp_minimum_bps_print(const u_char *dat, u_int length)
376223180Stuexen{
377253104Stuexen	print_int((u_int *)dat);
378253104Stuexen}
379253104Stuexen
380270363Stuexenstatic void
381270363Stuexenl2tp_maximum_bps_print(const u_char *dat, u_int length)
382270363Stuexen{
383270363Stuexen	print_int((u_int *)dat);
384270363Stuexen}
385270363Stuexen
386283724Stuexenstatic void
387283724Stuexenl2tp_bearer_type_print(const u_char *dat, u_int length)
388283724Stuexen{
389171572Srrs	u_int *ptr = (u_int *)dat;
390171572Srrs
391171572Srrs	if (ntohl(*ptr) &  L2TP_BEARER_TYPE_ANALOG_MASK) {
392169623Srrs		printf("A");
393165242Srrs	}
394165242Srrs	if (ntohl(*ptr) &  L2TP_BEARER_TYPE_DIGITAL_MASK) {
395165242Srrs		printf("D");
396165242Srrs	}
397165242Srrs}
398165242Srrs
399165242Srrsstatic void
400165242Srrsl2tp_framing_type_print(const u_char *dat, u_int length)
401165242Srrs{
402228630Stuexen	u_int *ptr = (u_int *)dat;
403165242Srrs
404165242Srrs	if (ntohl(*ptr) &  L2TP_FRAMING_TYPE_ASYNC_MASK) {
405165242Srrs		printf("A");
406165242Srrs	}
407165242Srrs	if (ntohl(*ptr) &  L2TP_FRAMING_TYPE_SYNC_MASK) {
408165242Srrs		printf("S");
409165242Srrs	}
410228630Stuexen}
411165242Srrs
412228630Stuexenstatic void
413165242Srrsl2tp_packet_proc_delay_print(const u_char *dat, u_int length)
414165242Srrs{
415165242Srrs	printf("obsolete");
416228630Stuexen}
417228630Stuexen
418165242Srrsstatic void
419242512Stuexenl2tp_called_number_print(const u_char *dat, u_int length)
420165242Srrs{
421165242Srrs	print_string(dat, length);
422165242Srrs}
423165242Srrs
424165242Srrsstatic void
425228630Stuexenl2tp_calling_number_print(const u_char *dat, u_int length)
426165242Srrs{
427165242Srrs	print_string(dat, length);
428165242Srrs}
429228630Stuexen
430165242Srrsstatic void
431165242Srrsl2tp_sub_address_print(const u_char *dat, u_int length)
432228630Stuexen{
433165242Srrs	print_string(dat, length);
434165242Srrs}
435165242Srrs
436165242Srrsstatic void
437165242Srrsl2tp_tx_conn_speed_print(const u_char *dat, u_int length)
438165242Srrs{
439165242Srrs	print_int((u_int *)dat);
440167598Srrs}
441165242Srrs
442165242Srrsstatic void
443165242Srrsl2tp_phy_channel_id_print(const u_char *dat, u_int length)
444165242Srrs{
445249333Stuexen	print_int((u_int *)dat);
446165242Srrs}
447165242Srrs
448165242Srrsstatic void
449165242Srrsl2tp_ini_recv_lcp_print(const u_char *dat, u_int length)
450165242Srrs{
451165242Srrs	print_octets(dat, length);
452165242Srrs}
453165242Srrs
454165242Srrsstatic void
455165242Srrsl2tp_last_sent_lcp_print(const u_char *dat, u_int length)
456165242Srrs{
457228630Stuexen	print_octets(dat, length);
458228630Stuexen}
459165242Srrs
460165242Srrsstatic void
461165242Srrsl2tp_last_recv_lcp_print(const u_char *dat, u_int length)
462165242Srrs{
463165242Srrs	print_octets(dat, length);
464165242Srrs}
465165242Srrs
466228630Stuexenstatic void
467165242Srrsl2tp_proxy_auth_type_print(const u_char *dat, u_int length)
468228630Stuexen{
469165242Srrs	u_short *ptr = (u_short *)dat;
470165242Srrs
471165242Srrs	switch (ntohs(*ptr)) {
472165242Srrs	case L2TP_AUTHEN_TYPE_RESERVED:
473165242Srrs		printf("Reserved");
474165242Srrs		break;
475165242Srrs	case L2TP_AUTHEN_TYPE_TEXTUAL:
476228630Stuexen		printf("Textual");
477228630Stuexen		break;
478228630Stuexen	case L2TP_AUTHEN_TYPE_CHAP:
479228630Stuexen		printf("CHAP");
480165242Srrs		break;
481165242Srrs	case L2TP_AUTHEN_TYPE_PAP:
482165242Srrs		printf("PAP");
483165242Srrs		break;
484165242Srrs	case L2TP_AUTHEN_TYPE_NO_AUTH:
485165242Srrs		printf("No Auth");
486165242Srrs		break;
487228630Stuexen	case L2TP_AUTHEN_TYPE_MSCHAP:
488165242Srrs		printf("MS-CHAP");
489165242Srrs		break;
490165242Srrs	default:
491165242Srrs		printf("unknown");
492228630Stuexen	}
493165242Srrs}
494165242Srrs
495228630Stuexenstatic void
496165242Srrsl2tp_proxy_auth_name_print(const u_char *dat, u_int length)
497165242Srrs{
498165242Srrs	print_octets(dat, length);
499165242Srrs}
500165242Srrs
501165242Srrsstatic void
502165242Srrsl2tp_proxy_auth_chal_print(const u_char *dat, u_int length)
503167598Srrs{
504165242Srrs	print_octets(dat, length);
505165242Srrs}
506165242Srrs
507165242Srrsstatic void
508249333Stuexenl2tp_proxy_auth_id_print(const u_char *dat, u_int length)
509165242Srrs{
510165242Srrs	u_short *ptr = (u_short *)dat;
511165242Srrs
512165242Srrs	printf("%u", ntohs(*ptr) & L2TP_PROXY_AUTH_ID_MASK);
513165242Srrs}
514165242Srrs
515165242Srrsstatic void
516165242Srrsl2tp_proxy_auth_resp_print(const u_char *dat, u_int length)
517165242Srrs{
518165242Srrs	print_octets(dat, length);
519169623Srrs}
520209684Sbrucec
521209684Sbrucecstatic void
522209684Sbrucecl2tp_call_errors_print(const u_char *dat, u_int length)
523209684Sbrucec{
524209684Sbrucec	struct l2tp_call_errors *ptr = (struct l2tp_call_errors *)dat;
525165242Srrs
526165242Srrs	printf("CRCErr=%d FrameErr=%d HardOver=%d BufOver=%d ",
527165242Srrs	       ptr->crc_errs,
528165242Srrs	       ptr->framing_errs,
529228531Stuexen	       ptr->hardware_overruns,
530165242Srrs	       ptr->buffer_overruns);
531165242Srrs	printf("Timeout=%d AlingErr=%d",
532165242Srrs	       ptr->timeout_errs,
533165242Srrs	       ptr->alignment_errs);
534165242Srrs}
535165242Srrs
536165242Srrsstatic void
537165242Srrsl2tp_accm_print(const u_char *dat, u_int length)
538165242Srrs{
539165242Srrs	struct l2tp_accm *ptr = (struct l2tp_accm *)dat;
540249333Stuexen
541221512Stuexen	printf("send=%x recv=%x", ptr->send_accm, ptr->recv_accm);
542249333Stuexen}
543165242Srrs
544165242Srrsstatic void
545165242Srrsl2tp_random_vector_print(const u_char *dat, u_int length)
546165242Srrs{
547165242Srrs	print_octets(dat, length);
548165242Srrs}
549165242Srrs
550221512Stuexenstatic void
551221512Stuexenl2tp_private_grp_id_print(const u_char *dat, u_int length)
552169623Srrs{
553246629Stuexen	print_string(dat, length);
554169623Srrs	/* XXX print_octets is more appropriate?? */
555249333Stuexen}
556249333Stuexen
557249333Stuexenstatic void
558169623Srrsl2tp_rx_conn_speed_print(const u_char *dat, u_int length)
559169623Srrs{
560246629Stuexen	print_int((u_int *)dat);
561165242Srrs}
562221512Stuexen
563221512Stuexenstatic void
564169623Srrsl2tp_seq_required_print(const u_char *dat, u_int length)
565246629Stuexen{
566169623Srrs	return;
567169623Srrs}
568169623Srrs
569249333Stuexenstatic void
570249333Stuexenl2tp_avp_print(const u_char *dat, u_int length)
571169623Srrs{
572169623Srrs	u_int len;
573246629Stuexen	const u_short *ptr = (u_short *)dat;
574169623Srrs	int hidden = FALSE;
575221512Stuexen
576221512Stuexen	printf(" ");
577169623Srrs	if (length > 0 && (snapend - dat) >= 2) {
578246629Stuexen		/* there must be at least two octets for the length
579169623Srrs		   to be decoded */
580169623Srrs		if ((len = (ntohs(*ptr) & L2TP_AVP_HDR_LEN_MASK)) <=
581169623Srrs		    (snapend - dat)) {
582249333Stuexen			if (ntohs(*ptr) & L2TP_AVP_HDR_FLAG_MANDATORY) {
583249333Stuexen				printf("*");
584169623Srrs			}
585246629Stuexen			if (ntohs(*ptr) & L2TP_AVP_HDR_FLAG_HIDDEN) {
586165242Srrs				hidden = TRUE;
587165242Srrs				printf("?");
588165242Srrs			}
589221512Stuexen		} else {
590221512Stuexen			printf("|...");
591165242Srrs			return;
592169623Srrs		}
593165242Srrs		ptr++;
594165242Srrs
595165242Srrs		if (ntohs(*ptr)) {	/* IETF == 0 */
596165242Srrs			printf("vendor=%04x", ntohs(*ptr));
597165242Srrs		}
598165242Srrs		ptr++;
599221512Stuexen
600165242Srrs		if (ntohs(*ptr) < L2TP_MAX_AVP_INDEX) {
601249333Stuexen			printf("%s", l2tp_avp[ntohs(*ptr)].name);
602249333Stuexen			printf("(");
603283702Stuexen			if (!hidden) {
604249333Stuexen				(l2tp_avp[ntohs(*ptr)].print)
605165242Srrs					((u_char *)ptr+2, len-6);
606165242Srrs			} else {
607165242Srrs				printf("???");
608249333Stuexen			}
609270362Stuexen			printf(")");
610249333Stuexen		} else {
611249333Stuexen			printf(" invalid AVP %u", ntohs(*ptr));
612249333Stuexen		}
613249333Stuexen
614249333Stuexen		l2tp_avp_print(dat + len, length - len);
615249333Stuexen	} else if (length == 0) {
616249333Stuexen		return;
617249333Stuexen	} else {
618165242Srrs		printf("|...");
619165242Srrs	}
620165242Srrs}
621165242Srrs
622165242Srrs
623165242Srrsvoid
624165242Srrsl2tp_print(const u_char *dat, u_int length)
625171440Srrs{
626165270Srodrigc	const u_short *ptr = (u_short *)dat;
627165242Srrs	u_int cnt = 0;			/* total octets consumed */
628165242Srrs	u_short pad;
629171440Srrs	int flag_t, flag_l, flag_s, flag_o, flag_p;
630165242Srrs	u_short l2tp_len;
631171440Srrs
632165242Srrs	flag_t = flag_l = flag_s = flag_o = flag_p = FALSE;
633171440Srrs
634249333Stuexen	if (min(length, snapend - dat) - 6 < 0) {
635165242Srrs		/* flag/ver, tunnel_id, session_id must be present for
636165242Srrs		   this packet to be properly decoded */
637171440Srrs		printf("%s", tstr);
638165242Srrs		return;
639165242Srrs	}
640165242Srrs
641165242Srrs	if ((ntohs(*ptr) & L2TP_VERSION_MASK) == L2TP_VERSION_L2TP) {
642165242Srrs		printf(" l2tp:");
643165242Srrs	} else if ((ntohs(*ptr) & L2TP_VERSION_MASK) == L2TP_VERSION_L2F) {
644165242Srrs		printf(" l2f:");
645165242Srrs		return;		/* nothing to do */
646165242Srrs	} else {
647165242Srrs		printf(" Unknown Version, neither L2F(1) nor L2TP(2)");
648165242Srrs		return;		/* nothing we can do */
649165242Srrs	}
650165242Srrs
651165242Srrs	printf("[");
652165242Srrs	if (ntohs(*ptr) & L2TP_FLAG_TYPE) {
653221512Stuexen		flag_t = TRUE;
654249333Stuexen		printf("T");
655165242Srrs	}
656165242Srrs	if (ntohs(*ptr) & L2TP_FLAG_LENGTH) {
657165242Srrs		flag_l = TRUE;
658171440Srrs		printf("L");
659171440Srrs	}
660165242Srrs	if (ntohs(*ptr) & L2TP_FLAG_SEQUENCE) {
661221512Stuexen		flag_s = TRUE;
662221512Stuexen		printf("S");
663165242Srrs	}
664249333Stuexen	if (ntohs(*ptr) & L2TP_FLAG_OFFSET) {
665165242Srrs		flag_o = TRUE;
666221512Stuexen		printf("O");
667165242Srrs	}
668249333Stuexen	if (ntohs(*ptr) & L2TP_FLAG_PRIORITY) {
669249333Stuexen		flag_p = TRUE;
670283702Stuexen		printf("P");
671249333Stuexen	}
672165242Srrs	printf("]");
673165242Srrs
674165242Srrs	ptr++;
675249333Stuexen	cnt += 2;
676249333Stuexen
677165242Srrs	if (flag_l) {
678165242Srrs		l2tp_len = ntohs(*ptr++);	/* XXX need to consider
679165242Srrs						   truncation ?? */
680165242Srrs		cnt += 2;
681165242Srrs	} else {
682165242Srrs		l2tp_len = 0;
683165242Srrs	}
684165242Srrs
685165242Srrs	printf("(%u/", ntohs(*ptr++));		/* Tunnel ID */
686165242Srrs	printf("%u)",  ntohs(*ptr++));		/* Session ID */
687165242Srrs	cnt += 4;
688209760Srrs
689165242Srrs	if (flag_s) {
690165242Srrs		printf("Ns=%u,", ntohs(*ptr++));
691165242Srrs		printf("Nr=%u",  ntohs(*ptr++));
692228630Stuexen		cnt += 4;
693228630Stuexen	}
694165242Srrs
695165242Srrs	if (flag_o) {
696171572Srrs		pad =  ntohs(*ptr++);
697171572Srrs		ptr += pad / sizeof(*ptr);
698171572Srrs		cnt += (2 + pad);
699171572Srrs	}
700166884Srrs
701221512Stuexen	if (flag_t) {
702166884Srrs		if (length - cnt == 0) {
703166884Srrs			printf(" ZLB");
704166884Srrs		} else {
705166884Srrs			l2tp_avp_print((u_char *)ptr, length - cnt);
706166884Srrs		}
707166884Srrs	} else {
708166884Srrs#if 0
709166884Srrs		printf(" {");
710166884Srrs		ppp_hdlc_print((u_char *)ptr, length - cnt);
711166884Srrs		printf("}");
712166884Srrs#else
713171440Srrs		printf("[hdlc|]");
714165242Srrs#endif
715165242Srrs	}
716165242Srrs}
717165242Srrs