print-l2tp.c revision 111726
156893Sfenner/* 256893Sfenner * Copyright (c) 1991, 1993, 1994, 1995, 1996, 1997 356893Sfenner * The Regents of the University of California. All rights reserved. 456893Sfenner * 556893Sfenner * Redistribution and use in source and binary forms, with or without 656893Sfenner * modification, are permitted provided that: (1) source code distributions 756893Sfenner * retain the above copyright notice and this paragraph in its entirety, (2) 856893Sfenner * distributions including binary code include the above copyright notice and 956893Sfenner * this paragraph in its entirety in the documentation or other materials 1056893Sfenner * provided with the distribution, and (3) all advertising materials mentioning 1156893Sfenner * features or use of this software display the following acknowledgement: 1256893Sfenner * ``This product includes software developed by the University of California, 1356893Sfenner * Lawrence Berkeley Laboratory and its contributors.'' Neither the name of 1456893Sfenner * the University nor the names of its contributors may be used to endorse 1556893Sfenner * or promote products derived from this software without specific prior 1656893Sfenner * written permission. 1756893Sfenner * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR IMPLIED 1856893Sfenner * WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF 1956893Sfenner * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. 2056893Sfenner * 2175115Sfenner * L2TP support contributed by Motonori Shindo (mshindo@mshindo.net) 2256893Sfenner */ 2356893Sfenner 2456893Sfenner#ifndef lint 2556893Sfennerstatic const char rcsid[] = 26111726Sfenner "@(#) $Header: /tcpdump/master/tcpdump/print-l2tp.c,v 1.10.2.1 2002/05/25 09:47:07 guy Exp $"; 2756893Sfenner#endif 2856893Sfenner 2956893Sfenner#ifdef HAVE_CONFIG_H 3056893Sfenner#include "config.h" 3156893Sfenner#endif 3256893Sfenner 3356893Sfenner#include <stdio.h> 3456893Sfenner#include <sys/types.h> 3556893Sfenner#include <sys/param.h> 3656893Sfenner#include <netinet/in.h> 3756893Sfenner#include <arpa/inet.h> 3856893Sfenner 3956893Sfenner#include "l2tp.h" 4056893Sfenner#include "interface.h" 41111726Sfenner#include "extract.h" 4256893Sfenner 4356893Sfennerstatic char tstr[] = " [|l2tp]"; 4456893Sfenner 4556893Sfenner#ifndef TRUE 4656893Sfenner#define TRUE 1 4756893Sfenner#endif 4856893Sfenner 4956893Sfenner#ifndef FALSE 5056893Sfenner#define FALSE 0 5156893Sfenner#endif 5256893Sfenner 5398524Sfenner#define L2TP_MSGTYPE_SCCRQ 1 /* Start-Control-Connection-Request */ 5498524Sfenner#define L2TP_MSGTYPE_SCCRP 2 /* Start-Control-Connection-Reply */ 5598524Sfenner#define L2TP_MSGTYPE_SCCCN 3 /* Start-Control-Connection-Connected */ 5698524Sfenner#define L2TP_MSGTYPE_STOPCCN 4 /* Stop-Control-Connection-Notification */ 5798524Sfenner#define L2TP_MSGTYPE_HELLO 6 /* Hello */ 5898524Sfenner#define L2TP_MSGTYPE_OCRQ 7 /* Outgoing-Call-Request */ 5998524Sfenner#define L2TP_MSGTYPE_OCRP 8 /* Outgoing-Call-Reply */ 6098524Sfenner#define L2TP_MSGTYPE_OCCN 9 /* Outgoing-Call-Connected */ 6198524Sfenner#define L2TP_MSGTYPE_ICRQ 10 /* Incoming-Call-Request */ 6298524Sfenner#define L2TP_MSGTYPE_ICRP 11 /* Incoming-Call-Reply */ 6398524Sfenner#define L2TP_MSGTYPE_ICCN 12 /* Incoming-Call-Connected */ 6498524Sfenner#define L2TP_MSGTYPE_CDN 14 /* Call-Disconnect-Notify */ 6598524Sfenner#define L2TP_MSGTYPE_WEN 15 /* WAN-Error-Notify */ 6698524Sfenner#define L2TP_MSGTYPE_SLI 16 /* Set-Link-Info */ 6798524Sfenner 6898524Sfennerstatic struct tok l2tp_msgtype2str[] = { 6998524Sfenner { L2TP_MSGTYPE_SCCRQ, "SCCRQ" }, 7098524Sfenner { L2TP_MSGTYPE_SCCRP, "SCCRP" }, 7198524Sfenner { L2TP_MSGTYPE_SCCCN, "SCCCN" }, 7298524Sfenner { L2TP_MSGTYPE_STOPCCN, "StopCCN" }, 7398524Sfenner { L2TP_MSGTYPE_HELLO, "HELLO" }, 7498524Sfenner { L2TP_MSGTYPE_OCRQ, "OCRQ" }, 7598524Sfenner { L2TP_MSGTYPE_OCRP, "OCRP" }, 7698524Sfenner { L2TP_MSGTYPE_OCCN, "OCCN" }, 7798524Sfenner { L2TP_MSGTYPE_ICRQ, "ICRQ" }, 7898524Sfenner { L2TP_MSGTYPE_ICRP, "ICRP" }, 7998524Sfenner { L2TP_MSGTYPE_ICCN, "ICCN" }, 8098524Sfenner { L2TP_MSGTYPE_CDN, "CDN" }, 8198524Sfenner { L2TP_MSGTYPE_WEN, "WEN" }, 8298524Sfenner { L2TP_MSGTYPE_SLI, "SLI" }, 8398524Sfenner { 0, NULL } 8456893Sfenner}; 8556893Sfenner 8698524Sfenner#define L2TP_AVP_MSGTYPE 0 /* Message Type */ 8798524Sfenner#define L2TP_AVP_RESULT_CODE 1 /* Result Code */ 8898524Sfenner#define L2TP_AVP_PROTO_VER 2 /* Protocol Version */ 8998524Sfenner#define L2TP_AVP_FRAMING_CAP 3 /* Framing Capabilities */ 9098524Sfenner#define L2TP_AVP_BEARER_CAP 4 /* Bearer Capabilities */ 9198524Sfenner#define L2TP_AVP_TIE_BREAKER 5 /* Tie Breaker */ 9298524Sfenner#define L2TP_AVP_FIRM_VER 6 /* Firmware Revision */ 9398524Sfenner#define L2TP_AVP_HOST_NAME 7 /* Host Name */ 9498524Sfenner#define L2TP_AVP_VENDOR_NAME 8 /* Vendor Name */ 9598524Sfenner#define L2TP_AVP_ASSND_TUN_ID 9 /* Assigned Tunnel ID */ 9698524Sfenner#define L2TP_AVP_RECV_WIN_SIZE 10 /* Receive Window Size */ 9798524Sfenner#define L2TP_AVP_CHALLENGE 11 /* Challenge */ 9898524Sfenner#define L2TP_AVP_Q931_CC 12 /* Q.931 Cause Code */ 9998524Sfenner#define L2TP_AVP_CHALLENGE_RESP 13 /* Challenge Response */ 10098524Sfenner#define L2TP_AVP_ASSND_SESS_ID 14 /* Assigned Session ID */ 10198524Sfenner#define L2TP_AVP_CALL_SER_NUM 15 /* Call Serial Number */ 10298524Sfenner#define L2TP_AVP_MINIMUM_BPS 16 /* Minimum BPS */ 10398524Sfenner#define L2TP_AVP_MAXIMUM_BPS 17 /* Maximum BPS */ 10498524Sfenner#define L2TP_AVP_BEARER_TYPE 18 /* Bearer Type */ 10598524Sfenner#define L2TP_AVP_FRAMING_TYPE 19 /* Framing Type */ 10698524Sfenner#define L2TP_AVP_PACKET_PROC_DELAY 20 /* Packet Processing Delay (OBSOLETE) */ 10798524Sfenner#define L2TP_AVP_CALLED_NUMBER 21 /* Called Number */ 10898524Sfenner#define L2TP_AVP_CALLING_NUMBER 22 /* Calling Number */ 10998524Sfenner#define L2TP_AVP_SUB_ADDRESS 23 /* Sub-Address */ 11098524Sfenner#define L2TP_AVP_TX_CONN_SPEED 24 /* (Tx) Connect Speed */ 11198524Sfenner#define L2TP_AVP_PHY_CHANNEL_ID 25 /* Physical Channel ID */ 11298524Sfenner#define L2TP_AVP_INI_RECV_LCP 26 /* Initial Received LCP CONFREQ */ 11398524Sfenner#define L2TP_AVP_LAST_SENT_LCP 27 /* Last Sent LCP CONFREQ */ 11498524Sfenner#define L2TP_AVP_LAST_RECV_LCP 28 /* Last Received LCP CONFREQ */ 11598524Sfenner#define L2TP_AVP_PROXY_AUTH_TYPE 29 /* Proxy Authen Type */ 11698524Sfenner#define L2TP_AVP_PROXY_AUTH_NAME 30 /* Proxy Authen Name */ 11798524Sfenner#define L2TP_AVP_PROXY_AUTH_CHAL 31 /* Proxy Authen Challenge */ 11898524Sfenner#define L2TP_AVP_PROXY_AUTH_ID 32 /* Proxy Authen ID */ 11998524Sfenner#define L2TP_AVP_PROXY_AUTH_RESP 33 /* Proxy Authen Response */ 12098524Sfenner#define L2TP_AVP_CALL_ERRORS 34 /* Call Errors */ 12198524Sfenner#define L2TP_AVP_ACCM 35 /* ACCM */ 12298524Sfenner#define L2TP_AVP_RANDOM_VECTOR 36 /* Random Vector */ 12398524Sfenner#define L2TP_AVP_PRIVATE_GRP_ID 37 /* Private Group ID */ 12498524Sfenner#define L2TP_AVP_RX_CONN_SPEED 38 /* (Rx) Connect Speed */ 12598524Sfenner#define L2TP_AVP_SEQ_REQUIRED 39 /* Sequencing Required */ 12698524Sfenner#define L2TP_AVP_PPP_DISCON_CC 46 /* PPP Disconnect Cause Code */ 12756893Sfenner 12898524Sfennerstatic struct tok l2tp_avp2str[] = { 12998524Sfenner { L2TP_AVP_MSGTYPE, "MSGTYPE" }, 13098524Sfenner { L2TP_AVP_RESULT_CODE, "RESULT_CODE" }, 13198524Sfenner { L2TP_AVP_PROTO_VER, "PROTO_VER" }, 13298524Sfenner { L2TP_AVP_FRAMING_CAP, "FRAMING_CAP" }, 13398524Sfenner { L2TP_AVP_BEARER_CAP, "BEARER_CAP" }, 13498524Sfenner { L2TP_AVP_TIE_BREAKER, "TIE_BREAKER" }, 13598524Sfenner { L2TP_AVP_FIRM_VER, "FIRM_VER" }, 13698524Sfenner { L2TP_AVP_HOST_NAME, "HOST_NAME" }, 13798524Sfenner { L2TP_AVP_VENDOR_NAME, "VENDOR_NAME" }, 13898524Sfenner { L2TP_AVP_ASSND_TUN_ID, "ASSND_TUN_ID" }, 13998524Sfenner { L2TP_AVP_RECV_WIN_SIZE, "RECV_WIN_SIZE" }, 14098524Sfenner { L2TP_AVP_CHALLENGE, "CHALLENGE" }, 14198524Sfenner { L2TP_AVP_Q931_CC, "Q931_CC", }, 14298524Sfenner { L2TP_AVP_CHALLENGE_RESP, "CHALLENGE_RESP" }, 14398524Sfenner { L2TP_AVP_ASSND_SESS_ID, "ASSND_SESS_ID" }, 14498524Sfenner { L2TP_AVP_CALL_SER_NUM, "CALL_SER_NUM" }, 14598524Sfenner { L2TP_AVP_MINIMUM_BPS, "MINIMUM_BPS" }, 14698524Sfenner { L2TP_AVP_MAXIMUM_BPS, "MAXIMUM_BPS" }, 14798524Sfenner { L2TP_AVP_BEARER_TYPE, "BEARER_TYPE" }, 14898524Sfenner { L2TP_AVP_FRAMING_TYPE, "FRAMING_TYPE" }, 14998524Sfenner { L2TP_AVP_PACKET_PROC_DELAY, "PACKET_PROC_DELAY" }, 15098524Sfenner { L2TP_AVP_CALLED_NUMBER, "CALLED_NUMBER" }, 15198524Sfenner { L2TP_AVP_CALLING_NUMBER, "CALLING_NUMBER" }, 15298524Sfenner { L2TP_AVP_SUB_ADDRESS, "SUB_ADDRESS" }, 15398524Sfenner { L2TP_AVP_TX_CONN_SPEED, "TX_CONN_SPEED" }, 15498524Sfenner { L2TP_AVP_PHY_CHANNEL_ID, "PHY_CHANNEL_ID" }, 15598524Sfenner { L2TP_AVP_INI_RECV_LCP, "INI_RECV_LCP" }, 15698524Sfenner { L2TP_AVP_LAST_SENT_LCP, "LAST_SENT_LCP" }, 15798524Sfenner { L2TP_AVP_LAST_RECV_LCP, "LAST_RECV_LCP" }, 15898524Sfenner { L2TP_AVP_PROXY_AUTH_TYPE, "PROXY_AUTH_TYPE" }, 15998524Sfenner { L2TP_AVP_PROXY_AUTH_NAME, "PROXY_AUTH_NAME" }, 16098524Sfenner { L2TP_AVP_PROXY_AUTH_CHAL, "PROXY_AUTH_CHAL" }, 16198524Sfenner { L2TP_AVP_PROXY_AUTH_ID, "PROXY_AUTH_ID" }, 16298524Sfenner { L2TP_AVP_PROXY_AUTH_RESP, "PROXY_AUTH_RESP" }, 16398524Sfenner { L2TP_AVP_CALL_ERRORS, "CALL_ERRORS" }, 16498524Sfenner { L2TP_AVP_ACCM, "ACCM" }, 16598524Sfenner { L2TP_AVP_RANDOM_VECTOR, "RANDOM_VECTOR" }, 16698524Sfenner { L2TP_AVP_PRIVATE_GRP_ID, "PRIVATE_GRP_ID" }, 16798524Sfenner { L2TP_AVP_RX_CONN_SPEED, "RX_CONN_SPEED" }, 16898524Sfenner { L2TP_AVP_SEQ_REQUIRED, "SEQ_REQUIRED" }, 16998524Sfenner { L2TP_AVP_PPP_DISCON_CC, "PPP_DISCON_CC" }, 17098524Sfenner { 0, NULL } 17156893Sfenner}; 17256893Sfenner 17398524Sfennerstatic struct tok l2tp_authentype2str[] = { 17498524Sfenner { L2TP_AUTHEN_TYPE_RESERVED, "Reserved" }, 17598524Sfenner { L2TP_AUTHEN_TYPE_TEXTUAL, "Textual" }, 17698524Sfenner { L2TP_AUTHEN_TYPE_CHAP, "CHAP" }, 17798524Sfenner { L2TP_AUTHEN_TYPE_PAP, "PAP" }, 17898524Sfenner { L2TP_AUTHEN_TYPE_NO_AUTH, "No Auth" }, 17998524Sfenner { L2TP_AUTHEN_TYPE_MSCHAPv1, "MS-CHAPv1" }, 18098524Sfenner { 0, NULL } 18198524Sfenner}; 18298524Sfenner 18398524Sfenner#define L2TP_PPP_DISCON_CC_DIRECTION_GLOBAL 0 18498524Sfenner#define L2TP_PPP_DISCON_CC_DIRECTION_AT_PEER 1 18598524Sfenner#define L2TP_PPP_DISCON_CC_DIRECTION_AT_LOCAL 2 18698524Sfenner 18798524Sfennerstatic struct tok l2tp_cc_direction2str[] = { 18898524Sfenner { L2TP_PPP_DISCON_CC_DIRECTION_GLOBAL, "global error" }, 18998524Sfenner { L2TP_PPP_DISCON_CC_DIRECTION_AT_PEER, "at peer" }, 19098524Sfenner { L2TP_PPP_DISCON_CC_DIRECTION_AT_LOCAL,"at local" }, 19198524Sfenner { 0, NULL } 19298524Sfenner}; 19398524Sfenner 19456893Sfenner#if 0 19556893Sfennerstatic char *l2tp_result_code_StopCCN[] = { 19656893Sfenner "Reserved", 19756893Sfenner "General request to clear control connection", 19856893Sfenner "General error--Error Code indicates the problem", 19956893Sfenner "Control channel already exists", 20056893Sfenner "Requester is not authorized to establish a control channel", 20156893Sfenner "The protocol version of the requester is not supported", 20256893Sfenner "Requester is being shut down", 20356893Sfenner "Finite State Machine error" 20456893Sfenner#define L2TP_MAX_RESULT_CODE_STOPCC_INDEX 8 20556893Sfenner}; 20656893Sfenner#endif 20756893Sfenner 20856893Sfenner#if 0 20956893Sfennerstatic char *l2tp_result_code_CDN[] = { 21056893Sfenner "Reserved", 21156893Sfenner "Call disconnected due to loss of carrier", 21256893Sfenner "Call disconnected for the reason indicated in error code", 21356893Sfenner "Call disconnected for administrative reasons", 21456893Sfenner "Call failed due to lack of appropriate facilities being " \ 21556893Sfenner "available (temporary condition)", 21656893Sfenner "Call failed due to lack of appropriate facilities being " \ 21756893Sfenner "available (permanent condition)", 21856893Sfenner "Invalid destination", 21956893Sfenner "Call failed due to no carrier detected", 22056893Sfenner "Call failed due to detection of a busy signal", 22156893Sfenner "Call failed due to lack of a dial tone", 22256893Sfenner "Call was not established within time allotted by LAC", 22356893Sfenner "Call was connected but no appropriate framing was detected" 22456893Sfenner#define L2TP_MAX_RESULT_CODE_CDN_INDEX 12 22556893Sfenner}; 22656893Sfenner#endif 22756893Sfenner 22856893Sfenner#if 0 22956893Sfennerstatic char *l2tp_error_code_general[] = { 23056893Sfenner "No general error", 23156893Sfenner "No control connection exists yet for this LAC-LNS pair", 23256893Sfenner "Length is wrong", 23356893Sfenner "One of the field values was out of range or " \ 23456893Sfenner "reserved field was non-zero" 23556893Sfenner "Insufficient resources to handle this operation now", 23656893Sfenner "The Session ID is invalid in this context", 23756893Sfenner "A generic vendor-specific error occurred in the LAC", 23856893Sfenner "Try another" 23956893Sfenner#define L2TP_MAX_ERROR_CODE_GENERAL_INDEX 8 24056893Sfenner}; 24156893Sfenner#endif 24256893Sfenner 24356893Sfenner/******************************/ 24456893Sfenner/* generic print out routines */ 24556893Sfenner/******************************/ 24656893Sfennerstatic void 24756893Sfennerprint_string(const u_char *dat, u_int length) 24856893Sfenner{ 24956893Sfenner int i; 25056893Sfenner for (i=0; i<length; i++) { 25156893Sfenner printf("%c", *dat++); 25256893Sfenner } 25356893Sfenner} 25456893Sfenner 25556893Sfennerstatic void 25656893Sfennerprint_octets(const u_char *dat, u_int length) 25756893Sfenner{ 25856893Sfenner int i; 25956893Sfenner for (i=0; i<length; i++) { 26056893Sfenner printf("%02x", *dat++); 26156893Sfenner } 26256893Sfenner} 26356893Sfenner 26456893Sfennerstatic void 26598524Sfennerprint_16bits_val(const u_int16_t *dat) 26656893Sfenner{ 267111726Sfenner printf("%u", EXTRACT_16BITS(dat)); 26856893Sfenner} 26956893Sfenner 27056893Sfennerstatic void 27198524Sfennerprint_32bits_val(const u_int32_t *dat) 27256893Sfenner{ 273111726Sfenner printf("%lu", (u_long)EXTRACT_32BITS(dat)); 27456893Sfenner} 27556893Sfenner 27698524Sfenner/***********************************/ 27798524Sfenner/* AVP-specific print out routines */ 27898524Sfenner/***********************************/ 27956893Sfennerstatic void 28098524Sfennerl2tp_msgtype_print(const u_char *dat) 28156893Sfenner{ 28298524Sfenner u_int16_t *ptr = (u_int16_t*)dat; 28356893Sfenner 284111726Sfenner printf("%s", tok2str(l2tp_msgtype2str, "MSGTYPE-#%u", 285111726Sfenner EXTRACT_16BITS(ptr))); 28656893Sfenner} 28756893Sfenner 28856893Sfennerstatic void 28956893Sfennerl2tp_result_code_print(const u_char *dat, u_int length) 29056893Sfenner{ 29198524Sfenner u_int16_t *ptr = (u_int16_t *)dat; 29256893Sfenner 293111726Sfenner printf("%u", EXTRACT_16BITS(ptr)); ptr++; /* Result Code */ 294111726Sfenner if (length > 2) { /* Error Code (opt) */ 295111726Sfenner printf("/%u", EXTRACT_16BITS(ptr)); ptr++; 29656893Sfenner } 297111726Sfenner if (length > 4) { /* Error Message (opt) */ 29898524Sfenner printf(" "); 29998524Sfenner print_string((u_char *)ptr, length - 4); 30098524Sfenner } 30156893Sfenner} 30256893Sfenner 30356893Sfennerstatic void 30498524Sfennerl2tp_proto_ver_print(const u_int16_t *dat) 30556893Sfenner{ 306111726Sfenner printf("%u.%u", (EXTRACT_16BITS(dat) >> 8), 307111726Sfenner (EXTRACT_16BITS(dat) & 0xff)); 30856893Sfenner} 30956893Sfenner 31056893Sfennerstatic void 31198524Sfennerl2tp_framing_cap_print(const u_char *dat) 31256893Sfenner{ 31398524Sfenner u_int32_t *ptr = (u_int32_t *)dat; 31456893Sfenner 315111726Sfenner if (EXTRACT_32BITS(ptr) & L2TP_FRAMING_CAP_ASYNC_MASK) { 31656893Sfenner printf("A"); 31756893Sfenner } 318111726Sfenner if (EXTRACT_32BITS(ptr) & L2TP_FRAMING_CAP_SYNC_MASK) { 31956893Sfenner printf("S"); 32056893Sfenner } 32156893Sfenner} 32256893Sfenner 32356893Sfennerstatic void 32498524Sfennerl2tp_bearer_cap_print(const u_char *dat) 32556893Sfenner{ 32698524Sfenner u_int32_t *ptr = (u_int32_t *)dat; 32756893Sfenner 328111726Sfenner if (EXTRACT_32BITS(ptr) & L2TP_BEARER_CAP_ANALOG_MASK) { 32956893Sfenner printf("A"); 33056893Sfenner } 331111726Sfenner if (EXTRACT_32BITS(ptr) & L2TP_BEARER_CAP_DIGITAL_MASK) { 33256893Sfenner printf("D"); 33356893Sfenner } 33456893Sfenner} 33556893Sfenner 33656893Sfennerstatic void 33756893Sfennerl2tp_q931_cc_print(const u_char *dat, u_int length) 33856893Sfenner{ 33998524Sfenner print_16bits_val((u_int16_t *)dat); 34056893Sfenner printf(", %02x", dat[2]); 34156893Sfenner if (length > 3) { 34256893Sfenner printf(" "); 34356893Sfenner print_string(dat+3, length-3); 34456893Sfenner } 34556893Sfenner} 34656893Sfenner 34756893Sfennerstatic void 34898524Sfennerl2tp_bearer_type_print(const u_char *dat) 34956893Sfenner{ 35098524Sfenner u_int32_t *ptr = (u_int32_t *)dat; 35156893Sfenner 352111726Sfenner if (EXTRACT_32BITS(ptr) & L2TP_BEARER_TYPE_ANALOG_MASK) { 35356893Sfenner printf("A"); 35456893Sfenner } 355111726Sfenner if (EXTRACT_32BITS(ptr) & L2TP_BEARER_TYPE_DIGITAL_MASK) { 35656893Sfenner printf("D"); 35756893Sfenner } 35856893Sfenner} 35956893Sfenner 36056893Sfennerstatic void 36198524Sfennerl2tp_framing_type_print(const u_char *dat) 36256893Sfenner{ 36398524Sfenner u_int32_t *ptr = (u_int32_t *)dat; 36456893Sfenner 365111726Sfenner if (EXTRACT_32BITS(ptr) & L2TP_FRAMING_TYPE_ASYNC_MASK) { 36656893Sfenner printf("A"); 36756893Sfenner } 368111726Sfenner if (EXTRACT_32BITS(ptr) & L2TP_FRAMING_TYPE_SYNC_MASK) { 36956893Sfenner printf("S"); 37056893Sfenner } 37156893Sfenner} 37256893Sfenner 37356893Sfennerstatic void 37498524Sfennerl2tp_packet_proc_delay_print(void) 37556893Sfenner{ 37656893Sfenner printf("obsolete"); 37756893Sfenner} 37856893Sfenner 37956893Sfennerstatic void 38098524Sfennerl2tp_proxy_auth_type_print(const u_char *dat) 38156893Sfenner{ 38298524Sfenner u_int16_t *ptr = (u_int16_t *)dat; 38356893Sfenner 38498524Sfenner printf("%s", tok2str(l2tp_authentype2str, 385111726Sfenner "AuthType-#%u", EXTRACT_16BITS(ptr))); 38656893Sfenner} 38756893Sfenner 38856893Sfennerstatic void 38998524Sfennerl2tp_proxy_auth_id_print(const u_char *dat) 39056893Sfenner{ 39198524Sfenner u_int16_t *ptr = (u_int16_t *)dat; 39256893Sfenner 393111726Sfenner printf("%u", EXTRACT_16BITS(ptr) & L2TP_PROXY_AUTH_ID_MASK); 39456893Sfenner} 39556893Sfenner 39656893Sfennerstatic void 39798524Sfennerl2tp_call_errors_print(const u_char *dat) 39856893Sfenner{ 39998524Sfenner u_int16_t *ptr = (u_int16_t *)dat; 40098524Sfenner u_int16_t val_h, val_l; 40198524Sfenner 40298524Sfenner ptr++; /* skip "Reserved" */ 40356893Sfenner 404111726Sfenner val_h = EXTRACT_16BITS(ptr); ptr++; 405111726Sfenner val_l = EXTRACT_16BITS(ptr); ptr++; 40698524Sfenner printf("CRCErr=%u ", (val_h<<16) + val_l); 40756893Sfenner 408111726Sfenner val_h = EXTRACT_16BITS(ptr); ptr++; 409111726Sfenner val_l = EXTRACT_16BITS(ptr); ptr++; 41098524Sfenner printf("FrameErr=%u ", (val_h<<16) + val_l); 41156893Sfenner 412111726Sfenner val_h = EXTRACT_16BITS(ptr); ptr++; 413111726Sfenner val_l = EXTRACT_16BITS(ptr); ptr++; 41498524Sfenner printf("HardOver=%u ", (val_h<<16) + val_l); 41556893Sfenner 416111726Sfenner val_h = EXTRACT_16BITS(ptr); ptr++; 417111726Sfenner val_l = EXTRACT_16BITS(ptr); ptr++; 41898524Sfenner printf("BufOver=%u ", (val_h<<16) + val_l); 41956893Sfenner 420111726Sfenner val_h = EXTRACT_16BITS(ptr); ptr++; 421111726Sfenner val_l = EXTRACT_16BITS(ptr); ptr++; 42298524Sfenner printf("Timeout=%u ", (val_h<<16) + val_l); 42356893Sfenner 424111726Sfenner val_h = EXTRACT_16BITS(ptr); ptr++; 425111726Sfenner val_l = EXTRACT_16BITS(ptr); ptr++; 42698524Sfenner printf("AlignErr=%u ", (val_h<<16) + val_l); 42756893Sfenner} 42856893Sfenner 42956893Sfennerstatic void 43098524Sfennerl2tp_accm_print(const u_char *dat) 43156893Sfenner{ 43298524Sfenner u_int16_t *ptr = (u_int16_t *)dat; 43398524Sfenner u_int16_t val_h, val_l; 43456893Sfenner 43598524Sfenner ptr++; /* skip "Reserved" */ 43656893Sfenner 437111726Sfenner val_h = EXTRACT_16BITS(ptr); ptr++; 438111726Sfenner val_l = EXTRACT_16BITS(ptr); ptr++; 43998524Sfenner printf("send=%08x ", (val_h<<16) + val_l); 44098524Sfenner 441111726Sfenner val_h = EXTRACT_16BITS(ptr); ptr++; 442111726Sfenner val_l = EXTRACT_16BITS(ptr); ptr++; 44398524Sfenner printf("recv=%08x ", (val_h<<16) + val_l); 44456893Sfenner} 44556893Sfenner 44656893Sfennerstatic void 44798524Sfennerl2tp_ppp_discon_cc_print(const u_char *dat, u_int length) 44856893Sfenner{ 44998524Sfenner u_int16_t *ptr = (u_int16_t *)dat; 45098524Sfenner 451111726Sfenner printf("%04x, ", EXTRACT_16BITS(ptr)); ptr++; /* Disconnect Code */ 452111726Sfenner printf("%04x ", EXTRACT_16BITS(ptr)); ptr++; /* Control Protocol Number */ 45398524Sfenner printf("%s", tok2str(l2tp_cc_direction2str, 45498524Sfenner "Direction-#%u", *((u_char *)ptr++))); 45556893Sfenner 45698524Sfenner if (length > 5) { 45798524Sfenner printf(" "); 45898524Sfenner print_string((const u_char *)ptr, length-5); 45998524Sfenner } 46056893Sfenner} 46156893Sfenner 46256893Sfennerstatic void 46398524Sfennerl2tp_avp_print(const u_char *dat, int length) 46456893Sfenner{ 46598524Sfenner u_int len; 46698524Sfenner const u_int16_t *ptr = (u_int16_t *)dat; 46798524Sfenner u_int16_t attr_type; 46898524Sfenner int hidden = FALSE; 46956893Sfenner 47098524Sfenner if (length <= 0) { 47198524Sfenner return; 47298524Sfenner } 47356893Sfenner 47498524Sfenner printf(" "); 47556893Sfenner 47698524Sfenner TCHECK(*ptr); /* Flags & Length */ 477111726Sfenner len = EXTRACT_16BITS(ptr) & L2TP_AVP_HDR_LEN_MASK; 47856893Sfenner 47998524Sfenner /* If it is not long enough to decode the entire AVP, we'll 48098524Sfenner abandon. */ 48198524Sfenner TCHECK2(*ptr, len); 48298524Sfenner /* After this point, no need to worry about truncation */ 48356893Sfenner 484111726Sfenner if (EXTRACT_16BITS(ptr) & L2TP_AVP_HDR_FLAG_MANDATORY) { 48598524Sfenner printf("*"); 48698524Sfenner } 487111726Sfenner if (EXTRACT_16BITS(ptr) & L2TP_AVP_HDR_FLAG_HIDDEN) { 48898524Sfenner hidden = TRUE; 48998524Sfenner printf("?"); 49098524Sfenner } 49198524Sfenner ptr++; 49256893Sfenner 493111726Sfenner if (EXTRACT_16BITS(ptr)) { 49498524Sfenner /* Vendor Specific Attribute */ 495111726Sfenner printf("VENDOR%04x:", EXTRACT_16BITS(ptr)); ptr++; 496111726Sfenner printf("ATTR%04x", EXTRACT_16BITS(ptr)); ptr++; 49798524Sfenner printf("("); 49898524Sfenner print_octets((u_char *)ptr, len-6); 49998524Sfenner printf(")"); 50098524Sfenner } else { 50198524Sfenner /* IETF-defined Attributes */ 50256893Sfenner ptr++; 503111726Sfenner attr_type = EXTRACT_16BITS(ptr); ptr++; 50498524Sfenner printf("%s", tok2str(l2tp_avp2str, "AVP-#%u", attr_type)); 50598524Sfenner printf("("); 50698524Sfenner if (hidden) { 50798524Sfenner printf("???"); 50875115Sfenner } else { 50998524Sfenner switch (attr_type) { 51098524Sfenner case L2TP_AVP_MSGTYPE: 51198524Sfenner l2tp_msgtype_print((u_char *)ptr); 51298524Sfenner break; 51398524Sfenner case L2TP_AVP_RESULT_CODE: 51498524Sfenner l2tp_result_code_print((u_char *)ptr, len-6); 51598524Sfenner break; 51698524Sfenner case L2TP_AVP_PROTO_VER: 51798524Sfenner l2tp_proto_ver_print(ptr); 51898524Sfenner break; 51998524Sfenner case L2TP_AVP_FRAMING_CAP: 52098524Sfenner l2tp_framing_cap_print((u_char *)ptr); 52198524Sfenner break; 52298524Sfenner case L2TP_AVP_BEARER_CAP: 52398524Sfenner l2tp_bearer_cap_print((u_char *)ptr); 52498524Sfenner break; 52598524Sfenner case L2TP_AVP_TIE_BREAKER: 52698524Sfenner print_octets((u_char *)ptr, 8); 52798524Sfenner break; 52898524Sfenner case L2TP_AVP_FIRM_VER: 52998524Sfenner case L2TP_AVP_ASSND_TUN_ID: 53098524Sfenner case L2TP_AVP_RECV_WIN_SIZE: 53198524Sfenner case L2TP_AVP_ASSND_SESS_ID: 53298524Sfenner print_16bits_val(ptr); 53398524Sfenner break; 53498524Sfenner case L2TP_AVP_HOST_NAME: 53598524Sfenner case L2TP_AVP_VENDOR_NAME: 53698524Sfenner case L2TP_AVP_CALLING_NUMBER: 53798524Sfenner case L2TP_AVP_CALLED_NUMBER: 53898524Sfenner case L2TP_AVP_SUB_ADDRESS: 53998524Sfenner case L2TP_AVP_PROXY_AUTH_NAME: 54098524Sfenner case L2TP_AVP_PRIVATE_GRP_ID: 54198524Sfenner print_string((u_char *)ptr, len-6); 54298524Sfenner break; 54398524Sfenner case L2TP_AVP_CHALLENGE: 54498524Sfenner case L2TP_AVP_INI_RECV_LCP: 54598524Sfenner case L2TP_AVP_LAST_SENT_LCP: 54698524Sfenner case L2TP_AVP_LAST_RECV_LCP: 54798524Sfenner case L2TP_AVP_PROXY_AUTH_CHAL: 54898524Sfenner case L2TP_AVP_PROXY_AUTH_RESP: 54998524Sfenner case L2TP_AVP_RANDOM_VECTOR: 55098524Sfenner print_octets((u_char *)ptr, len-6); 55198524Sfenner break; 55298524Sfenner case L2TP_AVP_Q931_CC: 55398524Sfenner l2tp_q931_cc_print((u_char *)ptr, len-6); 55498524Sfenner break; 55598524Sfenner case L2TP_AVP_CHALLENGE_RESP: 55698524Sfenner print_octets((u_char *)ptr, 16); 55798524Sfenner break; 55898524Sfenner case L2TP_AVP_CALL_SER_NUM: 55998524Sfenner case L2TP_AVP_MINIMUM_BPS: 56098524Sfenner case L2TP_AVP_MAXIMUM_BPS: 56198524Sfenner case L2TP_AVP_TX_CONN_SPEED: 56298524Sfenner case L2TP_AVP_PHY_CHANNEL_ID: 56398524Sfenner case L2TP_AVP_RX_CONN_SPEED: 56498524Sfenner print_32bits_val((u_int32_t *)ptr); 56598524Sfenner break; 56698524Sfenner case L2TP_AVP_BEARER_TYPE: 56798524Sfenner l2tp_bearer_type_print((u_char *)ptr); 56898524Sfenner break; 56998524Sfenner case L2TP_AVP_FRAMING_TYPE: 57098524Sfenner l2tp_framing_type_print((u_char *)ptr); 57198524Sfenner break; 57298524Sfenner case L2TP_AVP_PACKET_PROC_DELAY: 57398524Sfenner l2tp_packet_proc_delay_print(); 57498524Sfenner break; 57598524Sfenner case L2TP_AVP_PROXY_AUTH_TYPE: 57698524Sfenner l2tp_proxy_auth_type_print((u_char *)ptr); 57798524Sfenner break; 57898524Sfenner case L2TP_AVP_PROXY_AUTH_ID: 57998524Sfenner l2tp_proxy_auth_id_print((u_char *)ptr); 58098524Sfenner break; 58198524Sfenner case L2TP_AVP_CALL_ERRORS: 58298524Sfenner l2tp_call_errors_print((u_char *)ptr); 58398524Sfenner break; 58498524Sfenner case L2TP_AVP_ACCM: 58598524Sfenner l2tp_accm_print((u_char *)ptr); 58698524Sfenner break; 58798524Sfenner case L2TP_AVP_SEQ_REQUIRED: 58898524Sfenner break; /* No Attribute Value */ 58998524Sfenner case L2TP_AVP_PPP_DISCON_CC: 59098524Sfenner l2tp_ppp_discon_cc_print((u_char *)ptr, len-6); 59198524Sfenner break; 59298524Sfenner default: 59398524Sfenner break; 59456893Sfenner } 59556893Sfenner } 59698524Sfenner printf(")"); 59798524Sfenner } 59856893Sfenner 59998524Sfenner l2tp_avp_print(dat+len, length-len); 60098524Sfenner return; 60198524Sfenner 60298524Sfenner trunc: 60398524Sfenner printf("|..."); 60456893Sfenner} 60556893Sfenner 60656893Sfenner 60756893Sfennervoid 60856893Sfennerl2tp_print(const u_char *dat, u_int length) 60956893Sfenner{ 61098524Sfenner const u_int16_t *ptr = (u_int16_t *)dat; 61156893Sfenner u_int cnt = 0; /* total octets consumed */ 61298524Sfenner u_int16_t pad; 61356893Sfenner int flag_t, flag_l, flag_s, flag_o, flag_p; 61498524Sfenner u_int16_t l2tp_len; 61556893Sfenner 61656893Sfenner flag_t = flag_l = flag_s = flag_o = flag_p = FALSE; 61756893Sfenner 61898524Sfenner TCHECK(*ptr); /* Flags & Version */ 619111726Sfenner if ((EXTRACT_16BITS(ptr) & L2TP_VERSION_MASK) == L2TP_VERSION_L2TP) { 62056893Sfenner printf(" l2tp:"); 621111726Sfenner } else if ((EXTRACT_16BITS(ptr) & L2TP_VERSION_MASK) == L2TP_VERSION_L2F) { 62256893Sfenner printf(" l2f:"); 62356893Sfenner return; /* nothing to do */ 62456893Sfenner } else { 62556893Sfenner printf(" Unknown Version, neither L2F(1) nor L2TP(2)"); 62656893Sfenner return; /* nothing we can do */ 62756893Sfenner } 62856893Sfenner 62956893Sfenner printf("["); 630111726Sfenner if (EXTRACT_16BITS(ptr) & L2TP_FLAG_TYPE) { 63156893Sfenner flag_t = TRUE; 63256893Sfenner printf("T"); 63356893Sfenner } 634111726Sfenner if (EXTRACT_16BITS(ptr) & L2TP_FLAG_LENGTH) { 63556893Sfenner flag_l = TRUE; 63656893Sfenner printf("L"); 63756893Sfenner } 638111726Sfenner if (EXTRACT_16BITS(ptr) & L2TP_FLAG_SEQUENCE) { 63956893Sfenner flag_s = TRUE; 64056893Sfenner printf("S"); 64156893Sfenner } 642111726Sfenner if (EXTRACT_16BITS(ptr) & L2TP_FLAG_OFFSET) { 64356893Sfenner flag_o = TRUE; 64456893Sfenner printf("O"); 64556893Sfenner } 646111726Sfenner if (EXTRACT_16BITS(ptr) & L2TP_FLAG_PRIORITY) { 64756893Sfenner flag_p = TRUE; 64856893Sfenner printf("P"); 64956893Sfenner } 65056893Sfenner printf("]"); 65156893Sfenner 65256893Sfenner ptr++; 65356893Sfenner cnt += 2; 65456893Sfenner 65556893Sfenner if (flag_l) { 65698524Sfenner TCHECK(*ptr); /* Length */ 657111726Sfenner l2tp_len = EXTRACT_16BITS(ptr); ptr++; 65856893Sfenner cnt += 2; 65956893Sfenner } else { 66056893Sfenner l2tp_len = 0; 66156893Sfenner } 66256893Sfenner 66398524Sfenner TCHECK(*ptr); /* Tunnel ID */ 664111726Sfenner printf("(%u/", EXTRACT_16BITS(ptr)); ptr++; 66598524Sfenner cnt += 2; 66698524Sfenner TCHECK(*ptr); /* Session ID */ 667111726Sfenner printf("%u)", EXTRACT_16BITS(ptr)); ptr++; 66898524Sfenner cnt += 2; 66956893Sfenner 67056893Sfenner if (flag_s) { 67198524Sfenner TCHECK(*ptr); /* Ns */ 672111726Sfenner printf("Ns=%u,", EXTRACT_16BITS(ptr)); ptr++; 67398524Sfenner cnt += 2; 67498524Sfenner TCHECK(*ptr); /* Nr */ 675111726Sfenner printf("Nr=%u", EXTRACT_16BITS(ptr)); ptr++; 67698524Sfenner cnt += 2; 67756893Sfenner } 67856893Sfenner 67956893Sfenner if (flag_o) { 68098524Sfenner TCHECK(*ptr); /* Offset Size */ 681111726Sfenner pad = EXTRACT_16BITS(ptr); ptr++; 68256893Sfenner ptr += pad / sizeof(*ptr); 68356893Sfenner cnt += (2 + pad); 68456893Sfenner } 68556893Sfenner 68656893Sfenner if (flag_t) { 68756893Sfenner if (length - cnt == 0) { 68856893Sfenner printf(" ZLB"); 68956893Sfenner } else { 69056893Sfenner l2tp_avp_print((u_char *)ptr, length - cnt); 69156893Sfenner } 69256893Sfenner } else { 69356893Sfenner printf(" {"); 69475115Sfenner ppp_print((u_char *)ptr, length - cnt); 69556893Sfenner printf("}"); 69656893Sfenner } 69798524Sfenner 69898524Sfenner return; 69998524Sfenner 70098524Sfenner trunc: 70198524Sfenner printf("%s", tstr); 70256893Sfenner} 703