141c99275SPeter Avalos /*
241c99275SPeter Avalos * Copyright (c) 1991, 1993, 1994, 1995, 1996, 1997
341c99275SPeter Avalos * The Regents of the University of California. All rights reserved.
441c99275SPeter Avalos *
541c99275SPeter Avalos * Redistribution and use in source and binary forms, with or without
641c99275SPeter Avalos * modification, are permitted provided that: (1) source code distributions
741c99275SPeter Avalos * retain the above copyright notice and this paragraph in its entirety, (2)
841c99275SPeter Avalos * distributions including binary code include the above copyright notice and
941c99275SPeter Avalos * this paragraph in its entirety in the documentation or other materials
1041c99275SPeter Avalos * provided with the distribution, and (3) all advertising materials mentioning
1141c99275SPeter Avalos * features or use of this software display the following acknowledgement:
1241c99275SPeter Avalos * ``This product includes software developed by the University of California,
1341c99275SPeter Avalos * Lawrence Berkeley Laboratory and its contributors.'' Neither the name of
1441c99275SPeter Avalos * the University nor the names of its contributors may be used to endorse
1541c99275SPeter Avalos * or promote products derived from this software without specific prior
1641c99275SPeter Avalos * written permission.
1741c99275SPeter Avalos * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR IMPLIED
1841c99275SPeter Avalos * WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF
1941c99275SPeter Avalos * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
2041c99275SPeter Avalos *
2141c99275SPeter Avalos * L2TP support contributed by Motonori Shindo (mshindo@mshindo.net)
2241c99275SPeter Avalos */
2341c99275SPeter Avalos
24411677aeSAaron LI /* \summary: Layer Two Tunneling Protocol (L2TP) printer */
25411677aeSAaron LI
26411677aeSAaron LI /* specification: RFC 2661 */
2741c99275SPeter Avalos
2841c99275SPeter Avalos #ifdef HAVE_CONFIG_H
29*ed775ee7SAntonio Huete Jimenez #include <config.h>
3041c99275SPeter Avalos #endif
3141c99275SPeter Avalos
32*ed775ee7SAntonio Huete Jimenez #include "netdissect-stdinc.h"
3341c99275SPeter Avalos
34411677aeSAaron LI #include "netdissect.h"
3541c99275SPeter Avalos #include "extract.h"
3641c99275SPeter Avalos
37411677aeSAaron LI #define L2TP_FLAG_TYPE 0x8000 /* Type (0=Data, 1=Control) */
38411677aeSAaron LI #define L2TP_FLAG_LENGTH 0x4000 /* Length */
39411677aeSAaron LI #define L2TP_FLAG_SEQUENCE 0x0800 /* Sequence */
40411677aeSAaron LI #define L2TP_FLAG_OFFSET 0x0200 /* Offset */
41411677aeSAaron LI #define L2TP_FLAG_PRIORITY 0x0100 /* Priority */
42411677aeSAaron LI
43411677aeSAaron LI #define L2TP_VERSION_MASK 0x000f /* Version Mask */
44411677aeSAaron LI #define L2TP_VERSION_L2F 0x0001 /* L2F */
45411677aeSAaron LI #define L2TP_VERSION_L2TP 0x0002 /* L2TP */
46411677aeSAaron LI
47411677aeSAaron LI #define L2TP_AVP_HDR_FLAG_MANDATORY 0x8000 /* Mandatory Flag */
48411677aeSAaron LI #define L2TP_AVP_HDR_FLAG_HIDDEN 0x4000 /* Hidden Flag */
49411677aeSAaron LI #define L2TP_AVP_HDR_LEN_MASK 0x03ff /* Length Mask */
50411677aeSAaron LI
51411677aeSAaron LI #define L2TP_FRAMING_CAP_SYNC_MASK 0x00000001 /* Synchronous */
52411677aeSAaron LI #define L2TP_FRAMING_CAP_ASYNC_MASK 0x00000002 /* Asynchronous */
53411677aeSAaron LI
54411677aeSAaron LI #define L2TP_FRAMING_TYPE_SYNC_MASK 0x00000001 /* Synchronous */
55411677aeSAaron LI #define L2TP_FRAMING_TYPE_ASYNC_MASK 0x00000002 /* Asynchronous */
56411677aeSAaron LI
57411677aeSAaron LI #define L2TP_BEARER_CAP_DIGITAL_MASK 0x00000001 /* Digital */
58411677aeSAaron LI #define L2TP_BEARER_CAP_ANALOG_MASK 0x00000002 /* Analog */
59411677aeSAaron LI
60411677aeSAaron LI #define L2TP_BEARER_TYPE_DIGITAL_MASK 0x00000001 /* Digital */
61411677aeSAaron LI #define L2TP_BEARER_TYPE_ANALOG_MASK 0x00000002 /* Analog */
62411677aeSAaron LI
63411677aeSAaron LI /* Authen Type */
64411677aeSAaron LI #define L2TP_AUTHEN_TYPE_RESERVED 0x0000 /* Reserved */
65411677aeSAaron LI #define L2TP_AUTHEN_TYPE_TEXTUAL 0x0001 /* Textual username/password exchange */
66411677aeSAaron LI #define L2TP_AUTHEN_TYPE_CHAP 0x0002 /* PPP CHAP */
67411677aeSAaron LI #define L2TP_AUTHEN_TYPE_PAP 0x0003 /* PPP PAP */
68411677aeSAaron LI #define L2TP_AUTHEN_TYPE_NO_AUTH 0x0004 /* No Authentication */
69411677aeSAaron LI #define L2TP_AUTHEN_TYPE_MSCHAPv1 0x0005 /* MSCHAPv1 */
70411677aeSAaron LI
71411677aeSAaron LI #define L2TP_PROXY_AUTH_ID_MASK 0x00ff
72411677aeSAaron LI
7341c99275SPeter Avalos
7441c99275SPeter Avalos #define L2TP_MSGTYPE_SCCRQ 1 /* Start-Control-Connection-Request */
7541c99275SPeter Avalos #define L2TP_MSGTYPE_SCCRP 2 /* Start-Control-Connection-Reply */
7641c99275SPeter Avalos #define L2TP_MSGTYPE_SCCCN 3 /* Start-Control-Connection-Connected */
7741c99275SPeter Avalos #define L2TP_MSGTYPE_STOPCCN 4 /* Stop-Control-Connection-Notification */
7841c99275SPeter Avalos #define L2TP_MSGTYPE_HELLO 6 /* Hello */
7941c99275SPeter Avalos #define L2TP_MSGTYPE_OCRQ 7 /* Outgoing-Call-Request */
8041c99275SPeter Avalos #define L2TP_MSGTYPE_OCRP 8 /* Outgoing-Call-Reply */
8141c99275SPeter Avalos #define L2TP_MSGTYPE_OCCN 9 /* Outgoing-Call-Connected */
8241c99275SPeter Avalos #define L2TP_MSGTYPE_ICRQ 10 /* Incoming-Call-Request */
8341c99275SPeter Avalos #define L2TP_MSGTYPE_ICRP 11 /* Incoming-Call-Reply */
8441c99275SPeter Avalos #define L2TP_MSGTYPE_ICCN 12 /* Incoming-Call-Connected */
8541c99275SPeter Avalos #define L2TP_MSGTYPE_CDN 14 /* Call-Disconnect-Notify */
8641c99275SPeter Avalos #define L2TP_MSGTYPE_WEN 15 /* WAN-Error-Notify */
8741c99275SPeter Avalos #define L2TP_MSGTYPE_SLI 16 /* Set-Link-Info */
8841c99275SPeter Avalos
89411677aeSAaron LI static const struct tok l2tp_msgtype2str[] = {
9041c99275SPeter Avalos { L2TP_MSGTYPE_SCCRQ, "SCCRQ" },
9141c99275SPeter Avalos { L2TP_MSGTYPE_SCCRP, "SCCRP" },
9241c99275SPeter Avalos { L2TP_MSGTYPE_SCCCN, "SCCCN" },
9341c99275SPeter Avalos { L2TP_MSGTYPE_STOPCCN, "StopCCN" },
9441c99275SPeter Avalos { L2TP_MSGTYPE_HELLO, "HELLO" },
9541c99275SPeter Avalos { L2TP_MSGTYPE_OCRQ, "OCRQ" },
9641c99275SPeter Avalos { L2TP_MSGTYPE_OCRP, "OCRP" },
9741c99275SPeter Avalos { L2TP_MSGTYPE_OCCN, "OCCN" },
9841c99275SPeter Avalos { L2TP_MSGTYPE_ICRQ, "ICRQ" },
9941c99275SPeter Avalos { L2TP_MSGTYPE_ICRP, "ICRP" },
10041c99275SPeter Avalos { L2TP_MSGTYPE_ICCN, "ICCN" },
10141c99275SPeter Avalos { L2TP_MSGTYPE_CDN, "CDN" },
10241c99275SPeter Avalos { L2TP_MSGTYPE_WEN, "WEN" },
10341c99275SPeter Avalos { L2TP_MSGTYPE_SLI, "SLI" },
10441c99275SPeter Avalos { 0, NULL }
10541c99275SPeter Avalos };
10641c99275SPeter Avalos
10741c99275SPeter Avalos #define L2TP_AVP_MSGTYPE 0 /* Message Type */
10841c99275SPeter Avalos #define L2TP_AVP_RESULT_CODE 1 /* Result Code */
10941c99275SPeter Avalos #define L2TP_AVP_PROTO_VER 2 /* Protocol Version */
11041c99275SPeter Avalos #define L2TP_AVP_FRAMING_CAP 3 /* Framing Capabilities */
11141c99275SPeter Avalos #define L2TP_AVP_BEARER_CAP 4 /* Bearer Capabilities */
11241c99275SPeter Avalos #define L2TP_AVP_TIE_BREAKER 5 /* Tie Breaker */
11341c99275SPeter Avalos #define L2TP_AVP_FIRM_VER 6 /* Firmware Revision */
11441c99275SPeter Avalos #define L2TP_AVP_HOST_NAME 7 /* Host Name */
11541c99275SPeter Avalos #define L2TP_AVP_VENDOR_NAME 8 /* Vendor Name */
11641c99275SPeter Avalos #define L2TP_AVP_ASSND_TUN_ID 9 /* Assigned Tunnel ID */
11741c99275SPeter Avalos #define L2TP_AVP_RECV_WIN_SIZE 10 /* Receive Window Size */
11841c99275SPeter Avalos #define L2TP_AVP_CHALLENGE 11 /* Challenge */
11941c99275SPeter Avalos #define L2TP_AVP_Q931_CC 12 /* Q.931 Cause Code */
12041c99275SPeter Avalos #define L2TP_AVP_CHALLENGE_RESP 13 /* Challenge Response */
12141c99275SPeter Avalos #define L2TP_AVP_ASSND_SESS_ID 14 /* Assigned Session ID */
12241c99275SPeter Avalos #define L2TP_AVP_CALL_SER_NUM 15 /* Call Serial Number */
12341c99275SPeter Avalos #define L2TP_AVP_MINIMUM_BPS 16 /* Minimum BPS */
12441c99275SPeter Avalos #define L2TP_AVP_MAXIMUM_BPS 17 /* Maximum BPS */
12541c99275SPeter Avalos #define L2TP_AVP_BEARER_TYPE 18 /* Bearer Type */
12641c99275SPeter Avalos #define L2TP_AVP_FRAMING_TYPE 19 /* Framing Type */
12741c99275SPeter Avalos #define L2TP_AVP_PACKET_PROC_DELAY 20 /* Packet Processing Delay (OBSOLETE) */
12841c99275SPeter Avalos #define L2TP_AVP_CALLED_NUMBER 21 /* Called Number */
12941c99275SPeter Avalos #define L2TP_AVP_CALLING_NUMBER 22 /* Calling Number */
13041c99275SPeter Avalos #define L2TP_AVP_SUB_ADDRESS 23 /* Sub-Address */
13141c99275SPeter Avalos #define L2TP_AVP_TX_CONN_SPEED 24 /* (Tx) Connect Speed */
13241c99275SPeter Avalos #define L2TP_AVP_PHY_CHANNEL_ID 25 /* Physical Channel ID */
13341c99275SPeter Avalos #define L2TP_AVP_INI_RECV_LCP 26 /* Initial Received LCP CONFREQ */
13441c99275SPeter Avalos #define L2TP_AVP_LAST_SENT_LCP 27 /* Last Sent LCP CONFREQ */
13541c99275SPeter Avalos #define L2TP_AVP_LAST_RECV_LCP 28 /* Last Received LCP CONFREQ */
13641c99275SPeter Avalos #define L2TP_AVP_PROXY_AUTH_TYPE 29 /* Proxy Authen Type */
13741c99275SPeter Avalos #define L2TP_AVP_PROXY_AUTH_NAME 30 /* Proxy Authen Name */
13841c99275SPeter Avalos #define L2TP_AVP_PROXY_AUTH_CHAL 31 /* Proxy Authen Challenge */
13941c99275SPeter Avalos #define L2TP_AVP_PROXY_AUTH_ID 32 /* Proxy Authen ID */
14041c99275SPeter Avalos #define L2TP_AVP_PROXY_AUTH_RESP 33 /* Proxy Authen Response */
14141c99275SPeter Avalos #define L2TP_AVP_CALL_ERRORS 34 /* Call Errors */
14241c99275SPeter Avalos #define L2TP_AVP_ACCM 35 /* ACCM */
14341c99275SPeter Avalos #define L2TP_AVP_RANDOM_VECTOR 36 /* Random Vector */
14441c99275SPeter Avalos #define L2TP_AVP_PRIVATE_GRP_ID 37 /* Private Group ID */
14541c99275SPeter Avalos #define L2TP_AVP_RX_CONN_SPEED 38 /* (Rx) Connect Speed */
14641c99275SPeter Avalos #define L2TP_AVP_SEQ_REQUIRED 39 /* Sequencing Required */
147411677aeSAaron LI #define L2TP_AVP_PPP_DISCON_CC 46 /* PPP Disconnect Cause Code - RFC 3145 */
14841c99275SPeter Avalos
149411677aeSAaron LI static const struct tok l2tp_avp2str[] = {
15041c99275SPeter Avalos { L2TP_AVP_MSGTYPE, "MSGTYPE" },
15141c99275SPeter Avalos { L2TP_AVP_RESULT_CODE, "RESULT_CODE" },
15241c99275SPeter Avalos { L2TP_AVP_PROTO_VER, "PROTO_VER" },
15341c99275SPeter Avalos { L2TP_AVP_FRAMING_CAP, "FRAMING_CAP" },
15441c99275SPeter Avalos { L2TP_AVP_BEARER_CAP, "BEARER_CAP" },
15541c99275SPeter Avalos { L2TP_AVP_TIE_BREAKER, "TIE_BREAKER" },
15641c99275SPeter Avalos { L2TP_AVP_FIRM_VER, "FIRM_VER" },
15741c99275SPeter Avalos { L2TP_AVP_HOST_NAME, "HOST_NAME" },
15841c99275SPeter Avalos { L2TP_AVP_VENDOR_NAME, "VENDOR_NAME" },
15941c99275SPeter Avalos { L2TP_AVP_ASSND_TUN_ID, "ASSND_TUN_ID" },
16041c99275SPeter Avalos { L2TP_AVP_RECV_WIN_SIZE, "RECV_WIN_SIZE" },
16141c99275SPeter Avalos { L2TP_AVP_CHALLENGE, "CHALLENGE" },
16241c99275SPeter Avalos { L2TP_AVP_Q931_CC, "Q931_CC", },
16341c99275SPeter Avalos { L2TP_AVP_CHALLENGE_RESP, "CHALLENGE_RESP" },
16441c99275SPeter Avalos { L2TP_AVP_ASSND_SESS_ID, "ASSND_SESS_ID" },
16541c99275SPeter Avalos { L2TP_AVP_CALL_SER_NUM, "CALL_SER_NUM" },
16641c99275SPeter Avalos { L2TP_AVP_MINIMUM_BPS, "MINIMUM_BPS" },
16741c99275SPeter Avalos { L2TP_AVP_MAXIMUM_BPS, "MAXIMUM_BPS" },
16841c99275SPeter Avalos { L2TP_AVP_BEARER_TYPE, "BEARER_TYPE" },
16941c99275SPeter Avalos { L2TP_AVP_FRAMING_TYPE, "FRAMING_TYPE" },
17041c99275SPeter Avalos { L2TP_AVP_PACKET_PROC_DELAY, "PACKET_PROC_DELAY" },
17141c99275SPeter Avalos { L2TP_AVP_CALLED_NUMBER, "CALLED_NUMBER" },
17241c99275SPeter Avalos { L2TP_AVP_CALLING_NUMBER, "CALLING_NUMBER" },
17341c99275SPeter Avalos { L2TP_AVP_SUB_ADDRESS, "SUB_ADDRESS" },
17441c99275SPeter Avalos { L2TP_AVP_TX_CONN_SPEED, "TX_CONN_SPEED" },
17541c99275SPeter Avalos { L2TP_AVP_PHY_CHANNEL_ID, "PHY_CHANNEL_ID" },
17641c99275SPeter Avalos { L2TP_AVP_INI_RECV_LCP, "INI_RECV_LCP" },
17741c99275SPeter Avalos { L2TP_AVP_LAST_SENT_LCP, "LAST_SENT_LCP" },
17841c99275SPeter Avalos { L2TP_AVP_LAST_RECV_LCP, "LAST_RECV_LCP" },
17941c99275SPeter Avalos { L2TP_AVP_PROXY_AUTH_TYPE, "PROXY_AUTH_TYPE" },
18041c99275SPeter Avalos { L2TP_AVP_PROXY_AUTH_NAME, "PROXY_AUTH_NAME" },
18141c99275SPeter Avalos { L2TP_AVP_PROXY_AUTH_CHAL, "PROXY_AUTH_CHAL" },
18241c99275SPeter Avalos { L2TP_AVP_PROXY_AUTH_ID, "PROXY_AUTH_ID" },
18341c99275SPeter Avalos { L2TP_AVP_PROXY_AUTH_RESP, "PROXY_AUTH_RESP" },
18441c99275SPeter Avalos { L2TP_AVP_CALL_ERRORS, "CALL_ERRORS" },
18541c99275SPeter Avalos { L2TP_AVP_ACCM, "ACCM" },
18641c99275SPeter Avalos { L2TP_AVP_RANDOM_VECTOR, "RANDOM_VECTOR" },
18741c99275SPeter Avalos { L2TP_AVP_PRIVATE_GRP_ID, "PRIVATE_GRP_ID" },
18841c99275SPeter Avalos { L2TP_AVP_RX_CONN_SPEED, "RX_CONN_SPEED" },
18941c99275SPeter Avalos { L2TP_AVP_SEQ_REQUIRED, "SEQ_REQUIRED" },
19041c99275SPeter Avalos { L2TP_AVP_PPP_DISCON_CC, "PPP_DISCON_CC" },
19141c99275SPeter Avalos { 0, NULL }
19241c99275SPeter Avalos };
19341c99275SPeter Avalos
194411677aeSAaron LI static const struct tok l2tp_authentype2str[] = {
19541c99275SPeter Avalos { L2TP_AUTHEN_TYPE_RESERVED, "Reserved" },
19641c99275SPeter Avalos { L2TP_AUTHEN_TYPE_TEXTUAL, "Textual" },
19741c99275SPeter Avalos { L2TP_AUTHEN_TYPE_CHAP, "CHAP" },
19841c99275SPeter Avalos { L2TP_AUTHEN_TYPE_PAP, "PAP" },
19941c99275SPeter Avalos { L2TP_AUTHEN_TYPE_NO_AUTH, "No Auth" },
20041c99275SPeter Avalos { L2TP_AUTHEN_TYPE_MSCHAPv1, "MS-CHAPv1" },
20141c99275SPeter Avalos { 0, NULL }
20241c99275SPeter Avalos };
20341c99275SPeter Avalos
20441c99275SPeter Avalos #define L2TP_PPP_DISCON_CC_DIRECTION_GLOBAL 0
20541c99275SPeter Avalos #define L2TP_PPP_DISCON_CC_DIRECTION_AT_PEER 1
20641c99275SPeter Avalos #define L2TP_PPP_DISCON_CC_DIRECTION_AT_LOCAL 2
20741c99275SPeter Avalos
208411677aeSAaron LI static const struct tok l2tp_cc_direction2str[] = {
20941c99275SPeter Avalos { L2TP_PPP_DISCON_CC_DIRECTION_GLOBAL, "global error" },
21041c99275SPeter Avalos { L2TP_PPP_DISCON_CC_DIRECTION_AT_PEER, "at peer" },
21141c99275SPeter Avalos { L2TP_PPP_DISCON_CC_DIRECTION_AT_LOCAL,"at local" },
21241c99275SPeter Avalos { 0, NULL }
21341c99275SPeter Avalos };
21441c99275SPeter Avalos
21541c99275SPeter Avalos #if 0
21641c99275SPeter Avalos static char *l2tp_result_code_StopCCN[] = {
21741c99275SPeter Avalos "Reserved",
21841c99275SPeter Avalos "General request to clear control connection",
21941c99275SPeter Avalos "General error--Error Code indicates the problem",
22041c99275SPeter Avalos "Control channel already exists",
22141c99275SPeter Avalos "Requester is not authorized to establish a control channel",
22241c99275SPeter Avalos "The protocol version of the requester is not supported",
22341c99275SPeter Avalos "Requester is being shut down",
22441c99275SPeter Avalos "Finite State Machine error"
22541c99275SPeter Avalos #define L2TP_MAX_RESULT_CODE_STOPCC_INDEX 8
22641c99275SPeter Avalos };
22741c99275SPeter Avalos #endif
22841c99275SPeter Avalos
22941c99275SPeter Avalos #if 0
23041c99275SPeter Avalos static char *l2tp_result_code_CDN[] = {
23141c99275SPeter Avalos "Reserved",
23241c99275SPeter Avalos "Call disconnected due to loss of carrier",
23341c99275SPeter Avalos "Call disconnected for the reason indicated in error code",
23441c99275SPeter Avalos "Call disconnected for administrative reasons",
235*ed775ee7SAntonio Huete Jimenez "Call failed due to lack of appropriate facilities being "
23641c99275SPeter Avalos "available (temporary condition)",
237*ed775ee7SAntonio Huete Jimenez "Call failed due to lack of appropriate facilities being "
23841c99275SPeter Avalos "available (permanent condition)",
23941c99275SPeter Avalos "Invalid destination",
24041c99275SPeter Avalos "Call failed due to no carrier detected",
24141c99275SPeter Avalos "Call failed due to detection of a busy signal",
24241c99275SPeter Avalos "Call failed due to lack of a dial tone",
24341c99275SPeter Avalos "Call was not established within time allotted by LAC",
24441c99275SPeter Avalos "Call was connected but no appropriate framing was detected"
24541c99275SPeter Avalos #define L2TP_MAX_RESULT_CODE_CDN_INDEX 12
24641c99275SPeter Avalos };
24741c99275SPeter Avalos #endif
24841c99275SPeter Avalos
24941c99275SPeter Avalos #if 0
25041c99275SPeter Avalos static char *l2tp_error_code_general[] = {
25141c99275SPeter Avalos "No general error",
25241c99275SPeter Avalos "No control connection exists yet for this LAC-LNS pair",
25341c99275SPeter Avalos "Length is wrong",
254*ed775ee7SAntonio Huete Jimenez "One of the field values was out of range or "
25541c99275SPeter Avalos "reserved field was non-zero"
25641c99275SPeter Avalos "Insufficient resources to handle this operation now",
25741c99275SPeter Avalos "The Session ID is invalid in this context",
25841c99275SPeter Avalos "A generic vendor-specific error occurred in the LAC",
25941c99275SPeter Avalos "Try another"
26041c99275SPeter Avalos #define L2TP_MAX_ERROR_CODE_GENERAL_INDEX 8
26141c99275SPeter Avalos };
26241c99275SPeter Avalos #endif
26341c99275SPeter Avalos
26441c99275SPeter Avalos /******************************/
26541c99275SPeter Avalos /* generic print out routines */
26641c99275SPeter Avalos /******************************/
26741c99275SPeter Avalos static void
print_string(netdissect_options * ndo,const u_char * dat,u_int length)268411677aeSAaron LI print_string(netdissect_options *ndo, const u_char *dat, u_int length)
26941c99275SPeter Avalos {
27041c99275SPeter Avalos u_int i;
27141c99275SPeter Avalos for (i=0; i<length; i++) {
272*ed775ee7SAntonio Huete Jimenez fn_print_char(ndo, GET_U_1(dat));
273*ed775ee7SAntonio Huete Jimenez dat++;
27441c99275SPeter Avalos }
27541c99275SPeter Avalos }
27641c99275SPeter Avalos
27741c99275SPeter Avalos static void
print_octets(netdissect_options * ndo,const u_char * dat,u_int length)278411677aeSAaron LI print_octets(netdissect_options *ndo, const u_char *dat, u_int length)
27941c99275SPeter Avalos {
28041c99275SPeter Avalos u_int i;
28141c99275SPeter Avalos for (i=0; i<length; i++) {
282*ed775ee7SAntonio Huete Jimenez ND_PRINT("%02x", GET_U_1(dat));
283*ed775ee7SAntonio Huete Jimenez dat++;
28441c99275SPeter Avalos }
28541c99275SPeter Avalos }
28641c99275SPeter Avalos
28741c99275SPeter Avalos static void
print_16bits_val(netdissect_options * ndo,const uint8_t * dat)288411677aeSAaron LI print_16bits_val(netdissect_options *ndo, const uint8_t *dat)
28941c99275SPeter Avalos {
290*ed775ee7SAntonio Huete Jimenez ND_PRINT("%u", GET_BE_U_2(dat));
29141c99275SPeter Avalos }
29241c99275SPeter Avalos
29341c99275SPeter Avalos static void
print_32bits_val(netdissect_options * ndo,const uint8_t * dat)294411677aeSAaron LI print_32bits_val(netdissect_options *ndo, const uint8_t *dat)
29541c99275SPeter Avalos {
296*ed775ee7SAntonio Huete Jimenez ND_PRINT("%u", GET_BE_U_4(dat));
29741c99275SPeter Avalos }
29841c99275SPeter Avalos
29941c99275SPeter Avalos /***********************************/
30041c99275SPeter Avalos /* AVP-specific print out routines */
30141c99275SPeter Avalos /***********************************/
30241c99275SPeter Avalos static void
l2tp_msgtype_print(netdissect_options * ndo,const u_char * dat,u_int length)303411677aeSAaron LI l2tp_msgtype_print(netdissect_options *ndo, const u_char *dat, u_int length)
30441c99275SPeter Avalos {
305411677aeSAaron LI if (length < 2) {
306*ed775ee7SAntonio Huete Jimenez ND_PRINT("AVP too short");
30741c99275SPeter Avalos return;
30841c99275SPeter Avalos }
309*ed775ee7SAntonio Huete Jimenez ND_PRINT("%s", tok2str(l2tp_msgtype2str, "MSGTYPE-#%u",
310*ed775ee7SAntonio Huete Jimenez GET_BE_U_2(dat)));
311411677aeSAaron LI }
31241c99275SPeter Avalos
313411677aeSAaron LI static void
l2tp_result_code_print(netdissect_options * ndo,const u_char * dat,u_int length)314411677aeSAaron LI l2tp_result_code_print(netdissect_options *ndo, const u_char *dat, u_int length)
315411677aeSAaron LI {
316411677aeSAaron LI /* Result Code */
317411677aeSAaron LI if (length < 2) {
318*ed775ee7SAntonio Huete Jimenez ND_PRINT("AVP too short");
319411677aeSAaron LI return;
320411677aeSAaron LI }
321*ed775ee7SAntonio Huete Jimenez ND_PRINT("%u", GET_BE_U_2(dat));
322411677aeSAaron LI dat += 2;
323411677aeSAaron LI length -= 2;
32441c99275SPeter Avalos
325411677aeSAaron LI /* Error Code (opt) */
326411677aeSAaron LI if (length == 0)
327411677aeSAaron LI return;
328411677aeSAaron LI if (length < 2) {
329*ed775ee7SAntonio Huete Jimenez ND_PRINT(" AVP too short");
330411677aeSAaron LI return;
331411677aeSAaron LI }
332*ed775ee7SAntonio Huete Jimenez ND_PRINT("/%u", GET_BE_U_2(dat));
333411677aeSAaron LI dat += 2;
334411677aeSAaron LI length -= 2;
335411677aeSAaron LI
336411677aeSAaron LI /* Error Message (opt) */
337411677aeSAaron LI if (length == 0)
338411677aeSAaron LI return;
339*ed775ee7SAntonio Huete Jimenez ND_PRINT(" ");
340411677aeSAaron LI print_string(ndo, dat, length);
341411677aeSAaron LI }
342411677aeSAaron LI
343411677aeSAaron LI static void
l2tp_proto_ver_print(netdissect_options * ndo,const u_char * dat,u_int length)344411677aeSAaron LI l2tp_proto_ver_print(netdissect_options *ndo, const u_char *dat, u_int length)
345411677aeSAaron LI {
346411677aeSAaron LI if (length < 2) {
347*ed775ee7SAntonio Huete Jimenez ND_PRINT("AVP too short");
348411677aeSAaron LI return;
349411677aeSAaron LI }
350*ed775ee7SAntonio Huete Jimenez ND_PRINT("%u.%u", (GET_BE_U_2(dat) >> 8),
351*ed775ee7SAntonio Huete Jimenez (GET_BE_U_2(dat) & 0xff));
352411677aeSAaron LI }
353411677aeSAaron LI
354411677aeSAaron LI static void
l2tp_framing_cap_print(netdissect_options * ndo,const u_char * dat,u_int length)355411677aeSAaron LI l2tp_framing_cap_print(netdissect_options *ndo, const u_char *dat, u_int length)
356411677aeSAaron LI {
357411677aeSAaron LI if (length < 4) {
358*ed775ee7SAntonio Huete Jimenez ND_PRINT("AVP too short");
359411677aeSAaron LI return;
360411677aeSAaron LI }
361*ed775ee7SAntonio Huete Jimenez if (GET_BE_U_4(dat) & L2TP_FRAMING_CAP_ASYNC_MASK) {
362*ed775ee7SAntonio Huete Jimenez ND_PRINT("A");
363411677aeSAaron LI }
364*ed775ee7SAntonio Huete Jimenez if (GET_BE_U_4(dat) & L2TP_FRAMING_CAP_SYNC_MASK) {
365*ed775ee7SAntonio Huete Jimenez ND_PRINT("S");
366411677aeSAaron LI }
367411677aeSAaron LI }
368411677aeSAaron LI
369411677aeSAaron LI static void
l2tp_bearer_cap_print(netdissect_options * ndo,const u_char * dat,u_int length)370411677aeSAaron LI l2tp_bearer_cap_print(netdissect_options *ndo, const u_char *dat, u_int length)
371411677aeSAaron LI {
372411677aeSAaron LI if (length < 4) {
373*ed775ee7SAntonio Huete Jimenez ND_PRINT("AVP too short");
374411677aeSAaron LI return;
375411677aeSAaron LI }
376*ed775ee7SAntonio Huete Jimenez if (GET_BE_U_4(dat) & L2TP_BEARER_CAP_ANALOG_MASK) {
377*ed775ee7SAntonio Huete Jimenez ND_PRINT("A");
378411677aeSAaron LI }
379*ed775ee7SAntonio Huete Jimenez if (GET_BE_U_4(dat) & L2TP_BEARER_CAP_DIGITAL_MASK) {
380*ed775ee7SAntonio Huete Jimenez ND_PRINT("D");
381411677aeSAaron LI }
382411677aeSAaron LI }
383411677aeSAaron LI
384411677aeSAaron LI static void
l2tp_q931_cc_print(netdissect_options * ndo,const u_char * dat,u_int length)385411677aeSAaron LI l2tp_q931_cc_print(netdissect_options *ndo, const u_char *dat, u_int length)
386411677aeSAaron LI {
387411677aeSAaron LI if (length < 3) {
388*ed775ee7SAntonio Huete Jimenez ND_PRINT("AVP too short");
389411677aeSAaron LI return;
390411677aeSAaron LI }
391411677aeSAaron LI print_16bits_val(ndo, dat);
392*ed775ee7SAntonio Huete Jimenez ND_PRINT(", %02x", GET_U_1(dat + 2));
393411677aeSAaron LI dat += 3;
394411677aeSAaron LI length -= 3;
395411677aeSAaron LI if (length != 0) {
396*ed775ee7SAntonio Huete Jimenez ND_PRINT(" ");
397411677aeSAaron LI print_string(ndo, dat, length);
398411677aeSAaron LI }
399411677aeSAaron LI }
400411677aeSAaron LI
401411677aeSAaron LI static void
l2tp_bearer_type_print(netdissect_options * ndo,const u_char * dat,u_int length)402411677aeSAaron LI l2tp_bearer_type_print(netdissect_options *ndo, const u_char *dat, u_int length)
403411677aeSAaron LI {
404411677aeSAaron LI if (length < 4) {
405*ed775ee7SAntonio Huete Jimenez ND_PRINT("AVP too short");
406411677aeSAaron LI return;
407411677aeSAaron LI }
408*ed775ee7SAntonio Huete Jimenez if (GET_BE_U_4(dat) & L2TP_BEARER_TYPE_ANALOG_MASK) {
409*ed775ee7SAntonio Huete Jimenez ND_PRINT("A");
410411677aeSAaron LI }
411*ed775ee7SAntonio Huete Jimenez if (GET_BE_U_4(dat) & L2TP_BEARER_TYPE_DIGITAL_MASK) {
412*ed775ee7SAntonio Huete Jimenez ND_PRINT("D");
413411677aeSAaron LI }
414411677aeSAaron LI }
415411677aeSAaron LI
416411677aeSAaron LI static void
l2tp_framing_type_print(netdissect_options * ndo,const u_char * dat,u_int length)417411677aeSAaron LI l2tp_framing_type_print(netdissect_options *ndo, const u_char *dat, u_int length)
418411677aeSAaron LI {
419411677aeSAaron LI if (length < 4) {
420*ed775ee7SAntonio Huete Jimenez ND_PRINT("AVP too short");
421411677aeSAaron LI return;
422411677aeSAaron LI }
423*ed775ee7SAntonio Huete Jimenez if (GET_BE_U_4(dat) & L2TP_FRAMING_TYPE_ASYNC_MASK) {
424*ed775ee7SAntonio Huete Jimenez ND_PRINT("A");
425411677aeSAaron LI }
426*ed775ee7SAntonio Huete Jimenez if (GET_BE_U_4(dat) & L2TP_FRAMING_TYPE_SYNC_MASK) {
427*ed775ee7SAntonio Huete Jimenez ND_PRINT("S");
428411677aeSAaron LI }
429411677aeSAaron LI }
430411677aeSAaron LI
431411677aeSAaron LI static void
l2tp_packet_proc_delay_print(netdissect_options * ndo)432411677aeSAaron LI l2tp_packet_proc_delay_print(netdissect_options *ndo)
433411677aeSAaron LI {
434*ed775ee7SAntonio Huete Jimenez ND_PRINT("obsolete");
435411677aeSAaron LI }
436411677aeSAaron LI
437411677aeSAaron LI static void
l2tp_proxy_auth_type_print(netdissect_options * ndo,const u_char * dat,u_int length)438411677aeSAaron LI l2tp_proxy_auth_type_print(netdissect_options *ndo, const u_char *dat, u_int length)
439411677aeSAaron LI {
440411677aeSAaron LI if (length < 2) {
441*ed775ee7SAntonio Huete Jimenez ND_PRINT("AVP too short");
442411677aeSAaron LI return;
443411677aeSAaron LI }
444*ed775ee7SAntonio Huete Jimenez ND_PRINT("%s", tok2str(l2tp_authentype2str,
445*ed775ee7SAntonio Huete Jimenez "AuthType-#%u", GET_BE_U_2(dat)));
446411677aeSAaron LI }
447411677aeSAaron LI
448411677aeSAaron LI static void
l2tp_proxy_auth_id_print(netdissect_options * ndo,const u_char * dat,u_int length)449411677aeSAaron LI l2tp_proxy_auth_id_print(netdissect_options *ndo, const u_char *dat, u_int length)
450411677aeSAaron LI {
451411677aeSAaron LI if (length < 2) {
452*ed775ee7SAntonio Huete Jimenez ND_PRINT("AVP too short");
453411677aeSAaron LI return;
454411677aeSAaron LI }
455*ed775ee7SAntonio Huete Jimenez ND_PRINT("%u", GET_BE_U_2(dat) & L2TP_PROXY_AUTH_ID_MASK);
456411677aeSAaron LI }
457411677aeSAaron LI
458411677aeSAaron LI static void
l2tp_call_errors_print(netdissect_options * ndo,const u_char * dat,u_int length)459411677aeSAaron LI l2tp_call_errors_print(netdissect_options *ndo, const u_char *dat, u_int length)
460411677aeSAaron LI {
461411677aeSAaron LI uint32_t val;
462411677aeSAaron LI
463411677aeSAaron LI if (length < 2) {
464*ed775ee7SAntonio Huete Jimenez ND_PRINT("AVP too short");
465411677aeSAaron LI return;
466411677aeSAaron LI }
467411677aeSAaron LI dat += 2; /* skip "Reserved" */
468411677aeSAaron LI length -= 2;
469411677aeSAaron LI
470411677aeSAaron LI if (length < 4) {
471*ed775ee7SAntonio Huete Jimenez ND_PRINT("AVP too short");
472411677aeSAaron LI return;
473411677aeSAaron LI }
474*ed775ee7SAntonio Huete Jimenez val = GET_BE_U_4(dat); dat += 4; length -= 4;
475*ed775ee7SAntonio Huete Jimenez ND_PRINT("CRCErr=%u ", val);
476411677aeSAaron LI
477411677aeSAaron LI if (length < 4) {
478*ed775ee7SAntonio Huete Jimenez ND_PRINT("AVP too short");
479411677aeSAaron LI return;
480411677aeSAaron LI }
481*ed775ee7SAntonio Huete Jimenez val = GET_BE_U_4(dat); dat += 4; length -= 4;
482*ed775ee7SAntonio Huete Jimenez ND_PRINT("FrameErr=%u ", val);
483411677aeSAaron LI
484411677aeSAaron LI if (length < 4) {
485*ed775ee7SAntonio Huete Jimenez ND_PRINT("AVP too short");
486411677aeSAaron LI return;
487411677aeSAaron LI }
488*ed775ee7SAntonio Huete Jimenez val = GET_BE_U_4(dat); dat += 4; length -= 4;
489*ed775ee7SAntonio Huete Jimenez ND_PRINT("HardOver=%u ", val);
490411677aeSAaron LI
491411677aeSAaron LI if (length < 4) {
492*ed775ee7SAntonio Huete Jimenez ND_PRINT("AVP too short");
493411677aeSAaron LI return;
494411677aeSAaron LI }
495*ed775ee7SAntonio Huete Jimenez val = GET_BE_U_4(dat); dat += 4; length -= 4;
496*ed775ee7SAntonio Huete Jimenez ND_PRINT("BufOver=%u ", val);
497411677aeSAaron LI
498411677aeSAaron LI if (length < 4) {
499*ed775ee7SAntonio Huete Jimenez ND_PRINT("AVP too short");
500411677aeSAaron LI return;
501411677aeSAaron LI }
502*ed775ee7SAntonio Huete Jimenez val = GET_BE_U_4(dat); dat += 4; length -= 4;
503*ed775ee7SAntonio Huete Jimenez ND_PRINT("Timeout=%u ", val);
504411677aeSAaron LI
505411677aeSAaron LI if (length < 4) {
506*ed775ee7SAntonio Huete Jimenez ND_PRINT("AVP too short");
507411677aeSAaron LI return;
508411677aeSAaron LI }
509*ed775ee7SAntonio Huete Jimenez val = GET_BE_U_4(dat); dat += 4; length -= 4;
510*ed775ee7SAntonio Huete Jimenez ND_PRINT("AlignErr=%u ", val);
511411677aeSAaron LI }
512411677aeSAaron LI
513411677aeSAaron LI static void
l2tp_accm_print(netdissect_options * ndo,const u_char * dat,u_int length)514411677aeSAaron LI l2tp_accm_print(netdissect_options *ndo, const u_char *dat, u_int length)
515411677aeSAaron LI {
516411677aeSAaron LI uint32_t val;
517411677aeSAaron LI
518411677aeSAaron LI if (length < 2) {
519*ed775ee7SAntonio Huete Jimenez ND_PRINT("AVP too short");
520411677aeSAaron LI return;
521411677aeSAaron LI }
522411677aeSAaron LI dat += 2; /* skip "Reserved" */
523411677aeSAaron LI length -= 2;
524411677aeSAaron LI
525411677aeSAaron LI if (length < 4) {
526*ed775ee7SAntonio Huete Jimenez ND_PRINT("AVP too short");
527411677aeSAaron LI return;
528411677aeSAaron LI }
529*ed775ee7SAntonio Huete Jimenez val = GET_BE_U_4(dat); dat += 4; length -= 4;
530*ed775ee7SAntonio Huete Jimenez ND_PRINT("send=%08x ", val);
531411677aeSAaron LI
532411677aeSAaron LI if (length < 4) {
533*ed775ee7SAntonio Huete Jimenez ND_PRINT("AVP too short");
534411677aeSAaron LI return;
535411677aeSAaron LI }
536*ed775ee7SAntonio Huete Jimenez val = GET_BE_U_4(dat); dat += 4; length -= 4;
537*ed775ee7SAntonio Huete Jimenez ND_PRINT("recv=%08x ", val);
538411677aeSAaron LI }
539411677aeSAaron LI
540411677aeSAaron LI static void
l2tp_ppp_discon_cc_print(netdissect_options * ndo,const u_char * dat,u_int length)541411677aeSAaron LI l2tp_ppp_discon_cc_print(netdissect_options *ndo, const u_char *dat, u_int length)
542411677aeSAaron LI {
543411677aeSAaron LI if (length < 5) {
544*ed775ee7SAntonio Huete Jimenez ND_PRINT("AVP too short");
545411677aeSAaron LI return;
546411677aeSAaron LI }
547411677aeSAaron LI /* Disconnect Code */
548*ed775ee7SAntonio Huete Jimenez ND_PRINT("%04x, ", GET_BE_U_2(dat));
549411677aeSAaron LI dat += 2;
550411677aeSAaron LI length -= 2;
551411677aeSAaron LI /* Control Protocol Number */
552*ed775ee7SAntonio Huete Jimenez ND_PRINT("%04x ", GET_BE_U_2(dat));
553411677aeSAaron LI dat += 2;
554411677aeSAaron LI length -= 2;
555411677aeSAaron LI /* Direction */
556*ed775ee7SAntonio Huete Jimenez ND_PRINT("%s", tok2str(l2tp_cc_direction2str,
557*ed775ee7SAntonio Huete Jimenez "Direction-#%u", GET_U_1(dat)));
558411677aeSAaron LI dat++;
559411677aeSAaron LI length--;
560411677aeSAaron LI
561411677aeSAaron LI if (length != 0) {
562*ed775ee7SAntonio Huete Jimenez ND_PRINT(" ");
563411677aeSAaron LI print_string(ndo, (const u_char *)dat, length);
564411677aeSAaron LI }
565411677aeSAaron LI }
566411677aeSAaron LI
567411677aeSAaron LI static u_int
l2tp_avp_print(netdissect_options * ndo,const u_char * dat,u_int length)568411677aeSAaron LI l2tp_avp_print(netdissect_options *ndo, const u_char *dat, u_int length)
569411677aeSAaron LI {
570411677aeSAaron LI u_int len;
571411677aeSAaron LI uint16_t attr_type;
572411677aeSAaron LI int hidden = FALSE;
573411677aeSAaron LI
574*ed775ee7SAntonio Huete Jimenez ND_PRINT(" ");
575*ed775ee7SAntonio Huete Jimenez /* Flags & Length */
576*ed775ee7SAntonio Huete Jimenez len = GET_BE_U_2(dat) & L2TP_AVP_HDR_LEN_MASK;
57741c99275SPeter Avalos
57841c99275SPeter Avalos /* If it is not long enough to contain the header, we'll give up. */
57941c99275SPeter Avalos if (len < 6)
58041c99275SPeter Avalos goto trunc;
58141c99275SPeter Avalos
58241c99275SPeter Avalos /* If it goes past the end of the remaining length of the packet,
58341c99275SPeter Avalos we'll give up. */
58441c99275SPeter Avalos if (len > (u_int)length)
58541c99275SPeter Avalos goto trunc;
58641c99275SPeter Avalos
58741c99275SPeter Avalos /* If it goes past the end of the remaining length of the captured
58841c99275SPeter Avalos data, we'll give up. */
589*ed775ee7SAntonio Huete Jimenez ND_TCHECK_LEN(dat, len);
59041c99275SPeter Avalos
591411677aeSAaron LI /*
592411677aeSAaron LI * After this point, we don't need to check whether we go past
593411677aeSAaron LI * the length of the captured data; however, we *do* need to
594411677aeSAaron LI * check whether we go past the end of the AVP.
595411677aeSAaron LI */
596411677aeSAaron LI
597*ed775ee7SAntonio Huete Jimenez if (GET_BE_U_2(dat) & L2TP_AVP_HDR_FLAG_MANDATORY) {
598*ed775ee7SAntonio Huete Jimenez ND_PRINT("*");
59941c99275SPeter Avalos }
600*ed775ee7SAntonio Huete Jimenez if (GET_BE_U_2(dat) & L2TP_AVP_HDR_FLAG_HIDDEN) {
60141c99275SPeter Avalos hidden = TRUE;
602*ed775ee7SAntonio Huete Jimenez ND_PRINT("?");
60341c99275SPeter Avalos }
604411677aeSAaron LI dat += 2;
60541c99275SPeter Avalos
606*ed775ee7SAntonio Huete Jimenez if (GET_BE_U_2(dat)) {
60741c99275SPeter Avalos /* Vendor Specific Attribute */
608*ed775ee7SAntonio Huete Jimenez ND_PRINT("VENDOR%04x:", GET_BE_U_2(dat)); dat += 2;
609*ed775ee7SAntonio Huete Jimenez ND_PRINT("ATTR%04x", GET_BE_U_2(dat)); dat += 2;
610*ed775ee7SAntonio Huete Jimenez ND_PRINT("(");
611411677aeSAaron LI print_octets(ndo, dat, len-6);
612*ed775ee7SAntonio Huete Jimenez ND_PRINT(")");
61341c99275SPeter Avalos } else {
61441c99275SPeter Avalos /* IETF-defined Attributes */
615411677aeSAaron LI dat += 2;
616*ed775ee7SAntonio Huete Jimenez attr_type = GET_BE_U_2(dat); dat += 2;
617*ed775ee7SAntonio Huete Jimenez ND_PRINT("%s", tok2str(l2tp_avp2str, "AVP-#%u", attr_type));
618*ed775ee7SAntonio Huete Jimenez ND_PRINT("(");
61941c99275SPeter Avalos if (hidden) {
620*ed775ee7SAntonio Huete Jimenez ND_PRINT("???");
62141c99275SPeter Avalos } else {
62241c99275SPeter Avalos switch (attr_type) {
62341c99275SPeter Avalos case L2TP_AVP_MSGTYPE:
624411677aeSAaron LI l2tp_msgtype_print(ndo, dat, len-6);
62541c99275SPeter Avalos break;
62641c99275SPeter Avalos case L2TP_AVP_RESULT_CODE:
627411677aeSAaron LI l2tp_result_code_print(ndo, dat, len-6);
62841c99275SPeter Avalos break;
62941c99275SPeter Avalos case L2TP_AVP_PROTO_VER:
630411677aeSAaron LI l2tp_proto_ver_print(ndo, dat, len-6);
63141c99275SPeter Avalos break;
63241c99275SPeter Avalos case L2TP_AVP_FRAMING_CAP:
633411677aeSAaron LI l2tp_framing_cap_print(ndo, dat, len-6);
63441c99275SPeter Avalos break;
63541c99275SPeter Avalos case L2TP_AVP_BEARER_CAP:
636411677aeSAaron LI l2tp_bearer_cap_print(ndo, dat, len-6);
63741c99275SPeter Avalos break;
63841c99275SPeter Avalos case L2TP_AVP_TIE_BREAKER:
639411677aeSAaron LI if (len-6 < 8) {
640*ed775ee7SAntonio Huete Jimenez ND_PRINT("AVP too short");
641411677aeSAaron LI break;
642411677aeSAaron LI }
643411677aeSAaron LI print_octets(ndo, dat, 8);
64441c99275SPeter Avalos break;
64541c99275SPeter Avalos case L2TP_AVP_FIRM_VER:
64641c99275SPeter Avalos case L2TP_AVP_ASSND_TUN_ID:
64741c99275SPeter Avalos case L2TP_AVP_RECV_WIN_SIZE:
64841c99275SPeter Avalos case L2TP_AVP_ASSND_SESS_ID:
649411677aeSAaron LI if (len-6 < 2) {
650*ed775ee7SAntonio Huete Jimenez ND_PRINT("AVP too short");
651411677aeSAaron LI break;
652411677aeSAaron LI }
653411677aeSAaron LI print_16bits_val(ndo, dat);
65441c99275SPeter Avalos break;
65541c99275SPeter Avalos case L2TP_AVP_HOST_NAME:
65641c99275SPeter Avalos case L2TP_AVP_VENDOR_NAME:
65741c99275SPeter Avalos case L2TP_AVP_CALLING_NUMBER:
65841c99275SPeter Avalos case L2TP_AVP_CALLED_NUMBER:
65941c99275SPeter Avalos case L2TP_AVP_SUB_ADDRESS:
66041c99275SPeter Avalos case L2TP_AVP_PROXY_AUTH_NAME:
66141c99275SPeter Avalos case L2TP_AVP_PRIVATE_GRP_ID:
662411677aeSAaron LI print_string(ndo, dat, len-6);
66341c99275SPeter Avalos break;
66441c99275SPeter Avalos case L2TP_AVP_CHALLENGE:
66541c99275SPeter Avalos case L2TP_AVP_INI_RECV_LCP:
66641c99275SPeter Avalos case L2TP_AVP_LAST_SENT_LCP:
66741c99275SPeter Avalos case L2TP_AVP_LAST_RECV_LCP:
66841c99275SPeter Avalos case L2TP_AVP_PROXY_AUTH_CHAL:
66941c99275SPeter Avalos case L2TP_AVP_PROXY_AUTH_RESP:
67041c99275SPeter Avalos case L2TP_AVP_RANDOM_VECTOR:
671411677aeSAaron LI print_octets(ndo, dat, len-6);
67241c99275SPeter Avalos break;
67341c99275SPeter Avalos case L2TP_AVP_Q931_CC:
674411677aeSAaron LI l2tp_q931_cc_print(ndo, dat, len-6);
67541c99275SPeter Avalos break;
67641c99275SPeter Avalos case L2TP_AVP_CHALLENGE_RESP:
677411677aeSAaron LI if (len-6 < 16) {
678*ed775ee7SAntonio Huete Jimenez ND_PRINT("AVP too short");
679411677aeSAaron LI break;
680411677aeSAaron LI }
681411677aeSAaron LI print_octets(ndo, dat, 16);
68241c99275SPeter Avalos break;
68341c99275SPeter Avalos case L2TP_AVP_CALL_SER_NUM:
68441c99275SPeter Avalos case L2TP_AVP_MINIMUM_BPS:
68541c99275SPeter Avalos case L2TP_AVP_MAXIMUM_BPS:
68641c99275SPeter Avalos case L2TP_AVP_TX_CONN_SPEED:
68741c99275SPeter Avalos case L2TP_AVP_PHY_CHANNEL_ID:
68841c99275SPeter Avalos case L2TP_AVP_RX_CONN_SPEED:
689411677aeSAaron LI if (len-6 < 4) {
690*ed775ee7SAntonio Huete Jimenez ND_PRINT("AVP too short");
691411677aeSAaron LI break;
692411677aeSAaron LI }
693411677aeSAaron LI print_32bits_val(ndo, dat);
69441c99275SPeter Avalos break;
69541c99275SPeter Avalos case L2TP_AVP_BEARER_TYPE:
696411677aeSAaron LI l2tp_bearer_type_print(ndo, dat, len-6);
69741c99275SPeter Avalos break;
69841c99275SPeter Avalos case L2TP_AVP_FRAMING_TYPE:
699411677aeSAaron LI l2tp_framing_type_print(ndo, dat, len-6);
70041c99275SPeter Avalos break;
70141c99275SPeter Avalos case L2TP_AVP_PACKET_PROC_DELAY:
702411677aeSAaron LI l2tp_packet_proc_delay_print(ndo);
70341c99275SPeter Avalos break;
70441c99275SPeter Avalos case L2TP_AVP_PROXY_AUTH_TYPE:
705411677aeSAaron LI l2tp_proxy_auth_type_print(ndo, dat, len-6);
70641c99275SPeter Avalos break;
70741c99275SPeter Avalos case L2TP_AVP_PROXY_AUTH_ID:
708411677aeSAaron LI l2tp_proxy_auth_id_print(ndo, dat, len-6);
70941c99275SPeter Avalos break;
71041c99275SPeter Avalos case L2TP_AVP_CALL_ERRORS:
711411677aeSAaron LI l2tp_call_errors_print(ndo, dat, len-6);
71241c99275SPeter Avalos break;
71341c99275SPeter Avalos case L2TP_AVP_ACCM:
714411677aeSAaron LI l2tp_accm_print(ndo, dat, len-6);
71541c99275SPeter Avalos break;
71641c99275SPeter Avalos case L2TP_AVP_SEQ_REQUIRED:
71741c99275SPeter Avalos break; /* No Attribute Value */
71841c99275SPeter Avalos case L2TP_AVP_PPP_DISCON_CC:
719411677aeSAaron LI l2tp_ppp_discon_cc_print(ndo, dat, len-6);
72041c99275SPeter Avalos break;
72141c99275SPeter Avalos default:
72241c99275SPeter Avalos break;
72341c99275SPeter Avalos }
72441c99275SPeter Avalos }
725*ed775ee7SAntonio Huete Jimenez ND_PRINT(")");
72641c99275SPeter Avalos }
72741c99275SPeter Avalos
728411677aeSAaron LI return (len);
72941c99275SPeter Avalos
73041c99275SPeter Avalos trunc:
731*ed775ee7SAntonio Huete Jimenez nd_print_trunc(ndo);
732411677aeSAaron LI return (0);
73341c99275SPeter Avalos }
73441c99275SPeter Avalos
73541c99275SPeter Avalos
73641c99275SPeter Avalos void
l2tp_print(netdissect_options * ndo,const u_char * dat,u_int length)737411677aeSAaron LI l2tp_print(netdissect_options *ndo, const u_char *dat, u_int length)
73841c99275SPeter Avalos {
73927bfbee1SPeter Avalos const u_char *ptr = dat;
74041c99275SPeter Avalos u_int cnt = 0; /* total octets consumed */
741411677aeSAaron LI uint16_t pad;
74241c99275SPeter Avalos int flag_t, flag_l, flag_s, flag_o;
743411677aeSAaron LI uint16_t l2tp_len;
74441c99275SPeter Avalos
745*ed775ee7SAntonio Huete Jimenez ndo->ndo_protocol = "l2tp";
74641c99275SPeter Avalos flag_t = flag_l = flag_s = flag_o = FALSE;
74741c99275SPeter Avalos
748*ed775ee7SAntonio Huete Jimenez if ((GET_BE_U_2(ptr) & L2TP_VERSION_MASK) == L2TP_VERSION_L2TP) {
749*ed775ee7SAntonio Huete Jimenez ND_PRINT(" l2tp:");
750*ed775ee7SAntonio Huete Jimenez } else if ((GET_BE_U_2(ptr) & L2TP_VERSION_MASK) == L2TP_VERSION_L2F) {
751*ed775ee7SAntonio Huete Jimenez ND_PRINT(" l2f:");
75241c99275SPeter Avalos return; /* nothing to do */
75341c99275SPeter Avalos } else {
754*ed775ee7SAntonio Huete Jimenez ND_PRINT(" Unknown Version, neither L2F(1) nor L2TP(2)");
75541c99275SPeter Avalos return; /* nothing we can do */
75641c99275SPeter Avalos }
75741c99275SPeter Avalos
758*ed775ee7SAntonio Huete Jimenez ND_PRINT("[");
759*ed775ee7SAntonio Huete Jimenez if (GET_BE_U_2(ptr) & L2TP_FLAG_TYPE) {
76041c99275SPeter Avalos flag_t = TRUE;
761*ed775ee7SAntonio Huete Jimenez ND_PRINT("T");
76241c99275SPeter Avalos }
763*ed775ee7SAntonio Huete Jimenez if (GET_BE_U_2(ptr) & L2TP_FLAG_LENGTH) {
76441c99275SPeter Avalos flag_l = TRUE;
765*ed775ee7SAntonio Huete Jimenez ND_PRINT("L");
76641c99275SPeter Avalos }
767*ed775ee7SAntonio Huete Jimenez if (GET_BE_U_2(ptr) & L2TP_FLAG_SEQUENCE) {
76841c99275SPeter Avalos flag_s = TRUE;
769*ed775ee7SAntonio Huete Jimenez ND_PRINT("S");
77041c99275SPeter Avalos }
771*ed775ee7SAntonio Huete Jimenez if (GET_BE_U_2(ptr) & L2TP_FLAG_OFFSET) {
77241c99275SPeter Avalos flag_o = TRUE;
773*ed775ee7SAntonio Huete Jimenez ND_PRINT("O");
77441c99275SPeter Avalos }
775*ed775ee7SAntonio Huete Jimenez if (GET_BE_U_2(ptr) & L2TP_FLAG_PRIORITY)
776*ed775ee7SAntonio Huete Jimenez ND_PRINT("P");
777*ed775ee7SAntonio Huete Jimenez ND_PRINT("]");
77841c99275SPeter Avalos
77927bfbee1SPeter Avalos ptr += 2;
78041c99275SPeter Avalos cnt += 2;
78141c99275SPeter Avalos
78241c99275SPeter Avalos if (flag_l) {
783*ed775ee7SAntonio Huete Jimenez l2tp_len = GET_BE_U_2(ptr);
78427bfbee1SPeter Avalos ptr += 2;
78541c99275SPeter Avalos cnt += 2;
78641c99275SPeter Avalos } else {
78741c99275SPeter Avalos l2tp_len = 0;
78841c99275SPeter Avalos }
789*ed775ee7SAntonio Huete Jimenez /* Tunnel ID */
790*ed775ee7SAntonio Huete Jimenez ND_PRINT("(%u/", GET_BE_U_2(ptr));
79127bfbee1SPeter Avalos ptr += 2;
79241c99275SPeter Avalos cnt += 2;
793*ed775ee7SAntonio Huete Jimenez /* Session ID */
794*ed775ee7SAntonio Huete Jimenez ND_PRINT("%u)", GET_BE_U_2(ptr));
79527bfbee1SPeter Avalos ptr += 2;
79641c99275SPeter Avalos cnt += 2;
79741c99275SPeter Avalos
79841c99275SPeter Avalos if (flag_s) {
799*ed775ee7SAntonio Huete Jimenez ND_PRINT("Ns=%u,", GET_BE_U_2(ptr));
80027bfbee1SPeter Avalos ptr += 2;
80141c99275SPeter Avalos cnt += 2;
802*ed775ee7SAntonio Huete Jimenez ND_PRINT("Nr=%u", GET_BE_U_2(ptr));
80327bfbee1SPeter Avalos ptr += 2;
80441c99275SPeter Avalos cnt += 2;
80541c99275SPeter Avalos }
80641c99275SPeter Avalos
807*ed775ee7SAntonio Huete Jimenez if (flag_o) { /* Offset Size */
808*ed775ee7SAntonio Huete Jimenez pad = GET_BE_U_2(ptr);
809*ed775ee7SAntonio Huete Jimenez /* Offset padding octets in packet buffer? */
810*ed775ee7SAntonio Huete Jimenez ND_TCHECK_LEN(ptr + 2, pad);
81127bfbee1SPeter Avalos ptr += (2 + pad);
81241c99275SPeter Avalos cnt += (2 + pad);
81341c99275SPeter Avalos }
81441c99275SPeter Avalos
81541c99275SPeter Avalos if (flag_l) {
81641c99275SPeter Avalos if (length < l2tp_len) {
817*ed775ee7SAntonio Huete Jimenez ND_PRINT(" Length %u larger than packet", l2tp_len);
81841c99275SPeter Avalos return;
81941c99275SPeter Avalos }
82041c99275SPeter Avalos length = l2tp_len;
82141c99275SPeter Avalos }
82241c99275SPeter Avalos if (length < cnt) {
823*ed775ee7SAntonio Huete Jimenez ND_PRINT(" Length %u smaller than header length", length);
82441c99275SPeter Avalos return;
82541c99275SPeter Avalos }
82641c99275SPeter Avalos if (flag_t) {
82741c99275SPeter Avalos if (!flag_l) {
828*ed775ee7SAntonio Huete Jimenez ND_PRINT(" No length");
82941c99275SPeter Avalos return;
83041c99275SPeter Avalos }
83141c99275SPeter Avalos if (length - cnt == 0) {
832*ed775ee7SAntonio Huete Jimenez ND_PRINT(" ZLB");
83341c99275SPeter Avalos } else {
834411677aeSAaron LI /*
835411677aeSAaron LI * Print AVPs.
836411677aeSAaron LI */
837411677aeSAaron LI while (length - cnt != 0) {
838411677aeSAaron LI u_int avp_length;
839411677aeSAaron LI
840411677aeSAaron LI avp_length = l2tp_avp_print(ndo, ptr, length - cnt);
841411677aeSAaron LI if (avp_length == 0) {
842411677aeSAaron LI /*
843411677aeSAaron LI * Truncated.
844411677aeSAaron LI */
845411677aeSAaron LI break;
846411677aeSAaron LI }
847411677aeSAaron LI cnt += avp_length;
848411677aeSAaron LI ptr += avp_length;
849411677aeSAaron LI }
85041c99275SPeter Avalos }
85141c99275SPeter Avalos } else {
852*ed775ee7SAntonio Huete Jimenez ND_PRINT(" {");
853411677aeSAaron LI ppp_print(ndo, ptr, length - cnt);
854*ed775ee7SAntonio Huete Jimenez ND_PRINT("}");
85541c99275SPeter Avalos }
85641c99275SPeter Avalos return;
85741c99275SPeter Avalos trunc:
858*ed775ee7SAntonio Huete Jimenez nd_print_trunc(ndo);
85941c99275SPeter Avalos }
860