156893Sfenner/* 256893Sfenner * Copyright (c) 1991, 1993, 1994, 1995, 1996, 1997 356893Sfenner * The Regents of the University of California. All rights reserved. 456893Sfenner * 556893Sfenner * Redistribution and use in source and binary forms, with or without 656893Sfenner * modification, are permitted provided that: (1) source code distributions 756893Sfenner * retain the above copyright notice and this paragraph in its entirety, (2) 856893Sfenner * distributions including binary code include the above copyright notice and 956893Sfenner * this paragraph in its entirety in the documentation or other materials 1056893Sfenner * provided with the distribution, and (3) all advertising materials mentioning 1156893Sfenner * features or use of this software display the following acknowledgement: 1256893Sfenner * ``This product includes software developed by the University of California, 1356893Sfenner * Lawrence Berkeley Laboratory and its contributors.'' Neither the name of 1456893Sfenner * the University nor the names of its contributors may be used to endorse 1556893Sfenner * or promote products derived from this software without specific prior 1656893Sfenner * written permission. 1756893Sfenner * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR IMPLIED 1856893Sfenner * WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF 1956893Sfenner * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. 2056893Sfenner * 2175115Sfenner * L2TP support contributed by Motonori Shindo (mshindo@mshindo.net) 2256893Sfenner */ 2356893Sfenner 24276788Sdelphij#define NETDISSECT_REWORKED 2556893Sfenner#ifdef HAVE_CONFIG_H 2656893Sfenner#include "config.h" 2756893Sfenner#endif 2856893Sfenner 29127668Sbms#include <tcpdump-stdinc.h> 30127668Sbms 3156893Sfenner#include "interface.h" 32111726Sfenner#include "extract.h" 3356893Sfenner 34276788Sdelphij#define L2TP_FLAG_TYPE 0x8000 /* Type (0=Data, 1=Control) */ 35276788Sdelphij#define L2TP_FLAG_LENGTH 0x4000 /* Length */ 36276788Sdelphij#define L2TP_FLAG_SEQUENCE 0x0800 /* Sequence */ 37276788Sdelphij#define L2TP_FLAG_OFFSET 0x0200 /* Offset */ 38276788Sdelphij#define L2TP_FLAG_PRIORITY 0x0100 /* Priority */ 3956893Sfenner 40276788Sdelphij#define L2TP_VERSION_MASK 0x000f /* Version Mask */ 41276788Sdelphij#define L2TP_VERSION_L2F 0x0001 /* L2F */ 42276788Sdelphij#define L2TP_VERSION_L2TP 0x0002 /* L2TP */ 43276788Sdelphij 44276788Sdelphij#define L2TP_AVP_HDR_FLAG_MANDATORY 0x8000 /* Mandatory Flag */ 45276788Sdelphij#define L2TP_AVP_HDR_FLAG_HIDDEN 0x4000 /* Hidden Flag */ 46276788Sdelphij#define L2TP_AVP_HDR_LEN_MASK 0x03ff /* Length Mask */ 47276788Sdelphij 48276788Sdelphij#define L2TP_FRAMING_CAP_SYNC_MASK 0x00000001 /* Synchronous */ 49276788Sdelphij#define L2TP_FRAMING_CAP_ASYNC_MASK 0x00000002 /* Asynchronous */ 50276788Sdelphij 51276788Sdelphij#define L2TP_FRAMING_TYPE_SYNC_MASK 0x00000001 /* Synchronous */ 52276788Sdelphij#define L2TP_FRAMING_TYPE_ASYNC_MASK 0x00000002 /* Asynchronous */ 53276788Sdelphij 54276788Sdelphij#define L2TP_BEARER_CAP_DIGITAL_MASK 0x00000001 /* Digital */ 55276788Sdelphij#define L2TP_BEARER_CAP_ANALOG_MASK 0x00000002 /* Analog */ 56276788Sdelphij 57276788Sdelphij#define L2TP_BEARER_TYPE_DIGITAL_MASK 0x00000001 /* Digital */ 58276788Sdelphij#define L2TP_BEARER_TYPE_ANALOG_MASK 0x00000002 /* Analog */ 59276788Sdelphij 60276788Sdelphij/* Authen Type */ 61276788Sdelphij#define L2TP_AUTHEN_TYPE_RESERVED 0x0000 /* Reserved */ 62276788Sdelphij#define L2TP_AUTHEN_TYPE_TEXTUAL 0x0001 /* Textual username/password exchange */ 63276788Sdelphij#define L2TP_AUTHEN_TYPE_CHAP 0x0002 /* PPP CHAP */ 64276788Sdelphij#define L2TP_AUTHEN_TYPE_PAP 0x0003 /* PPP PAP */ 65276788Sdelphij#define L2TP_AUTHEN_TYPE_NO_AUTH 0x0004 /* No Authentication */ 66276788Sdelphij#define L2TP_AUTHEN_TYPE_MSCHAPv1 0x0005 /* MSCHAPv1 */ 67276788Sdelphij 68276788Sdelphij#define L2TP_PROXY_AUTH_ID_MASK 0x00ff 69276788Sdelphij 70276788Sdelphijstatic const char tstr[] = " [|l2tp]"; 71276788Sdelphij 7298524Sfenner#define L2TP_MSGTYPE_SCCRQ 1 /* Start-Control-Connection-Request */ 7398524Sfenner#define L2TP_MSGTYPE_SCCRP 2 /* Start-Control-Connection-Reply */ 7498524Sfenner#define L2TP_MSGTYPE_SCCCN 3 /* Start-Control-Connection-Connected */ 7598524Sfenner#define L2TP_MSGTYPE_STOPCCN 4 /* Stop-Control-Connection-Notification */ 7698524Sfenner#define L2TP_MSGTYPE_HELLO 6 /* Hello */ 7798524Sfenner#define L2TP_MSGTYPE_OCRQ 7 /* Outgoing-Call-Request */ 7898524Sfenner#define L2TP_MSGTYPE_OCRP 8 /* Outgoing-Call-Reply */ 7998524Sfenner#define L2TP_MSGTYPE_OCCN 9 /* Outgoing-Call-Connected */ 8098524Sfenner#define L2TP_MSGTYPE_ICRQ 10 /* Incoming-Call-Request */ 8198524Sfenner#define L2TP_MSGTYPE_ICRP 11 /* Incoming-Call-Reply */ 8298524Sfenner#define L2TP_MSGTYPE_ICCN 12 /* Incoming-Call-Connected */ 8398524Sfenner#define L2TP_MSGTYPE_CDN 14 /* Call-Disconnect-Notify */ 8498524Sfenner#define L2TP_MSGTYPE_WEN 15 /* WAN-Error-Notify */ 8598524Sfenner#define L2TP_MSGTYPE_SLI 16 /* Set-Link-Info */ 8698524Sfenner 87276788Sdelphijstatic const struct tok l2tp_msgtype2str[] = { 8898524Sfenner { L2TP_MSGTYPE_SCCRQ, "SCCRQ" }, 8998524Sfenner { L2TP_MSGTYPE_SCCRP, "SCCRP" }, 9098524Sfenner { L2TP_MSGTYPE_SCCCN, "SCCCN" }, 9198524Sfenner { L2TP_MSGTYPE_STOPCCN, "StopCCN" }, 9298524Sfenner { L2TP_MSGTYPE_HELLO, "HELLO" }, 9398524Sfenner { L2TP_MSGTYPE_OCRQ, "OCRQ" }, 9498524Sfenner { L2TP_MSGTYPE_OCRP, "OCRP" }, 9598524Sfenner { L2TP_MSGTYPE_OCCN, "OCCN" }, 9698524Sfenner { L2TP_MSGTYPE_ICRQ, "ICRQ" }, 9798524Sfenner { L2TP_MSGTYPE_ICRP, "ICRP" }, 9898524Sfenner { L2TP_MSGTYPE_ICCN, "ICCN" }, 9998524Sfenner { L2TP_MSGTYPE_CDN, "CDN" }, 10098524Sfenner { L2TP_MSGTYPE_WEN, "WEN" }, 10198524Sfenner { L2TP_MSGTYPE_SLI, "SLI" }, 10298524Sfenner { 0, NULL } 10356893Sfenner}; 10456893Sfenner 10598524Sfenner#define L2TP_AVP_MSGTYPE 0 /* Message Type */ 10698524Sfenner#define L2TP_AVP_RESULT_CODE 1 /* Result Code */ 10798524Sfenner#define L2TP_AVP_PROTO_VER 2 /* Protocol Version */ 10898524Sfenner#define L2TP_AVP_FRAMING_CAP 3 /* Framing Capabilities */ 10998524Sfenner#define L2TP_AVP_BEARER_CAP 4 /* Bearer Capabilities */ 11098524Sfenner#define L2TP_AVP_TIE_BREAKER 5 /* Tie Breaker */ 11198524Sfenner#define L2TP_AVP_FIRM_VER 6 /* Firmware Revision */ 11298524Sfenner#define L2TP_AVP_HOST_NAME 7 /* Host Name */ 11398524Sfenner#define L2TP_AVP_VENDOR_NAME 8 /* Vendor Name */ 11498524Sfenner#define L2TP_AVP_ASSND_TUN_ID 9 /* Assigned Tunnel ID */ 11598524Sfenner#define L2TP_AVP_RECV_WIN_SIZE 10 /* Receive Window Size */ 11698524Sfenner#define L2TP_AVP_CHALLENGE 11 /* Challenge */ 11798524Sfenner#define L2TP_AVP_Q931_CC 12 /* Q.931 Cause Code */ 11898524Sfenner#define L2TP_AVP_CHALLENGE_RESP 13 /* Challenge Response */ 11998524Sfenner#define L2TP_AVP_ASSND_SESS_ID 14 /* Assigned Session ID */ 12098524Sfenner#define L2TP_AVP_CALL_SER_NUM 15 /* Call Serial Number */ 12198524Sfenner#define L2TP_AVP_MINIMUM_BPS 16 /* Minimum BPS */ 12298524Sfenner#define L2TP_AVP_MAXIMUM_BPS 17 /* Maximum BPS */ 12398524Sfenner#define L2TP_AVP_BEARER_TYPE 18 /* Bearer Type */ 12498524Sfenner#define L2TP_AVP_FRAMING_TYPE 19 /* Framing Type */ 12598524Sfenner#define L2TP_AVP_PACKET_PROC_DELAY 20 /* Packet Processing Delay (OBSOLETE) */ 12698524Sfenner#define L2TP_AVP_CALLED_NUMBER 21 /* Called Number */ 12798524Sfenner#define L2TP_AVP_CALLING_NUMBER 22 /* Calling Number */ 12898524Sfenner#define L2TP_AVP_SUB_ADDRESS 23 /* Sub-Address */ 12998524Sfenner#define L2TP_AVP_TX_CONN_SPEED 24 /* (Tx) Connect Speed */ 13098524Sfenner#define L2TP_AVP_PHY_CHANNEL_ID 25 /* Physical Channel ID */ 13198524Sfenner#define L2TP_AVP_INI_RECV_LCP 26 /* Initial Received LCP CONFREQ */ 13298524Sfenner#define L2TP_AVP_LAST_SENT_LCP 27 /* Last Sent LCP CONFREQ */ 13398524Sfenner#define L2TP_AVP_LAST_RECV_LCP 28 /* Last Received LCP CONFREQ */ 13498524Sfenner#define L2TP_AVP_PROXY_AUTH_TYPE 29 /* Proxy Authen Type */ 13598524Sfenner#define L2TP_AVP_PROXY_AUTH_NAME 30 /* Proxy Authen Name */ 13698524Sfenner#define L2TP_AVP_PROXY_AUTH_CHAL 31 /* Proxy Authen Challenge */ 13798524Sfenner#define L2TP_AVP_PROXY_AUTH_ID 32 /* Proxy Authen ID */ 13898524Sfenner#define L2TP_AVP_PROXY_AUTH_RESP 33 /* Proxy Authen Response */ 13998524Sfenner#define L2TP_AVP_CALL_ERRORS 34 /* Call Errors */ 14098524Sfenner#define L2TP_AVP_ACCM 35 /* ACCM */ 14198524Sfenner#define L2TP_AVP_RANDOM_VECTOR 36 /* Random Vector */ 14298524Sfenner#define L2TP_AVP_PRIVATE_GRP_ID 37 /* Private Group ID */ 14398524Sfenner#define L2TP_AVP_RX_CONN_SPEED 38 /* (Rx) Connect Speed */ 14498524Sfenner#define L2TP_AVP_SEQ_REQUIRED 39 /* Sequencing Required */ 14598524Sfenner#define L2TP_AVP_PPP_DISCON_CC 46 /* PPP Disconnect Cause Code */ 14656893Sfenner 147276788Sdelphijstatic const struct tok l2tp_avp2str[] = { 14898524Sfenner { L2TP_AVP_MSGTYPE, "MSGTYPE" }, 14998524Sfenner { L2TP_AVP_RESULT_CODE, "RESULT_CODE" }, 15098524Sfenner { L2TP_AVP_PROTO_VER, "PROTO_VER" }, 15198524Sfenner { L2TP_AVP_FRAMING_CAP, "FRAMING_CAP" }, 15298524Sfenner { L2TP_AVP_BEARER_CAP, "BEARER_CAP" }, 15398524Sfenner { L2TP_AVP_TIE_BREAKER, "TIE_BREAKER" }, 15498524Sfenner { L2TP_AVP_FIRM_VER, "FIRM_VER" }, 15598524Sfenner { L2TP_AVP_HOST_NAME, "HOST_NAME" }, 15698524Sfenner { L2TP_AVP_VENDOR_NAME, "VENDOR_NAME" }, 15798524Sfenner { L2TP_AVP_ASSND_TUN_ID, "ASSND_TUN_ID" }, 15898524Sfenner { L2TP_AVP_RECV_WIN_SIZE, "RECV_WIN_SIZE" }, 15998524Sfenner { L2TP_AVP_CHALLENGE, "CHALLENGE" }, 16098524Sfenner { L2TP_AVP_Q931_CC, "Q931_CC", }, 16198524Sfenner { L2TP_AVP_CHALLENGE_RESP, "CHALLENGE_RESP" }, 16298524Sfenner { L2TP_AVP_ASSND_SESS_ID, "ASSND_SESS_ID" }, 16398524Sfenner { L2TP_AVP_CALL_SER_NUM, "CALL_SER_NUM" }, 16498524Sfenner { L2TP_AVP_MINIMUM_BPS, "MINIMUM_BPS" }, 16598524Sfenner { L2TP_AVP_MAXIMUM_BPS, "MAXIMUM_BPS" }, 16698524Sfenner { L2TP_AVP_BEARER_TYPE, "BEARER_TYPE" }, 16798524Sfenner { L2TP_AVP_FRAMING_TYPE, "FRAMING_TYPE" }, 168127668Sbms { L2TP_AVP_PACKET_PROC_DELAY, "PACKET_PROC_DELAY" }, 16998524Sfenner { L2TP_AVP_CALLED_NUMBER, "CALLED_NUMBER" }, 17098524Sfenner { L2TP_AVP_CALLING_NUMBER, "CALLING_NUMBER" }, 17198524Sfenner { L2TP_AVP_SUB_ADDRESS, "SUB_ADDRESS" }, 17298524Sfenner { L2TP_AVP_TX_CONN_SPEED, "TX_CONN_SPEED" }, 17398524Sfenner { L2TP_AVP_PHY_CHANNEL_ID, "PHY_CHANNEL_ID" }, 17498524Sfenner { L2TP_AVP_INI_RECV_LCP, "INI_RECV_LCP" }, 175127668Sbms { L2TP_AVP_LAST_SENT_LCP, "LAST_SENT_LCP" }, 176127668Sbms { L2TP_AVP_LAST_RECV_LCP, "LAST_RECV_LCP" }, 177127668Sbms { L2TP_AVP_PROXY_AUTH_TYPE, "PROXY_AUTH_TYPE" }, 17898524Sfenner { L2TP_AVP_PROXY_AUTH_NAME, "PROXY_AUTH_NAME" }, 179127668Sbms { L2TP_AVP_PROXY_AUTH_CHAL, "PROXY_AUTH_CHAL" }, 18098524Sfenner { L2TP_AVP_PROXY_AUTH_ID, "PROXY_AUTH_ID" }, 18198524Sfenner { L2TP_AVP_PROXY_AUTH_RESP, "PROXY_AUTH_RESP" }, 18298524Sfenner { L2TP_AVP_CALL_ERRORS, "CALL_ERRORS" }, 183127668Sbms { L2TP_AVP_ACCM, "ACCM" }, 184127668Sbms { L2TP_AVP_RANDOM_VECTOR, "RANDOM_VECTOR" }, 18598524Sfenner { L2TP_AVP_PRIVATE_GRP_ID, "PRIVATE_GRP_ID" }, 186127668Sbms { L2TP_AVP_RX_CONN_SPEED, "RX_CONN_SPEED" }, 187127668Sbms { L2TP_AVP_SEQ_REQUIRED, "SEQ_REQUIRED" }, 188127668Sbms { L2TP_AVP_PPP_DISCON_CC, "PPP_DISCON_CC" }, 18998524Sfenner { 0, NULL } 19056893Sfenner}; 19156893Sfenner 192276788Sdelphijstatic const struct tok l2tp_authentype2str[] = { 19398524Sfenner { L2TP_AUTHEN_TYPE_RESERVED, "Reserved" }, 19498524Sfenner { L2TP_AUTHEN_TYPE_TEXTUAL, "Textual" }, 19598524Sfenner { L2TP_AUTHEN_TYPE_CHAP, "CHAP" }, 19698524Sfenner { L2TP_AUTHEN_TYPE_PAP, "PAP" }, 19798524Sfenner { L2TP_AUTHEN_TYPE_NO_AUTH, "No Auth" }, 19898524Sfenner { L2TP_AUTHEN_TYPE_MSCHAPv1, "MS-CHAPv1" }, 19998524Sfenner { 0, NULL } 20098524Sfenner}; 20198524Sfenner 20298524Sfenner#define L2TP_PPP_DISCON_CC_DIRECTION_GLOBAL 0 20398524Sfenner#define L2TP_PPP_DISCON_CC_DIRECTION_AT_PEER 1 20498524Sfenner#define L2TP_PPP_DISCON_CC_DIRECTION_AT_LOCAL 2 20598524Sfenner 206276788Sdelphijstatic const struct tok l2tp_cc_direction2str[] = { 20798524Sfenner { L2TP_PPP_DISCON_CC_DIRECTION_GLOBAL, "global error" }, 20898524Sfenner { L2TP_PPP_DISCON_CC_DIRECTION_AT_PEER, "at peer" }, 20998524Sfenner { L2TP_PPP_DISCON_CC_DIRECTION_AT_LOCAL,"at local" }, 21098524Sfenner { 0, NULL } 21198524Sfenner}; 21298524Sfenner 21356893Sfenner#if 0 21456893Sfennerstatic char *l2tp_result_code_StopCCN[] = { 21556893Sfenner "Reserved", 21656893Sfenner "General request to clear control connection", 21756893Sfenner "General error--Error Code indicates the problem", 21856893Sfenner "Control channel already exists", 21956893Sfenner "Requester is not authorized to establish a control channel", 22056893Sfenner "The protocol version of the requester is not supported", 22156893Sfenner "Requester is being shut down", 22256893Sfenner "Finite State Machine error" 22356893Sfenner#define L2TP_MAX_RESULT_CODE_STOPCC_INDEX 8 22456893Sfenner}; 22556893Sfenner#endif 22656893Sfenner 22756893Sfenner#if 0 22856893Sfennerstatic char *l2tp_result_code_CDN[] = { 22956893Sfenner "Reserved", 23056893Sfenner "Call disconnected due to loss of carrier", 23156893Sfenner "Call disconnected for the reason indicated in error code", 23256893Sfenner "Call disconnected for administrative reasons", 23356893Sfenner "Call failed due to lack of appropriate facilities being " \ 23456893Sfenner "available (temporary condition)", 23556893Sfenner "Call failed due to lack of appropriate facilities being " \ 23656893Sfenner "available (permanent condition)", 23756893Sfenner "Invalid destination", 23856893Sfenner "Call failed due to no carrier detected", 23956893Sfenner "Call failed due to detection of a busy signal", 24056893Sfenner "Call failed due to lack of a dial tone", 24156893Sfenner "Call was not established within time allotted by LAC", 24256893Sfenner "Call was connected but no appropriate framing was detected" 24356893Sfenner#define L2TP_MAX_RESULT_CODE_CDN_INDEX 12 24456893Sfenner}; 24556893Sfenner#endif 24656893Sfenner 24756893Sfenner#if 0 24856893Sfennerstatic char *l2tp_error_code_general[] = { 24956893Sfenner "No general error", 25056893Sfenner "No control connection exists yet for this LAC-LNS pair", 25156893Sfenner "Length is wrong", 25256893Sfenner "One of the field values was out of range or " \ 25356893Sfenner "reserved field was non-zero" 25456893Sfenner "Insufficient resources to handle this operation now", 25556893Sfenner "The Session ID is invalid in this context", 25656893Sfenner "A generic vendor-specific error occurred in the LAC", 25756893Sfenner "Try another" 25856893Sfenner#define L2TP_MAX_ERROR_CODE_GENERAL_INDEX 8 25956893Sfenner}; 26056893Sfenner#endif 26156893Sfenner 26256893Sfenner/******************************/ 26356893Sfenner/* generic print out routines */ 26456893Sfenner/******************************/ 265127668Sbmsstatic void 266276788Sdelphijprint_string(netdissect_options *ndo, const u_char *dat, u_int length) 26756893Sfenner{ 268127668Sbms u_int i; 26956893Sfenner for (i=0; i<length; i++) { 270276788Sdelphij ND_PRINT((ndo, "%c", *dat++)); 27156893Sfenner } 27256893Sfenner} 27356893Sfenner 274127668Sbmsstatic void 275276788Sdelphijprint_octets(netdissect_options *ndo, const u_char *dat, u_int length) 27656893Sfenner{ 277127668Sbms u_int i; 27856893Sfenner for (i=0; i<length; i++) { 279276788Sdelphij ND_PRINT((ndo, "%02x", *dat++)); 28056893Sfenner } 28156893Sfenner} 28256893Sfenner 28356893Sfennerstatic void 284276788Sdelphijprint_16bits_val(netdissect_options *ndo, const uint16_t *dat) 28556893Sfenner{ 286276788Sdelphij ND_PRINT((ndo, "%u", EXTRACT_16BITS(dat))); 28756893Sfenner} 28856893Sfenner 28956893Sfennerstatic void 290276788Sdelphijprint_32bits_val(netdissect_options *ndo, const uint32_t *dat) 29156893Sfenner{ 292276788Sdelphij ND_PRINT((ndo, "%lu", (u_long)EXTRACT_32BITS(dat))); 29356893Sfenner} 29456893Sfenner 29598524Sfenner/***********************************/ 29698524Sfenner/* AVP-specific print out routines */ 29798524Sfenner/***********************************/ 29856893Sfennerstatic void 299276788Sdelphijl2tp_msgtype_print(netdissect_options *ndo, const u_char *dat) 30056893Sfenner{ 301276788Sdelphij uint16_t *ptr = (uint16_t*)dat; 30256893Sfenner 303276788Sdelphij ND_PRINT((ndo, "%s", tok2str(l2tp_msgtype2str, "MSGTYPE-#%u", 304276788Sdelphij EXTRACT_16BITS(ptr)))); 30556893Sfenner} 30656893Sfenner 30756893Sfennerstatic void 308276788Sdelphijl2tp_result_code_print(netdissect_options *ndo, const u_char *dat, u_int length) 30956893Sfenner{ 310276788Sdelphij uint16_t *ptr = (uint16_t *)dat; 311127668Sbms 312276788Sdelphij ND_PRINT((ndo, "%u", EXTRACT_16BITS(ptr))); ptr++; /* Result Code */ 313111726Sfenner if (length > 2) { /* Error Code (opt) */ 314276788Sdelphij ND_PRINT((ndo, "/%u", EXTRACT_16BITS(ptr))); ptr++; 31556893Sfenner } 316111726Sfenner if (length > 4) { /* Error Message (opt) */ 317276788Sdelphij ND_PRINT((ndo, " ")); 318276788Sdelphij print_string(ndo, (u_char *)ptr, length - 4); 31998524Sfenner } 32056893Sfenner} 32156893Sfenner 32256893Sfennerstatic void 323276788Sdelphijl2tp_proto_ver_print(netdissect_options *ndo, const uint16_t *dat) 32456893Sfenner{ 325276788Sdelphij ND_PRINT((ndo, "%u.%u", (EXTRACT_16BITS(dat) >> 8), 326276788Sdelphij (EXTRACT_16BITS(dat) & 0xff))); 32756893Sfenner} 32856893Sfenner 32956893Sfennerstatic void 330276788Sdelphijl2tp_framing_cap_print(netdissect_options *ndo, const u_char *dat) 33156893Sfenner{ 332276788Sdelphij uint32_t *ptr = (uint32_t *)dat; 33356893Sfenner 334111726Sfenner if (EXTRACT_32BITS(ptr) & L2TP_FRAMING_CAP_ASYNC_MASK) { 335276788Sdelphij ND_PRINT((ndo, "A")); 33656893Sfenner } 337111726Sfenner if (EXTRACT_32BITS(ptr) & L2TP_FRAMING_CAP_SYNC_MASK) { 338276788Sdelphij ND_PRINT((ndo, "S")); 33956893Sfenner } 34056893Sfenner} 34156893Sfenner 34256893Sfennerstatic void 343276788Sdelphijl2tp_bearer_cap_print(netdissect_options *ndo, const u_char *dat) 34456893Sfenner{ 345276788Sdelphij uint32_t *ptr = (uint32_t *)dat; 34656893Sfenner 347111726Sfenner if (EXTRACT_32BITS(ptr) & L2TP_BEARER_CAP_ANALOG_MASK) { 348276788Sdelphij ND_PRINT((ndo, "A")); 34956893Sfenner } 350111726Sfenner if (EXTRACT_32BITS(ptr) & L2TP_BEARER_CAP_DIGITAL_MASK) { 351276788Sdelphij ND_PRINT((ndo, "D")); 35256893Sfenner } 35356893Sfenner} 35456893Sfenner 35556893Sfennerstatic void 356276788Sdelphijl2tp_q931_cc_print(netdissect_options *ndo, const u_char *dat, u_int length) 35756893Sfenner{ 358276788Sdelphij print_16bits_val(ndo, (uint16_t *)dat); 359276788Sdelphij ND_PRINT((ndo, ", %02x", dat[2])); 36056893Sfenner if (length > 3) { 361276788Sdelphij ND_PRINT((ndo, " ")); 362276788Sdelphij print_string(ndo, dat+3, length-3); 363127668Sbms } 36456893Sfenner} 36556893Sfenner 36656893Sfennerstatic void 367276788Sdelphijl2tp_bearer_type_print(netdissect_options *ndo, const u_char *dat) 36856893Sfenner{ 369276788Sdelphij uint32_t *ptr = (uint32_t *)dat; 37056893Sfenner 371111726Sfenner if (EXTRACT_32BITS(ptr) & L2TP_BEARER_TYPE_ANALOG_MASK) { 372276788Sdelphij ND_PRINT((ndo, "A")); 37356893Sfenner } 374111726Sfenner if (EXTRACT_32BITS(ptr) & L2TP_BEARER_TYPE_DIGITAL_MASK) { 375276788Sdelphij ND_PRINT((ndo, "D")); 37656893Sfenner } 37756893Sfenner} 37856893Sfenner 37956893Sfennerstatic void 380276788Sdelphijl2tp_framing_type_print(netdissect_options *ndo, const u_char *dat) 38156893Sfenner{ 382276788Sdelphij uint32_t *ptr = (uint32_t *)dat; 38356893Sfenner 384111726Sfenner if (EXTRACT_32BITS(ptr) & L2TP_FRAMING_TYPE_ASYNC_MASK) { 385276788Sdelphij ND_PRINT((ndo, "A")); 38656893Sfenner } 387111726Sfenner if (EXTRACT_32BITS(ptr) & L2TP_FRAMING_TYPE_SYNC_MASK) { 388276788Sdelphij ND_PRINT((ndo, "S")); 38956893Sfenner } 39056893Sfenner} 39156893Sfenner 39256893Sfennerstatic void 393276788Sdelphijl2tp_packet_proc_delay_print(netdissect_options *ndo) 39456893Sfenner{ 395276788Sdelphij ND_PRINT((ndo, "obsolete")); 39656893Sfenner} 39756893Sfenner 39856893Sfennerstatic void 399276788Sdelphijl2tp_proxy_auth_type_print(netdissect_options *ndo, const u_char *dat) 40056893Sfenner{ 401276788Sdelphij uint16_t *ptr = (uint16_t *)dat; 40256893Sfenner 403276788Sdelphij ND_PRINT((ndo, "%s", tok2str(l2tp_authentype2str, 404276788Sdelphij "AuthType-#%u", EXTRACT_16BITS(ptr)))); 40556893Sfenner} 40656893Sfenner 40756893Sfennerstatic void 408276788Sdelphijl2tp_proxy_auth_id_print(netdissect_options *ndo, const u_char *dat) 40956893Sfenner{ 410276788Sdelphij uint16_t *ptr = (uint16_t *)dat; 41156893Sfenner 412276788Sdelphij ND_PRINT((ndo, "%u", EXTRACT_16BITS(ptr) & L2TP_PROXY_AUTH_ID_MASK)); 41356893Sfenner} 41456893Sfenner 41556893Sfennerstatic void 416276788Sdelphijl2tp_call_errors_print(netdissect_options *ndo, const u_char *dat) 41756893Sfenner{ 418276788Sdelphij uint16_t *ptr = (uint16_t *)dat; 419276788Sdelphij uint16_t val_h, val_l; 420127668Sbms 42198524Sfenner ptr++; /* skip "Reserved" */ 42256893Sfenner 423111726Sfenner val_h = EXTRACT_16BITS(ptr); ptr++; 424111726Sfenner val_l = EXTRACT_16BITS(ptr); ptr++; 425276788Sdelphij ND_PRINT((ndo, "CRCErr=%u ", (val_h<<16) + val_l)); 42656893Sfenner 427111726Sfenner val_h = EXTRACT_16BITS(ptr); ptr++; 428111726Sfenner val_l = EXTRACT_16BITS(ptr); ptr++; 429276788Sdelphij ND_PRINT((ndo, "FrameErr=%u ", (val_h<<16) + val_l)); 43056893Sfenner 431111726Sfenner val_h = EXTRACT_16BITS(ptr); ptr++; 432111726Sfenner val_l = EXTRACT_16BITS(ptr); ptr++; 433276788Sdelphij ND_PRINT((ndo, "HardOver=%u ", (val_h<<16) + val_l)); 43456893Sfenner 435111726Sfenner val_h = EXTRACT_16BITS(ptr); ptr++; 436111726Sfenner val_l = EXTRACT_16BITS(ptr); ptr++; 437276788Sdelphij ND_PRINT((ndo, "BufOver=%u ", (val_h<<16) + val_l)); 43856893Sfenner 439111726Sfenner val_h = EXTRACT_16BITS(ptr); ptr++; 440111726Sfenner val_l = EXTRACT_16BITS(ptr); ptr++; 441276788Sdelphij ND_PRINT((ndo, "Timeout=%u ", (val_h<<16) + val_l)); 44256893Sfenner 443111726Sfenner val_h = EXTRACT_16BITS(ptr); ptr++; 444111726Sfenner val_l = EXTRACT_16BITS(ptr); ptr++; 445276788Sdelphij ND_PRINT((ndo, "AlignErr=%u ", (val_h<<16) + val_l)); 44656893Sfenner} 44756893Sfenner 44856893Sfennerstatic void 449276788Sdelphijl2tp_accm_print(netdissect_options *ndo, const u_char *dat) 45056893Sfenner{ 451276788Sdelphij uint16_t *ptr = (uint16_t *)dat; 452276788Sdelphij uint16_t val_h, val_l; 45356893Sfenner 45498524Sfenner ptr++; /* skip "Reserved" */ 45556893Sfenner 456111726Sfenner val_h = EXTRACT_16BITS(ptr); ptr++; 457111726Sfenner val_l = EXTRACT_16BITS(ptr); ptr++; 458276788Sdelphij ND_PRINT((ndo, "send=%08x ", (val_h<<16) + val_l)); 459127668Sbms 460111726Sfenner val_h = EXTRACT_16BITS(ptr); ptr++; 461111726Sfenner val_l = EXTRACT_16BITS(ptr); ptr++; 462276788Sdelphij ND_PRINT((ndo, "recv=%08x ", (val_h<<16) + val_l)); 46356893Sfenner} 46456893Sfenner 46556893Sfennerstatic void 466276788Sdelphijl2tp_ppp_discon_cc_print(netdissect_options *ndo, const u_char *dat, u_int length) 46756893Sfenner{ 468276788Sdelphij uint16_t *ptr = (uint16_t *)dat; 469127668Sbms 470276788Sdelphij ND_PRINT((ndo, "%04x, ", EXTRACT_16BITS(ptr))); ptr++; /* Disconnect Code */ 471276788Sdelphij ND_PRINT((ndo, "%04x ", EXTRACT_16BITS(ptr))); ptr++; /* Control Protocol Number */ 472276788Sdelphij ND_PRINT((ndo, "%s", tok2str(l2tp_cc_direction2str, 473276788Sdelphij "Direction-#%u", *((u_char *)ptr++)))); 47456893Sfenner 47598524Sfenner if (length > 5) { 476276788Sdelphij ND_PRINT((ndo, " ")); 477276788Sdelphij print_string(ndo, (const u_char *)ptr, length-5); 47898524Sfenner } 47956893Sfenner} 48056893Sfenner 48156893Sfennerstatic void 482276788Sdelphijl2tp_avp_print(netdissect_options *ndo, const u_char *dat, int length) 48356893Sfenner{ 48498524Sfenner u_int len; 485276788Sdelphij const uint16_t *ptr = (uint16_t *)dat; 486276788Sdelphij uint16_t attr_type; 48798524Sfenner int hidden = FALSE; 48856893Sfenner 48998524Sfenner if (length <= 0) { 49098524Sfenner return; 49198524Sfenner } 49256893Sfenner 493276788Sdelphij ND_PRINT((ndo, " ")); 49456893Sfenner 495276788Sdelphij ND_TCHECK(*ptr); /* Flags & Length */ 496111726Sfenner len = EXTRACT_16BITS(ptr) & L2TP_AVP_HDR_LEN_MASK; 49756893Sfenner 498124486Sfenner /* If it is not long enough to contain the header, we'll give up. */ 499124486Sfenner if (len < 6) 500124486Sfenner goto trunc; 501124486Sfenner 502124486Sfenner /* If it goes past the end of the remaining length of the packet, 503124486Sfenner we'll give up. */ 504124486Sfenner if (len > (u_int)length) 505124486Sfenner goto trunc; 506124486Sfenner 507124486Sfenner /* If it goes past the end of the remaining length of the captured 508124486Sfenner data, we'll give up. */ 509276788Sdelphij ND_TCHECK2(*ptr, len); 51098524Sfenner /* After this point, no need to worry about truncation */ 51156893Sfenner 512111726Sfenner if (EXTRACT_16BITS(ptr) & L2TP_AVP_HDR_FLAG_MANDATORY) { 513276788Sdelphij ND_PRINT((ndo, "*")); 51498524Sfenner } 515111726Sfenner if (EXTRACT_16BITS(ptr) & L2TP_AVP_HDR_FLAG_HIDDEN) { 51698524Sfenner hidden = TRUE; 517276788Sdelphij ND_PRINT((ndo, "?")); 51898524Sfenner } 51998524Sfenner ptr++; 52056893Sfenner 521111726Sfenner if (EXTRACT_16BITS(ptr)) { 52298524Sfenner /* Vendor Specific Attribute */ 523276788Sdelphij ND_PRINT((ndo, "VENDOR%04x:", EXTRACT_16BITS(ptr))); ptr++; 524276788Sdelphij ND_PRINT((ndo, "ATTR%04x", EXTRACT_16BITS(ptr))); ptr++; 525276788Sdelphij ND_PRINT((ndo, "(")); 526276788Sdelphij print_octets(ndo, (u_char *)ptr, len-6); 527276788Sdelphij ND_PRINT((ndo, ")")); 52898524Sfenner } else { 529127668Sbms /* IETF-defined Attributes */ 53056893Sfenner ptr++; 531111726Sfenner attr_type = EXTRACT_16BITS(ptr); ptr++; 532276788Sdelphij ND_PRINT((ndo, "%s", tok2str(l2tp_avp2str, "AVP-#%u", attr_type))); 533276788Sdelphij ND_PRINT((ndo, "(")); 53498524Sfenner if (hidden) { 535276788Sdelphij ND_PRINT((ndo, "???")); 53675115Sfenner } else { 53798524Sfenner switch (attr_type) { 53898524Sfenner case L2TP_AVP_MSGTYPE: 539276788Sdelphij l2tp_msgtype_print(ndo, (u_char *)ptr); 54098524Sfenner break; 54198524Sfenner case L2TP_AVP_RESULT_CODE: 542276788Sdelphij l2tp_result_code_print(ndo, (u_char *)ptr, len-6); 54398524Sfenner break; 54498524Sfenner case L2TP_AVP_PROTO_VER: 545276788Sdelphij l2tp_proto_ver_print(ndo, ptr); 54698524Sfenner break; 54798524Sfenner case L2TP_AVP_FRAMING_CAP: 548276788Sdelphij l2tp_framing_cap_print(ndo, (u_char *)ptr); 54998524Sfenner break; 55098524Sfenner case L2TP_AVP_BEARER_CAP: 551276788Sdelphij l2tp_bearer_cap_print(ndo, (u_char *)ptr); 55298524Sfenner break; 55398524Sfenner case L2TP_AVP_TIE_BREAKER: 554276788Sdelphij print_octets(ndo, (u_char *)ptr, 8); 55598524Sfenner break; 55698524Sfenner case L2TP_AVP_FIRM_VER: 55798524Sfenner case L2TP_AVP_ASSND_TUN_ID: 55898524Sfenner case L2TP_AVP_RECV_WIN_SIZE: 55998524Sfenner case L2TP_AVP_ASSND_SESS_ID: 560276788Sdelphij print_16bits_val(ndo, ptr); 56198524Sfenner break; 56298524Sfenner case L2TP_AVP_HOST_NAME: 56398524Sfenner case L2TP_AVP_VENDOR_NAME: 56498524Sfenner case L2TP_AVP_CALLING_NUMBER: 56598524Sfenner case L2TP_AVP_CALLED_NUMBER: 56698524Sfenner case L2TP_AVP_SUB_ADDRESS: 56798524Sfenner case L2TP_AVP_PROXY_AUTH_NAME: 568127668Sbms case L2TP_AVP_PRIVATE_GRP_ID: 569276788Sdelphij print_string(ndo, (u_char *)ptr, len-6); 57098524Sfenner break; 57198524Sfenner case L2TP_AVP_CHALLENGE: 57298524Sfenner case L2TP_AVP_INI_RECV_LCP: 57398524Sfenner case L2TP_AVP_LAST_SENT_LCP: 57498524Sfenner case L2TP_AVP_LAST_RECV_LCP: 57598524Sfenner case L2TP_AVP_PROXY_AUTH_CHAL: 57698524Sfenner case L2TP_AVP_PROXY_AUTH_RESP: 57798524Sfenner case L2TP_AVP_RANDOM_VECTOR: 578276788Sdelphij print_octets(ndo, (u_char *)ptr, len-6); 57998524Sfenner break; 58098524Sfenner case L2TP_AVP_Q931_CC: 581276788Sdelphij l2tp_q931_cc_print(ndo, (u_char *)ptr, len-6); 58298524Sfenner break; 58398524Sfenner case L2TP_AVP_CHALLENGE_RESP: 584276788Sdelphij print_octets(ndo, (u_char *)ptr, 16); 58598524Sfenner break; 58698524Sfenner case L2TP_AVP_CALL_SER_NUM: 58798524Sfenner case L2TP_AVP_MINIMUM_BPS: 58898524Sfenner case L2TP_AVP_MAXIMUM_BPS: 58998524Sfenner case L2TP_AVP_TX_CONN_SPEED: 59098524Sfenner case L2TP_AVP_PHY_CHANNEL_ID: 59198524Sfenner case L2TP_AVP_RX_CONN_SPEED: 592276788Sdelphij print_32bits_val(ndo, (uint32_t *)ptr); 59398524Sfenner break; 59498524Sfenner case L2TP_AVP_BEARER_TYPE: 595276788Sdelphij l2tp_bearer_type_print(ndo, (u_char *)ptr); 59698524Sfenner break; 59798524Sfenner case L2TP_AVP_FRAMING_TYPE: 598276788Sdelphij l2tp_framing_type_print(ndo, (u_char *)ptr); 59998524Sfenner break; 60098524Sfenner case L2TP_AVP_PACKET_PROC_DELAY: 601276788Sdelphij l2tp_packet_proc_delay_print(ndo); 60298524Sfenner break; 60398524Sfenner case L2TP_AVP_PROXY_AUTH_TYPE: 604276788Sdelphij l2tp_proxy_auth_type_print(ndo, (u_char *)ptr); 60598524Sfenner break; 60698524Sfenner case L2TP_AVP_PROXY_AUTH_ID: 607276788Sdelphij l2tp_proxy_auth_id_print(ndo, (u_char *)ptr); 60898524Sfenner break; 60998524Sfenner case L2TP_AVP_CALL_ERRORS: 610276788Sdelphij l2tp_call_errors_print(ndo, (u_char *)ptr); 61198524Sfenner break; 61298524Sfenner case L2TP_AVP_ACCM: 613276788Sdelphij l2tp_accm_print(ndo, (u_char *)ptr); 61498524Sfenner break; 61598524Sfenner case L2TP_AVP_SEQ_REQUIRED: 61698524Sfenner break; /* No Attribute Value */ 61798524Sfenner case L2TP_AVP_PPP_DISCON_CC: 618276788Sdelphij l2tp_ppp_discon_cc_print(ndo, (u_char *)ptr, len-6); 61998524Sfenner break; 62098524Sfenner default: 62198524Sfenner break; 62256893Sfenner } 62356893Sfenner } 624276788Sdelphij ND_PRINT((ndo, ")")); 62598524Sfenner } 62656893Sfenner 627276788Sdelphij l2tp_avp_print(ndo, dat+len, length-len); 62898524Sfenner return; 62998524Sfenner 63098524Sfenner trunc: 631276788Sdelphij ND_PRINT((ndo, "|...")); 63256893Sfenner} 63356893Sfenner 63456893Sfenner 63556893Sfennervoid 636276788Sdelphijl2tp_print(netdissect_options *ndo, const u_char *dat, u_int length) 63756893Sfenner{ 638214478Srpaulo const u_char *ptr = dat; 63956893Sfenner u_int cnt = 0; /* total octets consumed */ 640276788Sdelphij uint16_t pad; 641147899Ssam int flag_t, flag_l, flag_s, flag_o; 642276788Sdelphij uint16_t l2tp_len; 64356893Sfenner 644147899Ssam flag_t = flag_l = flag_s = flag_o = FALSE; 64556893Sfenner 646276788Sdelphij ND_TCHECK2(*ptr, 2); /* Flags & Version */ 647111726Sfenner if ((EXTRACT_16BITS(ptr) & L2TP_VERSION_MASK) == L2TP_VERSION_L2TP) { 648276788Sdelphij ND_PRINT((ndo, " l2tp:")); 649111726Sfenner } else if ((EXTRACT_16BITS(ptr) & L2TP_VERSION_MASK) == L2TP_VERSION_L2F) { 650276788Sdelphij ND_PRINT((ndo, " l2f:")); 65156893Sfenner return; /* nothing to do */ 65256893Sfenner } else { 653276788Sdelphij ND_PRINT((ndo, " Unknown Version, neither L2F(1) nor L2TP(2)")); 65456893Sfenner return; /* nothing we can do */ 65556893Sfenner } 65656893Sfenner 657276788Sdelphij ND_PRINT((ndo, "[")); 658111726Sfenner if (EXTRACT_16BITS(ptr) & L2TP_FLAG_TYPE) { 65956893Sfenner flag_t = TRUE; 660276788Sdelphij ND_PRINT((ndo, "T")); 66156893Sfenner } 662111726Sfenner if (EXTRACT_16BITS(ptr) & L2TP_FLAG_LENGTH) { 66356893Sfenner flag_l = TRUE; 664276788Sdelphij ND_PRINT((ndo, "L")); 66556893Sfenner } 666111726Sfenner if (EXTRACT_16BITS(ptr) & L2TP_FLAG_SEQUENCE) { 66756893Sfenner flag_s = TRUE; 668276788Sdelphij ND_PRINT((ndo, "S")); 66956893Sfenner } 670111726Sfenner if (EXTRACT_16BITS(ptr) & L2TP_FLAG_OFFSET) { 67156893Sfenner flag_o = TRUE; 672276788Sdelphij ND_PRINT((ndo, "O")); 67356893Sfenner } 674147899Ssam if (EXTRACT_16BITS(ptr) & L2TP_FLAG_PRIORITY) 675276788Sdelphij ND_PRINT((ndo, "P")); 676276788Sdelphij ND_PRINT((ndo, "]")); 67756893Sfenner 678214478Srpaulo ptr += 2; 67956893Sfenner cnt += 2; 680127668Sbms 68156893Sfenner if (flag_l) { 682276788Sdelphij ND_TCHECK2(*ptr, 2); /* Length */ 683214478Srpaulo l2tp_len = EXTRACT_16BITS(ptr); 684214478Srpaulo ptr += 2; 68556893Sfenner cnt += 2; 68656893Sfenner } else { 68756893Sfenner l2tp_len = 0; 68856893Sfenner } 68956893Sfenner 690276788Sdelphij ND_TCHECK2(*ptr, 2); /* Tunnel ID */ 691276788Sdelphij ND_PRINT((ndo, "(%u/", EXTRACT_16BITS(ptr))); 692214478Srpaulo ptr += 2; 69398524Sfenner cnt += 2; 694276788Sdelphij ND_TCHECK2(*ptr, 2); /* Session ID */ 695276788Sdelphij ND_PRINT((ndo, "%u)", EXTRACT_16BITS(ptr))); 696214478Srpaulo ptr += 2; 69798524Sfenner cnt += 2; 69856893Sfenner 69956893Sfenner if (flag_s) { 700276788Sdelphij ND_TCHECK2(*ptr, 2); /* Ns */ 701276788Sdelphij ND_PRINT((ndo, "Ns=%u,", EXTRACT_16BITS(ptr))); 702214478Srpaulo ptr += 2; 70398524Sfenner cnt += 2; 704276788Sdelphij ND_TCHECK2(*ptr, 2); /* Nr */ 705276788Sdelphij ND_PRINT((ndo, "Nr=%u", EXTRACT_16BITS(ptr))); 706214478Srpaulo ptr += 2; 70798524Sfenner cnt += 2; 70856893Sfenner } 70956893Sfenner 71056893Sfenner if (flag_o) { 711276788Sdelphij ND_TCHECK2(*ptr, 2); /* Offset Size */ 712214478Srpaulo pad = EXTRACT_16BITS(ptr); 713214478Srpaulo ptr += (2 + pad); 71456893Sfenner cnt += (2 + pad); 71556893Sfenner } 71656893Sfenner 717147899Ssam if (flag_l) { 718147899Ssam if (length < l2tp_len) { 719276788Sdelphij ND_PRINT((ndo, " Length %u larger than packet", l2tp_len)); 720147899Ssam return; 721147899Ssam } 722147899Ssam length = l2tp_len; 723147899Ssam } 724147899Ssam if (length < cnt) { 725276788Sdelphij ND_PRINT((ndo, " Length %u smaller than header length", length)); 726147899Ssam return; 727147899Ssam } 72856893Sfenner if (flag_t) { 729147899Ssam if (!flag_l) { 730276788Sdelphij ND_PRINT((ndo, " No length")); 731147899Ssam return; 732147899Ssam } 73356893Sfenner if (length - cnt == 0) { 734276788Sdelphij ND_PRINT((ndo, " ZLB")); 73556893Sfenner } else { 736276788Sdelphij l2tp_avp_print(ndo, ptr, length - cnt); 73756893Sfenner } 73856893Sfenner } else { 739276788Sdelphij ND_PRINT((ndo, " {")); 740276788Sdelphij ppp_print(ndo, ptr, length - cnt); 741276788Sdelphij ND_PRINT((ndo, "}")); 74256893Sfenner } 74398524Sfenner 74498524Sfenner return; 74598524Sfenner 74698524Sfenner trunc: 747276788Sdelphij ND_PRINT((ndo, "%s", tstr)); 748127668Sbms} 749