1b0453382SBill Fenner /*
2b0453382SBill Fenner * Copyright (c) 1991, 1993, 1994, 1995, 1996, 1997
3b0453382SBill Fenner * The Regents of the University of California. All rights reserved.
4b0453382SBill Fenner *
5b0453382SBill Fenner * Redistribution and use in source and binary forms, with or without
6b0453382SBill Fenner * modification, are permitted provided that: (1) source code distributions
7b0453382SBill Fenner * retain the above copyright notice and this paragraph in its entirety, (2)
8b0453382SBill Fenner * distributions including binary code include the above copyright notice and
9b0453382SBill Fenner * this paragraph in its entirety in the documentation or other materials
10b0453382SBill Fenner * provided with the distribution, and (3) all advertising materials mentioning
11b0453382SBill Fenner * features or use of this software display the following acknowledgement:
12b0453382SBill Fenner * ``This product includes software developed by the University of California,
13b0453382SBill Fenner * Lawrence Berkeley Laboratory and its contributors.'' Neither the name of
14b0453382SBill Fenner * the University nor the names of its contributors may be used to endorse
15b0453382SBill Fenner * or promote products derived from this software without specific prior
16b0453382SBill Fenner * written permission.
17b0453382SBill Fenner * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR IMPLIED
18b0453382SBill Fenner * WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF
19b0453382SBill Fenner * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
20b0453382SBill Fenner *
21685295f4SBill Fenner * L2TP support contributed by Motonori Shindo (mshindo@mshindo.net)
22b0453382SBill Fenner */
23b0453382SBill Fenner
243340d773SGleb Smirnoff /* \summary: Layer Two Tunneling Protocol (L2TP) printer */
253340d773SGleb Smirnoff
2639e421e8SCy Schubert /* specification: RFC 2661 */
2739e421e8SCy Schubert
28b0453382SBill Fenner #ifdef HAVE_CONFIG_H
29ee67461eSJoseph Mingrone #include <config.h>
30b0453382SBill Fenner #endif
31b0453382SBill Fenner
32ee67461eSJoseph Mingrone #include "netdissect-stdinc.h"
335b0fe478SBruce M Simpson
343340d773SGleb Smirnoff #include "netdissect.h"
359afd0c29SBill Fenner #include "extract.h"
36b0453382SBill Fenner
373c602fabSXin LI #define L2TP_FLAG_TYPE 0x8000 /* Type (0=Data, 1=Control) */
383c602fabSXin LI #define L2TP_FLAG_LENGTH 0x4000 /* Length */
393c602fabSXin LI #define L2TP_FLAG_SEQUENCE 0x0800 /* Sequence */
403c602fabSXin LI #define L2TP_FLAG_OFFSET 0x0200 /* Offset */
413c602fabSXin LI #define L2TP_FLAG_PRIORITY 0x0100 /* Priority */
423c602fabSXin LI
433c602fabSXin LI #define L2TP_VERSION_MASK 0x000f /* Version Mask */
443c602fabSXin LI #define L2TP_VERSION_L2F 0x0001 /* L2F */
453c602fabSXin LI #define L2TP_VERSION_L2TP 0x0002 /* L2TP */
463c602fabSXin LI
473c602fabSXin LI #define L2TP_AVP_HDR_FLAG_MANDATORY 0x8000 /* Mandatory Flag */
483c602fabSXin LI #define L2TP_AVP_HDR_FLAG_HIDDEN 0x4000 /* Hidden Flag */
493c602fabSXin LI #define L2TP_AVP_HDR_LEN_MASK 0x03ff /* Length Mask */
503c602fabSXin LI
513c602fabSXin LI #define L2TP_FRAMING_CAP_SYNC_MASK 0x00000001 /* Synchronous */
523c602fabSXin LI #define L2TP_FRAMING_CAP_ASYNC_MASK 0x00000002 /* Asynchronous */
533c602fabSXin LI
543c602fabSXin LI #define L2TP_FRAMING_TYPE_SYNC_MASK 0x00000001 /* Synchronous */
553c602fabSXin LI #define L2TP_FRAMING_TYPE_ASYNC_MASK 0x00000002 /* Asynchronous */
563c602fabSXin LI
573c602fabSXin LI #define L2TP_BEARER_CAP_DIGITAL_MASK 0x00000001 /* Digital */
583c602fabSXin LI #define L2TP_BEARER_CAP_ANALOG_MASK 0x00000002 /* Analog */
593c602fabSXin LI
603c602fabSXin LI #define L2TP_BEARER_TYPE_DIGITAL_MASK 0x00000001 /* Digital */
613c602fabSXin LI #define L2TP_BEARER_TYPE_ANALOG_MASK 0x00000002 /* Analog */
623c602fabSXin LI
633c602fabSXin LI /* Authen Type */
643c602fabSXin LI #define L2TP_AUTHEN_TYPE_RESERVED 0x0000 /* Reserved */
653c602fabSXin LI #define L2TP_AUTHEN_TYPE_TEXTUAL 0x0001 /* Textual username/password exchange */
663c602fabSXin LI #define L2TP_AUTHEN_TYPE_CHAP 0x0002 /* PPP CHAP */
673c602fabSXin LI #define L2TP_AUTHEN_TYPE_PAP 0x0003 /* PPP PAP */
683c602fabSXin LI #define L2TP_AUTHEN_TYPE_NO_AUTH 0x0004 /* No Authentication */
693c602fabSXin LI #define L2TP_AUTHEN_TYPE_MSCHAPv1 0x0005 /* MSCHAPv1 */
703c602fabSXin LI
713c602fabSXin LI #define L2TP_PROXY_AUTH_ID_MASK 0x00ff
723c602fabSXin LI
73b0453382SBill Fenner
74a90e161bSBill Fenner #define L2TP_MSGTYPE_SCCRQ 1 /* Start-Control-Connection-Request */
75a90e161bSBill Fenner #define L2TP_MSGTYPE_SCCRP 2 /* Start-Control-Connection-Reply */
76a90e161bSBill Fenner #define L2TP_MSGTYPE_SCCCN 3 /* Start-Control-Connection-Connected */
77a90e161bSBill Fenner #define L2TP_MSGTYPE_STOPCCN 4 /* Stop-Control-Connection-Notification */
78a90e161bSBill Fenner #define L2TP_MSGTYPE_HELLO 6 /* Hello */
79a90e161bSBill Fenner #define L2TP_MSGTYPE_OCRQ 7 /* Outgoing-Call-Request */
80a90e161bSBill Fenner #define L2TP_MSGTYPE_OCRP 8 /* Outgoing-Call-Reply */
81a90e161bSBill Fenner #define L2TP_MSGTYPE_OCCN 9 /* Outgoing-Call-Connected */
82a90e161bSBill Fenner #define L2TP_MSGTYPE_ICRQ 10 /* Incoming-Call-Request */
83a90e161bSBill Fenner #define L2TP_MSGTYPE_ICRP 11 /* Incoming-Call-Reply */
84a90e161bSBill Fenner #define L2TP_MSGTYPE_ICCN 12 /* Incoming-Call-Connected */
85a90e161bSBill Fenner #define L2TP_MSGTYPE_CDN 14 /* Call-Disconnect-Notify */
86a90e161bSBill Fenner #define L2TP_MSGTYPE_WEN 15 /* WAN-Error-Notify */
87a90e161bSBill Fenner #define L2TP_MSGTYPE_SLI 16 /* Set-Link-Info */
88a90e161bSBill Fenner
893c602fabSXin LI static const struct tok l2tp_msgtype2str[] = {
90a90e161bSBill Fenner { L2TP_MSGTYPE_SCCRQ, "SCCRQ" },
91a90e161bSBill Fenner { L2TP_MSGTYPE_SCCRP, "SCCRP" },
92a90e161bSBill Fenner { L2TP_MSGTYPE_SCCCN, "SCCCN" },
93a90e161bSBill Fenner { L2TP_MSGTYPE_STOPCCN, "StopCCN" },
94a90e161bSBill Fenner { L2TP_MSGTYPE_HELLO, "HELLO" },
95a90e161bSBill Fenner { L2TP_MSGTYPE_OCRQ, "OCRQ" },
96a90e161bSBill Fenner { L2TP_MSGTYPE_OCRP, "OCRP" },
97a90e161bSBill Fenner { L2TP_MSGTYPE_OCCN, "OCCN" },
98a90e161bSBill Fenner { L2TP_MSGTYPE_ICRQ, "ICRQ" },
99a90e161bSBill Fenner { L2TP_MSGTYPE_ICRP, "ICRP" },
100a90e161bSBill Fenner { L2TP_MSGTYPE_ICCN, "ICCN" },
101a90e161bSBill Fenner { L2TP_MSGTYPE_CDN, "CDN" },
102a90e161bSBill Fenner { L2TP_MSGTYPE_WEN, "WEN" },
103a90e161bSBill Fenner { L2TP_MSGTYPE_SLI, "SLI" },
104a90e161bSBill Fenner { 0, NULL }
105b0453382SBill Fenner };
106b0453382SBill Fenner
107a90e161bSBill Fenner #define L2TP_AVP_MSGTYPE 0 /* Message Type */
108a90e161bSBill Fenner #define L2TP_AVP_RESULT_CODE 1 /* Result Code */
109a90e161bSBill Fenner #define L2TP_AVP_PROTO_VER 2 /* Protocol Version */
110a90e161bSBill Fenner #define L2TP_AVP_FRAMING_CAP 3 /* Framing Capabilities */
111a90e161bSBill Fenner #define L2TP_AVP_BEARER_CAP 4 /* Bearer Capabilities */
112a90e161bSBill Fenner #define L2TP_AVP_TIE_BREAKER 5 /* Tie Breaker */
113a90e161bSBill Fenner #define L2TP_AVP_FIRM_VER 6 /* Firmware Revision */
114a90e161bSBill Fenner #define L2TP_AVP_HOST_NAME 7 /* Host Name */
115a90e161bSBill Fenner #define L2TP_AVP_VENDOR_NAME 8 /* Vendor Name */
116a90e161bSBill Fenner #define L2TP_AVP_ASSND_TUN_ID 9 /* Assigned Tunnel ID */
117a90e161bSBill Fenner #define L2TP_AVP_RECV_WIN_SIZE 10 /* Receive Window Size */
118a90e161bSBill Fenner #define L2TP_AVP_CHALLENGE 11 /* Challenge */
119a90e161bSBill Fenner #define L2TP_AVP_Q931_CC 12 /* Q.931 Cause Code */
120a90e161bSBill Fenner #define L2TP_AVP_CHALLENGE_RESP 13 /* Challenge Response */
121a90e161bSBill Fenner #define L2TP_AVP_ASSND_SESS_ID 14 /* Assigned Session ID */
122a90e161bSBill Fenner #define L2TP_AVP_CALL_SER_NUM 15 /* Call Serial Number */
123a90e161bSBill Fenner #define L2TP_AVP_MINIMUM_BPS 16 /* Minimum BPS */
124a90e161bSBill Fenner #define L2TP_AVP_MAXIMUM_BPS 17 /* Maximum BPS */
125a90e161bSBill Fenner #define L2TP_AVP_BEARER_TYPE 18 /* Bearer Type */
126a90e161bSBill Fenner #define L2TP_AVP_FRAMING_TYPE 19 /* Framing Type */
127a90e161bSBill Fenner #define L2TP_AVP_PACKET_PROC_DELAY 20 /* Packet Processing Delay (OBSOLETE) */
128a90e161bSBill Fenner #define L2TP_AVP_CALLED_NUMBER 21 /* Called Number */
129a90e161bSBill Fenner #define L2TP_AVP_CALLING_NUMBER 22 /* Calling Number */
130a90e161bSBill Fenner #define L2TP_AVP_SUB_ADDRESS 23 /* Sub-Address */
131a90e161bSBill Fenner #define L2TP_AVP_TX_CONN_SPEED 24 /* (Tx) Connect Speed */
132a90e161bSBill Fenner #define L2TP_AVP_PHY_CHANNEL_ID 25 /* Physical Channel ID */
133a90e161bSBill Fenner #define L2TP_AVP_INI_RECV_LCP 26 /* Initial Received LCP CONFREQ */
134a90e161bSBill Fenner #define L2TP_AVP_LAST_SENT_LCP 27 /* Last Sent LCP CONFREQ */
135a90e161bSBill Fenner #define L2TP_AVP_LAST_RECV_LCP 28 /* Last Received LCP CONFREQ */
136a90e161bSBill Fenner #define L2TP_AVP_PROXY_AUTH_TYPE 29 /* Proxy Authen Type */
137a90e161bSBill Fenner #define L2TP_AVP_PROXY_AUTH_NAME 30 /* Proxy Authen Name */
138a90e161bSBill Fenner #define L2TP_AVP_PROXY_AUTH_CHAL 31 /* Proxy Authen Challenge */
139a90e161bSBill Fenner #define L2TP_AVP_PROXY_AUTH_ID 32 /* Proxy Authen ID */
140a90e161bSBill Fenner #define L2TP_AVP_PROXY_AUTH_RESP 33 /* Proxy Authen Response */
141a90e161bSBill Fenner #define L2TP_AVP_CALL_ERRORS 34 /* Call Errors */
142a90e161bSBill Fenner #define L2TP_AVP_ACCM 35 /* ACCM */
143a90e161bSBill Fenner #define L2TP_AVP_RANDOM_VECTOR 36 /* Random Vector */
144a90e161bSBill Fenner #define L2TP_AVP_PRIVATE_GRP_ID 37 /* Private Group ID */
145a90e161bSBill Fenner #define L2TP_AVP_RX_CONN_SPEED 38 /* (Rx) Connect Speed */
146a90e161bSBill Fenner #define L2TP_AVP_SEQ_REQUIRED 39 /* Sequencing Required */
14739e421e8SCy Schubert #define L2TP_AVP_PPP_DISCON_CC 46 /* PPP Disconnect Cause Code - RFC 3145 */
148b0453382SBill Fenner
1493c602fabSXin LI static const struct tok l2tp_avp2str[] = {
150a90e161bSBill Fenner { L2TP_AVP_MSGTYPE, "MSGTYPE" },
151a90e161bSBill Fenner { L2TP_AVP_RESULT_CODE, "RESULT_CODE" },
152a90e161bSBill Fenner { L2TP_AVP_PROTO_VER, "PROTO_VER" },
153a90e161bSBill Fenner { L2TP_AVP_FRAMING_CAP, "FRAMING_CAP" },
154a90e161bSBill Fenner { L2TP_AVP_BEARER_CAP, "BEARER_CAP" },
155a90e161bSBill Fenner { L2TP_AVP_TIE_BREAKER, "TIE_BREAKER" },
156a90e161bSBill Fenner { L2TP_AVP_FIRM_VER, "FIRM_VER" },
157a90e161bSBill Fenner { L2TP_AVP_HOST_NAME, "HOST_NAME" },
158a90e161bSBill Fenner { L2TP_AVP_VENDOR_NAME, "VENDOR_NAME" },
159a90e161bSBill Fenner { L2TP_AVP_ASSND_TUN_ID, "ASSND_TUN_ID" },
160a90e161bSBill Fenner { L2TP_AVP_RECV_WIN_SIZE, "RECV_WIN_SIZE" },
161a90e161bSBill Fenner { L2TP_AVP_CHALLENGE, "CHALLENGE" },
162a90e161bSBill Fenner { L2TP_AVP_Q931_CC, "Q931_CC", },
163a90e161bSBill Fenner { L2TP_AVP_CHALLENGE_RESP, "CHALLENGE_RESP" },
164a90e161bSBill Fenner { L2TP_AVP_ASSND_SESS_ID, "ASSND_SESS_ID" },
165a90e161bSBill Fenner { L2TP_AVP_CALL_SER_NUM, "CALL_SER_NUM" },
166a90e161bSBill Fenner { L2TP_AVP_MINIMUM_BPS, "MINIMUM_BPS" },
167a90e161bSBill Fenner { L2TP_AVP_MAXIMUM_BPS, "MAXIMUM_BPS" },
168a90e161bSBill Fenner { L2TP_AVP_BEARER_TYPE, "BEARER_TYPE" },
169a90e161bSBill Fenner { L2TP_AVP_FRAMING_TYPE, "FRAMING_TYPE" },
170a90e161bSBill Fenner { L2TP_AVP_PACKET_PROC_DELAY, "PACKET_PROC_DELAY" },
171a90e161bSBill Fenner { L2TP_AVP_CALLED_NUMBER, "CALLED_NUMBER" },
172a90e161bSBill Fenner { L2TP_AVP_CALLING_NUMBER, "CALLING_NUMBER" },
173a90e161bSBill Fenner { L2TP_AVP_SUB_ADDRESS, "SUB_ADDRESS" },
174a90e161bSBill Fenner { L2TP_AVP_TX_CONN_SPEED, "TX_CONN_SPEED" },
175a90e161bSBill Fenner { L2TP_AVP_PHY_CHANNEL_ID, "PHY_CHANNEL_ID" },
176a90e161bSBill Fenner { L2TP_AVP_INI_RECV_LCP, "INI_RECV_LCP" },
177a90e161bSBill Fenner { L2TP_AVP_LAST_SENT_LCP, "LAST_SENT_LCP" },
178a90e161bSBill Fenner { L2TP_AVP_LAST_RECV_LCP, "LAST_RECV_LCP" },
179a90e161bSBill Fenner { L2TP_AVP_PROXY_AUTH_TYPE, "PROXY_AUTH_TYPE" },
180a90e161bSBill Fenner { L2TP_AVP_PROXY_AUTH_NAME, "PROXY_AUTH_NAME" },
181a90e161bSBill Fenner { L2TP_AVP_PROXY_AUTH_CHAL, "PROXY_AUTH_CHAL" },
182a90e161bSBill Fenner { L2TP_AVP_PROXY_AUTH_ID, "PROXY_AUTH_ID" },
183a90e161bSBill Fenner { L2TP_AVP_PROXY_AUTH_RESP, "PROXY_AUTH_RESP" },
184a90e161bSBill Fenner { L2TP_AVP_CALL_ERRORS, "CALL_ERRORS" },
185a90e161bSBill Fenner { L2TP_AVP_ACCM, "ACCM" },
186a90e161bSBill Fenner { L2TP_AVP_RANDOM_VECTOR, "RANDOM_VECTOR" },
187a90e161bSBill Fenner { L2TP_AVP_PRIVATE_GRP_ID, "PRIVATE_GRP_ID" },
188a90e161bSBill Fenner { L2TP_AVP_RX_CONN_SPEED, "RX_CONN_SPEED" },
189a90e161bSBill Fenner { L2TP_AVP_SEQ_REQUIRED, "SEQ_REQUIRED" },
190a90e161bSBill Fenner { L2TP_AVP_PPP_DISCON_CC, "PPP_DISCON_CC" },
191a90e161bSBill Fenner { 0, NULL }
192a90e161bSBill Fenner };
193a90e161bSBill Fenner
1943c602fabSXin LI static const struct tok l2tp_authentype2str[] = {
195a90e161bSBill Fenner { L2TP_AUTHEN_TYPE_RESERVED, "Reserved" },
196a90e161bSBill Fenner { L2TP_AUTHEN_TYPE_TEXTUAL, "Textual" },
197a90e161bSBill Fenner { L2TP_AUTHEN_TYPE_CHAP, "CHAP" },
198a90e161bSBill Fenner { L2TP_AUTHEN_TYPE_PAP, "PAP" },
199a90e161bSBill Fenner { L2TP_AUTHEN_TYPE_NO_AUTH, "No Auth" },
200a90e161bSBill Fenner { L2TP_AUTHEN_TYPE_MSCHAPv1, "MS-CHAPv1" },
201a90e161bSBill Fenner { 0, NULL }
202a90e161bSBill Fenner };
203a90e161bSBill Fenner
204a90e161bSBill Fenner #define L2TP_PPP_DISCON_CC_DIRECTION_GLOBAL 0
205a90e161bSBill Fenner #define L2TP_PPP_DISCON_CC_DIRECTION_AT_PEER 1
206a90e161bSBill Fenner #define L2TP_PPP_DISCON_CC_DIRECTION_AT_LOCAL 2
207a90e161bSBill Fenner
2083c602fabSXin LI static const struct tok l2tp_cc_direction2str[] = {
209a90e161bSBill Fenner { L2TP_PPP_DISCON_CC_DIRECTION_GLOBAL, "global error" },
210a90e161bSBill Fenner { L2TP_PPP_DISCON_CC_DIRECTION_AT_PEER, "at peer" },
211a90e161bSBill Fenner { L2TP_PPP_DISCON_CC_DIRECTION_AT_LOCAL,"at local" },
212a90e161bSBill Fenner { 0, NULL }
213b0453382SBill Fenner };
214b0453382SBill Fenner
215b0453382SBill Fenner #if 0
216b0453382SBill Fenner static char *l2tp_result_code_StopCCN[] = {
217b0453382SBill Fenner "Reserved",
218b0453382SBill Fenner "General request to clear control connection",
219b0453382SBill Fenner "General error--Error Code indicates the problem",
220b0453382SBill Fenner "Control channel already exists",
221b0453382SBill Fenner "Requester is not authorized to establish a control channel",
222b0453382SBill Fenner "The protocol version of the requester is not supported",
223b0453382SBill Fenner "Requester is being shut down",
224b0453382SBill Fenner "Finite State Machine error"
225b0453382SBill Fenner #define L2TP_MAX_RESULT_CODE_STOPCC_INDEX 8
226b0453382SBill Fenner };
227b0453382SBill Fenner #endif
228b0453382SBill Fenner
229b0453382SBill Fenner #if 0
230b0453382SBill Fenner static char *l2tp_result_code_CDN[] = {
231b0453382SBill Fenner "Reserved",
232b0453382SBill Fenner "Call disconnected due to loss of carrier",
233b0453382SBill Fenner "Call disconnected for the reason indicated in error code",
234b0453382SBill Fenner "Call disconnected for administrative reasons",
235ee67461eSJoseph Mingrone "Call failed due to lack of appropriate facilities being "
236b0453382SBill Fenner "available (temporary condition)",
237ee67461eSJoseph Mingrone "Call failed due to lack of appropriate facilities being "
238b0453382SBill Fenner "available (permanent condition)",
239b0453382SBill Fenner "Invalid destination",
240b0453382SBill Fenner "Call failed due to no carrier detected",
241b0453382SBill Fenner "Call failed due to detection of a busy signal",
242b0453382SBill Fenner "Call failed due to lack of a dial tone",
243b0453382SBill Fenner "Call was not established within time allotted by LAC",
244b0453382SBill Fenner "Call was connected but no appropriate framing was detected"
245b0453382SBill Fenner #define L2TP_MAX_RESULT_CODE_CDN_INDEX 12
246b0453382SBill Fenner };
247b0453382SBill Fenner #endif
248b0453382SBill Fenner
249b0453382SBill Fenner #if 0
250b0453382SBill Fenner static char *l2tp_error_code_general[] = {
251b0453382SBill Fenner "No general error",
252b0453382SBill Fenner "No control connection exists yet for this LAC-LNS pair",
253b0453382SBill Fenner "Length is wrong",
254ee67461eSJoseph Mingrone "One of the field values was out of range or "
255b0453382SBill Fenner "reserved field was non-zero"
256b0453382SBill Fenner "Insufficient resources to handle this operation now",
257b0453382SBill Fenner "The Session ID is invalid in this context",
258b0453382SBill Fenner "A generic vendor-specific error occurred in the LAC",
259b0453382SBill Fenner "Try another"
260b0453382SBill Fenner #define L2TP_MAX_ERROR_CODE_GENERAL_INDEX 8
261b0453382SBill Fenner };
262b0453382SBill Fenner #endif
263b0453382SBill Fenner
264b0453382SBill Fenner /******************************/
265b0453382SBill Fenner /* generic print out routines */
266b0453382SBill Fenner /******************************/
267b0453382SBill Fenner static void
print_string(netdissect_options * ndo,const u_char * dat,u_int length)2683c602fabSXin LI print_string(netdissect_options *ndo, const u_char *dat, u_int length)
269b0453382SBill Fenner {
2705b0fe478SBruce M Simpson u_int i;
271b0453382SBill Fenner for (i=0; i<length; i++) {
272ee67461eSJoseph Mingrone fn_print_char(ndo, GET_U_1(dat));
273ee67461eSJoseph Mingrone dat++;
274b0453382SBill Fenner }
275b0453382SBill Fenner }
276b0453382SBill Fenner
277b0453382SBill Fenner static void
print_octets(netdissect_options * ndo,const u_char * dat,u_int length)2783c602fabSXin LI print_octets(netdissect_options *ndo, const u_char *dat, u_int length)
279b0453382SBill Fenner {
2805b0fe478SBruce M Simpson u_int i;
281b0453382SBill Fenner for (i=0; i<length; i++) {
282ee67461eSJoseph Mingrone ND_PRINT("%02x", GET_U_1(dat));
283ee67461eSJoseph Mingrone dat++;
284b0453382SBill Fenner }
285b0453382SBill Fenner }
286b0453382SBill Fenner
287b0453382SBill Fenner static void
print_16bits_val(netdissect_options * ndo,const uint8_t * dat)28839e421e8SCy Schubert print_16bits_val(netdissect_options *ndo, const uint8_t *dat)
289b0453382SBill Fenner {
290ee67461eSJoseph Mingrone ND_PRINT("%u", GET_BE_U_2(dat));
291b0453382SBill Fenner }
292b0453382SBill Fenner
293b0453382SBill Fenner static void
print_32bits_val(netdissect_options * ndo,const uint8_t * dat)29439e421e8SCy Schubert print_32bits_val(netdissect_options *ndo, const uint8_t *dat)
295b0453382SBill Fenner {
296ee67461eSJoseph Mingrone ND_PRINT("%u", GET_BE_U_4(dat));
297b0453382SBill Fenner }
298b0453382SBill Fenner
299a90e161bSBill Fenner /***********************************/
300b0453382SBill Fenner /* AVP-specific print out routines */
301a90e161bSBill Fenner /***********************************/
302b0453382SBill Fenner static void
l2tp_msgtype_print(netdissect_options * ndo,const u_char * dat,u_int length)3030bff6a5aSEd Maste l2tp_msgtype_print(netdissect_options *ndo, const u_char *dat, u_int length)
304b0453382SBill Fenner {
3050bff6a5aSEd Maste if (length < 2) {
306ee67461eSJoseph Mingrone ND_PRINT("AVP too short");
3070bff6a5aSEd Maste return;
3080bff6a5aSEd Maste }
309ee67461eSJoseph Mingrone ND_PRINT("%s", tok2str(l2tp_msgtype2str, "MSGTYPE-#%u",
310ee67461eSJoseph Mingrone GET_BE_U_2(dat)));
311b0453382SBill Fenner }
312b0453382SBill Fenner
313b0453382SBill Fenner static void
l2tp_result_code_print(netdissect_options * ndo,const u_char * dat,u_int length)3143c602fabSXin LI l2tp_result_code_print(netdissect_options *ndo, const u_char *dat, u_int length)
315b0453382SBill Fenner {
3160bff6a5aSEd Maste /* Result Code */
3170bff6a5aSEd Maste if (length < 2) {
318ee67461eSJoseph Mingrone ND_PRINT("AVP too short");
3190bff6a5aSEd Maste return;
320a90e161bSBill Fenner }
321ee67461eSJoseph Mingrone ND_PRINT("%u", GET_BE_U_2(dat));
32239e421e8SCy Schubert dat += 2;
3230bff6a5aSEd Maste length -= 2;
3240bff6a5aSEd Maste
3250bff6a5aSEd Maste /* Error Code (opt) */
3260bff6a5aSEd Maste if (length == 0)
3270bff6a5aSEd Maste return;
3280bff6a5aSEd Maste if (length < 2) {
329ee67461eSJoseph Mingrone ND_PRINT(" AVP too short");
3300bff6a5aSEd Maste return;
3310bff6a5aSEd Maste }
332ee67461eSJoseph Mingrone ND_PRINT("/%u", GET_BE_U_2(dat));
33339e421e8SCy Schubert dat += 2;
3340bff6a5aSEd Maste length -= 2;
3350bff6a5aSEd Maste
3360bff6a5aSEd Maste /* Error Message (opt) */
3370bff6a5aSEd Maste if (length == 0)
3380bff6a5aSEd Maste return;
339ee67461eSJoseph Mingrone ND_PRINT(" ");
34039e421e8SCy Schubert print_string(ndo, dat, length);
341b0453382SBill Fenner }
342b0453382SBill Fenner
343b0453382SBill Fenner static void
l2tp_proto_ver_print(netdissect_options * ndo,const u_char * dat,u_int length)34439e421e8SCy Schubert l2tp_proto_ver_print(netdissect_options *ndo, const u_char *dat, u_int length)
345b0453382SBill Fenner {
3460bff6a5aSEd Maste if (length < 2) {
347ee67461eSJoseph Mingrone ND_PRINT("AVP too short");
3480bff6a5aSEd Maste return;
3490bff6a5aSEd Maste }
350ee67461eSJoseph Mingrone ND_PRINT("%u.%u", (GET_BE_U_2(dat) >> 8),
351ee67461eSJoseph Mingrone (GET_BE_U_2(dat) & 0xff));
352b0453382SBill Fenner }
353b0453382SBill Fenner
354b0453382SBill Fenner static void
l2tp_framing_cap_print(netdissect_options * ndo,const u_char * dat,u_int length)3550bff6a5aSEd Maste l2tp_framing_cap_print(netdissect_options *ndo, const u_char *dat, u_int length)
356b0453382SBill Fenner {
3570bff6a5aSEd Maste if (length < 4) {
358ee67461eSJoseph Mingrone ND_PRINT("AVP too short");
3590bff6a5aSEd Maste return;
3600bff6a5aSEd Maste }
361ee67461eSJoseph Mingrone if (GET_BE_U_4(dat) & L2TP_FRAMING_CAP_ASYNC_MASK) {
362ee67461eSJoseph Mingrone ND_PRINT("A");
363b0453382SBill Fenner }
364ee67461eSJoseph Mingrone if (GET_BE_U_4(dat) & L2TP_FRAMING_CAP_SYNC_MASK) {
365ee67461eSJoseph Mingrone ND_PRINT("S");
366b0453382SBill Fenner }
367b0453382SBill Fenner }
368b0453382SBill Fenner
369b0453382SBill Fenner static void
l2tp_bearer_cap_print(netdissect_options * ndo,const u_char * dat,u_int length)3700bff6a5aSEd Maste l2tp_bearer_cap_print(netdissect_options *ndo, const u_char *dat, u_int length)
371b0453382SBill Fenner {
3720bff6a5aSEd Maste if (length < 4) {
373ee67461eSJoseph Mingrone ND_PRINT("AVP too short");
3740bff6a5aSEd Maste return;
3750bff6a5aSEd Maste }
376ee67461eSJoseph Mingrone if (GET_BE_U_4(dat) & L2TP_BEARER_CAP_ANALOG_MASK) {
377ee67461eSJoseph Mingrone ND_PRINT("A");
378b0453382SBill Fenner }
379ee67461eSJoseph Mingrone if (GET_BE_U_4(dat) & L2TP_BEARER_CAP_DIGITAL_MASK) {
380ee67461eSJoseph Mingrone ND_PRINT("D");
381b0453382SBill Fenner }
382b0453382SBill Fenner }
383b0453382SBill Fenner
384b0453382SBill Fenner static void
l2tp_q931_cc_print(netdissect_options * ndo,const u_char * dat,u_int length)3853c602fabSXin LI l2tp_q931_cc_print(netdissect_options *ndo, const u_char *dat, u_int length)
386b0453382SBill Fenner {
3870bff6a5aSEd Maste if (length < 3) {
388ee67461eSJoseph Mingrone ND_PRINT("AVP too short");
3890bff6a5aSEd Maste return;
3900bff6a5aSEd Maste }
39139e421e8SCy Schubert print_16bits_val(ndo, dat);
392ee67461eSJoseph Mingrone ND_PRINT(", %02x", GET_U_1(dat + 2));
3930bff6a5aSEd Maste dat += 3;
3940bff6a5aSEd Maste length -= 3;
3950bff6a5aSEd Maste if (length != 0) {
396ee67461eSJoseph Mingrone ND_PRINT(" ");
3970bff6a5aSEd Maste print_string(ndo, dat, length);
398b0453382SBill Fenner }
399b0453382SBill Fenner }
400b0453382SBill Fenner
401b0453382SBill Fenner static void
l2tp_bearer_type_print(netdissect_options * ndo,const u_char * dat,u_int length)4020bff6a5aSEd Maste l2tp_bearer_type_print(netdissect_options *ndo, const u_char *dat, u_int length)
403b0453382SBill Fenner {
4040bff6a5aSEd Maste if (length < 4) {
405ee67461eSJoseph Mingrone ND_PRINT("AVP too short");
4060bff6a5aSEd Maste return;
4070bff6a5aSEd Maste }
408ee67461eSJoseph Mingrone if (GET_BE_U_4(dat) & L2TP_BEARER_TYPE_ANALOG_MASK) {
409ee67461eSJoseph Mingrone ND_PRINT("A");
410b0453382SBill Fenner }
411ee67461eSJoseph Mingrone if (GET_BE_U_4(dat) & L2TP_BEARER_TYPE_DIGITAL_MASK) {
412ee67461eSJoseph Mingrone ND_PRINT("D");
413b0453382SBill Fenner }
414b0453382SBill Fenner }
415b0453382SBill Fenner
416b0453382SBill Fenner static void
l2tp_framing_type_print(netdissect_options * ndo,const u_char * dat,u_int length)4170bff6a5aSEd Maste l2tp_framing_type_print(netdissect_options *ndo, const u_char *dat, u_int length)
418b0453382SBill Fenner {
4190bff6a5aSEd Maste if (length < 4) {
420ee67461eSJoseph Mingrone ND_PRINT("AVP too short");
4210bff6a5aSEd Maste return;
4220bff6a5aSEd Maste }
423ee67461eSJoseph Mingrone if (GET_BE_U_4(dat) & L2TP_FRAMING_TYPE_ASYNC_MASK) {
424ee67461eSJoseph Mingrone ND_PRINT("A");
425b0453382SBill Fenner }
426ee67461eSJoseph Mingrone if (GET_BE_U_4(dat) & L2TP_FRAMING_TYPE_SYNC_MASK) {
427ee67461eSJoseph Mingrone ND_PRINT("S");
428b0453382SBill Fenner }
429b0453382SBill Fenner }
430b0453382SBill Fenner
431b0453382SBill Fenner static void
l2tp_packet_proc_delay_print(netdissect_options * ndo)4323c602fabSXin LI l2tp_packet_proc_delay_print(netdissect_options *ndo)
433b0453382SBill Fenner {
434ee67461eSJoseph Mingrone ND_PRINT("obsolete");
435b0453382SBill Fenner }
436b0453382SBill Fenner
437b0453382SBill Fenner static void
l2tp_proxy_auth_type_print(netdissect_options * ndo,const u_char * dat,u_int length)4380bff6a5aSEd Maste l2tp_proxy_auth_type_print(netdissect_options *ndo, const u_char *dat, u_int length)
439b0453382SBill Fenner {
4400bff6a5aSEd Maste if (length < 2) {
441ee67461eSJoseph Mingrone ND_PRINT("AVP too short");
4420bff6a5aSEd Maste return;
4430bff6a5aSEd Maste }
444ee67461eSJoseph Mingrone ND_PRINT("%s", tok2str(l2tp_authentype2str,
445ee67461eSJoseph Mingrone "AuthType-#%u", GET_BE_U_2(dat)));
446b0453382SBill Fenner }
447b0453382SBill Fenner
448b0453382SBill Fenner static void
l2tp_proxy_auth_id_print(netdissect_options * ndo,const u_char * dat,u_int length)4490bff6a5aSEd Maste l2tp_proxy_auth_id_print(netdissect_options *ndo, const u_char *dat, u_int length)
450b0453382SBill Fenner {
4510bff6a5aSEd Maste if (length < 2) {
452ee67461eSJoseph Mingrone ND_PRINT("AVP too short");
4530bff6a5aSEd Maste return;
4540bff6a5aSEd Maste }
455ee67461eSJoseph Mingrone ND_PRINT("%u", GET_BE_U_2(dat) & L2TP_PROXY_AUTH_ID_MASK);
456b0453382SBill Fenner }
457b0453382SBill Fenner
458b0453382SBill Fenner static void
l2tp_call_errors_print(netdissect_options * ndo,const u_char * dat,u_int length)4590bff6a5aSEd Maste l2tp_call_errors_print(netdissect_options *ndo, const u_char *dat, u_int length)
460b0453382SBill Fenner {
46139e421e8SCy Schubert uint32_t val;
462a90e161bSBill Fenner
4630bff6a5aSEd Maste if (length < 2) {
464ee67461eSJoseph Mingrone ND_PRINT("AVP too short");
4650bff6a5aSEd Maste return;
4660bff6a5aSEd Maste }
46739e421e8SCy Schubert dat += 2; /* skip "Reserved" */
4680bff6a5aSEd Maste length -= 2;
469a90e161bSBill Fenner
4700bff6a5aSEd Maste if (length < 4) {
471ee67461eSJoseph Mingrone ND_PRINT("AVP too short");
4720bff6a5aSEd Maste return;
4730bff6a5aSEd Maste }
474ee67461eSJoseph Mingrone val = GET_BE_U_4(dat); dat += 4; length -= 4;
475ee67461eSJoseph Mingrone ND_PRINT("CRCErr=%u ", val);
476a90e161bSBill Fenner
4770bff6a5aSEd Maste if (length < 4) {
478ee67461eSJoseph Mingrone ND_PRINT("AVP too short");
4790bff6a5aSEd Maste return;
4800bff6a5aSEd Maste }
481ee67461eSJoseph Mingrone val = GET_BE_U_4(dat); dat += 4; length -= 4;
482ee67461eSJoseph Mingrone ND_PRINT("FrameErr=%u ", val);
483a90e161bSBill Fenner
4840bff6a5aSEd Maste if (length < 4) {
485ee67461eSJoseph Mingrone ND_PRINT("AVP too short");
4860bff6a5aSEd Maste return;
4870bff6a5aSEd Maste }
488ee67461eSJoseph Mingrone val = GET_BE_U_4(dat); dat += 4; length -= 4;
489ee67461eSJoseph Mingrone ND_PRINT("HardOver=%u ", val);
490a90e161bSBill Fenner
4910bff6a5aSEd Maste if (length < 4) {
492ee67461eSJoseph Mingrone ND_PRINT("AVP too short");
4930bff6a5aSEd Maste return;
4940bff6a5aSEd Maste }
495ee67461eSJoseph Mingrone val = GET_BE_U_4(dat); dat += 4; length -= 4;
496ee67461eSJoseph Mingrone ND_PRINT("BufOver=%u ", val);
497a90e161bSBill Fenner
4980bff6a5aSEd Maste if (length < 4) {
499ee67461eSJoseph Mingrone ND_PRINT("AVP too short");
5000bff6a5aSEd Maste return;
5010bff6a5aSEd Maste }
502ee67461eSJoseph Mingrone val = GET_BE_U_4(dat); dat += 4; length -= 4;
503ee67461eSJoseph Mingrone ND_PRINT("Timeout=%u ", val);
504a90e161bSBill Fenner
5050bff6a5aSEd Maste if (length < 4) {
506ee67461eSJoseph Mingrone ND_PRINT("AVP too short");
5070bff6a5aSEd Maste return;
5080bff6a5aSEd Maste }
509ee67461eSJoseph Mingrone val = GET_BE_U_4(dat); dat += 4; length -= 4;
510ee67461eSJoseph Mingrone ND_PRINT("AlignErr=%u ", val);
511b0453382SBill Fenner }
512b0453382SBill Fenner
513b0453382SBill Fenner static void
l2tp_accm_print(netdissect_options * ndo,const u_char * dat,u_int length)5140bff6a5aSEd Maste l2tp_accm_print(netdissect_options *ndo, const u_char *dat, u_int length)
515b0453382SBill Fenner {
51639e421e8SCy Schubert uint32_t val;
517b0453382SBill Fenner
5180bff6a5aSEd Maste if (length < 2) {
519ee67461eSJoseph Mingrone ND_PRINT("AVP too short");
5200bff6a5aSEd Maste return;
5210bff6a5aSEd Maste }
52239e421e8SCy Schubert dat += 2; /* skip "Reserved" */
5230bff6a5aSEd Maste length -= 2;
524a90e161bSBill Fenner
5250bff6a5aSEd Maste if (length < 4) {
526ee67461eSJoseph Mingrone ND_PRINT("AVP too short");
5270bff6a5aSEd Maste return;
5280bff6a5aSEd Maste }
529ee67461eSJoseph Mingrone val = GET_BE_U_4(dat); dat += 4; length -= 4;
530ee67461eSJoseph Mingrone ND_PRINT("send=%08x ", val);
531a90e161bSBill Fenner
5320bff6a5aSEd Maste if (length < 4) {
533ee67461eSJoseph Mingrone ND_PRINT("AVP too short");
5340bff6a5aSEd Maste return;
5350bff6a5aSEd Maste }
536ee67461eSJoseph Mingrone val = GET_BE_U_4(dat); dat += 4; length -= 4;
537ee67461eSJoseph Mingrone ND_PRINT("recv=%08x ", val);
538b0453382SBill Fenner }
539b0453382SBill Fenner
540b0453382SBill Fenner static void
l2tp_ppp_discon_cc_print(netdissect_options * ndo,const u_char * dat,u_int length)5413c602fabSXin LI l2tp_ppp_discon_cc_print(netdissect_options *ndo, const u_char *dat, u_int length)
542b0453382SBill Fenner {
5430bff6a5aSEd Maste if (length < 5) {
544ee67461eSJoseph Mingrone ND_PRINT("AVP too short");
5450bff6a5aSEd Maste return;
5460bff6a5aSEd Maste }
5470bff6a5aSEd Maste /* Disconnect Code */
548ee67461eSJoseph Mingrone ND_PRINT("%04x, ", GET_BE_U_2(dat));
5490bff6a5aSEd Maste dat += 2;
5500bff6a5aSEd Maste length -= 2;
5510bff6a5aSEd Maste /* Control Protocol Number */
552ee67461eSJoseph Mingrone ND_PRINT("%04x ", GET_BE_U_2(dat));
5530bff6a5aSEd Maste dat += 2;
5540bff6a5aSEd Maste length -= 2;
5550bff6a5aSEd Maste /* Direction */
556ee67461eSJoseph Mingrone ND_PRINT("%s", tok2str(l2tp_cc_direction2str,
557ee67461eSJoseph Mingrone "Direction-#%u", GET_U_1(dat)));
55839e421e8SCy Schubert dat++;
5590bff6a5aSEd Maste length--;
560a90e161bSBill Fenner
5610bff6a5aSEd Maste if (length != 0) {
562ee67461eSJoseph Mingrone ND_PRINT(" ");
56339e421e8SCy Schubert print_string(ndo, (const u_char *)dat, length);
564a90e161bSBill Fenner }
565b0453382SBill Fenner }
566b0453382SBill Fenner
56739e421e8SCy Schubert static u_int
l2tp_avp_print(netdissect_options * ndo,const u_char * dat,u_int length)56839e421e8SCy Schubert l2tp_avp_print(netdissect_options *ndo, const u_char *dat, u_int length)
569b0453382SBill Fenner {
570a90e161bSBill Fenner u_int len;
5713c602fabSXin LI uint16_t attr_type;
572a90e161bSBill Fenner int hidden = FALSE;
573b0453382SBill Fenner
574ee67461eSJoseph Mingrone ND_PRINT(" ");
575ee67461eSJoseph Mingrone /* Flags & Length */
576ee67461eSJoseph Mingrone len = GET_BE_U_2(dat) & L2TP_AVP_HDR_LEN_MASK;
577a90e161bSBill Fenner
578b97c9af5SBill Fenner /* If it is not long enough to contain the header, we'll give up. */
579b97c9af5SBill Fenner if (len < 6)
580b97c9af5SBill Fenner goto trunc;
581b97c9af5SBill Fenner
582b97c9af5SBill Fenner /* If it goes past the end of the remaining length of the packet,
583b97c9af5SBill Fenner we'll give up. */
584b97c9af5SBill Fenner if (len > (u_int)length)
585b97c9af5SBill Fenner goto trunc;
586b97c9af5SBill Fenner
587b97c9af5SBill Fenner /* If it goes past the end of the remaining length of the captured
588b97c9af5SBill Fenner data, we'll give up. */
589ee67461eSJoseph Mingrone ND_TCHECK_LEN(dat, len);
5900bff6a5aSEd Maste
5910bff6a5aSEd Maste /*
5920bff6a5aSEd Maste * After this point, we don't need to check whether we go past
5930bff6a5aSEd Maste * the length of the captured data; however, we *do* need to
5940bff6a5aSEd Maste * check whether we go past the end of the AVP.
5950bff6a5aSEd Maste */
596a90e161bSBill Fenner
597ee67461eSJoseph Mingrone if (GET_BE_U_2(dat) & L2TP_AVP_HDR_FLAG_MANDATORY) {
598ee67461eSJoseph Mingrone ND_PRINT("*");
599b0453382SBill Fenner }
600ee67461eSJoseph Mingrone if (GET_BE_U_2(dat) & L2TP_AVP_HDR_FLAG_HIDDEN) {
601b0453382SBill Fenner hidden = TRUE;
602ee67461eSJoseph Mingrone ND_PRINT("?");
603b0453382SBill Fenner }
60439e421e8SCy Schubert dat += 2;
605b0453382SBill Fenner
606ee67461eSJoseph Mingrone if (GET_BE_U_2(dat)) {
607685295f4SBill Fenner /* Vendor Specific Attribute */
608ee67461eSJoseph Mingrone ND_PRINT("VENDOR%04x:", GET_BE_U_2(dat)); dat += 2;
609ee67461eSJoseph Mingrone ND_PRINT("ATTR%04x", GET_BE_U_2(dat)); dat += 2;
610ee67461eSJoseph Mingrone ND_PRINT("(");
61139e421e8SCy Schubert print_octets(ndo, dat, len-6);
612ee67461eSJoseph Mingrone ND_PRINT(")");
613685295f4SBill Fenner } else {
614a90e161bSBill Fenner /* IETF-defined Attributes */
61539e421e8SCy Schubert dat += 2;
616ee67461eSJoseph Mingrone attr_type = GET_BE_U_2(dat); dat += 2;
617ee67461eSJoseph Mingrone ND_PRINT("%s", tok2str(l2tp_avp2str, "AVP-#%u", attr_type));
618ee67461eSJoseph Mingrone ND_PRINT("(");
619a90e161bSBill Fenner if (hidden) {
620ee67461eSJoseph Mingrone ND_PRINT("???");
621a90e161bSBill Fenner } else {
622a90e161bSBill Fenner switch (attr_type) {
623a90e161bSBill Fenner case L2TP_AVP_MSGTYPE:
62439e421e8SCy Schubert l2tp_msgtype_print(ndo, dat, len-6);
625a90e161bSBill Fenner break;
626a90e161bSBill Fenner case L2TP_AVP_RESULT_CODE:
62739e421e8SCy Schubert l2tp_result_code_print(ndo, dat, len-6);
628a90e161bSBill Fenner break;
629a90e161bSBill Fenner case L2TP_AVP_PROTO_VER:
63039e421e8SCy Schubert l2tp_proto_ver_print(ndo, dat, len-6);
631a90e161bSBill Fenner break;
632a90e161bSBill Fenner case L2TP_AVP_FRAMING_CAP:
63339e421e8SCy Schubert l2tp_framing_cap_print(ndo, dat, len-6);
634a90e161bSBill Fenner break;
635a90e161bSBill Fenner case L2TP_AVP_BEARER_CAP:
63639e421e8SCy Schubert l2tp_bearer_cap_print(ndo, dat, len-6);
637a90e161bSBill Fenner break;
638a90e161bSBill Fenner case L2TP_AVP_TIE_BREAKER:
6390bff6a5aSEd Maste if (len-6 < 8) {
640ee67461eSJoseph Mingrone ND_PRINT("AVP too short");
6410bff6a5aSEd Maste break;
6420bff6a5aSEd Maste }
64339e421e8SCy Schubert print_octets(ndo, dat, 8);
644a90e161bSBill Fenner break;
645a90e161bSBill Fenner case L2TP_AVP_FIRM_VER:
646a90e161bSBill Fenner case L2TP_AVP_ASSND_TUN_ID:
647a90e161bSBill Fenner case L2TP_AVP_RECV_WIN_SIZE:
648a90e161bSBill Fenner case L2TP_AVP_ASSND_SESS_ID:
6490bff6a5aSEd Maste if (len-6 < 2) {
650ee67461eSJoseph Mingrone ND_PRINT("AVP too short");
6510bff6a5aSEd Maste break;
6520bff6a5aSEd Maste }
65339e421e8SCy Schubert print_16bits_val(ndo, dat);
654a90e161bSBill Fenner break;
655a90e161bSBill Fenner case L2TP_AVP_HOST_NAME:
656a90e161bSBill Fenner case L2TP_AVP_VENDOR_NAME:
657a90e161bSBill Fenner case L2TP_AVP_CALLING_NUMBER:
658a90e161bSBill Fenner case L2TP_AVP_CALLED_NUMBER:
659a90e161bSBill Fenner case L2TP_AVP_SUB_ADDRESS:
660a90e161bSBill Fenner case L2TP_AVP_PROXY_AUTH_NAME:
661a90e161bSBill Fenner case L2TP_AVP_PRIVATE_GRP_ID:
66239e421e8SCy Schubert print_string(ndo, dat, len-6);
663a90e161bSBill Fenner break;
664a90e161bSBill Fenner case L2TP_AVP_CHALLENGE:
665a90e161bSBill Fenner case L2TP_AVP_INI_RECV_LCP:
666a90e161bSBill Fenner case L2TP_AVP_LAST_SENT_LCP:
667a90e161bSBill Fenner case L2TP_AVP_LAST_RECV_LCP:
668a90e161bSBill Fenner case L2TP_AVP_PROXY_AUTH_CHAL:
669a90e161bSBill Fenner case L2TP_AVP_PROXY_AUTH_RESP:
670a90e161bSBill Fenner case L2TP_AVP_RANDOM_VECTOR:
67139e421e8SCy Schubert print_octets(ndo, dat, len-6);
672a90e161bSBill Fenner break;
673a90e161bSBill Fenner case L2TP_AVP_Q931_CC:
67439e421e8SCy Schubert l2tp_q931_cc_print(ndo, dat, len-6);
675a90e161bSBill Fenner break;
676a90e161bSBill Fenner case L2TP_AVP_CHALLENGE_RESP:
6770bff6a5aSEd Maste if (len-6 < 16) {
678ee67461eSJoseph Mingrone ND_PRINT("AVP too short");
6790bff6a5aSEd Maste break;
6800bff6a5aSEd Maste }
68139e421e8SCy Schubert print_octets(ndo, dat, 16);
682a90e161bSBill Fenner break;
683a90e161bSBill Fenner case L2TP_AVP_CALL_SER_NUM:
684a90e161bSBill Fenner case L2TP_AVP_MINIMUM_BPS:
685a90e161bSBill Fenner case L2TP_AVP_MAXIMUM_BPS:
686a90e161bSBill Fenner case L2TP_AVP_TX_CONN_SPEED:
687a90e161bSBill Fenner case L2TP_AVP_PHY_CHANNEL_ID:
688a90e161bSBill Fenner case L2TP_AVP_RX_CONN_SPEED:
6890bff6a5aSEd Maste if (len-6 < 4) {
690ee67461eSJoseph Mingrone ND_PRINT("AVP too short");
6910bff6a5aSEd Maste break;
6920bff6a5aSEd Maste }
69339e421e8SCy Schubert print_32bits_val(ndo, dat);
694a90e161bSBill Fenner break;
695a90e161bSBill Fenner case L2TP_AVP_BEARER_TYPE:
69639e421e8SCy Schubert l2tp_bearer_type_print(ndo, dat, len-6);
697a90e161bSBill Fenner break;
698a90e161bSBill Fenner case L2TP_AVP_FRAMING_TYPE:
69939e421e8SCy Schubert l2tp_framing_type_print(ndo, dat, len-6);
700a90e161bSBill Fenner break;
701a90e161bSBill Fenner case L2TP_AVP_PACKET_PROC_DELAY:
7023c602fabSXin LI l2tp_packet_proc_delay_print(ndo);
703a90e161bSBill Fenner break;
704a90e161bSBill Fenner case L2TP_AVP_PROXY_AUTH_TYPE:
70539e421e8SCy Schubert l2tp_proxy_auth_type_print(ndo, dat, len-6);
706a90e161bSBill Fenner break;
707a90e161bSBill Fenner case L2TP_AVP_PROXY_AUTH_ID:
70839e421e8SCy Schubert l2tp_proxy_auth_id_print(ndo, dat, len-6);
709a90e161bSBill Fenner break;
710a90e161bSBill Fenner case L2TP_AVP_CALL_ERRORS:
71139e421e8SCy Schubert l2tp_call_errors_print(ndo, dat, len-6);
712a90e161bSBill Fenner break;
713a90e161bSBill Fenner case L2TP_AVP_ACCM:
71439e421e8SCy Schubert l2tp_accm_print(ndo, dat, len-6);
715a90e161bSBill Fenner break;
716a90e161bSBill Fenner case L2TP_AVP_SEQ_REQUIRED:
717a90e161bSBill Fenner break; /* No Attribute Value */
718a90e161bSBill Fenner case L2TP_AVP_PPP_DISCON_CC:
71939e421e8SCy Schubert l2tp_ppp_discon_cc_print(ndo, dat, len-6);
720a90e161bSBill Fenner break;
721a90e161bSBill Fenner default:
722a90e161bSBill Fenner break;
723a90e161bSBill Fenner }
724b0453382SBill Fenner }
725ee67461eSJoseph Mingrone ND_PRINT(")");
726685295f4SBill Fenner }
727b0453382SBill Fenner
72839e421e8SCy Schubert return (len);
729a90e161bSBill Fenner
730a90e161bSBill Fenner trunc:
731ee67461eSJoseph Mingrone nd_print_trunc(ndo);
73239e421e8SCy Schubert return (0);
733b0453382SBill Fenner }
734b0453382SBill Fenner
735b0453382SBill Fenner
736b0453382SBill Fenner void
l2tp_print(netdissect_options * ndo,const u_char * dat,u_int length)7373c602fabSXin LI l2tp_print(netdissect_options *ndo, const u_char *dat, u_int length)
738b0453382SBill Fenner {
73927df3f5dSRui Paulo const u_char *ptr = dat;
740b0453382SBill Fenner u_int cnt = 0; /* total octets consumed */
7413c602fabSXin LI uint16_t pad;
742f4d0c64aSSam Leffler int flag_t, flag_l, flag_s, flag_o;
7433c602fabSXin LI uint16_t l2tp_len;
744b0453382SBill Fenner
745ee67461eSJoseph Mingrone ndo->ndo_protocol = "l2tp";
746f4d0c64aSSam Leffler flag_t = flag_l = flag_s = flag_o = FALSE;
747b0453382SBill Fenner
748ee67461eSJoseph Mingrone if ((GET_BE_U_2(ptr) & L2TP_VERSION_MASK) == L2TP_VERSION_L2TP) {
749ee67461eSJoseph Mingrone ND_PRINT(" l2tp:");
750ee67461eSJoseph Mingrone } else if ((GET_BE_U_2(ptr) & L2TP_VERSION_MASK) == L2TP_VERSION_L2F) {
751ee67461eSJoseph Mingrone ND_PRINT(" l2f:");
752b0453382SBill Fenner return; /* nothing to do */
753b0453382SBill Fenner } else {
754ee67461eSJoseph Mingrone ND_PRINT(" Unknown Version, neither L2F(1) nor L2TP(2)");
755b0453382SBill Fenner return; /* nothing we can do */
756b0453382SBill Fenner }
757b0453382SBill Fenner
758ee67461eSJoseph Mingrone ND_PRINT("[");
759ee67461eSJoseph Mingrone if (GET_BE_U_2(ptr) & L2TP_FLAG_TYPE) {
760b0453382SBill Fenner flag_t = TRUE;
761ee67461eSJoseph Mingrone ND_PRINT("T");
762b0453382SBill Fenner }
763ee67461eSJoseph Mingrone if (GET_BE_U_2(ptr) & L2TP_FLAG_LENGTH) {
764b0453382SBill Fenner flag_l = TRUE;
765ee67461eSJoseph Mingrone ND_PRINT("L");
766b0453382SBill Fenner }
767ee67461eSJoseph Mingrone if (GET_BE_U_2(ptr) & L2TP_FLAG_SEQUENCE) {
768b0453382SBill Fenner flag_s = TRUE;
769ee67461eSJoseph Mingrone ND_PRINT("S");
770b0453382SBill Fenner }
771ee67461eSJoseph Mingrone if (GET_BE_U_2(ptr) & L2TP_FLAG_OFFSET) {
772b0453382SBill Fenner flag_o = TRUE;
773ee67461eSJoseph Mingrone ND_PRINT("O");
774b0453382SBill Fenner }
775ee67461eSJoseph Mingrone if (GET_BE_U_2(ptr) & L2TP_FLAG_PRIORITY)
776ee67461eSJoseph Mingrone ND_PRINT("P");
777ee67461eSJoseph Mingrone ND_PRINT("]");
778b0453382SBill Fenner
77927df3f5dSRui Paulo ptr += 2;
780b0453382SBill Fenner cnt += 2;
781b0453382SBill Fenner
782b0453382SBill Fenner if (flag_l) {
783ee67461eSJoseph Mingrone l2tp_len = GET_BE_U_2(ptr);
78427df3f5dSRui Paulo ptr += 2;
785b0453382SBill Fenner cnt += 2;
786b0453382SBill Fenner } else {
787b0453382SBill Fenner l2tp_len = 0;
788b0453382SBill Fenner }
789ee67461eSJoseph Mingrone /* Tunnel ID */
790ee67461eSJoseph Mingrone ND_PRINT("(%u/", GET_BE_U_2(ptr));
79127df3f5dSRui Paulo ptr += 2;
792a90e161bSBill Fenner cnt += 2;
793ee67461eSJoseph Mingrone /* Session ID */
794ee67461eSJoseph Mingrone ND_PRINT("%u)", GET_BE_U_2(ptr));
79527df3f5dSRui Paulo ptr += 2;
796a90e161bSBill Fenner cnt += 2;
797b0453382SBill Fenner
798b0453382SBill Fenner if (flag_s) {
799ee67461eSJoseph Mingrone ND_PRINT("Ns=%u,", GET_BE_U_2(ptr));
80027df3f5dSRui Paulo ptr += 2;
801a90e161bSBill Fenner cnt += 2;
802ee67461eSJoseph Mingrone ND_PRINT("Nr=%u", GET_BE_U_2(ptr));
80327df3f5dSRui Paulo ptr += 2;
804a90e161bSBill Fenner cnt += 2;
805b0453382SBill Fenner }
806b0453382SBill Fenner
807ee67461eSJoseph Mingrone if (flag_o) { /* Offset Size */
808ee67461eSJoseph Mingrone pad = GET_BE_U_2(ptr);
809ee67461eSJoseph Mingrone /* Offset padding octets in packet buffer? */
810ee67461eSJoseph Mingrone ND_TCHECK_LEN(ptr + 2, pad);
81127df3f5dSRui Paulo ptr += (2 + pad);
812b0453382SBill Fenner cnt += (2 + pad);
813b0453382SBill Fenner }
814b0453382SBill Fenner
815f4d0c64aSSam Leffler if (flag_l) {
816f4d0c64aSSam Leffler if (length < l2tp_len) {
817ee67461eSJoseph Mingrone ND_PRINT(" Length %u larger than packet", l2tp_len);
818f4d0c64aSSam Leffler return;
819f4d0c64aSSam Leffler }
820f4d0c64aSSam Leffler length = l2tp_len;
821f4d0c64aSSam Leffler }
822f4d0c64aSSam Leffler if (length < cnt) {
823ee67461eSJoseph Mingrone ND_PRINT(" Length %u smaller than header length", length);
824f4d0c64aSSam Leffler return;
825f4d0c64aSSam Leffler }
826b0453382SBill Fenner if (flag_t) {
827f4d0c64aSSam Leffler if (!flag_l) {
828ee67461eSJoseph Mingrone ND_PRINT(" No length");
829f4d0c64aSSam Leffler return;
830f4d0c64aSSam Leffler }
831b0453382SBill Fenner if (length - cnt == 0) {
832ee67461eSJoseph Mingrone ND_PRINT(" ZLB");
833b0453382SBill Fenner } else {
83439e421e8SCy Schubert /*
83539e421e8SCy Schubert * Print AVPs.
83639e421e8SCy Schubert */
83739e421e8SCy Schubert while (length - cnt != 0) {
83839e421e8SCy Schubert u_int avp_length;
83939e421e8SCy Schubert
84039e421e8SCy Schubert avp_length = l2tp_avp_print(ndo, ptr, length - cnt);
84139e421e8SCy Schubert if (avp_length == 0) {
84239e421e8SCy Schubert /*
84339e421e8SCy Schubert * Truncated.
84439e421e8SCy Schubert */
84539e421e8SCy Schubert break;
84639e421e8SCy Schubert }
84739e421e8SCy Schubert cnt += avp_length;
84839e421e8SCy Schubert ptr += avp_length;
84939e421e8SCy Schubert }
850b0453382SBill Fenner }
851b0453382SBill Fenner } else {
852ee67461eSJoseph Mingrone ND_PRINT(" {");
8533c602fabSXin LI ppp_print(ndo, ptr, length - cnt);
854ee67461eSJoseph Mingrone ND_PRINT("}");
855b0453382SBill Fenner }
856a90e161bSBill Fenner return;
857a90e161bSBill Fenner trunc:
858ee67461eSJoseph Mingrone nd_print_trunc(ndo);
859b0453382SBill Fenner }
860