print-l2tp.c revision 75115
156893Sfenner/*
256893Sfenner * Copyright (c) 1991, 1993, 1994, 1995, 1996, 1997
356893Sfenner *      The Regents of the University of California.  All rights reserved.
456893Sfenner *
556893Sfenner * Redistribution and use in source and binary forms, with or without
656893Sfenner * modification, are permitted provided that: (1) source code distributions
756893Sfenner * retain the above copyright notice and this paragraph in its entirety, (2)
856893Sfenner * distributions including binary code include the above copyright notice and
956893Sfenner * this paragraph in its entirety in the documentation or other materials
1056893Sfenner * provided with the distribution, and (3) all advertising materials mentioning
1156893Sfenner * features or use of this software display the following acknowledgement:
1256893Sfenner * ``This product includes software developed by the University of California,
1356893Sfenner * Lawrence Berkeley Laboratory and its contributors.'' Neither the name of
1456893Sfenner * the University nor the names of its contributors may be used to endorse
1556893Sfenner * or promote products derived from this software without specific prior
1656893Sfenner * written permission.
1756893Sfenner * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR IMPLIED
1856893Sfenner * WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF
1956893Sfenner * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
2056893Sfenner *
2175115Sfenner * L2TP support contributed by Motonori Shindo (mshindo@mshindo.net)
2256893Sfenner */
2356893Sfenner
2456893Sfenner#ifndef lint
2556893Sfennerstatic const char rcsid[] =
2675115Sfenner    "@(#) $Header: /tcpdump/master/tcpdump/print-l2tp.c,v 1.8 2000/08/18 07:44:46 itojun Exp $";
2756893Sfenner#endif
2856893Sfenner
2956893Sfenner#ifdef HAVE_CONFIG_H
3056893Sfenner#include "config.h"
3156893Sfenner#endif
3256893Sfenner
3356893Sfenner#include <stdio.h>
3456893Sfenner#include <sys/types.h>
3556893Sfenner#include <sys/param.h>
3656893Sfenner#include <netinet/in.h>
3756893Sfenner#include <arpa/inet.h>
3856893Sfenner
3956893Sfenner#include "l2tp.h"
4056893Sfenner#include "interface.h"
4156893Sfenner
4256893Sfennerstatic char tstr[] = " [|l2tp]";
4356893Sfenner
4456893Sfenner#ifndef TRUE
4556893Sfenner#define TRUE 1
4656893Sfenner#endif
4756893Sfenner
4856893Sfenner#ifndef FALSE
4956893Sfenner#define FALSE 0
5056893Sfenner#endif
5156893Sfenner
5256893Sfennerstatic char *l2tp_message_type_string[] = {
5356893Sfenner	"RESERVED_0",		/* 0  Reserved */
5456893Sfenner	"SCCRQ",		/* 1  Start-Control-Connection-Request */
5556893Sfenner	"SCCRP",		/* 2  Start-Control-Connection-Reply */
5656893Sfenner	"SCCCN",		/* 3  Start-Control-Connection-Connected */
5756893Sfenner	"StopCCN",		/* 4  Stop-Control-Connection-Notification */
5856893Sfenner	"RESERVED_5",		/* 5  Reserved */
5956893Sfenner	"HELLO",		/* 6  Hello */
6056893Sfenner	"OCRQ",			/* 7  Outgoing-Call-Request */
6156893Sfenner	"OCRP",			/* 8  Outgoing-Call-Reply */
6256893Sfenner	"OCCN",			/* 9  Outgoing-Call-Connected */
6356893Sfenner	"ICRQ",			/* 10 Incoming-Call-Request */
6456893Sfenner	"ICRP",			/* 11 Incoming-Call-Reply */
6556893Sfenner	"ICCN",			/* 12 Incoming-Call-Connected */
6656893Sfenner	"RESERVED_13",		/* 13 Reserved */
6756893Sfenner	"CDN",			/* 14 Call-Disconnect-Notify */
6856893Sfenner	"WEN",			/* 15 WAN-Error-Notify */
6956893Sfenner	"SLI"			/* 16 Set-Link-Info */
7056893Sfenner#define L2TP_MAX_MSGTYPE_INDEX	17
7156893Sfenner};
7256893Sfenner
7356893Sfennerstatic void l2tp_msgtype_print(const u_char *dat, u_int length);
7456893Sfennerstatic void l2tp_result_code_print(const u_char *dat, u_int length);
7556893Sfennerstatic void l2tp_proto_ver_print(const u_char *dat, u_int length);
7656893Sfennerstatic void l2tp_framing_cap_print(const u_char *dat, u_int length);
7756893Sfennerstatic void l2tp_bearer_cap_print(const u_char *dat, u_int length);
7856893Sfennerstatic void l2tp_tie_breaker_print(const u_char *dat, u_int length);
7956893Sfennerstatic void l2tp_firm_ver_print(const u_char *dat, u_int length);
8056893Sfennerstatic void l2tp_host_name_print(const u_char *dat, u_int length);
8156893Sfennerstatic void l2tp_vendor_name_print(const u_char *dat, u_int length);
8256893Sfennerstatic void l2tp_assnd_tun_id_print(const u_char *dat, u_int length);
8356893Sfennerstatic void l2tp_recv_win_size_print(const u_char *dat, u_int length);
8456893Sfennerstatic void l2tp_challenge_print(const u_char *dat, u_int length);
8556893Sfennerstatic void l2tp_q931_cc_print(const u_char *dat, u_int length);
8656893Sfennerstatic void l2tp_challenge_resp_print(const u_char *dat, u_int length);
8756893Sfennerstatic void l2tp_assnd_sess_id_print(const u_char *dat, u_int length);
8856893Sfennerstatic void l2tp_call_ser_num_print(const u_char *dat, u_int length);
8956893Sfennerstatic void l2tp_minimum_bps_print(const u_char *dat, u_int length);
9056893Sfennerstatic void l2tp_maximum_bps_print(const u_char *dat, u_int length);
9156893Sfennerstatic void l2tp_bearer_type_print(const u_char *dat, u_int length);
9256893Sfennerstatic void l2tp_framing_type_print(const u_char *dat, u_int length);
9356893Sfennerstatic void l2tp_packet_proc_delay_print(const u_char *dat, u_int length);
9456893Sfennerstatic void l2tp_called_number_print(const u_char *dat, u_int length);
9556893Sfennerstatic void l2tp_calling_number_print(const u_char *dat, u_int length);
9656893Sfennerstatic void l2tp_sub_address_print(const u_char *dat, u_int length);
9756893Sfennerstatic void l2tp_tx_conn_speed_print(const u_char *dat, u_int length);
9856893Sfennerstatic void l2tp_phy_channel_id_print(const u_char *dat, u_int length);
9956893Sfennerstatic void l2tp_ini_recv_lcp_print(const u_char *dat, u_int length);
10056893Sfennerstatic void l2tp_last_sent_lcp_print(const u_char *dat, u_int length);
10156893Sfennerstatic void l2tp_last_recv_lcp_print(const u_char *dat, u_int length);
10256893Sfennerstatic void l2tp_proxy_auth_type_print(const u_char *dat, u_int length);
10356893Sfennerstatic void l2tp_proxy_auth_name_print(const u_char *dat, u_int length);
10456893Sfennerstatic void l2tp_proxy_auth_chal_print(const u_char *dat, u_int length);
10556893Sfennerstatic void l2tp_proxy_auth_id_print(const u_char *dat, u_int length);
10656893Sfennerstatic void l2tp_proxy_auth_resp_print(const u_char *dat, u_int length);
10756893Sfennerstatic void l2tp_call_errors_print(const u_char *dat, u_int length);
10856893Sfennerstatic void l2tp_accm_print(const u_char *dat, u_int length);
10956893Sfennerstatic void l2tp_random_vector_print(const u_char *dat, u_int length);
11056893Sfennerstatic void l2tp_private_grp_id_print(const u_char *dat, u_int length);
11156893Sfennerstatic void l2tp_rx_conn_speed_print(const u_char *dat, u_int length);
11256893Sfennerstatic void l2tp_seq_required_print(const u_char *dat, u_int length);
11356893Sfennerstatic void l2tp_avp_print(const u_char *dat, u_int length);
11456893Sfenner
11556893Sfennerstatic struct l2tp_avp_vec l2tp_avp[] = {
11656893Sfenner  {"MSGTYPE", l2tp_msgtype_print}, 		/* 0  Message Type */
11756893Sfenner  {"RESULT_CODE", l2tp_result_code_print},	/* 1  Result Code */
11856893Sfenner  {"PROTO_VER", l2tp_proto_ver_print},		/* 2  Protocol Version */
11956893Sfenner  {"FRAMING_CAP", l2tp_framing_cap_print},	/* 3  Framing Capabilities */
12056893Sfenner  {"BEARER_CAP", l2tp_bearer_cap_print},	/* 4  Bearer Capabilities */
12156893Sfenner  {"TIE_BREAKER", l2tp_tie_breaker_print},	/* 5  Tie Breaker */
12256893Sfenner  {"FIRM_VER", l2tp_firm_ver_print},		/* 6  Firmware Revision */
12356893Sfenner  {"HOST_NAME", l2tp_host_name_print},		/* 7  Host Name */
12456893Sfenner  {"VENDOR_NAME", l2tp_vendor_name_print},	/* 8  Vendor Name */
12556893Sfenner  {"ASSND_TUN_ID", l2tp_assnd_tun_id_print}, 	/* 9  Assigned Tunnel ID */
12656893Sfenner  {"RECV_WIN_SIZE", l2tp_recv_win_size_print},	/* 10 Receive Window Size */
12756893Sfenner  {"CHALLENGE", l2tp_challenge_print},		/* 11 Challenge */
12856893Sfenner  {"Q931_CC", l2tp_q931_cc_print},		/* 12 Q.931 Cause Code */
12956893Sfenner  {"CHALLENGE_RESP", l2tp_challenge_resp_print},/* 13 Challenge Response */
13056893Sfenner  {"ASSND_SESS_ID", l2tp_assnd_sess_id_print},  /* 14 Assigned Session ID */
13156893Sfenner  {"CALL_SER_NUM", l2tp_call_ser_num_print}, 	/* 15 Call Serial Number */
13256893Sfenner  {"MINIMUM_BPS",	l2tp_minimum_bps_print},/* 16 Minimum BPS */
13356893Sfenner  {"MAXIMUM_BPS", l2tp_maximum_bps_print},	/* 17 Maximum BPS */
13456893Sfenner  {"BEARER_TYPE",	l2tp_bearer_type_print},/* 18 Bearer Type */
13556893Sfenner  {"FRAMING_TYPE", l2tp_framing_type_print}, 	/* 19 Framing Type */
13656893Sfenner  {"PACKET_PROC_DELAY", l2tp_packet_proc_delay_print}, /* 20 Packet Processing Delay (OBSOLETE) */
13756893Sfenner  {"CALLED_NUMBER", l2tp_called_number_print},	/* 21 Called Number */
13856893Sfenner  {"CALLING_NUMBER", l2tp_calling_number_print},/* 22 Calling Number */
13956893Sfenner  {"SUB_ADDRESS",	l2tp_sub_address_print},/* 23 Sub-Address */
14056893Sfenner  {"TX_CONN_SPEED", l2tp_tx_conn_speed_print},	/* 24 (Tx) Connect Speed */
14156893Sfenner  {"PHY_CHANNEL_ID", l2tp_phy_channel_id_print},/* 25 Physical Channel ID */
14256893Sfenner  {"INI_RECV_LCP", l2tp_ini_recv_lcp_print}, 	/* 26 Initial Received LCP CONFREQ */
14356893Sfenner  {"LAST_SENT_LCP", l2tp_last_sent_lcp_print},	/* 27 Last Sent LCP CONFREQ */
14456893Sfenner  {"LAST_RECV_LCP", l2tp_last_recv_lcp_print},	/* 28 Last Received LCP CONFREQ */
14556893Sfenner  {"PROXY_AUTH_TYPE", l2tp_proxy_auth_type_print},/* 29 Proxy Authen Type */
14656893Sfenner  {"PROXY_AUTH_NAME", l2tp_proxy_auth_name_print},/* 30 Proxy Authen Name */
14756893Sfenner  {"PROXY_AUTH_CHAL", l2tp_proxy_auth_chal_print},/* 31 Proxy Authen Challenge */
14856893Sfenner  {"PROXY_AUTH_ID", l2tp_proxy_auth_id_print},	/* 32 Proxy Authen ID */
14956893Sfenner  {"PROXY_AUTH_RESP", l2tp_proxy_auth_resp_print},/* 33 Proxy Authen Response */
15056893Sfenner  {"CALL_ERRORS", l2tp_call_errors_print},	/* 34 Call Errors */
15156893Sfenner  {"ACCM", l2tp_accm_print},			/* 35 ACCM */
15256893Sfenner  {"RANDOM_VECTOR", l2tp_random_vector_print},	/* 36 Random Vector */
15356893Sfenner  {"PRIVATE_GRP_ID", l2tp_private_grp_id_print},/* 37 Private Group ID */
15456893Sfenner  {"RX_CONN_SPEED", l2tp_rx_conn_speed_print},	/* 38 (Rx) Connect Speed */
15556893Sfenner  {"SEQ_REQUIRED", l2tp_seq_required_print}, 	/* 39 Sequencing Required */
15656893Sfenner#define L2TP_MAX_AVP_INDEX	40
15756893Sfenner};
15856893Sfenner
15956893Sfenner#if 0
16056893Sfennerstatic char *l2tp_result_code_StopCCN[] = {
16156893Sfenner         "Reserved",
16256893Sfenner         "General request to clear control connection",
16356893Sfenner         "General error--Error Code indicates the problem",
16456893Sfenner         "Control channel already exists",
16556893Sfenner         "Requester is not authorized to establish a control channel",
16656893Sfenner         "The protocol version of the requester is not supported",
16756893Sfenner         "Requester is being shut down",
16856893Sfenner         "Finite State Machine error"
16956893Sfenner#define L2TP_MAX_RESULT_CODE_STOPCC_INDEX	8
17056893Sfenner};
17156893Sfenner#endif
17256893Sfenner
17356893Sfenner#if 0
17456893Sfennerstatic char *l2tp_result_code_CDN[] = {
17556893Sfenner	"Reserved",
17656893Sfenner	"Call disconnected due to loss of carrier",
17756893Sfenner	"Call disconnected for the reason indicated in error code",
17856893Sfenner	"Call disconnected for administrative reasons",
17956893Sfenner	"Call failed due to lack of appropriate facilities being " \
18056893Sfenner	"available (temporary condition)",
18156893Sfenner	"Call failed due to lack of appropriate facilities being " \
18256893Sfenner	"available (permanent condition)",
18356893Sfenner	"Invalid destination",
18456893Sfenner	"Call failed due to no carrier detected",
18556893Sfenner	"Call failed due to detection of a busy signal",
18656893Sfenner	"Call failed due to lack of a dial tone",
18756893Sfenner	"Call was not established within time allotted by LAC",
18856893Sfenner	"Call was connected but no appropriate framing was detected"
18956893Sfenner#define L2TP_MAX_RESULT_CODE_CDN_INDEX	12
19056893Sfenner};
19156893Sfenner#endif
19256893Sfenner
19356893Sfenner#if 0
19456893Sfennerstatic char *l2tp_error_code_general[] = {
19556893Sfenner	"No general error",
19656893Sfenner	"No control connection exists yet for this LAC-LNS pair",
19756893Sfenner	"Length is wrong",
19856893Sfenner	"One of the field values was out of range or " \
19956893Sfenner	"reserved field was non-zero"
20056893Sfenner	"Insufficient resources to handle this operation now",
20156893Sfenner	"The Session ID is invalid in this context",
20256893Sfenner	"A generic vendor-specific error occurred in the LAC",
20356893Sfenner	"Try another"
20456893Sfenner#define L2TP_MAX_ERROR_CODE_GENERAL_INDEX	8
20556893Sfenner};
20656893Sfenner#endif
20756893Sfenner
20856893Sfenner/******************************/
20956893Sfenner/* generic print out routines */
21056893Sfenner/******************************/
21156893Sfennerstatic void
21256893Sfennerprint_string(const u_char *dat, u_int length)
21356893Sfenner{
21456893Sfenner	int i;
21556893Sfenner	for (i=0; i<length; i++) {
21656893Sfenner		printf("%c", *dat++);
21756893Sfenner	}
21856893Sfenner}
21956893Sfenner
22056893Sfennerstatic void
22156893Sfennerprint_octets(const u_char *dat, u_int length)
22256893Sfenner{
22356893Sfenner	int i;
22456893Sfenner	for (i=0; i<length; i++) {
22556893Sfenner		printf("%02x", *dat++);
22656893Sfenner	}
22756893Sfenner}
22856893Sfenner
22956893Sfennerstatic void
23056893Sfennerprint_short(const u_short *dat)
23156893Sfenner{
23256893Sfenner	printf("%u", ntohs(*dat));
23356893Sfenner}
23456893Sfenner
23556893Sfennerstatic void
23656893Sfennerprint_int(const u_int *dat)
23756893Sfenner{
23856893Sfenner	printf("%lu", (u_long)ntohl(*dat));
23956893Sfenner}
24056893Sfenner
24156893Sfenner/**********************************/
24256893Sfenner/* AVP-specific print out routines*/
24356893Sfenner/**********************************/
24456893Sfennerstatic void
24556893Sfennerl2tp_msgtype_print(const u_char *dat, u_int length)
24656893Sfenner{
24756893Sfenner	u_short *ptr = (u_short *)dat;
24856893Sfenner
24956893Sfenner	if (ntohs(*ptr) < L2TP_MAX_MSGTYPE_INDEX) {
25056893Sfenner		printf("%s", l2tp_message_type_string[ntohs(*ptr)]);
25156893Sfenner	}
25256893Sfenner}
25356893Sfenner
25456893Sfennerstatic void
25556893Sfennerl2tp_result_code_print(const u_char *dat, u_int length)
25656893Sfenner{
25756893Sfenner	/* we just print out the result and error code number */
25856893Sfenner	u_short *ptr = (u_short *)dat;
25956893Sfenner
26056893Sfenner	if (length == 2) {		/* result code */
26156893Sfenner		printf("%u", ntohs(*ptr));
26256893Sfenner	} else if (length == 4) { 	/* result & error code */
26356893Sfenner		printf("%u/%u", ntohs(*ptr), ntohs(*(ptr+1)));
26456893Sfenner	} else if (length > 4) {	/* result & error code & msg */
26556893Sfenner		printf("%u/%u ", ntohs(*ptr), ntohs(*(ptr+1)));
26656893Sfenner		print_string((u_char *)(ptr+2), length - 4);
26756893Sfenner	}
26856893Sfenner}
26956893Sfenner
27056893Sfennerstatic void
27156893Sfennerl2tp_proto_ver_print(const u_char *dat, u_int length)
27256893Sfenner{
27356893Sfenner	printf("%d.%d", *dat, *(dat+1));
27456893Sfenner}
27556893Sfenner
27656893Sfenner
27756893Sfennerstatic void
27856893Sfennerl2tp_framing_cap_print(const u_char *dat, u_int length)
27956893Sfenner{
28056893Sfenner	u_int *ptr = (u_int *)dat;
28156893Sfenner
28256893Sfenner	if (ntohl(*ptr) &  L2TP_FRAMING_CAP_ASYNC_MASK) {
28356893Sfenner		printf("A");
28456893Sfenner	}
28556893Sfenner	if (ntohl(*ptr) &  L2TP_FRAMING_CAP_SYNC_MASK) {
28656893Sfenner		printf("S");
28756893Sfenner	}
28856893Sfenner}
28956893Sfenner
29056893Sfennerstatic void
29156893Sfennerl2tp_bearer_cap_print(const u_char *dat, u_int length)
29256893Sfenner{
29356893Sfenner	u_int *ptr = (u_int *)dat;
29456893Sfenner
29556893Sfenner	if (ntohl(*ptr) &  L2TP_BEARER_CAP_ANALOG_MASK) {
29656893Sfenner		printf("A");
29756893Sfenner	}
29856893Sfenner	if (ntohl(*ptr) &  L2TP_BEARER_CAP_DIGITAL_MASK) {
29956893Sfenner		printf("D");
30056893Sfenner	}
30156893Sfenner}
30256893Sfenner
30356893Sfennerstatic void
30456893Sfennerl2tp_tie_breaker_print(const u_char *dat, u_int length)
30556893Sfenner{
30675115Sfenner	print_octets(dat, 8);	/* Tie Break Value is 64bits long */
30756893Sfenner}
30856893Sfenner
30956893Sfennerstatic void
31056893Sfennerl2tp_firm_ver_print(const u_char *dat, u_int length)
31156893Sfenner{
31256893Sfenner	print_short((u_short *)dat);
31356893Sfenner}
31456893Sfenner
31556893Sfennerstatic void
31656893Sfennerl2tp_host_name_print(const u_char *dat, u_int length)
31756893Sfenner{
31856893Sfenner	print_string(dat, length);
31956893Sfenner}
32056893Sfenner
32156893Sfennerstatic void
32256893Sfennerl2tp_vendor_name_print(const u_char *dat, u_int length)
32356893Sfenner{
32456893Sfenner	print_string(dat, length);
32556893Sfenner}
32656893Sfenner
32756893Sfennerstatic void
32856893Sfennerl2tp_assnd_tun_id_print(const u_char *dat, u_int length)
32956893Sfenner{
33056893Sfenner	print_short((u_short *)dat);
33156893Sfenner}
33256893Sfenner
33356893Sfennerstatic void
33456893Sfennerl2tp_recv_win_size_print(const u_char *dat, u_int length)
33556893Sfenner{
33656893Sfenner	print_short((u_short *)dat);
33756893Sfenner}
33856893Sfenner
33956893Sfennerstatic void
34056893Sfennerl2tp_challenge_print(const u_char *dat, u_int length)
34156893Sfenner{
34256893Sfenner	print_octets(dat, length);
34356893Sfenner}
34456893Sfenner
34556893Sfennerstatic void
34656893Sfennerl2tp_q931_cc_print(const u_char *dat, u_int length)
34756893Sfenner{
34856893Sfenner	print_short((u_short *)dat);
34956893Sfenner	printf(", %02x", dat[2]);
35056893Sfenner	if (length > 3) {
35156893Sfenner		printf(" ");
35256893Sfenner		print_string(dat+3, length-3);
35356893Sfenner	}
35456893Sfenner}
35556893Sfenner
35656893Sfennerstatic void
35756893Sfennerl2tp_challenge_resp_print(const u_char *dat, u_int length)
35856893Sfenner{
35956893Sfenner	print_octets(dat, 16);		/* XXX length should be 16? */
36056893Sfenner}
36156893Sfenner
36256893Sfennerstatic void
36356893Sfennerl2tp_assnd_sess_id_print(const u_char *dat, u_int length)
36456893Sfenner{
36556893Sfenner	print_short((u_short *)dat);
36656893Sfenner}
36756893Sfenner
36856893Sfennerstatic void
36956893Sfennerl2tp_call_ser_num_print(const u_char *dat, u_int length)
37056893Sfenner{
37156893Sfenner	print_int((u_int *)dat);
37256893Sfenner}
37356893Sfenner
37456893Sfennerstatic void
37556893Sfennerl2tp_minimum_bps_print(const u_char *dat, u_int length)
37656893Sfenner{
37756893Sfenner	print_int((u_int *)dat);
37856893Sfenner}
37956893Sfenner
38056893Sfennerstatic void
38156893Sfennerl2tp_maximum_bps_print(const u_char *dat, u_int length)
38256893Sfenner{
38356893Sfenner	print_int((u_int *)dat);
38456893Sfenner}
38556893Sfenner
38656893Sfennerstatic void
38756893Sfennerl2tp_bearer_type_print(const u_char *dat, u_int length)
38856893Sfenner{
38956893Sfenner	u_int *ptr = (u_int *)dat;
39056893Sfenner
39156893Sfenner	if (ntohl(*ptr) &  L2TP_BEARER_TYPE_ANALOG_MASK) {
39256893Sfenner		printf("A");
39356893Sfenner	}
39456893Sfenner	if (ntohl(*ptr) &  L2TP_BEARER_TYPE_DIGITAL_MASK) {
39556893Sfenner		printf("D");
39656893Sfenner	}
39756893Sfenner}
39856893Sfenner
39956893Sfennerstatic void
40056893Sfennerl2tp_framing_type_print(const u_char *dat, u_int length)
40156893Sfenner{
40256893Sfenner	u_int *ptr = (u_int *)dat;
40356893Sfenner
40456893Sfenner	if (ntohl(*ptr) &  L2TP_FRAMING_TYPE_ASYNC_MASK) {
40556893Sfenner		printf("A");
40656893Sfenner	}
40756893Sfenner	if (ntohl(*ptr) &  L2TP_FRAMING_TYPE_SYNC_MASK) {
40856893Sfenner		printf("S");
40956893Sfenner	}
41056893Sfenner}
41156893Sfenner
41256893Sfennerstatic void
41356893Sfennerl2tp_packet_proc_delay_print(const u_char *dat, u_int length)
41456893Sfenner{
41556893Sfenner	printf("obsolete");
41656893Sfenner}
41756893Sfenner
41856893Sfennerstatic void
41956893Sfennerl2tp_called_number_print(const u_char *dat, u_int length)
42056893Sfenner{
42156893Sfenner	print_string(dat, length);
42256893Sfenner}
42356893Sfenner
42456893Sfennerstatic void
42556893Sfennerl2tp_calling_number_print(const u_char *dat, u_int length)
42656893Sfenner{
42756893Sfenner	print_string(dat, length);
42856893Sfenner}
42956893Sfenner
43056893Sfennerstatic void
43156893Sfennerl2tp_sub_address_print(const u_char *dat, u_int length)
43256893Sfenner{
43356893Sfenner	print_string(dat, length);
43456893Sfenner}
43556893Sfenner
43656893Sfennerstatic void
43756893Sfennerl2tp_tx_conn_speed_print(const u_char *dat, u_int length)
43856893Sfenner{
43956893Sfenner	print_int((u_int *)dat);
44056893Sfenner}
44156893Sfenner
44256893Sfennerstatic void
44356893Sfennerl2tp_phy_channel_id_print(const u_char *dat, u_int length)
44456893Sfenner{
44556893Sfenner	print_int((u_int *)dat);
44656893Sfenner}
44756893Sfenner
44856893Sfennerstatic void
44956893Sfennerl2tp_ini_recv_lcp_print(const u_char *dat, u_int length)
45056893Sfenner{
45156893Sfenner	print_octets(dat, length);
45256893Sfenner}
45356893Sfenner
45456893Sfennerstatic void
45556893Sfennerl2tp_last_sent_lcp_print(const u_char *dat, u_int length)
45656893Sfenner{
45756893Sfenner	print_octets(dat, length);
45856893Sfenner}
45956893Sfenner
46056893Sfennerstatic void
46156893Sfennerl2tp_last_recv_lcp_print(const u_char *dat, u_int length)
46256893Sfenner{
46356893Sfenner	print_octets(dat, length);
46456893Sfenner}
46556893Sfenner
46656893Sfennerstatic void
46756893Sfennerl2tp_proxy_auth_type_print(const u_char *dat, u_int length)
46856893Sfenner{
46956893Sfenner	u_short *ptr = (u_short *)dat;
47056893Sfenner
47156893Sfenner	switch (ntohs(*ptr)) {
47256893Sfenner	case L2TP_AUTHEN_TYPE_RESERVED:
47356893Sfenner		printf("Reserved");
47456893Sfenner		break;
47556893Sfenner	case L2TP_AUTHEN_TYPE_TEXTUAL:
47656893Sfenner		printf("Textual");
47756893Sfenner		break;
47856893Sfenner	case L2TP_AUTHEN_TYPE_CHAP:
47956893Sfenner		printf("CHAP");
48056893Sfenner		break;
48156893Sfenner	case L2TP_AUTHEN_TYPE_PAP:
48256893Sfenner		printf("PAP");
48356893Sfenner		break;
48456893Sfenner	case L2TP_AUTHEN_TYPE_NO_AUTH:
48556893Sfenner		printf("No Auth");
48656893Sfenner		break;
48756893Sfenner	case L2TP_AUTHEN_TYPE_MSCHAP:
48856893Sfenner		printf("MS-CHAP");
48956893Sfenner		break;
49056893Sfenner	default:
49156893Sfenner		printf("unknown");
49256893Sfenner	}
49356893Sfenner}
49456893Sfenner
49556893Sfennerstatic void
49656893Sfennerl2tp_proxy_auth_name_print(const u_char *dat, u_int length)
49756893Sfenner{
49856893Sfenner	print_octets(dat, length);
49956893Sfenner}
50056893Sfenner
50156893Sfennerstatic void
50256893Sfennerl2tp_proxy_auth_chal_print(const u_char *dat, u_int length)
50356893Sfenner{
50456893Sfenner	print_octets(dat, length);
50556893Sfenner}
50656893Sfenner
50756893Sfennerstatic void
50856893Sfennerl2tp_proxy_auth_id_print(const u_char *dat, u_int length)
50956893Sfenner{
51056893Sfenner	u_short *ptr = (u_short *)dat;
51156893Sfenner
51256893Sfenner	printf("%u", ntohs(*ptr) & L2TP_PROXY_AUTH_ID_MASK);
51356893Sfenner}
51456893Sfenner
51556893Sfennerstatic void
51656893Sfennerl2tp_proxy_auth_resp_print(const u_char *dat, u_int length)
51756893Sfenner{
51856893Sfenner	print_octets(dat, length);
51956893Sfenner}
52056893Sfenner
52156893Sfennerstatic void
52256893Sfennerl2tp_call_errors_print(const u_char *dat, u_int length)
52356893Sfenner{
52456893Sfenner	struct l2tp_call_errors *ptr = (struct l2tp_call_errors *)dat;
52556893Sfenner
52656893Sfenner	printf("CRCErr=%d FrameErr=%d HardOver=%d BufOver=%d ",
52756893Sfenner	       ptr->crc_errs,
52856893Sfenner	       ptr->framing_errs,
52956893Sfenner	       ptr->hardware_overruns,
53056893Sfenner	       ptr->buffer_overruns);
53156893Sfenner	printf("Timeout=%d AlingErr=%d",
53256893Sfenner	       ptr->timeout_errs,
53356893Sfenner	       ptr->alignment_errs);
53456893Sfenner}
53556893Sfenner
53656893Sfennerstatic void
53756893Sfennerl2tp_accm_print(const u_char *dat, u_int length)
53856893Sfenner{
53956893Sfenner	struct l2tp_accm *ptr = (struct l2tp_accm *)dat;
54056893Sfenner
54156893Sfenner	printf("send=%x recv=%x", ptr->send_accm, ptr->recv_accm);
54256893Sfenner}
54356893Sfenner
54456893Sfennerstatic void
54556893Sfennerl2tp_random_vector_print(const u_char *dat, u_int length)
54656893Sfenner{
54756893Sfenner	print_octets(dat, length);
54856893Sfenner}
54956893Sfenner
55056893Sfennerstatic void
55156893Sfennerl2tp_private_grp_id_print(const u_char *dat, u_int length)
55256893Sfenner{
55356893Sfenner	print_string(dat, length);
55456893Sfenner	/* XXX print_octets is more appropriate?? */
55556893Sfenner}
55656893Sfenner
55756893Sfennerstatic void
55856893Sfennerl2tp_rx_conn_speed_print(const u_char *dat, u_int length)
55956893Sfenner{
56056893Sfenner	print_int((u_int *)dat);
56156893Sfenner}
56256893Sfenner
56356893Sfennerstatic void
56456893Sfennerl2tp_seq_required_print(const u_char *dat, u_int length)
56556893Sfenner{
56656893Sfenner	return;
56756893Sfenner}
56856893Sfenner
56956893Sfennerstatic void
57056893Sfennerl2tp_avp_print(const u_char *dat, u_int length)
57156893Sfenner{
57256893Sfenner	u_int len;
57356893Sfenner	const u_short *ptr = (u_short *)dat;
57456893Sfenner	int hidden = FALSE;
57556893Sfenner
57656893Sfenner	printf(" ");
57756893Sfenner	if (length > 0 && (snapend - dat) >= 2) {
57856893Sfenner		/* there must be at least two octets for the length
57956893Sfenner		   to be decoded */
58056893Sfenner		if ((len = (ntohs(*ptr) & L2TP_AVP_HDR_LEN_MASK)) <=
58156893Sfenner		    (snapend - dat)) {
58256893Sfenner			if (ntohs(*ptr) & L2TP_AVP_HDR_FLAG_MANDATORY) {
58356893Sfenner				printf("*");
58456893Sfenner			}
58556893Sfenner			if (ntohs(*ptr) & L2TP_AVP_HDR_FLAG_HIDDEN) {
58656893Sfenner				hidden = TRUE;
58756893Sfenner				printf("?");
58856893Sfenner			}
58956893Sfenner		} else {
59056893Sfenner			printf("|...");
59156893Sfenner			return;
59256893Sfenner		}
59356893Sfenner		ptr++;
59456893Sfenner
59575115Sfenner		if (ntohs(*ptr)) {
59675115Sfenner			/* Vendor Specific Attribute */
59775115Sfenner			printf("VENDOR%04x:", ntohs(*ptr));
59875115Sfenner			ptr++;
59975115Sfenner			printf("ATTR%04x", ntohs(*ptr));
60056893Sfenner			printf("(");
60175115Sfenner			print_octets((u_char *)ptr+2, len-6);
60275115Sfenner			printf(")");
60375115Sfenner		} else {
60475115Sfenner			/* IETF-defined Attribute */
60575115Sfenner			ptr++;
60675115Sfenner			if (ntohs(*ptr) < L2TP_MAX_AVP_INDEX) {
60775115Sfenner				printf("%s", l2tp_avp[ntohs(*ptr)].name);
60875115Sfenner				printf("(");
60975115Sfenner				if (!hidden) {
61075115Sfenner					(l2tp_avp[ntohs(*ptr)].print)
61175115Sfenner						((u_char *)ptr+2, len-6);
61275115Sfenner				} else {
61375115Sfenner					printf("???");
61475115Sfenner				}
61575115Sfenner				printf(")");
61656893Sfenner			} else {
61775115Sfenner				printf(" invalid AVP %u", ntohs(*ptr));
61856893Sfenner			}
61956893Sfenner		}
62056893Sfenner
62156893Sfenner		l2tp_avp_print(dat + len, length - len);
62256893Sfenner	} else if (length == 0) {
62356893Sfenner		return;
62456893Sfenner	} else {
62556893Sfenner		printf("|...");
62656893Sfenner	}
62756893Sfenner}
62856893Sfenner
62956893Sfenner
63056893Sfennervoid
63156893Sfennerl2tp_print(const u_char *dat, u_int length)
63256893Sfenner{
63356893Sfenner	const u_short *ptr = (u_short *)dat;
63456893Sfenner	u_int cnt = 0;			/* total octets consumed */
63556893Sfenner	u_short pad;
63656893Sfenner	int flag_t, flag_l, flag_s, flag_o, flag_p;
63756893Sfenner	u_short l2tp_len;
63856893Sfenner
63956893Sfenner	flag_t = flag_l = flag_s = flag_o = flag_p = FALSE;
64056893Sfenner
64156893Sfenner	if (min(length, snapend - dat) - 6 < 0) {
64256893Sfenner		/* flag/ver, tunnel_id, session_id must be present for
64356893Sfenner		   this packet to be properly decoded */
64456893Sfenner		printf("%s", tstr);
64556893Sfenner		return;
64656893Sfenner	}
64756893Sfenner
64856893Sfenner	if ((ntohs(*ptr) & L2TP_VERSION_MASK) == L2TP_VERSION_L2TP) {
64956893Sfenner		printf(" l2tp:");
65056893Sfenner	} else if ((ntohs(*ptr) & L2TP_VERSION_MASK) == L2TP_VERSION_L2F) {
65156893Sfenner		printf(" l2f:");
65256893Sfenner		return;		/* nothing to do */
65356893Sfenner	} else {
65456893Sfenner		printf(" Unknown Version, neither L2F(1) nor L2TP(2)");
65556893Sfenner		return;		/* nothing we can do */
65656893Sfenner	}
65756893Sfenner
65856893Sfenner	printf("[");
65956893Sfenner	if (ntohs(*ptr) & L2TP_FLAG_TYPE) {
66056893Sfenner		flag_t = TRUE;
66156893Sfenner		printf("T");
66256893Sfenner	}
66356893Sfenner	if (ntohs(*ptr) & L2TP_FLAG_LENGTH) {
66456893Sfenner		flag_l = TRUE;
66556893Sfenner		printf("L");
66656893Sfenner	}
66756893Sfenner	if (ntohs(*ptr) & L2TP_FLAG_SEQUENCE) {
66856893Sfenner		flag_s = TRUE;
66956893Sfenner		printf("S");
67056893Sfenner	}
67156893Sfenner	if (ntohs(*ptr) & L2TP_FLAG_OFFSET) {
67256893Sfenner		flag_o = TRUE;
67356893Sfenner		printf("O");
67456893Sfenner	}
67556893Sfenner	if (ntohs(*ptr) & L2TP_FLAG_PRIORITY) {
67656893Sfenner		flag_p = TRUE;
67756893Sfenner		printf("P");
67856893Sfenner	}
67956893Sfenner	printf("]");
68056893Sfenner
68156893Sfenner	ptr++;
68256893Sfenner	cnt += 2;
68356893Sfenner
68456893Sfenner	if (flag_l) {
68556893Sfenner		l2tp_len = ntohs(*ptr++);	/* XXX need to consider
68656893Sfenner						   truncation ?? */
68756893Sfenner		cnt += 2;
68856893Sfenner	} else {
68956893Sfenner		l2tp_len = 0;
69056893Sfenner	}
69156893Sfenner
69256893Sfenner	printf("(%u/", ntohs(*ptr++));		/* Tunnel ID */
69356893Sfenner	printf("%u)",  ntohs(*ptr++));		/* Session ID */
69456893Sfenner	cnt += 4;
69556893Sfenner
69656893Sfenner	if (flag_s) {
69756893Sfenner		printf("Ns=%u,", ntohs(*ptr++));
69856893Sfenner		printf("Nr=%u",  ntohs(*ptr++));
69956893Sfenner		cnt += 4;
70056893Sfenner	}
70156893Sfenner
70256893Sfenner	if (flag_o) {
70356893Sfenner		pad =  ntohs(*ptr++);
70456893Sfenner		ptr += pad / sizeof(*ptr);
70556893Sfenner		cnt += (2 + pad);
70656893Sfenner	}
70756893Sfenner
70856893Sfenner	if (flag_t) {
70956893Sfenner		if (length - cnt == 0) {
71056893Sfenner			printf(" ZLB");
71156893Sfenner		} else {
71256893Sfenner			l2tp_avp_print((u_char *)ptr, length - cnt);
71356893Sfenner		}
71456893Sfenner	} else {
71556893Sfenner		printf(" {");
71675115Sfenner		ppp_print((u_char *)ptr, length - cnt);
71756893Sfenner		printf("}");
71856893Sfenner	}
71956893Sfenner}
720