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 26b0453382SBill Fenner #ifdef HAVE_CONFIG_H 27b0453382SBill Fenner #include "config.h" 28b0453382SBill Fenner #endif 29b0453382SBill Fenner 303340d773SGleb Smirnoff #include <netdissect-stdinc.h> 315b0fe478SBruce M Simpson 323340d773SGleb Smirnoff #include "netdissect.h" 339afd0c29SBill Fenner #include "extract.h" 34b0453382SBill Fenner 353c602fabSXin LI #define L2TP_FLAG_TYPE 0x8000 /* Type (0=Data, 1=Control) */ 363c602fabSXin LI #define L2TP_FLAG_LENGTH 0x4000 /* Length */ 373c602fabSXin LI #define L2TP_FLAG_SEQUENCE 0x0800 /* Sequence */ 383c602fabSXin LI #define L2TP_FLAG_OFFSET 0x0200 /* Offset */ 393c602fabSXin LI #define L2TP_FLAG_PRIORITY 0x0100 /* Priority */ 403c602fabSXin LI 413c602fabSXin LI #define L2TP_VERSION_MASK 0x000f /* Version Mask */ 423c602fabSXin LI #define L2TP_VERSION_L2F 0x0001 /* L2F */ 433c602fabSXin LI #define L2TP_VERSION_L2TP 0x0002 /* L2TP */ 443c602fabSXin LI 453c602fabSXin LI #define L2TP_AVP_HDR_FLAG_MANDATORY 0x8000 /* Mandatory Flag */ 463c602fabSXin LI #define L2TP_AVP_HDR_FLAG_HIDDEN 0x4000 /* Hidden Flag */ 473c602fabSXin LI #define L2TP_AVP_HDR_LEN_MASK 0x03ff /* Length Mask */ 483c602fabSXin LI 493c602fabSXin LI #define L2TP_FRAMING_CAP_SYNC_MASK 0x00000001 /* Synchronous */ 503c602fabSXin LI #define L2TP_FRAMING_CAP_ASYNC_MASK 0x00000002 /* Asynchronous */ 513c602fabSXin LI 523c602fabSXin LI #define L2TP_FRAMING_TYPE_SYNC_MASK 0x00000001 /* Synchronous */ 533c602fabSXin LI #define L2TP_FRAMING_TYPE_ASYNC_MASK 0x00000002 /* Asynchronous */ 543c602fabSXin LI 553c602fabSXin LI #define L2TP_BEARER_CAP_DIGITAL_MASK 0x00000001 /* Digital */ 563c602fabSXin LI #define L2TP_BEARER_CAP_ANALOG_MASK 0x00000002 /* Analog */ 573c602fabSXin LI 583c602fabSXin LI #define L2TP_BEARER_TYPE_DIGITAL_MASK 0x00000001 /* Digital */ 593c602fabSXin LI #define L2TP_BEARER_TYPE_ANALOG_MASK 0x00000002 /* Analog */ 603c602fabSXin LI 613c602fabSXin LI /* Authen Type */ 623c602fabSXin LI #define L2TP_AUTHEN_TYPE_RESERVED 0x0000 /* Reserved */ 633c602fabSXin LI #define L2TP_AUTHEN_TYPE_TEXTUAL 0x0001 /* Textual username/password exchange */ 643c602fabSXin LI #define L2TP_AUTHEN_TYPE_CHAP 0x0002 /* PPP CHAP */ 653c602fabSXin LI #define L2TP_AUTHEN_TYPE_PAP 0x0003 /* PPP PAP */ 663c602fabSXin LI #define L2TP_AUTHEN_TYPE_NO_AUTH 0x0004 /* No Authentication */ 673c602fabSXin LI #define L2TP_AUTHEN_TYPE_MSCHAPv1 0x0005 /* MSCHAPv1 */ 683c602fabSXin LI 693c602fabSXin LI #define L2TP_PROXY_AUTH_ID_MASK 0x00ff 703c602fabSXin LI 713c602fabSXin LI static const char tstr[] = " [|l2tp]"; 72b0453382SBill Fenner 73a90e161bSBill Fenner #define L2TP_MSGTYPE_SCCRQ 1 /* Start-Control-Connection-Request */ 74a90e161bSBill Fenner #define L2TP_MSGTYPE_SCCRP 2 /* Start-Control-Connection-Reply */ 75a90e161bSBill Fenner #define L2TP_MSGTYPE_SCCCN 3 /* Start-Control-Connection-Connected */ 76a90e161bSBill Fenner #define L2TP_MSGTYPE_STOPCCN 4 /* Stop-Control-Connection-Notification */ 77a90e161bSBill Fenner #define L2TP_MSGTYPE_HELLO 6 /* Hello */ 78a90e161bSBill Fenner #define L2TP_MSGTYPE_OCRQ 7 /* Outgoing-Call-Request */ 79a90e161bSBill Fenner #define L2TP_MSGTYPE_OCRP 8 /* Outgoing-Call-Reply */ 80a90e161bSBill Fenner #define L2TP_MSGTYPE_OCCN 9 /* Outgoing-Call-Connected */ 81a90e161bSBill Fenner #define L2TP_MSGTYPE_ICRQ 10 /* Incoming-Call-Request */ 82a90e161bSBill Fenner #define L2TP_MSGTYPE_ICRP 11 /* Incoming-Call-Reply */ 83a90e161bSBill Fenner #define L2TP_MSGTYPE_ICCN 12 /* Incoming-Call-Connected */ 84a90e161bSBill Fenner #define L2TP_MSGTYPE_CDN 14 /* Call-Disconnect-Notify */ 85a90e161bSBill Fenner #define L2TP_MSGTYPE_WEN 15 /* WAN-Error-Notify */ 86a90e161bSBill Fenner #define L2TP_MSGTYPE_SLI 16 /* Set-Link-Info */ 87a90e161bSBill Fenner 883c602fabSXin LI static const struct tok l2tp_msgtype2str[] = { 89a90e161bSBill Fenner { L2TP_MSGTYPE_SCCRQ, "SCCRQ" }, 90a90e161bSBill Fenner { L2TP_MSGTYPE_SCCRP, "SCCRP" }, 91a90e161bSBill Fenner { L2TP_MSGTYPE_SCCCN, "SCCCN" }, 92a90e161bSBill Fenner { L2TP_MSGTYPE_STOPCCN, "StopCCN" }, 93a90e161bSBill Fenner { L2TP_MSGTYPE_HELLO, "HELLO" }, 94a90e161bSBill Fenner { L2TP_MSGTYPE_OCRQ, "OCRQ" }, 95a90e161bSBill Fenner { L2TP_MSGTYPE_OCRP, "OCRP" }, 96a90e161bSBill Fenner { L2TP_MSGTYPE_OCCN, "OCCN" }, 97a90e161bSBill Fenner { L2TP_MSGTYPE_ICRQ, "ICRQ" }, 98a90e161bSBill Fenner { L2TP_MSGTYPE_ICRP, "ICRP" }, 99a90e161bSBill Fenner { L2TP_MSGTYPE_ICCN, "ICCN" }, 100a90e161bSBill Fenner { L2TP_MSGTYPE_CDN, "CDN" }, 101a90e161bSBill Fenner { L2TP_MSGTYPE_WEN, "WEN" }, 102a90e161bSBill Fenner { L2TP_MSGTYPE_SLI, "SLI" }, 103a90e161bSBill Fenner { 0, NULL } 104b0453382SBill Fenner }; 105b0453382SBill Fenner 106a90e161bSBill Fenner #define L2TP_AVP_MSGTYPE 0 /* Message Type */ 107a90e161bSBill Fenner #define L2TP_AVP_RESULT_CODE 1 /* Result Code */ 108a90e161bSBill Fenner #define L2TP_AVP_PROTO_VER 2 /* Protocol Version */ 109a90e161bSBill Fenner #define L2TP_AVP_FRAMING_CAP 3 /* Framing Capabilities */ 110a90e161bSBill Fenner #define L2TP_AVP_BEARER_CAP 4 /* Bearer Capabilities */ 111a90e161bSBill Fenner #define L2TP_AVP_TIE_BREAKER 5 /* Tie Breaker */ 112a90e161bSBill Fenner #define L2TP_AVP_FIRM_VER 6 /* Firmware Revision */ 113a90e161bSBill Fenner #define L2TP_AVP_HOST_NAME 7 /* Host Name */ 114a90e161bSBill Fenner #define L2TP_AVP_VENDOR_NAME 8 /* Vendor Name */ 115a90e161bSBill Fenner #define L2TP_AVP_ASSND_TUN_ID 9 /* Assigned Tunnel ID */ 116a90e161bSBill Fenner #define L2TP_AVP_RECV_WIN_SIZE 10 /* Receive Window Size */ 117a90e161bSBill Fenner #define L2TP_AVP_CHALLENGE 11 /* Challenge */ 118a90e161bSBill Fenner #define L2TP_AVP_Q931_CC 12 /* Q.931 Cause Code */ 119a90e161bSBill Fenner #define L2TP_AVP_CHALLENGE_RESP 13 /* Challenge Response */ 120a90e161bSBill Fenner #define L2TP_AVP_ASSND_SESS_ID 14 /* Assigned Session ID */ 121a90e161bSBill Fenner #define L2TP_AVP_CALL_SER_NUM 15 /* Call Serial Number */ 122a90e161bSBill Fenner #define L2TP_AVP_MINIMUM_BPS 16 /* Minimum BPS */ 123a90e161bSBill Fenner #define L2TP_AVP_MAXIMUM_BPS 17 /* Maximum BPS */ 124a90e161bSBill Fenner #define L2TP_AVP_BEARER_TYPE 18 /* Bearer Type */ 125a90e161bSBill Fenner #define L2TP_AVP_FRAMING_TYPE 19 /* Framing Type */ 126a90e161bSBill Fenner #define L2TP_AVP_PACKET_PROC_DELAY 20 /* Packet Processing Delay (OBSOLETE) */ 127a90e161bSBill Fenner #define L2TP_AVP_CALLED_NUMBER 21 /* Called Number */ 128a90e161bSBill Fenner #define L2TP_AVP_CALLING_NUMBER 22 /* Calling Number */ 129a90e161bSBill Fenner #define L2TP_AVP_SUB_ADDRESS 23 /* Sub-Address */ 130a90e161bSBill Fenner #define L2TP_AVP_TX_CONN_SPEED 24 /* (Tx) Connect Speed */ 131a90e161bSBill Fenner #define L2TP_AVP_PHY_CHANNEL_ID 25 /* Physical Channel ID */ 132a90e161bSBill Fenner #define L2TP_AVP_INI_RECV_LCP 26 /* Initial Received LCP CONFREQ */ 133a90e161bSBill Fenner #define L2TP_AVP_LAST_SENT_LCP 27 /* Last Sent LCP CONFREQ */ 134a90e161bSBill Fenner #define L2TP_AVP_LAST_RECV_LCP 28 /* Last Received LCP CONFREQ */ 135a90e161bSBill Fenner #define L2TP_AVP_PROXY_AUTH_TYPE 29 /* Proxy Authen Type */ 136a90e161bSBill Fenner #define L2TP_AVP_PROXY_AUTH_NAME 30 /* Proxy Authen Name */ 137a90e161bSBill Fenner #define L2TP_AVP_PROXY_AUTH_CHAL 31 /* Proxy Authen Challenge */ 138a90e161bSBill Fenner #define L2TP_AVP_PROXY_AUTH_ID 32 /* Proxy Authen ID */ 139a90e161bSBill Fenner #define L2TP_AVP_PROXY_AUTH_RESP 33 /* Proxy Authen Response */ 140a90e161bSBill Fenner #define L2TP_AVP_CALL_ERRORS 34 /* Call Errors */ 141a90e161bSBill Fenner #define L2TP_AVP_ACCM 35 /* ACCM */ 142a90e161bSBill Fenner #define L2TP_AVP_RANDOM_VECTOR 36 /* Random Vector */ 143a90e161bSBill Fenner #define L2TP_AVP_PRIVATE_GRP_ID 37 /* Private Group ID */ 144a90e161bSBill Fenner #define L2TP_AVP_RX_CONN_SPEED 38 /* (Rx) Connect Speed */ 145a90e161bSBill Fenner #define L2TP_AVP_SEQ_REQUIRED 39 /* Sequencing Required */ 146a90e161bSBill Fenner #define L2TP_AVP_PPP_DISCON_CC 46 /* PPP Disconnect Cause Code */ 147b0453382SBill Fenner 1483c602fabSXin LI static const struct tok l2tp_avp2str[] = { 149a90e161bSBill Fenner { L2TP_AVP_MSGTYPE, "MSGTYPE" }, 150a90e161bSBill Fenner { L2TP_AVP_RESULT_CODE, "RESULT_CODE" }, 151a90e161bSBill Fenner { L2TP_AVP_PROTO_VER, "PROTO_VER" }, 152a90e161bSBill Fenner { L2TP_AVP_FRAMING_CAP, "FRAMING_CAP" }, 153a90e161bSBill Fenner { L2TP_AVP_BEARER_CAP, "BEARER_CAP" }, 154a90e161bSBill Fenner { L2TP_AVP_TIE_BREAKER, "TIE_BREAKER" }, 155a90e161bSBill Fenner { L2TP_AVP_FIRM_VER, "FIRM_VER" }, 156a90e161bSBill Fenner { L2TP_AVP_HOST_NAME, "HOST_NAME" }, 157a90e161bSBill Fenner { L2TP_AVP_VENDOR_NAME, "VENDOR_NAME" }, 158a90e161bSBill Fenner { L2TP_AVP_ASSND_TUN_ID, "ASSND_TUN_ID" }, 159a90e161bSBill Fenner { L2TP_AVP_RECV_WIN_SIZE, "RECV_WIN_SIZE" }, 160a90e161bSBill Fenner { L2TP_AVP_CHALLENGE, "CHALLENGE" }, 161a90e161bSBill Fenner { L2TP_AVP_Q931_CC, "Q931_CC", }, 162a90e161bSBill Fenner { L2TP_AVP_CHALLENGE_RESP, "CHALLENGE_RESP" }, 163a90e161bSBill Fenner { L2TP_AVP_ASSND_SESS_ID, "ASSND_SESS_ID" }, 164a90e161bSBill Fenner { L2TP_AVP_CALL_SER_NUM, "CALL_SER_NUM" }, 165a90e161bSBill Fenner { L2TP_AVP_MINIMUM_BPS, "MINIMUM_BPS" }, 166a90e161bSBill Fenner { L2TP_AVP_MAXIMUM_BPS, "MAXIMUM_BPS" }, 167a90e161bSBill Fenner { L2TP_AVP_BEARER_TYPE, "BEARER_TYPE" }, 168a90e161bSBill Fenner { L2TP_AVP_FRAMING_TYPE, "FRAMING_TYPE" }, 169a90e161bSBill Fenner { L2TP_AVP_PACKET_PROC_DELAY, "PACKET_PROC_DELAY" }, 170a90e161bSBill Fenner { L2TP_AVP_CALLED_NUMBER, "CALLED_NUMBER" }, 171a90e161bSBill Fenner { L2TP_AVP_CALLING_NUMBER, "CALLING_NUMBER" }, 172a90e161bSBill Fenner { L2TP_AVP_SUB_ADDRESS, "SUB_ADDRESS" }, 173a90e161bSBill Fenner { L2TP_AVP_TX_CONN_SPEED, "TX_CONN_SPEED" }, 174a90e161bSBill Fenner { L2TP_AVP_PHY_CHANNEL_ID, "PHY_CHANNEL_ID" }, 175a90e161bSBill Fenner { L2TP_AVP_INI_RECV_LCP, "INI_RECV_LCP" }, 176a90e161bSBill Fenner { L2TP_AVP_LAST_SENT_LCP, "LAST_SENT_LCP" }, 177a90e161bSBill Fenner { L2TP_AVP_LAST_RECV_LCP, "LAST_RECV_LCP" }, 178a90e161bSBill Fenner { L2TP_AVP_PROXY_AUTH_TYPE, "PROXY_AUTH_TYPE" }, 179a90e161bSBill Fenner { L2TP_AVP_PROXY_AUTH_NAME, "PROXY_AUTH_NAME" }, 180a90e161bSBill Fenner { L2TP_AVP_PROXY_AUTH_CHAL, "PROXY_AUTH_CHAL" }, 181a90e161bSBill Fenner { L2TP_AVP_PROXY_AUTH_ID, "PROXY_AUTH_ID" }, 182a90e161bSBill Fenner { L2TP_AVP_PROXY_AUTH_RESP, "PROXY_AUTH_RESP" }, 183a90e161bSBill Fenner { L2TP_AVP_CALL_ERRORS, "CALL_ERRORS" }, 184a90e161bSBill Fenner { L2TP_AVP_ACCM, "ACCM" }, 185a90e161bSBill Fenner { L2TP_AVP_RANDOM_VECTOR, "RANDOM_VECTOR" }, 186a90e161bSBill Fenner { L2TP_AVP_PRIVATE_GRP_ID, "PRIVATE_GRP_ID" }, 187a90e161bSBill Fenner { L2TP_AVP_RX_CONN_SPEED, "RX_CONN_SPEED" }, 188a90e161bSBill Fenner { L2TP_AVP_SEQ_REQUIRED, "SEQ_REQUIRED" }, 189a90e161bSBill Fenner { L2TP_AVP_PPP_DISCON_CC, "PPP_DISCON_CC" }, 190a90e161bSBill Fenner { 0, NULL } 191a90e161bSBill Fenner }; 192a90e161bSBill Fenner 1933c602fabSXin LI static const struct tok l2tp_authentype2str[] = { 194a90e161bSBill Fenner { L2TP_AUTHEN_TYPE_RESERVED, "Reserved" }, 195a90e161bSBill Fenner { L2TP_AUTHEN_TYPE_TEXTUAL, "Textual" }, 196a90e161bSBill Fenner { L2TP_AUTHEN_TYPE_CHAP, "CHAP" }, 197a90e161bSBill Fenner { L2TP_AUTHEN_TYPE_PAP, "PAP" }, 198a90e161bSBill Fenner { L2TP_AUTHEN_TYPE_NO_AUTH, "No Auth" }, 199a90e161bSBill Fenner { L2TP_AUTHEN_TYPE_MSCHAPv1, "MS-CHAPv1" }, 200a90e161bSBill Fenner { 0, NULL } 201a90e161bSBill Fenner }; 202a90e161bSBill Fenner 203a90e161bSBill Fenner #define L2TP_PPP_DISCON_CC_DIRECTION_GLOBAL 0 204a90e161bSBill Fenner #define L2TP_PPP_DISCON_CC_DIRECTION_AT_PEER 1 205a90e161bSBill Fenner #define L2TP_PPP_DISCON_CC_DIRECTION_AT_LOCAL 2 206a90e161bSBill Fenner 2073c602fabSXin LI static const struct tok l2tp_cc_direction2str[] = { 208a90e161bSBill Fenner { L2TP_PPP_DISCON_CC_DIRECTION_GLOBAL, "global error" }, 209a90e161bSBill Fenner { L2TP_PPP_DISCON_CC_DIRECTION_AT_PEER, "at peer" }, 210a90e161bSBill Fenner { L2TP_PPP_DISCON_CC_DIRECTION_AT_LOCAL,"at local" }, 211a90e161bSBill Fenner { 0, NULL } 212b0453382SBill Fenner }; 213b0453382SBill Fenner 214b0453382SBill Fenner #if 0 215b0453382SBill Fenner static char *l2tp_result_code_StopCCN[] = { 216b0453382SBill Fenner "Reserved", 217b0453382SBill Fenner "General request to clear control connection", 218b0453382SBill Fenner "General error--Error Code indicates the problem", 219b0453382SBill Fenner "Control channel already exists", 220b0453382SBill Fenner "Requester is not authorized to establish a control channel", 221b0453382SBill Fenner "The protocol version of the requester is not supported", 222b0453382SBill Fenner "Requester is being shut down", 223b0453382SBill Fenner "Finite State Machine error" 224b0453382SBill Fenner #define L2TP_MAX_RESULT_CODE_STOPCC_INDEX 8 225b0453382SBill Fenner }; 226b0453382SBill Fenner #endif 227b0453382SBill Fenner 228b0453382SBill Fenner #if 0 229b0453382SBill Fenner static char *l2tp_result_code_CDN[] = { 230b0453382SBill Fenner "Reserved", 231b0453382SBill Fenner "Call disconnected due to loss of carrier", 232b0453382SBill Fenner "Call disconnected for the reason indicated in error code", 233b0453382SBill Fenner "Call disconnected for administrative reasons", 234b0453382SBill Fenner "Call failed due to lack of appropriate facilities being " \ 235b0453382SBill Fenner "available (temporary condition)", 236b0453382SBill Fenner "Call failed due to lack of appropriate facilities being " \ 237b0453382SBill Fenner "available (permanent condition)", 238b0453382SBill Fenner "Invalid destination", 239b0453382SBill Fenner "Call failed due to no carrier detected", 240b0453382SBill Fenner "Call failed due to detection of a busy signal", 241b0453382SBill Fenner "Call failed due to lack of a dial tone", 242b0453382SBill Fenner "Call was not established within time allotted by LAC", 243b0453382SBill Fenner "Call was connected but no appropriate framing was detected" 244b0453382SBill Fenner #define L2TP_MAX_RESULT_CODE_CDN_INDEX 12 245b0453382SBill Fenner }; 246b0453382SBill Fenner #endif 247b0453382SBill Fenner 248b0453382SBill Fenner #if 0 249b0453382SBill Fenner static char *l2tp_error_code_general[] = { 250b0453382SBill Fenner "No general error", 251b0453382SBill Fenner "No control connection exists yet for this LAC-LNS pair", 252b0453382SBill Fenner "Length is wrong", 253b0453382SBill Fenner "One of the field values was out of range or " \ 254b0453382SBill Fenner "reserved field was non-zero" 255b0453382SBill Fenner "Insufficient resources to handle this operation now", 256b0453382SBill Fenner "The Session ID is invalid in this context", 257b0453382SBill Fenner "A generic vendor-specific error occurred in the LAC", 258b0453382SBill Fenner "Try another" 259b0453382SBill Fenner #define L2TP_MAX_ERROR_CODE_GENERAL_INDEX 8 260b0453382SBill Fenner }; 261b0453382SBill Fenner #endif 262b0453382SBill Fenner 263b0453382SBill Fenner /******************************/ 264b0453382SBill Fenner /* generic print out routines */ 265b0453382SBill Fenner /******************************/ 266b0453382SBill Fenner static void 2673c602fabSXin LI print_string(netdissect_options *ndo, const u_char *dat, u_int length) 268b0453382SBill Fenner { 2695b0fe478SBruce M Simpson u_int i; 270b0453382SBill Fenner for (i=0; i<length; i++) { 2713c602fabSXin LI ND_PRINT((ndo, "%c", *dat++)); 272b0453382SBill Fenner } 273b0453382SBill Fenner } 274b0453382SBill Fenner 275b0453382SBill Fenner static void 2763c602fabSXin LI print_octets(netdissect_options *ndo, const u_char *dat, u_int length) 277b0453382SBill Fenner { 2785b0fe478SBruce M Simpson u_int i; 279b0453382SBill Fenner for (i=0; i<length; i++) { 2803c602fabSXin LI ND_PRINT((ndo, "%02x", *dat++)); 281b0453382SBill Fenner } 282b0453382SBill Fenner } 283b0453382SBill Fenner 284b0453382SBill Fenner static void 2853c602fabSXin LI print_16bits_val(netdissect_options *ndo, const uint16_t *dat) 286b0453382SBill Fenner { 2873c602fabSXin LI ND_PRINT((ndo, "%u", EXTRACT_16BITS(dat))); 288b0453382SBill Fenner } 289b0453382SBill Fenner 290b0453382SBill Fenner static void 2913c602fabSXin LI print_32bits_val(netdissect_options *ndo, const uint32_t *dat) 292b0453382SBill Fenner { 2933c602fabSXin LI ND_PRINT((ndo, "%lu", (u_long)EXTRACT_32BITS(dat))); 294b0453382SBill Fenner } 295b0453382SBill Fenner 296a90e161bSBill Fenner /***********************************/ 297b0453382SBill Fenner /* AVP-specific print out routines */ 298a90e161bSBill Fenner /***********************************/ 299b0453382SBill Fenner static void 300*0bff6a5aSEd Maste l2tp_msgtype_print(netdissect_options *ndo, const u_char *dat, u_int length) 301b0453382SBill Fenner { 3023340d773SGleb Smirnoff const uint16_t *ptr = (const uint16_t *)dat; 303b0453382SBill Fenner 304*0bff6a5aSEd Maste if (length < 2) { 305*0bff6a5aSEd Maste ND_PRINT((ndo, "AVP too short")); 306*0bff6a5aSEd Maste return; 307*0bff6a5aSEd Maste } 3083c602fabSXin LI ND_PRINT((ndo, "%s", tok2str(l2tp_msgtype2str, "MSGTYPE-#%u", 3093c602fabSXin LI EXTRACT_16BITS(ptr)))); 310b0453382SBill Fenner } 311b0453382SBill Fenner 312b0453382SBill Fenner static void 3133c602fabSXin LI l2tp_result_code_print(netdissect_options *ndo, const u_char *dat, u_int length) 314b0453382SBill Fenner { 3153340d773SGleb Smirnoff const uint16_t *ptr = (const uint16_t *)dat; 316b0453382SBill Fenner 317*0bff6a5aSEd Maste /* Result Code */ 318*0bff6a5aSEd Maste if (length < 2) { 319*0bff6a5aSEd Maste ND_PRINT((ndo, "AVP too short")); 320*0bff6a5aSEd Maste return; 321a90e161bSBill Fenner } 322*0bff6a5aSEd Maste ND_PRINT((ndo, "%u", EXTRACT_16BITS(ptr))); 323*0bff6a5aSEd Maste ptr++; 324*0bff6a5aSEd Maste length -= 2; 325*0bff6a5aSEd Maste 326*0bff6a5aSEd Maste /* Error Code (opt) */ 327*0bff6a5aSEd Maste if (length == 0) 328*0bff6a5aSEd Maste return; 329*0bff6a5aSEd Maste if (length < 2) { 330*0bff6a5aSEd Maste ND_PRINT((ndo, " AVP too short")); 331*0bff6a5aSEd Maste return; 332*0bff6a5aSEd Maste } 333*0bff6a5aSEd Maste ND_PRINT((ndo, "/%u", EXTRACT_16BITS(ptr))); 334*0bff6a5aSEd Maste ptr++; 335*0bff6a5aSEd Maste length -= 2; 336*0bff6a5aSEd Maste 337*0bff6a5aSEd Maste /* Error Message (opt) */ 338*0bff6a5aSEd Maste if (length == 0) 339*0bff6a5aSEd Maste return; 3403c602fabSXin LI ND_PRINT((ndo, " ")); 341*0bff6a5aSEd Maste print_string(ndo, (const u_char *)ptr, length); 342b0453382SBill Fenner } 343b0453382SBill Fenner 344b0453382SBill Fenner static void 345*0bff6a5aSEd Maste l2tp_proto_ver_print(netdissect_options *ndo, const uint16_t *dat, u_int length) 346b0453382SBill Fenner { 347*0bff6a5aSEd Maste if (length < 2) { 348*0bff6a5aSEd Maste ND_PRINT((ndo, "AVP too short")); 349*0bff6a5aSEd Maste return; 350*0bff6a5aSEd Maste } 3513c602fabSXin LI ND_PRINT((ndo, "%u.%u", (EXTRACT_16BITS(dat) >> 8), 3523c602fabSXin LI (EXTRACT_16BITS(dat) & 0xff))); 353b0453382SBill Fenner } 354b0453382SBill Fenner 355b0453382SBill Fenner static void 356*0bff6a5aSEd Maste l2tp_framing_cap_print(netdissect_options *ndo, const u_char *dat, u_int length) 357b0453382SBill Fenner { 3583340d773SGleb Smirnoff const uint32_t *ptr = (const uint32_t *)dat; 359b0453382SBill Fenner 360*0bff6a5aSEd Maste if (length < 4) { 361*0bff6a5aSEd Maste ND_PRINT((ndo, "AVP too short")); 362*0bff6a5aSEd Maste return; 363*0bff6a5aSEd Maste } 3649afd0c29SBill Fenner if (EXTRACT_32BITS(ptr) & L2TP_FRAMING_CAP_ASYNC_MASK) { 3653c602fabSXin LI ND_PRINT((ndo, "A")); 366b0453382SBill Fenner } 3679afd0c29SBill Fenner if (EXTRACT_32BITS(ptr) & L2TP_FRAMING_CAP_SYNC_MASK) { 3683c602fabSXin LI ND_PRINT((ndo, "S")); 369b0453382SBill Fenner } 370b0453382SBill Fenner } 371b0453382SBill Fenner 372b0453382SBill Fenner static void 373*0bff6a5aSEd Maste l2tp_bearer_cap_print(netdissect_options *ndo, const u_char *dat, u_int length) 374b0453382SBill Fenner { 3753340d773SGleb Smirnoff const uint32_t *ptr = (const uint32_t *)dat; 376b0453382SBill Fenner 377*0bff6a5aSEd Maste if (length < 4) { 378*0bff6a5aSEd Maste ND_PRINT((ndo, "AVP too short")); 379*0bff6a5aSEd Maste return; 380*0bff6a5aSEd Maste } 3819afd0c29SBill Fenner if (EXTRACT_32BITS(ptr) & L2TP_BEARER_CAP_ANALOG_MASK) { 3823c602fabSXin LI ND_PRINT((ndo, "A")); 383b0453382SBill Fenner } 3849afd0c29SBill Fenner if (EXTRACT_32BITS(ptr) & L2TP_BEARER_CAP_DIGITAL_MASK) { 3853c602fabSXin LI ND_PRINT((ndo, "D")); 386b0453382SBill Fenner } 387b0453382SBill Fenner } 388b0453382SBill Fenner 389b0453382SBill Fenner static void 3903c602fabSXin LI l2tp_q931_cc_print(netdissect_options *ndo, const u_char *dat, u_int length) 391b0453382SBill Fenner { 392*0bff6a5aSEd Maste if (length < 3) { 393*0bff6a5aSEd Maste ND_PRINT((ndo, "AVP too short")); 394*0bff6a5aSEd Maste return; 395*0bff6a5aSEd Maste } 3963340d773SGleb Smirnoff print_16bits_val(ndo, (const uint16_t *)dat); 3973c602fabSXin LI ND_PRINT((ndo, ", %02x", dat[2])); 398*0bff6a5aSEd Maste dat += 3; 399*0bff6a5aSEd Maste length -= 3; 400*0bff6a5aSEd Maste if (length != 0) { 4013c602fabSXin LI ND_PRINT((ndo, " ")); 402*0bff6a5aSEd Maste print_string(ndo, dat, length); 403b0453382SBill Fenner } 404b0453382SBill Fenner } 405b0453382SBill Fenner 406b0453382SBill Fenner static void 407*0bff6a5aSEd Maste l2tp_bearer_type_print(netdissect_options *ndo, const u_char *dat, u_int length) 408b0453382SBill Fenner { 4093340d773SGleb Smirnoff const uint32_t *ptr = (const uint32_t *)dat; 410b0453382SBill Fenner 411*0bff6a5aSEd Maste if (length < 4) { 412*0bff6a5aSEd Maste ND_PRINT((ndo, "AVP too short")); 413*0bff6a5aSEd Maste return; 414*0bff6a5aSEd Maste } 4159afd0c29SBill Fenner if (EXTRACT_32BITS(ptr) & L2TP_BEARER_TYPE_ANALOG_MASK) { 4163c602fabSXin LI ND_PRINT((ndo, "A")); 417b0453382SBill Fenner } 4189afd0c29SBill Fenner if (EXTRACT_32BITS(ptr) & L2TP_BEARER_TYPE_DIGITAL_MASK) { 4193c602fabSXin LI ND_PRINT((ndo, "D")); 420b0453382SBill Fenner } 421b0453382SBill Fenner } 422b0453382SBill Fenner 423b0453382SBill Fenner static void 424*0bff6a5aSEd Maste l2tp_framing_type_print(netdissect_options *ndo, const u_char *dat, u_int length) 425b0453382SBill Fenner { 4263340d773SGleb Smirnoff const uint32_t *ptr = (const uint32_t *)dat; 427b0453382SBill Fenner 428*0bff6a5aSEd Maste if (length < 4) { 429*0bff6a5aSEd Maste ND_PRINT((ndo, "AVP too short")); 430*0bff6a5aSEd Maste return; 431*0bff6a5aSEd Maste } 4329afd0c29SBill Fenner if (EXTRACT_32BITS(ptr) & L2TP_FRAMING_TYPE_ASYNC_MASK) { 4333c602fabSXin LI ND_PRINT((ndo, "A")); 434b0453382SBill Fenner } 4359afd0c29SBill Fenner if (EXTRACT_32BITS(ptr) & L2TP_FRAMING_TYPE_SYNC_MASK) { 4363c602fabSXin LI ND_PRINT((ndo, "S")); 437b0453382SBill Fenner } 438b0453382SBill Fenner } 439b0453382SBill Fenner 440b0453382SBill Fenner static void 4413c602fabSXin LI l2tp_packet_proc_delay_print(netdissect_options *ndo) 442b0453382SBill Fenner { 4433c602fabSXin LI ND_PRINT((ndo, "obsolete")); 444b0453382SBill Fenner } 445b0453382SBill Fenner 446b0453382SBill Fenner static void 447*0bff6a5aSEd Maste l2tp_proxy_auth_type_print(netdissect_options *ndo, const u_char *dat, u_int length) 448b0453382SBill Fenner { 4493340d773SGleb Smirnoff const uint16_t *ptr = (const uint16_t *)dat; 450a90e161bSBill Fenner 451*0bff6a5aSEd Maste if (length < 2) { 452*0bff6a5aSEd Maste ND_PRINT((ndo, "AVP too short")); 453*0bff6a5aSEd Maste return; 454*0bff6a5aSEd Maste } 4553c602fabSXin LI ND_PRINT((ndo, "%s", tok2str(l2tp_authentype2str, 4563c602fabSXin LI "AuthType-#%u", EXTRACT_16BITS(ptr)))); 457b0453382SBill Fenner } 458b0453382SBill Fenner 459b0453382SBill Fenner static void 460*0bff6a5aSEd Maste l2tp_proxy_auth_id_print(netdissect_options *ndo, const u_char *dat, u_int length) 461b0453382SBill Fenner { 4623340d773SGleb Smirnoff const uint16_t *ptr = (const uint16_t *)dat; 463b0453382SBill Fenner 464*0bff6a5aSEd Maste if (length < 2) { 465*0bff6a5aSEd Maste ND_PRINT((ndo, "AVP too short")); 466*0bff6a5aSEd Maste return; 467*0bff6a5aSEd Maste } 4683c602fabSXin LI ND_PRINT((ndo, "%u", EXTRACT_16BITS(ptr) & L2TP_PROXY_AUTH_ID_MASK)); 469b0453382SBill Fenner } 470b0453382SBill Fenner 471b0453382SBill Fenner static void 472*0bff6a5aSEd Maste l2tp_call_errors_print(netdissect_options *ndo, const u_char *dat, u_int length) 473b0453382SBill Fenner { 4743340d773SGleb Smirnoff const uint16_t *ptr = (const uint16_t *)dat; 4753c602fabSXin LI uint16_t val_h, val_l; 476a90e161bSBill Fenner 477*0bff6a5aSEd Maste if (length < 2) { 478*0bff6a5aSEd Maste ND_PRINT((ndo, "AVP too short")); 479*0bff6a5aSEd Maste return; 480*0bff6a5aSEd Maste } 481a90e161bSBill Fenner ptr++; /* skip "Reserved" */ 482*0bff6a5aSEd Maste length -= 2; 483a90e161bSBill Fenner 484*0bff6a5aSEd Maste if (length < 4) { 485*0bff6a5aSEd Maste ND_PRINT((ndo, "AVP too short")); 486*0bff6a5aSEd Maste return; 487*0bff6a5aSEd Maste } 488*0bff6a5aSEd Maste val_h = EXTRACT_16BITS(ptr); ptr++; length -= 2; 489*0bff6a5aSEd Maste val_l = EXTRACT_16BITS(ptr); ptr++; length -= 2; 4903c602fabSXin LI ND_PRINT((ndo, "CRCErr=%u ", (val_h<<16) + val_l)); 491a90e161bSBill Fenner 492*0bff6a5aSEd Maste if (length < 4) { 493*0bff6a5aSEd Maste ND_PRINT((ndo, "AVP too short")); 494*0bff6a5aSEd Maste return; 495*0bff6a5aSEd Maste } 496*0bff6a5aSEd Maste val_h = EXTRACT_16BITS(ptr); ptr++; length -= 2; 497*0bff6a5aSEd Maste val_l = EXTRACT_16BITS(ptr); ptr++; length -= 2; 4983c602fabSXin LI ND_PRINT((ndo, "FrameErr=%u ", (val_h<<16) + val_l)); 499a90e161bSBill Fenner 500*0bff6a5aSEd Maste if (length < 4) { 501*0bff6a5aSEd Maste ND_PRINT((ndo, "AVP too short")); 502*0bff6a5aSEd Maste return; 503*0bff6a5aSEd Maste } 504*0bff6a5aSEd Maste val_h = EXTRACT_16BITS(ptr); ptr++; length -= 2; 505*0bff6a5aSEd Maste val_l = EXTRACT_16BITS(ptr); ptr++; length -= 2; 5063c602fabSXin LI ND_PRINT((ndo, "HardOver=%u ", (val_h<<16) + val_l)); 507a90e161bSBill Fenner 508*0bff6a5aSEd Maste if (length < 4) { 509*0bff6a5aSEd Maste ND_PRINT((ndo, "AVP too short")); 510*0bff6a5aSEd Maste return; 511*0bff6a5aSEd Maste } 512*0bff6a5aSEd Maste val_h = EXTRACT_16BITS(ptr); ptr++; length -= 2; 513*0bff6a5aSEd Maste val_l = EXTRACT_16BITS(ptr); ptr++; length -= 2; 5143c602fabSXin LI ND_PRINT((ndo, "BufOver=%u ", (val_h<<16) + val_l)); 515a90e161bSBill Fenner 516*0bff6a5aSEd Maste if (length < 4) { 517*0bff6a5aSEd Maste ND_PRINT((ndo, "AVP too short")); 518*0bff6a5aSEd Maste return; 519*0bff6a5aSEd Maste } 520*0bff6a5aSEd Maste val_h = EXTRACT_16BITS(ptr); ptr++; length -= 2; 521*0bff6a5aSEd Maste val_l = EXTRACT_16BITS(ptr); ptr++; length -= 2; 5223c602fabSXin LI ND_PRINT((ndo, "Timeout=%u ", (val_h<<16) + val_l)); 523a90e161bSBill Fenner 524*0bff6a5aSEd Maste if (length < 4) { 525*0bff6a5aSEd Maste ND_PRINT((ndo, "AVP too short")); 526*0bff6a5aSEd Maste return; 527*0bff6a5aSEd Maste } 5289afd0c29SBill Fenner val_h = EXTRACT_16BITS(ptr); ptr++; 5299afd0c29SBill Fenner val_l = EXTRACT_16BITS(ptr); ptr++; 5303c602fabSXin LI ND_PRINT((ndo, "AlignErr=%u ", (val_h<<16) + val_l)); 531b0453382SBill Fenner } 532b0453382SBill Fenner 533b0453382SBill Fenner static void 534*0bff6a5aSEd Maste l2tp_accm_print(netdissect_options *ndo, const u_char *dat, u_int length) 535b0453382SBill Fenner { 5363340d773SGleb Smirnoff const uint16_t *ptr = (const uint16_t *)dat; 5373c602fabSXin LI uint16_t val_h, val_l; 538b0453382SBill Fenner 539*0bff6a5aSEd Maste if (length < 2) { 540*0bff6a5aSEd Maste ND_PRINT((ndo, "AVP too short")); 541*0bff6a5aSEd Maste return; 542*0bff6a5aSEd Maste } 543a90e161bSBill Fenner ptr++; /* skip "Reserved" */ 544*0bff6a5aSEd Maste length -= 2; 545a90e161bSBill Fenner 546*0bff6a5aSEd Maste if (length < 4) { 547*0bff6a5aSEd Maste ND_PRINT((ndo, "AVP too short")); 548*0bff6a5aSEd Maste return; 549*0bff6a5aSEd Maste } 550*0bff6a5aSEd Maste val_h = EXTRACT_16BITS(ptr); ptr++; length -= 2; 551*0bff6a5aSEd Maste val_l = EXTRACT_16BITS(ptr); ptr++; length -= 2; 5523c602fabSXin LI ND_PRINT((ndo, "send=%08x ", (val_h<<16) + val_l)); 553a90e161bSBill Fenner 554*0bff6a5aSEd Maste if (length < 4) { 555*0bff6a5aSEd Maste ND_PRINT((ndo, "AVP too short")); 556*0bff6a5aSEd Maste return; 557*0bff6a5aSEd Maste } 5589afd0c29SBill Fenner val_h = EXTRACT_16BITS(ptr); ptr++; 5599afd0c29SBill Fenner val_l = EXTRACT_16BITS(ptr); ptr++; 5603c602fabSXin LI ND_PRINT((ndo, "recv=%08x ", (val_h<<16) + val_l)); 561b0453382SBill Fenner } 562b0453382SBill Fenner 563b0453382SBill Fenner static void 5643c602fabSXin LI l2tp_ppp_discon_cc_print(netdissect_options *ndo, const u_char *dat, u_int length) 565b0453382SBill Fenner { 5663340d773SGleb Smirnoff const uint16_t *ptr = (const uint16_t *)dat; 567b0453382SBill Fenner 568*0bff6a5aSEd Maste if (length < 5) { 569*0bff6a5aSEd Maste ND_PRINT((ndo, "AVP too short")); 570*0bff6a5aSEd Maste return; 571*0bff6a5aSEd Maste } 572*0bff6a5aSEd Maste /* Disconnect Code */ 573*0bff6a5aSEd Maste ND_PRINT((ndo, "%04x, ", EXTRACT_16BITS(dat))); 574*0bff6a5aSEd Maste dat += 2; 575*0bff6a5aSEd Maste length -= 2; 576*0bff6a5aSEd Maste /* Control Protocol Number */ 577*0bff6a5aSEd Maste ND_PRINT((ndo, "%04x ", EXTRACT_16BITS(dat))); 578*0bff6a5aSEd Maste dat += 2; 579*0bff6a5aSEd Maste length -= 2; 580*0bff6a5aSEd Maste /* Direction */ 5813c602fabSXin LI ND_PRINT((ndo, "%s", tok2str(l2tp_cc_direction2str, 582*0bff6a5aSEd Maste "Direction-#%u", EXTRACT_8BITS(ptr)))); 583*0bff6a5aSEd Maste ptr++; 584*0bff6a5aSEd Maste length--; 585a90e161bSBill Fenner 586*0bff6a5aSEd Maste if (length != 0) { 5873c602fabSXin LI ND_PRINT((ndo, " ")); 588*0bff6a5aSEd Maste print_string(ndo, (const u_char *)ptr, length); 589a90e161bSBill Fenner } 590b0453382SBill Fenner } 591b0453382SBill Fenner 592b0453382SBill Fenner static void 5933c602fabSXin LI l2tp_avp_print(netdissect_options *ndo, const u_char *dat, int length) 594b0453382SBill Fenner { 595a90e161bSBill Fenner u_int len; 5963340d773SGleb Smirnoff const uint16_t *ptr = (const uint16_t *)dat; 5973c602fabSXin LI uint16_t attr_type; 598a90e161bSBill Fenner int hidden = FALSE; 599b0453382SBill Fenner 600a90e161bSBill Fenner if (length <= 0) { 601b0453382SBill Fenner return; 602b0453382SBill Fenner } 603b0453382SBill Fenner 6043c602fabSXin LI ND_PRINT((ndo, " ")); 605a90e161bSBill Fenner 6063c602fabSXin LI ND_TCHECK(*ptr); /* Flags & Length */ 6079afd0c29SBill Fenner len = EXTRACT_16BITS(ptr) & L2TP_AVP_HDR_LEN_MASK; 608a90e161bSBill Fenner 609b97c9af5SBill Fenner /* If it is not long enough to contain the header, we'll give up. */ 610b97c9af5SBill Fenner if (len < 6) 611b97c9af5SBill Fenner goto trunc; 612b97c9af5SBill Fenner 613b97c9af5SBill Fenner /* If it goes past the end of the remaining length of the packet, 614b97c9af5SBill Fenner we'll give up. */ 615b97c9af5SBill Fenner if (len > (u_int)length) 616b97c9af5SBill Fenner goto trunc; 617b97c9af5SBill Fenner 618b97c9af5SBill Fenner /* If it goes past the end of the remaining length of the captured 619b97c9af5SBill Fenner data, we'll give up. */ 6203c602fabSXin LI ND_TCHECK2(*ptr, len); 621*0bff6a5aSEd Maste 622*0bff6a5aSEd Maste /* 623*0bff6a5aSEd Maste * After this point, we don't need to check whether we go past 624*0bff6a5aSEd Maste * the length of the captured data; however, we *do* need to 625*0bff6a5aSEd Maste * check whether we go past the end of the AVP. 626*0bff6a5aSEd Maste */ 627a90e161bSBill Fenner 6289afd0c29SBill Fenner if (EXTRACT_16BITS(ptr) & L2TP_AVP_HDR_FLAG_MANDATORY) { 6293c602fabSXin LI ND_PRINT((ndo, "*")); 630b0453382SBill Fenner } 6319afd0c29SBill Fenner if (EXTRACT_16BITS(ptr) & L2TP_AVP_HDR_FLAG_HIDDEN) { 632b0453382SBill Fenner hidden = TRUE; 6333c602fabSXin LI ND_PRINT((ndo, "?")); 634b0453382SBill Fenner } 635b0453382SBill Fenner ptr++; 636b0453382SBill Fenner 6379afd0c29SBill Fenner if (EXTRACT_16BITS(ptr)) { 638685295f4SBill Fenner /* Vendor Specific Attribute */ 6393c602fabSXin LI ND_PRINT((ndo, "VENDOR%04x:", EXTRACT_16BITS(ptr))); ptr++; 6403c602fabSXin LI ND_PRINT((ndo, "ATTR%04x", EXTRACT_16BITS(ptr))); ptr++; 6413c602fabSXin LI ND_PRINT((ndo, "(")); 6423340d773SGleb Smirnoff print_octets(ndo, (const u_char *)ptr, len-6); 6433c602fabSXin LI ND_PRINT((ndo, ")")); 644685295f4SBill Fenner } else { 645a90e161bSBill Fenner /* IETF-defined Attributes */ 646685295f4SBill Fenner ptr++; 6479afd0c29SBill Fenner attr_type = EXTRACT_16BITS(ptr); ptr++; 6483c602fabSXin LI ND_PRINT((ndo, "%s", tok2str(l2tp_avp2str, "AVP-#%u", attr_type))); 6493c602fabSXin LI ND_PRINT((ndo, "(")); 650a90e161bSBill Fenner if (hidden) { 6513c602fabSXin LI ND_PRINT((ndo, "???")); 652a90e161bSBill Fenner } else { 653a90e161bSBill Fenner switch (attr_type) { 654a90e161bSBill Fenner case L2TP_AVP_MSGTYPE: 655*0bff6a5aSEd Maste l2tp_msgtype_print(ndo, (const u_char *)ptr, len-6); 656a90e161bSBill Fenner break; 657a90e161bSBill Fenner case L2TP_AVP_RESULT_CODE: 6583340d773SGleb Smirnoff l2tp_result_code_print(ndo, (const u_char *)ptr, len-6); 659a90e161bSBill Fenner break; 660a90e161bSBill Fenner case L2TP_AVP_PROTO_VER: 661*0bff6a5aSEd Maste l2tp_proto_ver_print(ndo, ptr, len-6); 662a90e161bSBill Fenner break; 663a90e161bSBill Fenner case L2TP_AVP_FRAMING_CAP: 664*0bff6a5aSEd Maste l2tp_framing_cap_print(ndo, (const u_char *)ptr, len-6); 665a90e161bSBill Fenner break; 666a90e161bSBill Fenner case L2TP_AVP_BEARER_CAP: 667*0bff6a5aSEd Maste l2tp_bearer_cap_print(ndo, (const u_char *)ptr, len-6); 668a90e161bSBill Fenner break; 669a90e161bSBill Fenner case L2TP_AVP_TIE_BREAKER: 670*0bff6a5aSEd Maste if (len-6 < 8) { 671*0bff6a5aSEd Maste ND_PRINT((ndo, "AVP too short")); 672*0bff6a5aSEd Maste break; 673*0bff6a5aSEd Maste } 6743340d773SGleb Smirnoff print_octets(ndo, (const u_char *)ptr, 8); 675a90e161bSBill Fenner break; 676a90e161bSBill Fenner case L2TP_AVP_FIRM_VER: 677a90e161bSBill Fenner case L2TP_AVP_ASSND_TUN_ID: 678a90e161bSBill Fenner case L2TP_AVP_RECV_WIN_SIZE: 679a90e161bSBill Fenner case L2TP_AVP_ASSND_SESS_ID: 680*0bff6a5aSEd Maste if (len-6 < 2) { 681*0bff6a5aSEd Maste ND_PRINT((ndo, "AVP too short")); 682*0bff6a5aSEd Maste break; 683*0bff6a5aSEd Maste } 6843c602fabSXin LI print_16bits_val(ndo, ptr); 685a90e161bSBill Fenner break; 686a90e161bSBill Fenner case L2TP_AVP_HOST_NAME: 687a90e161bSBill Fenner case L2TP_AVP_VENDOR_NAME: 688a90e161bSBill Fenner case L2TP_AVP_CALLING_NUMBER: 689a90e161bSBill Fenner case L2TP_AVP_CALLED_NUMBER: 690a90e161bSBill Fenner case L2TP_AVP_SUB_ADDRESS: 691a90e161bSBill Fenner case L2TP_AVP_PROXY_AUTH_NAME: 692a90e161bSBill Fenner case L2TP_AVP_PRIVATE_GRP_ID: 6933340d773SGleb Smirnoff print_string(ndo, (const u_char *)ptr, len-6); 694a90e161bSBill Fenner break; 695a90e161bSBill Fenner case L2TP_AVP_CHALLENGE: 696a90e161bSBill Fenner case L2TP_AVP_INI_RECV_LCP: 697a90e161bSBill Fenner case L2TP_AVP_LAST_SENT_LCP: 698a90e161bSBill Fenner case L2TP_AVP_LAST_RECV_LCP: 699a90e161bSBill Fenner case L2TP_AVP_PROXY_AUTH_CHAL: 700a90e161bSBill Fenner case L2TP_AVP_PROXY_AUTH_RESP: 701a90e161bSBill Fenner case L2TP_AVP_RANDOM_VECTOR: 7023340d773SGleb Smirnoff print_octets(ndo, (const u_char *)ptr, len-6); 703a90e161bSBill Fenner break; 704a90e161bSBill Fenner case L2TP_AVP_Q931_CC: 7053340d773SGleb Smirnoff l2tp_q931_cc_print(ndo, (const u_char *)ptr, len-6); 706a90e161bSBill Fenner break; 707a90e161bSBill Fenner case L2TP_AVP_CHALLENGE_RESP: 708*0bff6a5aSEd Maste if (len-6 < 16) { 709*0bff6a5aSEd Maste ND_PRINT((ndo, "AVP too short")); 710*0bff6a5aSEd Maste break; 711*0bff6a5aSEd Maste } 7123340d773SGleb Smirnoff print_octets(ndo, (const u_char *)ptr, 16); 713a90e161bSBill Fenner break; 714a90e161bSBill Fenner case L2TP_AVP_CALL_SER_NUM: 715a90e161bSBill Fenner case L2TP_AVP_MINIMUM_BPS: 716a90e161bSBill Fenner case L2TP_AVP_MAXIMUM_BPS: 717a90e161bSBill Fenner case L2TP_AVP_TX_CONN_SPEED: 718a90e161bSBill Fenner case L2TP_AVP_PHY_CHANNEL_ID: 719a90e161bSBill Fenner case L2TP_AVP_RX_CONN_SPEED: 720*0bff6a5aSEd Maste if (len-6 < 4) { 721*0bff6a5aSEd Maste ND_PRINT((ndo, "AVP too short")); 722*0bff6a5aSEd Maste break; 723*0bff6a5aSEd Maste } 7243340d773SGleb Smirnoff print_32bits_val(ndo, (const uint32_t *)ptr); 725a90e161bSBill Fenner break; 726a90e161bSBill Fenner case L2TP_AVP_BEARER_TYPE: 727*0bff6a5aSEd Maste l2tp_bearer_type_print(ndo, (const u_char *)ptr, len-6); 728a90e161bSBill Fenner break; 729a90e161bSBill Fenner case L2TP_AVP_FRAMING_TYPE: 730*0bff6a5aSEd Maste l2tp_framing_type_print(ndo, (const u_char *)ptr, len-6); 731a90e161bSBill Fenner break; 732a90e161bSBill Fenner case L2TP_AVP_PACKET_PROC_DELAY: 7333c602fabSXin LI l2tp_packet_proc_delay_print(ndo); 734a90e161bSBill Fenner break; 735a90e161bSBill Fenner case L2TP_AVP_PROXY_AUTH_TYPE: 736*0bff6a5aSEd Maste l2tp_proxy_auth_type_print(ndo, (const u_char *)ptr, len-6); 737a90e161bSBill Fenner break; 738a90e161bSBill Fenner case L2TP_AVP_PROXY_AUTH_ID: 739*0bff6a5aSEd Maste l2tp_proxy_auth_id_print(ndo, (const u_char *)ptr, len-6); 740a90e161bSBill Fenner break; 741a90e161bSBill Fenner case L2TP_AVP_CALL_ERRORS: 742*0bff6a5aSEd Maste l2tp_call_errors_print(ndo, (const u_char *)ptr, len-6); 743a90e161bSBill Fenner break; 744a90e161bSBill Fenner case L2TP_AVP_ACCM: 745*0bff6a5aSEd Maste l2tp_accm_print(ndo, (const u_char *)ptr, len-6); 746a90e161bSBill Fenner break; 747a90e161bSBill Fenner case L2TP_AVP_SEQ_REQUIRED: 748a90e161bSBill Fenner break; /* No Attribute Value */ 749a90e161bSBill Fenner case L2TP_AVP_PPP_DISCON_CC: 7503340d773SGleb Smirnoff l2tp_ppp_discon_cc_print(ndo, (const u_char *)ptr, len-6); 751a90e161bSBill Fenner break; 752a90e161bSBill Fenner default: 753a90e161bSBill Fenner break; 754a90e161bSBill Fenner } 755b0453382SBill Fenner } 7563c602fabSXin LI ND_PRINT((ndo, ")")); 757685295f4SBill Fenner } 758b0453382SBill Fenner 7593c602fabSXin LI l2tp_avp_print(ndo, dat+len, length-len); 760b0453382SBill Fenner return; 761a90e161bSBill Fenner 762a90e161bSBill Fenner trunc: 7633c602fabSXin LI ND_PRINT((ndo, "|...")); 764b0453382SBill Fenner } 765b0453382SBill Fenner 766b0453382SBill Fenner 767b0453382SBill Fenner void 7683c602fabSXin LI l2tp_print(netdissect_options *ndo, const u_char *dat, u_int length) 769b0453382SBill Fenner { 77027df3f5dSRui Paulo const u_char *ptr = dat; 771b0453382SBill Fenner u_int cnt = 0; /* total octets consumed */ 7723c602fabSXin LI uint16_t pad; 773f4d0c64aSSam Leffler int flag_t, flag_l, flag_s, flag_o; 7743c602fabSXin LI uint16_t l2tp_len; 775b0453382SBill Fenner 776f4d0c64aSSam Leffler flag_t = flag_l = flag_s = flag_o = FALSE; 777b0453382SBill Fenner 7783c602fabSXin LI ND_TCHECK2(*ptr, 2); /* Flags & Version */ 7799afd0c29SBill Fenner if ((EXTRACT_16BITS(ptr) & L2TP_VERSION_MASK) == L2TP_VERSION_L2TP) { 7803c602fabSXin LI ND_PRINT((ndo, " l2tp:")); 7819afd0c29SBill Fenner } else if ((EXTRACT_16BITS(ptr) & L2TP_VERSION_MASK) == L2TP_VERSION_L2F) { 7823c602fabSXin LI ND_PRINT((ndo, " l2f:")); 783b0453382SBill Fenner return; /* nothing to do */ 784b0453382SBill Fenner } else { 7853c602fabSXin LI ND_PRINT((ndo, " Unknown Version, neither L2F(1) nor L2TP(2)")); 786b0453382SBill Fenner return; /* nothing we can do */ 787b0453382SBill Fenner } 788b0453382SBill Fenner 7893c602fabSXin LI ND_PRINT((ndo, "[")); 7909afd0c29SBill Fenner if (EXTRACT_16BITS(ptr) & L2TP_FLAG_TYPE) { 791b0453382SBill Fenner flag_t = TRUE; 7923c602fabSXin LI ND_PRINT((ndo, "T")); 793b0453382SBill Fenner } 7949afd0c29SBill Fenner if (EXTRACT_16BITS(ptr) & L2TP_FLAG_LENGTH) { 795b0453382SBill Fenner flag_l = TRUE; 7963c602fabSXin LI ND_PRINT((ndo, "L")); 797b0453382SBill Fenner } 7989afd0c29SBill Fenner if (EXTRACT_16BITS(ptr) & L2TP_FLAG_SEQUENCE) { 799b0453382SBill Fenner flag_s = TRUE; 8003c602fabSXin LI ND_PRINT((ndo, "S")); 801b0453382SBill Fenner } 8029afd0c29SBill Fenner if (EXTRACT_16BITS(ptr) & L2TP_FLAG_OFFSET) { 803b0453382SBill Fenner flag_o = TRUE; 8043c602fabSXin LI ND_PRINT((ndo, "O")); 805b0453382SBill Fenner } 806f4d0c64aSSam Leffler if (EXTRACT_16BITS(ptr) & L2TP_FLAG_PRIORITY) 8073c602fabSXin LI ND_PRINT((ndo, "P")); 8083c602fabSXin LI ND_PRINT((ndo, "]")); 809b0453382SBill Fenner 81027df3f5dSRui Paulo ptr += 2; 811b0453382SBill Fenner cnt += 2; 812b0453382SBill Fenner 813b0453382SBill Fenner if (flag_l) { 8143c602fabSXin LI ND_TCHECK2(*ptr, 2); /* Length */ 81527df3f5dSRui Paulo l2tp_len = EXTRACT_16BITS(ptr); 81627df3f5dSRui Paulo ptr += 2; 817b0453382SBill Fenner cnt += 2; 818b0453382SBill Fenner } else { 819b0453382SBill Fenner l2tp_len = 0; 820b0453382SBill Fenner } 821b0453382SBill Fenner 8223c602fabSXin LI ND_TCHECK2(*ptr, 2); /* Tunnel ID */ 8233c602fabSXin LI ND_PRINT((ndo, "(%u/", EXTRACT_16BITS(ptr))); 82427df3f5dSRui Paulo ptr += 2; 825a90e161bSBill Fenner cnt += 2; 8263c602fabSXin LI ND_TCHECK2(*ptr, 2); /* Session ID */ 8273c602fabSXin LI ND_PRINT((ndo, "%u)", EXTRACT_16BITS(ptr))); 82827df3f5dSRui Paulo ptr += 2; 829a90e161bSBill Fenner cnt += 2; 830b0453382SBill Fenner 831b0453382SBill Fenner if (flag_s) { 8323c602fabSXin LI ND_TCHECK2(*ptr, 2); /* Ns */ 8333c602fabSXin LI ND_PRINT((ndo, "Ns=%u,", EXTRACT_16BITS(ptr))); 83427df3f5dSRui Paulo ptr += 2; 835a90e161bSBill Fenner cnt += 2; 8363c602fabSXin LI ND_TCHECK2(*ptr, 2); /* Nr */ 8373c602fabSXin LI ND_PRINT((ndo, "Nr=%u", EXTRACT_16BITS(ptr))); 83827df3f5dSRui Paulo ptr += 2; 839a90e161bSBill Fenner cnt += 2; 840b0453382SBill Fenner } 841b0453382SBill Fenner 842b0453382SBill Fenner if (flag_o) { 8433c602fabSXin LI ND_TCHECK2(*ptr, 2); /* Offset Size */ 84427df3f5dSRui Paulo pad = EXTRACT_16BITS(ptr); 84527df3f5dSRui Paulo ptr += (2 + pad); 846b0453382SBill Fenner cnt += (2 + pad); 847b0453382SBill Fenner } 848b0453382SBill Fenner 849f4d0c64aSSam Leffler if (flag_l) { 850f4d0c64aSSam Leffler if (length < l2tp_len) { 8513c602fabSXin LI ND_PRINT((ndo, " Length %u larger than packet", l2tp_len)); 852f4d0c64aSSam Leffler return; 853f4d0c64aSSam Leffler } 854f4d0c64aSSam Leffler length = l2tp_len; 855f4d0c64aSSam Leffler } 856f4d0c64aSSam Leffler if (length < cnt) { 8573c602fabSXin LI ND_PRINT((ndo, " Length %u smaller than header length", length)); 858f4d0c64aSSam Leffler return; 859f4d0c64aSSam Leffler } 860b0453382SBill Fenner if (flag_t) { 861f4d0c64aSSam Leffler if (!flag_l) { 8623c602fabSXin LI ND_PRINT((ndo, " No length")); 863f4d0c64aSSam Leffler return; 864f4d0c64aSSam Leffler } 865b0453382SBill Fenner if (length - cnt == 0) { 8663c602fabSXin LI ND_PRINT((ndo, " ZLB")); 867b0453382SBill Fenner } else { 8683c602fabSXin LI l2tp_avp_print(ndo, ptr, length - cnt); 869b0453382SBill Fenner } 870b0453382SBill Fenner } else { 8713c602fabSXin LI ND_PRINT((ndo, " {")); 8723c602fabSXin LI ppp_print(ndo, ptr, length - cnt); 8733c602fabSXin LI ND_PRINT((ndo, "}")); 874b0453382SBill Fenner } 875a90e161bSBill Fenner 876a90e161bSBill Fenner return; 877a90e161bSBill Fenner 878a90e161bSBill Fenner trunc: 8793c602fabSXin LI ND_PRINT((ndo, "%s", tstr)); 880b0453382SBill Fenner } 881