1190203Srpaulo/* 2190203Srpaulo * Copyright (c) 1998-2007 The TCPDUMP project 3190203Srpaulo * 4190203Srpaulo * Redistribution and use in source and binary forms, with or without 5190203Srpaulo * modification, are permitted provided that: (1) source code 6190203Srpaulo * distributions retain the above copyright notice and this paragraph 7190203Srpaulo * in its entirety, and (2) distributions including binary code include 8190203Srpaulo * the above copyright notice and this paragraph in its entirety in 9190203Srpaulo * the documentation or other materials provided with the distribution. 10190203Srpaulo * THIS SOFTWARE IS PROVIDED ``AS IS'' AND 11190203Srpaulo * WITHOUT ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, WITHOUT 12190203Srpaulo * LIMITATION, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS 13190203Srpaulo * FOR A PARTICULAR PURPOSE. 14190203Srpaulo * 15235530Sdelphij * support for the IEEE Link Discovery Protocol as per 802.1AB 16190203Srpaulo * 17190203Srpaulo * Original code by Hannes Gredler (hannes@juniper.net) 18190203Srpaulo * IEEE and TIA extensions by Carles Kishimoto <carles.kishimoto@gmail.com> 19235530Sdelphij * DCBX extensions by Kaladhar Musunuru <kaladharm@sourceforge.net> 20190203Srpaulo */ 21190203Srpaulo 22190203Srpaulo#ifndef lint 23190203Srpaulostatic const char rcsid[] _U_ = 24214478Srpaulo"@(#) $Header: /tcpdump/master/tcpdump/print-lldp.c,v 1.10 2008-03-20 09:30:56 hannes Exp $"; 25190203Srpaulo#endif 26190203Srpaulo 27190203Srpaulo#ifdef HAVE_CONFIG_H 28190203Srpaulo#include "config.h" 29190203Srpaulo#endif 30190203Srpaulo 31190203Srpaulo#include <tcpdump-stdinc.h> 32190203Srpaulo 33190203Srpaulo#include <stdio.h> 34190203Srpaulo#include <stdlib.h> 35190203Srpaulo#include <string.h> 36190203Srpaulo 37190203Srpaulo#include "interface.h" 38190203Srpaulo#include "extract.h" 39190203Srpaulo#include "addrtoname.h" 40190203Srpaulo#include "af.h" 41190203Srpaulo#include "oui.h" 42190203Srpaulo 43190203Srpaulo#define LLDP_EXTRACT_TYPE(x) (((x)&0xfe00)>>9) 44190203Srpaulo#define LLDP_EXTRACT_LEN(x) ((x)&0x01ff) 45190203Srpaulo 46190203Srpaulo/* 47190203Srpaulo * TLV type codes 48190203Srpaulo */ 49190203Srpaulo#define LLDP_END_TLV 0 50190203Srpaulo#define LLDP_CHASSIS_ID_TLV 1 51190203Srpaulo#define LLDP_PORT_ID_TLV 2 52190203Srpaulo#define LLDP_TTL_TLV 3 53190203Srpaulo#define LLDP_PORT_DESCR_TLV 4 54190203Srpaulo#define LLDP_SYSTEM_NAME_TLV 5 55190203Srpaulo#define LLDP_SYSTEM_DESCR_TLV 6 56190203Srpaulo#define LLDP_SYSTEM_CAP_TLV 7 57190203Srpaulo#define LLDP_MGMT_ADDR_TLV 8 58190203Srpaulo#define LLDP_PRIVATE_TLV 127 59190203Srpaulo 60190203Srpaulostatic const struct tok lldp_tlv_values[] = { 61190203Srpaulo { LLDP_END_TLV, "End" }, 62190203Srpaulo { LLDP_CHASSIS_ID_TLV, "Chassis ID" }, 63190203Srpaulo { LLDP_PORT_ID_TLV, "Port ID" }, 64190203Srpaulo { LLDP_TTL_TLV, "Time to Live" }, 65190203Srpaulo { LLDP_PORT_DESCR_TLV, "Port Description" }, 66190203Srpaulo { LLDP_SYSTEM_NAME_TLV, "System Name" }, 67190203Srpaulo { LLDP_SYSTEM_DESCR_TLV, "System Description" }, 68190203Srpaulo { LLDP_SYSTEM_CAP_TLV, "System Capabilities" }, 69190203Srpaulo { LLDP_MGMT_ADDR_TLV, "Management Address" }, 70190203Srpaulo { LLDP_PRIVATE_TLV, "Organization specific" }, 71190203Srpaulo { 0, NULL} 72190203Srpaulo}; 73190203Srpaulo 74190203Srpaulo/* 75190203Srpaulo * Chassis ID subtypes 76190203Srpaulo */ 77190203Srpaulo#define LLDP_CHASSIS_CHASSIS_COMP_SUBTYPE 1 78190203Srpaulo#define LLDP_CHASSIS_INTF_ALIAS_SUBTYPE 2 79190203Srpaulo#define LLDP_CHASSIS_PORT_COMP_SUBTYPE 3 80190203Srpaulo#define LLDP_CHASSIS_MAC_ADDR_SUBTYPE 4 81190203Srpaulo#define LLDP_CHASSIS_NETWORK_ADDR_SUBTYPE 5 82190203Srpaulo#define LLDP_CHASSIS_INTF_NAME_SUBTYPE 6 83190203Srpaulo#define LLDP_CHASSIS_LOCAL_SUBTYPE 7 84190203Srpaulo 85190203Srpaulostatic const struct tok lldp_chassis_subtype_values[] = { 86190203Srpaulo { LLDP_CHASSIS_CHASSIS_COMP_SUBTYPE, "Chassis component"}, 87190203Srpaulo { LLDP_CHASSIS_INTF_ALIAS_SUBTYPE, "Interface alias"}, 88190203Srpaulo { LLDP_CHASSIS_PORT_COMP_SUBTYPE, "Port component"}, 89190203Srpaulo { LLDP_CHASSIS_MAC_ADDR_SUBTYPE, "MAC address"}, 90190203Srpaulo { LLDP_CHASSIS_NETWORK_ADDR_SUBTYPE, "Network address"}, 91190203Srpaulo { LLDP_CHASSIS_INTF_NAME_SUBTYPE, "Interface name"}, 92190203Srpaulo { LLDP_CHASSIS_LOCAL_SUBTYPE, "Local"}, 93190203Srpaulo { 0, NULL} 94190203Srpaulo}; 95190203Srpaulo 96190203Srpaulo/* 97190203Srpaulo * Port ID subtypes 98190203Srpaulo */ 99190203Srpaulo#define LLDP_PORT_INTF_ALIAS_SUBTYPE 1 100190203Srpaulo#define LLDP_PORT_PORT_COMP_SUBTYPE 2 101190203Srpaulo#define LLDP_PORT_MAC_ADDR_SUBTYPE 3 102190203Srpaulo#define LLDP_PORT_NETWORK_ADDR_SUBTYPE 4 103190203Srpaulo#define LLDP_PORT_INTF_NAME_SUBTYPE 5 104190203Srpaulo#define LLDP_PORT_AGENT_CIRC_ID_SUBTYPE 6 105190203Srpaulo#define LLDP_PORT_LOCAL_SUBTYPE 7 106190203Srpaulo 107190203Srpaulostatic const struct tok lldp_port_subtype_values[] = { 108190203Srpaulo { LLDP_PORT_INTF_ALIAS_SUBTYPE, "Interface alias"}, 109190203Srpaulo { LLDP_PORT_PORT_COMP_SUBTYPE, "Port component"}, 110190203Srpaulo { LLDP_PORT_MAC_ADDR_SUBTYPE, "MAC address"}, 111190203Srpaulo { LLDP_PORT_NETWORK_ADDR_SUBTYPE, "Network Address"}, 112190203Srpaulo { LLDP_PORT_INTF_NAME_SUBTYPE, "Interface Name"}, 113190203Srpaulo { LLDP_PORT_AGENT_CIRC_ID_SUBTYPE, "Agent circuit ID"}, 114190203Srpaulo { LLDP_PORT_LOCAL_SUBTYPE, "Local"}, 115190203Srpaulo { 0, NULL} 116190203Srpaulo}; 117190203Srpaulo 118190203Srpaulo/* 119190203Srpaulo * System Capabilities 120190203Srpaulo */ 121190203Srpaulo#define LLDP_CAP_OTHER (1 << 0) 122190203Srpaulo#define LLDP_CAP_REPEATER (1 << 1) 123190203Srpaulo#define LLDP_CAP_BRIDGE (1 << 2) 124190203Srpaulo#define LLDP_CAP_WLAN_AP (1 << 3) 125190203Srpaulo#define LLDP_CAP_ROUTER (1 << 4) 126190203Srpaulo#define LLDP_CAP_PHONE (1 << 5) 127190203Srpaulo#define LLDP_CAP_DOCSIS (1 << 6) 128190203Srpaulo#define LLDP_CAP_STATION_ONLY (1 << 7) 129190203Srpaulo 130190203Srpaulostatic const struct tok lldp_cap_values[] = { 131190203Srpaulo { LLDP_CAP_OTHER, "Other"}, 132190203Srpaulo { LLDP_CAP_REPEATER, "Repeater"}, 133190203Srpaulo { LLDP_CAP_BRIDGE, "Bridge"}, 134190203Srpaulo { LLDP_CAP_WLAN_AP, "WLAN AP"}, 135190203Srpaulo { LLDP_CAP_ROUTER, "Router"}, 136190203Srpaulo { LLDP_CAP_PHONE, "Telephone"}, 137190203Srpaulo { LLDP_CAP_DOCSIS, "Docsis"}, 138190203Srpaulo { LLDP_CAP_STATION_ONLY, "Station Only"}, 139190203Srpaulo { 0, NULL} 140190203Srpaulo}; 141190203Srpaulo 142190203Srpaulo#define LLDP_PRIVATE_8021_SUBTYPE_PORT_VLAN_ID 1 143190203Srpaulo#define LLDP_PRIVATE_8021_SUBTYPE_PROTOCOL_VLAN_ID 2 144190203Srpaulo#define LLDP_PRIVATE_8021_SUBTYPE_VLAN_NAME 3 145190203Srpaulo#define LLDP_PRIVATE_8021_SUBTYPE_PROTOCOL_IDENTITY 4 146190203Srpaulo 147190203Srpaulostatic const struct tok lldp_8021_subtype_values[] = { 148190203Srpaulo { LLDP_PRIVATE_8021_SUBTYPE_PORT_VLAN_ID, "Port VLAN Id"}, 149190203Srpaulo { LLDP_PRIVATE_8021_SUBTYPE_PROTOCOL_VLAN_ID, "Port and Protocol VLAN ID"}, 150190203Srpaulo { LLDP_PRIVATE_8021_SUBTYPE_VLAN_NAME, "VLAN name"}, 151190203Srpaulo { LLDP_PRIVATE_8021_SUBTYPE_PROTOCOL_IDENTITY, "Protocol Identity"}, 152190203Srpaulo { 0, NULL} 153190203Srpaulo}; 154190203Srpaulo 155190203Srpaulo#define LLDP_8021_PORT_PROTOCOL_VLAN_SUPPORT (1 << 1) 156190203Srpaulo#define LLDP_8021_PORT_PROTOCOL_VLAN_STATUS (1 << 2) 157190203Srpaulo 158190203Srpaulostatic const struct tok lldp_8021_port_protocol_id_values[] = { 159190203Srpaulo { LLDP_8021_PORT_PROTOCOL_VLAN_SUPPORT, "supported"}, 160190203Srpaulo { LLDP_8021_PORT_PROTOCOL_VLAN_STATUS, "enabled"}, 161190203Srpaulo { 0, NULL} 162190203Srpaulo}; 163190203Srpaulo 164190203Srpaulo#define LLDP_PRIVATE_8023_SUBTYPE_MACPHY 1 165190203Srpaulo#define LLDP_PRIVATE_8023_SUBTYPE_MDIPOWER 2 166190203Srpaulo#define LLDP_PRIVATE_8023_SUBTYPE_LINKAGGR 3 167190203Srpaulo#define LLDP_PRIVATE_8023_SUBTYPE_MTU 4 168190203Srpaulo 169190203Srpaulostatic const struct tok lldp_8023_subtype_values[] = { 170190203Srpaulo { LLDP_PRIVATE_8023_SUBTYPE_MACPHY, "MAC/PHY configuration/status"}, 171190203Srpaulo { LLDP_PRIVATE_8023_SUBTYPE_MDIPOWER, "Power via MDI"}, 172190203Srpaulo { LLDP_PRIVATE_8023_SUBTYPE_LINKAGGR, "Link aggregation"}, 173190203Srpaulo { LLDP_PRIVATE_8023_SUBTYPE_MTU, "Max frame size"}, 174190203Srpaulo { 0, NULL} 175190203Srpaulo}; 176190203Srpaulo 177190203Srpaulo#define LLDP_PRIVATE_TIA_SUBTYPE_CAPABILITIES 1 178190203Srpaulo#define LLDP_PRIVATE_TIA_SUBTYPE_NETWORK_POLICY 2 179190203Srpaulo#define LLDP_PRIVATE_TIA_SUBTYPE_LOCAL_ID 3 180190203Srpaulo#define LLDP_PRIVATE_TIA_SUBTYPE_EXTENDED_POWER_MDI 4 181190203Srpaulo#define LLDP_PRIVATE_TIA_SUBTYPE_INVENTORY_HARDWARE_REV 5 182190203Srpaulo#define LLDP_PRIVATE_TIA_SUBTYPE_INVENTORY_FIRMWARE_REV 6 183190203Srpaulo#define LLDP_PRIVATE_TIA_SUBTYPE_INVENTORY_SOFTWARE_REV 7 184190203Srpaulo#define LLDP_PRIVATE_TIA_SUBTYPE_INVENTORY_SERIAL_NUMBER 8 185190203Srpaulo#define LLDP_PRIVATE_TIA_SUBTYPE_INVENTORY_MANUFACTURER_NAME 9 186190203Srpaulo#define LLDP_PRIVATE_TIA_SUBTYPE_INVENTORY_MODEL_NAME 10 187190203Srpaulo#define LLDP_PRIVATE_TIA_SUBTYPE_INVENTORY_ASSET_ID 11 188190203Srpaulo 189190203Srpaulostatic const struct tok lldp_tia_subtype_values[] = { 190190203Srpaulo { LLDP_PRIVATE_TIA_SUBTYPE_CAPABILITIES, "LLDP-MED Capabilities" }, 191190203Srpaulo { LLDP_PRIVATE_TIA_SUBTYPE_NETWORK_POLICY, "Network policy" }, 192190203Srpaulo { LLDP_PRIVATE_TIA_SUBTYPE_LOCAL_ID, "Location identification" }, 193190203Srpaulo { LLDP_PRIVATE_TIA_SUBTYPE_EXTENDED_POWER_MDI, "Extended power-via-MDI" }, 194190203Srpaulo { LLDP_PRIVATE_TIA_SUBTYPE_INVENTORY_HARDWARE_REV, "Inventory - hardware revision" }, 195190203Srpaulo { LLDP_PRIVATE_TIA_SUBTYPE_INVENTORY_FIRMWARE_REV, "Inventory - firmware revision" }, 196190203Srpaulo { LLDP_PRIVATE_TIA_SUBTYPE_INVENTORY_SOFTWARE_REV, "Inventory - software revision" }, 197190203Srpaulo { LLDP_PRIVATE_TIA_SUBTYPE_INVENTORY_SERIAL_NUMBER, "Inventory - serial number" }, 198190203Srpaulo { LLDP_PRIVATE_TIA_SUBTYPE_INVENTORY_MANUFACTURER_NAME, "Inventory - manufacturer name" }, 199190203Srpaulo { LLDP_PRIVATE_TIA_SUBTYPE_INVENTORY_MODEL_NAME, "Inventory - model name" }, 200190203Srpaulo { LLDP_PRIVATE_TIA_SUBTYPE_INVENTORY_ASSET_ID, "Inventory - asset ID" }, 201190203Srpaulo { 0, NULL} 202190203Srpaulo}; 203190203Srpaulo 204190203Srpaulo#define LLDP_PRIVATE_TIA_LOCATION_ALTITUDE_METERS 1 205190203Srpaulo#define LLDP_PRIVATE_TIA_LOCATION_ALTITUDE_FLOORS 2 206190203Srpaulo 207190203Srpaulostatic const struct tok lldp_tia_location_altitude_type_values[] = { 208190203Srpaulo { LLDP_PRIVATE_TIA_LOCATION_ALTITUDE_METERS, "meters"}, 209190203Srpaulo { LLDP_PRIVATE_TIA_LOCATION_ALTITUDE_FLOORS, "floors"}, 210190203Srpaulo { 0, NULL} 211190203Srpaulo}; 212190203Srpaulo 213190203Srpaulo/* ANSI/TIA-1057 - Annex B */ 214190203Srpaulo#define LLDP_PRIVATE_TIA_LOCATION_LCI_CATYPE_A1 1 215190203Srpaulo#define LLDP_PRIVATE_TIA_LOCATION_LCI_CATYPE_A2 2 216190203Srpaulo#define LLDP_PRIVATE_TIA_LOCATION_LCI_CATYPE_A3 3 217190203Srpaulo#define LLDP_PRIVATE_TIA_LOCATION_LCI_CATYPE_A4 4 218190203Srpaulo#define LLDP_PRIVATE_TIA_LOCATION_LCI_CATYPE_A5 5 219190203Srpaulo#define LLDP_PRIVATE_TIA_LOCATION_LCI_CATYPE_A6 6 220190203Srpaulo 221190203Srpaulostatic const struct tok lldp_tia_location_lci_catype_values[] = { 222190203Srpaulo { LLDP_PRIVATE_TIA_LOCATION_LCI_CATYPE_A1, "national subdivisions (state,canton,region,province,prefecture)"}, 223190203Srpaulo { LLDP_PRIVATE_TIA_LOCATION_LCI_CATYPE_A2, "county, parish, gun, district"}, 224190203Srpaulo { LLDP_PRIVATE_TIA_LOCATION_LCI_CATYPE_A3, "city, township, shi"}, 225190203Srpaulo { LLDP_PRIVATE_TIA_LOCATION_LCI_CATYPE_A4, "city division, borough, city district, ward chou"}, 226190203Srpaulo { LLDP_PRIVATE_TIA_LOCATION_LCI_CATYPE_A5, "neighborhood, block"}, 227190203Srpaulo { LLDP_PRIVATE_TIA_LOCATION_LCI_CATYPE_A6, "street"}, 228190203Srpaulo { 0, NULL} 229190203Srpaulo}; 230190203Srpaulo 231190203Srpaulostatic const struct tok lldp_tia_location_lci_what_values[] = { 232190203Srpaulo { 0, "location of DHCP server"}, 233190203Srpaulo { 1, "location of the network element believed to be closest to the client"}, 234190203Srpaulo { 2, "location of the client"}, 235190203Srpaulo { 0, NULL} 236190203Srpaulo}; 237190203Srpaulo 238190203Srpaulo/* 239190203Srpaulo * From RFC 3636 - dot3MauType 240190203Srpaulo */ 241190203Srpaulo#define LLDP_MAU_TYPE_UNKNOWN 0 242190203Srpaulo#define LLDP_MAU_TYPE_AUI 1 243190203Srpaulo#define LLDP_MAU_TYPE_10BASE_5 2 244190203Srpaulo#define LLDP_MAU_TYPE_FOIRL 3 245190203Srpaulo#define LLDP_MAU_TYPE_10BASE_2 4 246190203Srpaulo#define LLDP_MAU_TYPE_10BASE_T 5 247190203Srpaulo#define LLDP_MAU_TYPE_10BASE_FP 6 248190203Srpaulo#define LLDP_MAU_TYPE_10BASE_FB 7 249190203Srpaulo#define LLDP_MAU_TYPE_10BASE_FL 8 250190203Srpaulo#define LLDP_MAU_TYPE_10BROAD36 9 251190203Srpaulo#define LLDP_MAU_TYPE_10BASE_T_HD 10 252190203Srpaulo#define LLDP_MAU_TYPE_10BASE_T_FD 11 253190203Srpaulo#define LLDP_MAU_TYPE_10BASE_FL_HD 12 254190203Srpaulo#define LLDP_MAU_TYPE_10BASE_FL_FD 13 255190203Srpaulo#define LLDP_MAU_TYPE_100BASE_T4 14 256190203Srpaulo#define LLDP_MAU_TYPE_100BASE_TX_HD 15 257190203Srpaulo#define LLDP_MAU_TYPE_100BASE_TX_FD 16 258190203Srpaulo#define LLDP_MAU_TYPE_100BASE_FX_HD 17 259190203Srpaulo#define LLDP_MAU_TYPE_100BASE_FX_FD 18 260190203Srpaulo#define LLDP_MAU_TYPE_100BASE_T2_HD 19 261190203Srpaulo#define LLDP_MAU_TYPE_100BASE_T2_FD 20 262190203Srpaulo#define LLDP_MAU_TYPE_1000BASE_X_HD 21 263190203Srpaulo#define LLDP_MAU_TYPE_1000BASE_X_FD 22 264190203Srpaulo#define LLDP_MAU_TYPE_1000BASE_LX_HD 23 265190203Srpaulo#define LLDP_MAU_TYPE_1000BASE_LX_FD 24 266190203Srpaulo#define LLDP_MAU_TYPE_1000BASE_SX_HD 25 267190203Srpaulo#define LLDP_MAU_TYPE_1000BASE_SX_FD 26 268190203Srpaulo#define LLDP_MAU_TYPE_1000BASE_CX_HD 27 269190203Srpaulo#define LLDP_MAU_TYPE_1000BASE_CX_FD 28 270190203Srpaulo#define LLDP_MAU_TYPE_1000BASE_T_HD 29 271190203Srpaulo#define LLDP_MAU_TYPE_1000BASE_T_FD 30 272190203Srpaulo#define LLDP_MAU_TYPE_10GBASE_X 31 273190203Srpaulo#define LLDP_MAU_TYPE_10GBASE_LX4 32 274190203Srpaulo#define LLDP_MAU_TYPE_10GBASE_R 33 275190203Srpaulo#define LLDP_MAU_TYPE_10GBASE_ER 34 276190203Srpaulo#define LLDP_MAU_TYPE_10GBASE_LR 35 277190203Srpaulo#define LLDP_MAU_TYPE_10GBASE_SR 36 278190203Srpaulo#define LLDP_MAU_TYPE_10GBASE_W 37 279190203Srpaulo#define LLDP_MAU_TYPE_10GBASE_EW 38 280190203Srpaulo#define LLDP_MAU_TYPE_10GBASE_LW 39 281190203Srpaulo#define LLDP_MAU_TYPE_10GBASE_SW 40 282190203Srpaulo 283190203Srpaulostatic const struct tok lldp_mau_types_values[] = { 284190203Srpaulo { LLDP_MAU_TYPE_UNKNOWN, "Unknown"}, 285190203Srpaulo { LLDP_MAU_TYPE_AUI, "AUI"}, 286190203Srpaulo { LLDP_MAU_TYPE_10BASE_5, "10BASE_5"}, 287190203Srpaulo { LLDP_MAU_TYPE_FOIRL, "FOIRL"}, 288190203Srpaulo { LLDP_MAU_TYPE_10BASE_2, "10BASE2"}, 289190203Srpaulo { LLDP_MAU_TYPE_10BASE_T, "10BASET duplex mode unknown"}, 290190203Srpaulo { LLDP_MAU_TYPE_10BASE_FP, "10BASEFP"}, 291190203Srpaulo { LLDP_MAU_TYPE_10BASE_FB, "10BASEFB"}, 292190203Srpaulo { LLDP_MAU_TYPE_10BASE_FL, "10BASEFL duplex mode unknown"}, 293190203Srpaulo { LLDP_MAU_TYPE_10BROAD36, "10BROAD36"}, 294190203Srpaulo { LLDP_MAU_TYPE_10BASE_T_HD, "10BASET hdx"}, 295190203Srpaulo { LLDP_MAU_TYPE_10BASE_T_FD, "10BASET fdx"}, 296190203Srpaulo { LLDP_MAU_TYPE_10BASE_FL_HD, "10BASEFL hdx"}, 297190203Srpaulo { LLDP_MAU_TYPE_10BASE_FL_FD, "10BASEFL fdx"}, 298190203Srpaulo { LLDP_MAU_TYPE_100BASE_T4, "100BASET4"}, 299190203Srpaulo { LLDP_MAU_TYPE_100BASE_TX_HD, "100BASETX hdx"}, 300190203Srpaulo { LLDP_MAU_TYPE_100BASE_TX_FD, "100BASETX fdx"}, 301190203Srpaulo { LLDP_MAU_TYPE_100BASE_FX_HD, "100BASEFX hdx"}, 302190203Srpaulo { LLDP_MAU_TYPE_100BASE_FX_FD, "100BASEFX fdx"}, 303190203Srpaulo { LLDP_MAU_TYPE_100BASE_T2_HD, "100BASET2 hdx"}, 304190203Srpaulo { LLDP_MAU_TYPE_100BASE_T2_FD, "100BASET2 fdx"}, 305190203Srpaulo { LLDP_MAU_TYPE_1000BASE_X_HD, "1000BASEX hdx"}, 306190203Srpaulo { LLDP_MAU_TYPE_1000BASE_X_FD, "1000BASEX fdx"}, 307190203Srpaulo { LLDP_MAU_TYPE_1000BASE_LX_HD, "1000BASELX hdx"}, 308190203Srpaulo { LLDP_MAU_TYPE_1000BASE_LX_FD, "1000BASELX fdx"}, 309190203Srpaulo { LLDP_MAU_TYPE_1000BASE_SX_HD, "1000BASESX hdx"}, 310190203Srpaulo { LLDP_MAU_TYPE_1000BASE_SX_FD, "1000BASESX fdx"}, 311190203Srpaulo { LLDP_MAU_TYPE_1000BASE_CX_HD, "1000BASECX hdx"}, 312190203Srpaulo { LLDP_MAU_TYPE_1000BASE_CX_FD, "1000BASECX fdx"}, 313190203Srpaulo { LLDP_MAU_TYPE_1000BASE_T_HD, "1000BASET hdx"}, 314190203Srpaulo { LLDP_MAU_TYPE_1000BASE_T_FD, "1000BASET fdx"}, 315190203Srpaulo { LLDP_MAU_TYPE_10GBASE_X, "10GBASEX"}, 316190203Srpaulo { LLDP_MAU_TYPE_10GBASE_LX4, "10GBASELX4"}, 317190203Srpaulo { LLDP_MAU_TYPE_10GBASE_R, "10GBASER"}, 318190203Srpaulo { LLDP_MAU_TYPE_10GBASE_ER, "10GBASEER"}, 319190203Srpaulo { LLDP_MAU_TYPE_10GBASE_LR, "10GBASELR"}, 320190203Srpaulo { LLDP_MAU_TYPE_10GBASE_SR, "10GBASESR"}, 321190203Srpaulo { LLDP_MAU_TYPE_10GBASE_W, "10GBASEW"}, 322190203Srpaulo { LLDP_MAU_TYPE_10GBASE_EW, "10GBASEEW"}, 323190203Srpaulo { LLDP_MAU_TYPE_10GBASE_LW, "10GBASELW"}, 324190203Srpaulo { LLDP_MAU_TYPE_10GBASE_SW, "10GBASESW"}, 325190203Srpaulo { 0, NULL} 326190203Srpaulo}; 327190203Srpaulo 328190203Srpaulo#define LLDP_8023_AUTONEGOTIATION_SUPPORT (1 << 0) 329190203Srpaulo#define LLDP_8023_AUTONEGOTIATION_STATUS (1 << 1) 330190203Srpaulo 331190203Srpaulostatic const struct tok lldp_8023_autonegotiation_values[] = { 332190203Srpaulo { LLDP_8023_AUTONEGOTIATION_SUPPORT, "supported"}, 333190203Srpaulo { LLDP_8023_AUTONEGOTIATION_STATUS, "enabled"}, 334190203Srpaulo { 0, NULL} 335190203Srpaulo}; 336190203Srpaulo 337190203Srpaulo#define LLDP_TIA_CAPABILITY_MED (1 << 0) 338190203Srpaulo#define LLDP_TIA_CAPABILITY_NETWORK_POLICY (1 << 1) 339190203Srpaulo#define LLDP_TIA_CAPABILITY_LOCATION_IDENTIFICATION (1 << 2) 340190203Srpaulo#define LLDP_TIA_CAPABILITY_EXTENDED_POWER_MDI_PSE (1 << 3) 341190203Srpaulo#define LLDP_TIA_CAPABILITY_EXTENDED_POWER_MDI_PD (1 << 4) 342190203Srpaulo#define LLDP_TIA_CAPABILITY_INVENTORY (1 << 5) 343190203Srpaulo 344190203Srpaulostatic const struct tok lldp_tia_capabilities_values[] = { 345190203Srpaulo { LLDP_TIA_CAPABILITY_MED, "LLDP-MED capabilities"}, 346190203Srpaulo { LLDP_TIA_CAPABILITY_NETWORK_POLICY, "network policy"}, 347190203Srpaulo { LLDP_TIA_CAPABILITY_LOCATION_IDENTIFICATION, "location identification"}, 348190203Srpaulo { LLDP_TIA_CAPABILITY_EXTENDED_POWER_MDI_PSE, "extended power via MDI-PSE"}, 349190203Srpaulo { LLDP_TIA_CAPABILITY_EXTENDED_POWER_MDI_PD, "extended power via MDI-PD"}, 350190203Srpaulo { LLDP_TIA_CAPABILITY_INVENTORY, "Inventory"}, 351190203Srpaulo { 0, NULL} 352190203Srpaulo}; 353190203Srpaulo 354190203Srpaulo#define LLDP_TIA_DEVICE_TYPE_ENDPOINT_CLASS_1 1 355190203Srpaulo#define LLDP_TIA_DEVICE_TYPE_ENDPOINT_CLASS_2 2 356190203Srpaulo#define LLDP_TIA_DEVICE_TYPE_ENDPOINT_CLASS_3 3 357190203Srpaulo#define LLDP_TIA_DEVICE_TYPE_NETWORK_CONNECTIVITY 4 358190203Srpaulo 359190203Srpaulostatic const struct tok lldp_tia_device_type_values[] = { 360190203Srpaulo { LLDP_TIA_DEVICE_TYPE_ENDPOINT_CLASS_1, "endpoint class 1"}, 361190203Srpaulo { LLDP_TIA_DEVICE_TYPE_ENDPOINT_CLASS_2, "endpoint class 2"}, 362190203Srpaulo { LLDP_TIA_DEVICE_TYPE_ENDPOINT_CLASS_3, "endpoint class 3"}, 363190203Srpaulo { LLDP_TIA_DEVICE_TYPE_NETWORK_CONNECTIVITY, "network connectivity"}, 364190203Srpaulo { 0, NULL} 365190203Srpaulo}; 366190203Srpaulo 367190203Srpaulo#define LLDP_TIA_APPLICATION_TYPE_VOICE 1 368190203Srpaulo#define LLDP_TIA_APPLICATION_TYPE_VOICE_SIGNALING 2 369190203Srpaulo#define LLDP_TIA_APPLICATION_TYPE_GUEST_VOICE 3 370190203Srpaulo#define LLDP_TIA_APPLICATION_TYPE_GUEST_VOICE_SIGNALING 4 371190203Srpaulo#define LLDP_TIA_APPLICATION_TYPE_SOFTPHONE_VOICE 5 372190203Srpaulo#define LLDP_TIA_APPLICATION_TYPE_VIDEO_CONFERENCING 6 373190203Srpaulo#define LLDP_TIA_APPLICATION_TYPE_STREAMING_VIDEO 7 374190203Srpaulo#define LLDP_TIA_APPLICATION_TYPE_VIDEO_SIGNALING 8 375190203Srpaulo 376190203Srpaulostatic const struct tok lldp_tia_application_type_values[] = { 377190203Srpaulo { LLDP_TIA_APPLICATION_TYPE_VOICE, "voice"}, 378190203Srpaulo { LLDP_TIA_APPLICATION_TYPE_VOICE_SIGNALING, "voice signaling"}, 379190203Srpaulo { LLDP_TIA_APPLICATION_TYPE_GUEST_VOICE, "guest voice"}, 380190203Srpaulo { LLDP_TIA_APPLICATION_TYPE_GUEST_VOICE_SIGNALING, "guest voice signaling"}, 381190203Srpaulo { LLDP_TIA_APPLICATION_TYPE_SOFTPHONE_VOICE, "softphone voice"}, 382190203Srpaulo { LLDP_TIA_APPLICATION_TYPE_VIDEO_CONFERENCING, "video conferencing"}, 383190203Srpaulo { LLDP_TIA_APPLICATION_TYPE_STREAMING_VIDEO, "streaming video"}, 384190203Srpaulo { LLDP_TIA_APPLICATION_TYPE_VIDEO_SIGNALING, "video signaling"}, 385190203Srpaulo { 0, NULL} 386190203Srpaulo}; 387190203Srpaulo 388241235Sdelphij#define LLDP_TIA_NETWORK_POLICY_X_BIT (1 << 5) 389190203Srpaulo#define LLDP_TIA_NETWORK_POLICY_T_BIT (1 << 6) 390241235Sdelphij#define LLDP_TIA_NETWORK_POLICY_U_BIT (1 << 7) 391190203Srpaulo 392190203Srpaulostatic const struct tok lldp_tia_network_policy_bits_values[] = { 393190203Srpaulo { LLDP_TIA_NETWORK_POLICY_U_BIT, "Unknown"}, 394190203Srpaulo { LLDP_TIA_NETWORK_POLICY_T_BIT, "Tagged"}, 395190203Srpaulo { LLDP_TIA_NETWORK_POLICY_X_BIT, "reserved"}, 396190203Srpaulo { 0, NULL} 397190203Srpaulo}; 398190203Srpaulo 399190203Srpaulo#define LLDP_EXTRACT_NETWORK_POLICY_VLAN(x) (((x)&0x1ffe)>>1) 400190203Srpaulo#define LLDP_EXTRACT_NETWORK_POLICY_L2_PRIORITY(x) (((x)&0x01ff)>>6) 401190203Srpaulo#define LLDP_EXTRACT_NETWORK_POLICY_DSCP(x) ((x)&0x003f) 402190203Srpaulo 403190203Srpaulo#define LLDP_TIA_LOCATION_DATA_FORMAT_COORDINATE_BASED 1 404190203Srpaulo#define LLDP_TIA_LOCATION_DATA_FORMAT_CIVIC_ADDRESS 2 405190203Srpaulo#define LLDP_TIA_LOCATION_DATA_FORMAT_ECS_ELIN 3 406190203Srpaulo 407190203Srpaulostatic const struct tok lldp_tia_location_data_format_values[] = { 408190203Srpaulo { LLDP_TIA_LOCATION_DATA_FORMAT_COORDINATE_BASED, "coordinate-based LCI"}, 409190203Srpaulo { LLDP_TIA_LOCATION_DATA_FORMAT_CIVIC_ADDRESS, "civic address LCI"}, 410190203Srpaulo { LLDP_TIA_LOCATION_DATA_FORMAT_ECS_ELIN, "ECS ELIN"}, 411190203Srpaulo { 0, NULL} 412190203Srpaulo}; 413190203Srpaulo 414190203Srpaulo#define LLDP_TIA_LOCATION_DATUM_WGS_84 1 415190203Srpaulo#define LLDP_TIA_LOCATION_DATUM_NAD_83_NAVD_88 2 416190203Srpaulo#define LLDP_TIA_LOCATION_DATUM_NAD_83_MLLW 3 417190203Srpaulo 418190203Srpaulostatic const struct tok lldp_tia_location_datum_type_values[] = { 419190203Srpaulo { LLDP_TIA_LOCATION_DATUM_WGS_84, "World Geodesic System 1984"}, 420190203Srpaulo { LLDP_TIA_LOCATION_DATUM_NAD_83_NAVD_88, "North American Datum 1983 (NAVD88)"}, 421190203Srpaulo { LLDP_TIA_LOCATION_DATUM_NAD_83_MLLW, "North American Datum 1983 (MLLW)"}, 422190203Srpaulo { 0, NULL} 423190203Srpaulo}; 424190203Srpaulo 425190203Srpaulo#define LLDP_TIA_POWER_SOURCE_PSE 1 426190203Srpaulo#define LLDP_TIA_POWER_SOURCE_LOCAL 2 427190203Srpaulo#define LLDP_TIA_POWER_SOURCE_PSE_AND_LOCAL 3 428190203Srpaulo 429190203Srpaulostatic const struct tok lldp_tia_power_source_values[] = { 430190203Srpaulo { LLDP_TIA_POWER_SOURCE_PSE, "PSE - primary power source"}, 431190203Srpaulo { LLDP_TIA_POWER_SOURCE_LOCAL, "local - backup power source"}, 432190203Srpaulo { LLDP_TIA_POWER_SOURCE_PSE_AND_LOCAL, "PSE+local - reserved"}, 433190203Srpaulo { 0, NULL} 434190203Srpaulo}; 435190203Srpaulo 436190203Srpaulo#define LLDP_TIA_POWER_PRIORITY_CRITICAL 1 437190203Srpaulo#define LLDP_TIA_POWER_PRIORITY_HIGH 2 438190203Srpaulo#define LLDP_TIA_POWER_PRIORITY_LOW 3 439190203Srpaulo 440190203Srpaulostatic const struct tok lldp_tia_power_priority_values[] = { 441190203Srpaulo { LLDP_TIA_POWER_PRIORITY_CRITICAL, "critical"}, 442190203Srpaulo { LLDP_TIA_POWER_PRIORITY_HIGH, "high"}, 443190203Srpaulo { LLDP_TIA_POWER_PRIORITY_LOW, "low"}, 444190203Srpaulo { 0, NULL} 445190203Srpaulo}; 446190203Srpaulo 447190203Srpaulo#define LLDP_TIA_POWER_VAL_MAX 1024 448190203Srpaulo 449190203Srpaulostatic const struct tok lldp_tia_inventory_values[] = { 450190203Srpaulo { LLDP_PRIVATE_TIA_SUBTYPE_INVENTORY_HARDWARE_REV, "Hardware revision" }, 451190203Srpaulo { LLDP_PRIVATE_TIA_SUBTYPE_INVENTORY_FIRMWARE_REV, "Firmware revision" }, 452190203Srpaulo { LLDP_PRIVATE_TIA_SUBTYPE_INVENTORY_SOFTWARE_REV, "Software revision" }, 453190203Srpaulo { LLDP_PRIVATE_TIA_SUBTYPE_INVENTORY_SERIAL_NUMBER, "Serial number" }, 454190203Srpaulo { LLDP_PRIVATE_TIA_SUBTYPE_INVENTORY_MANUFACTURER_NAME, "Manufacturer name" }, 455190203Srpaulo { LLDP_PRIVATE_TIA_SUBTYPE_INVENTORY_MODEL_NAME, "Model name" }, 456190203Srpaulo { LLDP_PRIVATE_TIA_SUBTYPE_INVENTORY_ASSET_ID, "Asset ID" }, 457190203Srpaulo { 0, NULL} 458190203Srpaulo}; 459190203Srpaulo 460190203Srpaulo/* 461190203Srpaulo * From RFC 3636 - ifMauAutoNegCapAdvertisedBits 462190203Srpaulo */ 463190203Srpaulo#define LLDP_MAU_PMD_OTHER (1 << 15) 464190203Srpaulo#define LLDP_MAU_PMD_10BASE_T (1 << 14) 465190203Srpaulo#define LLDP_MAU_PMD_10BASE_T_FD (1 << 13) 466190203Srpaulo#define LLDP_MAU_PMD_100BASE_T4 (1 << 12) 467190203Srpaulo#define LLDP_MAU_PMD_100BASE_TX (1 << 11) 468190203Srpaulo#define LLDP_MAU_PMD_100BASE_TX_FD (1 << 10) 469190203Srpaulo#define LLDP_MAU_PMD_100BASE_T2 (1 << 9) 470190203Srpaulo#define LLDP_MAU_PMD_100BASE_T2_FD (1 << 8) 471190203Srpaulo#define LLDP_MAU_PMD_FDXPAUSE (1 << 7) 472190203Srpaulo#define LLDP_MAU_PMD_FDXAPAUSE (1 << 6) 473190203Srpaulo#define LLDP_MAU_PMD_FDXSPAUSE (1 << 5) 474190203Srpaulo#define LLDP_MAU_PMD_FDXBPAUSE (1 << 4) 475190203Srpaulo#define LLDP_MAU_PMD_1000BASE_X (1 << 3) 476190203Srpaulo#define LLDP_MAU_PMD_1000BASE_X_FD (1 << 2) 477190203Srpaulo#define LLDP_MAU_PMD_1000BASE_T (1 << 1) 478190203Srpaulo#define LLDP_MAU_PMD_1000BASE_T_FD (1 << 0) 479190203Srpaulo 480190203Srpaulostatic const struct tok lldp_pmd_capability_values[] = { 481190203Srpaulo { LLDP_MAU_PMD_10BASE_T, "10BASE-T hdx"}, 482190203Srpaulo { LLDP_MAU_PMD_10BASE_T_FD, "10BASE-T fdx"}, 483190203Srpaulo { LLDP_MAU_PMD_100BASE_T4, "100BASE-T4"}, 484190203Srpaulo { LLDP_MAU_PMD_100BASE_TX, "100BASE-TX hdx"}, 485190203Srpaulo { LLDP_MAU_PMD_100BASE_TX_FD, "100BASE-TX fdx"}, 486190203Srpaulo { LLDP_MAU_PMD_100BASE_T2, "100BASE-T2 hdx"}, 487190203Srpaulo { LLDP_MAU_PMD_100BASE_T2_FD, "100BASE-T2 fdx"}, 488190203Srpaulo { LLDP_MAU_PMD_FDXPAUSE, "Pause for fdx links"}, 489190203Srpaulo { LLDP_MAU_PMD_FDXAPAUSE, "Asym PAUSE for fdx"}, 490190203Srpaulo { LLDP_MAU_PMD_FDXSPAUSE, "Sym PAUSE for fdx"}, 491190203Srpaulo { LLDP_MAU_PMD_FDXBPAUSE, "Asym and Sym PAUSE for fdx"}, 492190203Srpaulo { LLDP_MAU_PMD_1000BASE_X, "1000BASE-{X LX SX CX} hdx"}, 493190203Srpaulo { LLDP_MAU_PMD_1000BASE_X_FD, "1000BASE-{X LX SX CX} fdx"}, 494190203Srpaulo { LLDP_MAU_PMD_1000BASE_T, "1000BASE-T hdx"}, 495190203Srpaulo { LLDP_MAU_PMD_1000BASE_T_FD, "1000BASE-T fdx"}, 496190203Srpaulo { 0, NULL} 497190203Srpaulo}; 498190203Srpaulo 499190203Srpaulo#define LLDP_MDI_PORT_CLASS (1 << 0) 500190203Srpaulo#define LLDP_MDI_POWER_SUPPORT (1 << 1) 501190203Srpaulo#define LLDP_MDI_POWER_STATE (1 << 2) 502190203Srpaulo#define LLDP_MDI_PAIR_CONTROL_ABILITY (1 << 3) 503190203Srpaulo 504190203Srpaulostatic const struct tok lldp_mdi_values[] = { 505190203Srpaulo { LLDP_MDI_PORT_CLASS, "PSE"}, 506190203Srpaulo { LLDP_MDI_POWER_SUPPORT, "supported"}, 507190203Srpaulo { LLDP_MDI_POWER_STATE, "enabled"}, 508190203Srpaulo { LLDP_MDI_PAIR_CONTROL_ABILITY, "can be controlled"}, 509190203Srpaulo { 0, NULL} 510190203Srpaulo}; 511190203Srpaulo 512190203Srpaulo#define LLDP_MDI_PSE_PORT_POWER_PAIRS_SIGNAL 1 513190203Srpaulo#define LLDP_MDI_PSE_PORT_POWER_PAIRS_SPARE 2 514190203Srpaulo 515190203Srpaulostatic const struct tok lldp_mdi_power_pairs_values[] = { 516190203Srpaulo { LLDP_MDI_PSE_PORT_POWER_PAIRS_SIGNAL, "signal"}, 517190203Srpaulo { LLDP_MDI_PSE_PORT_POWER_PAIRS_SPARE, "spare"}, 518190203Srpaulo { 0, NULL} 519190203Srpaulo}; 520190203Srpaulo 521190203Srpaulo#define LLDP_MDI_POWER_CLASS0 1 522190203Srpaulo#define LLDP_MDI_POWER_CLASS1 2 523190203Srpaulo#define LLDP_MDI_POWER_CLASS2 3 524190203Srpaulo#define LLDP_MDI_POWER_CLASS3 4 525190203Srpaulo#define LLDP_MDI_POWER_CLASS4 5 526190203Srpaulo 527190203Srpaulostatic const struct tok lldp_mdi_power_class_values[] = { 528190203Srpaulo { LLDP_MDI_POWER_CLASS0, "class0"}, 529190203Srpaulo { LLDP_MDI_POWER_CLASS1, "class1"}, 530190203Srpaulo { LLDP_MDI_POWER_CLASS2, "class2"}, 531190203Srpaulo { LLDP_MDI_POWER_CLASS3, "class3"}, 532190203Srpaulo { LLDP_MDI_POWER_CLASS4, "class4"}, 533190203Srpaulo { 0, NULL} 534190203Srpaulo}; 535190203Srpaulo 536190203Srpaulo#define LLDP_AGGREGATION_CAPABILTIY (1 << 0) 537190203Srpaulo#define LLDP_AGGREGATION_STATUS (1 << 1) 538190203Srpaulo 539190203Srpaulostatic const struct tok lldp_aggregation_values[] = { 540190203Srpaulo { LLDP_AGGREGATION_CAPABILTIY, "supported"}, 541190203Srpaulo { LLDP_AGGREGATION_STATUS, "enabled"}, 542190203Srpaulo { 0, NULL} 543190203Srpaulo}; 544190203Srpaulo 545190203Srpaulo/* 546235530Sdelphij * DCBX protocol subtypes. 547235530Sdelphij */ 548235530Sdelphij#define LLDP_DCBX_SUBTYPE_1 1 549235530Sdelphij#define LLDP_DCBX_SUBTYPE_2 2 550235530Sdelphij 551235530Sdelphijstatic const struct tok lldp_dcbx_subtype_values[] = { 552235530Sdelphij { LLDP_DCBX_SUBTYPE_1, "DCB Capability Exchange Protocol Rev 1" }, 553235530Sdelphij { LLDP_DCBX_SUBTYPE_2, "DCB Capability Exchange Protocol Rev 1.01" }, 554235530Sdelphij { 0, NULL} 555235530Sdelphij}; 556235530Sdelphij 557235530Sdelphij#define LLDP_DCBX_CONTROL_TLV 1 558235530Sdelphij#define LLDP_DCBX_PRIORITY_GROUPS_TLV 2 559235530Sdelphij#define LLDP_DCBX_PRIORITY_FLOW_CONTROL_TLV 3 560235530Sdelphij#define LLDP_DCBX_APPLICATION_TLV 4 561235530Sdelphij 562235530Sdelphij/* 563190203Srpaulo * Interface numbering subtypes. 564190203Srpaulo */ 565190203Srpaulo#define LLDP_INTF_NUMB_IFX_SUBTYPE 2 566190203Srpaulo#define LLDP_INTF_NUMB_SYSPORT_SUBTYPE 3 567190203Srpaulo 568190203Srpaulostatic const struct tok lldp_intf_numb_subtype_values[] = { 569190203Srpaulo { LLDP_INTF_NUMB_IFX_SUBTYPE, "Interface Index" }, 570190203Srpaulo { LLDP_INTF_NUMB_SYSPORT_SUBTYPE, "System Port Number" }, 571190203Srpaulo { 0, NULL} 572190203Srpaulo}; 573190203Srpaulo 574190203Srpaulo#define LLDP_INTF_NUM_LEN 5 575190203Srpaulo 576190203Srpaulo/* 577235530Sdelphij * Print IEEE 802.1 private extensions. (802.1AB annex E) 578190203Srpaulo */ 579190203Srpaulostatic int 580235530Sdelphijlldp_private_8021_print(const u_char *tptr, u_int tlv_len) 581190203Srpaulo{ 582190203Srpaulo int subtype, hexdump = FALSE; 583235530Sdelphij u_int sublen; 584190203Srpaulo 585235530Sdelphij if (tlv_len < 4) { 586235530Sdelphij return hexdump; 587235530Sdelphij } 588190203Srpaulo subtype = *(tptr+3); 589190203Srpaulo 590190203Srpaulo printf("\n\t %s Subtype (%u)", 591190203Srpaulo tok2str(lldp_8021_subtype_values, "unknown", subtype), 592190203Srpaulo subtype); 593190203Srpaulo 594190203Srpaulo switch (subtype) { 595190203Srpaulo case LLDP_PRIVATE_8021_SUBTYPE_PORT_VLAN_ID: 596235530Sdelphij if (tlv_len < 6) { 597235530Sdelphij return hexdump; 598235530Sdelphij } 599190203Srpaulo printf("\n\t port vlan id (PVID): %u", 600190203Srpaulo EXTRACT_16BITS(tptr+4)); 601190203Srpaulo break; 602190203Srpaulo case LLDP_PRIVATE_8021_SUBTYPE_PROTOCOL_VLAN_ID: 603235530Sdelphij if (tlv_len < 7) { 604235530Sdelphij return hexdump; 605235530Sdelphij } 606190203Srpaulo printf("\n\t port and protocol vlan id (PPVID): %u, flags [%s] (0x%02x)", 607190203Srpaulo EXTRACT_16BITS(tptr+5), 608190203Srpaulo bittok2str(lldp_8021_port_protocol_id_values, "none", *(tptr+4)), 609190203Srpaulo *(tptr+4)); 610190203Srpaulo break; 611190203Srpaulo case LLDP_PRIVATE_8021_SUBTYPE_VLAN_NAME: 612235530Sdelphij if (tlv_len < 6) { 613235530Sdelphij return hexdump; 614235530Sdelphij } 615190203Srpaulo printf("\n\t vlan id (VID): %u", 616190203Srpaulo EXTRACT_16BITS(tptr+4)); 617235530Sdelphij if (tlv_len < 7) { 618235530Sdelphij return hexdump; 619235530Sdelphij } 620235530Sdelphij sublen = *(tptr+6); 621235530Sdelphij if (tlv_len < 7+sublen) { 622235530Sdelphij return hexdump; 623235530Sdelphij } 624190203Srpaulo printf("\n\t vlan name: "); 625235530Sdelphij safeputs((const char *)tptr+7, sublen); 626190203Srpaulo break; 627190203Srpaulo case LLDP_PRIVATE_8021_SUBTYPE_PROTOCOL_IDENTITY: 628235530Sdelphij if (tlv_len < 5) { 629235530Sdelphij return hexdump; 630235530Sdelphij } 631235530Sdelphij sublen = *(tptr+4); 632235530Sdelphij if (tlv_len < 5+sublen) { 633235530Sdelphij return hexdump; 634235530Sdelphij } 635190203Srpaulo printf("\n\t protocol identity: "); 636235530Sdelphij safeputs((const char *)tptr+5, sublen); 637190203Srpaulo break; 638190203Srpaulo 639190203Srpaulo default: 640190203Srpaulo hexdump = TRUE; 641190203Srpaulo break; 642190203Srpaulo } 643190203Srpaulo 644190203Srpaulo return hexdump; 645190203Srpaulo} 646190203Srpaulo 647190203Srpaulo/* 648235530Sdelphij * Print IEEE 802.3 private extensions. (802.3bc) 649190203Srpaulo */ 650190203Srpaulostatic int 651235530Sdelphijlldp_private_8023_print(const u_char *tptr, u_int tlv_len) 652190203Srpaulo{ 653190203Srpaulo int subtype, hexdump = FALSE; 654190203Srpaulo 655235530Sdelphij if (tlv_len < 4) { 656235530Sdelphij return hexdump; 657235530Sdelphij } 658190203Srpaulo subtype = *(tptr+3); 659190203Srpaulo 660190203Srpaulo printf("\n\t %s Subtype (%u)", 661190203Srpaulo tok2str(lldp_8023_subtype_values, "unknown", subtype), 662190203Srpaulo subtype); 663190203Srpaulo 664190203Srpaulo switch (subtype) { 665190203Srpaulo case LLDP_PRIVATE_8023_SUBTYPE_MACPHY: 666235530Sdelphij if (tlv_len < 9) { 667235530Sdelphij return hexdump; 668235530Sdelphij } 669190203Srpaulo printf("\n\t autonegotiation [%s] (0x%02x)", 670190203Srpaulo bittok2str(lldp_8023_autonegotiation_values, "none", *(tptr+4)), 671190203Srpaulo *(tptr+4)); 672190203Srpaulo printf("\n\t PMD autoneg capability [%s] (0x%04x)", 673190203Srpaulo bittok2str(lldp_pmd_capability_values,"unknown", EXTRACT_16BITS(tptr+5)), 674190203Srpaulo EXTRACT_16BITS(tptr+5)); 675190203Srpaulo printf("\n\t MAU type %s (0x%04x)", 676190203Srpaulo tok2str(lldp_mau_types_values, "unknown", EXTRACT_16BITS(tptr+7)), 677190203Srpaulo EXTRACT_16BITS(tptr+7)); 678190203Srpaulo break; 679190203Srpaulo 680190203Srpaulo case LLDP_PRIVATE_8023_SUBTYPE_MDIPOWER: 681235530Sdelphij if (tlv_len < 7) { 682235530Sdelphij return hexdump; 683235530Sdelphij } 684190203Srpaulo printf("\n\t MDI power support [%s], power pair %s, power class %s", 685190203Srpaulo bittok2str(lldp_mdi_values, "none", *(tptr+4)), 686190203Srpaulo tok2str(lldp_mdi_power_pairs_values, "unknown", *(tptr+5)), 687190203Srpaulo tok2str(lldp_mdi_power_class_values, "unknown", *(tptr+6))); 688190203Srpaulo break; 689190203Srpaulo 690190203Srpaulo case LLDP_PRIVATE_8023_SUBTYPE_LINKAGGR: 691235530Sdelphij if (tlv_len < 9) { 692235530Sdelphij return hexdump; 693235530Sdelphij } 694190203Srpaulo printf("\n\t aggregation status [%s], aggregation port ID %u", 695190203Srpaulo bittok2str(lldp_aggregation_values, "none", *(tptr+4)), 696190203Srpaulo EXTRACT_32BITS(tptr+5)); 697190203Srpaulo break; 698190203Srpaulo 699190203Srpaulo case LLDP_PRIVATE_8023_SUBTYPE_MTU: 700190203Srpaulo printf("\n\t MTU size %u", EXTRACT_16BITS(tptr+4)); 701190203Srpaulo break; 702190203Srpaulo 703190203Srpaulo default: 704190203Srpaulo hexdump = TRUE; 705190203Srpaulo break; 706190203Srpaulo } 707190203Srpaulo 708190203Srpaulo return hexdump; 709190203Srpaulo} 710190203Srpaulo 711190203Srpaulo/* 712190203Srpaulo * Extract 34bits of latitude/longitude coordinates. 713190203Srpaulo */ 714190203Srpaulostatic u_int64_t 715190203Srpaulolldp_extract_latlon(const u_char *tptr) 716190203Srpaulo{ 717190203Srpaulo u_int64_t latlon; 718190203Srpaulo 719190203Srpaulo latlon = *tptr & 0x3; 720190203Srpaulo latlon = (latlon << 32) | EXTRACT_32BITS(tptr+1); 721190203Srpaulo 722190203Srpaulo return latlon; 723190203Srpaulo} 724190203Srpaulo 725190203Srpaulo/* 726190203Srpaulo * Print private TIA extensions. 727190203Srpaulo */ 728190203Srpaulostatic int 729190203Srpaulolldp_private_tia_print(const u_char *tptr, u_int tlv_len) 730190203Srpaulo{ 731190203Srpaulo int subtype, hexdump = FALSE; 732190203Srpaulo u_int8_t location_format; 733190203Srpaulo u_int16_t power_val; 734235530Sdelphij u_int lci_len; 735235530Sdelphij u_int8_t ca_type, ca_len; 736190203Srpaulo 737235530Sdelphij if (tlv_len < 4) { 738235530Sdelphij return hexdump; 739235530Sdelphij } 740190203Srpaulo subtype = *(tptr+3); 741190203Srpaulo 742190203Srpaulo printf("\n\t %s Subtype (%u)", 743190203Srpaulo tok2str(lldp_tia_subtype_values, "unknown", subtype), 744190203Srpaulo subtype); 745190203Srpaulo 746190203Srpaulo switch (subtype) { 747190203Srpaulo case LLDP_PRIVATE_TIA_SUBTYPE_CAPABILITIES: 748235530Sdelphij if (tlv_len < 7) { 749235530Sdelphij return hexdump; 750235530Sdelphij } 751190203Srpaulo printf("\n\t Media capabilities [%s] (0x%04x)", 752190203Srpaulo bittok2str(lldp_tia_capabilities_values, "none", 753190203Srpaulo EXTRACT_16BITS(tptr+4)), EXTRACT_16BITS(tptr+4)); 754190203Srpaulo printf("\n\t Device type [%s] (0x%02x)", 755190203Srpaulo tok2str(lldp_tia_device_type_values, "unknown", *(tptr+6)), 756190203Srpaulo *(tptr+6)); 757190203Srpaulo break; 758190203Srpaulo 759190203Srpaulo case LLDP_PRIVATE_TIA_SUBTYPE_NETWORK_POLICY: 760235530Sdelphij if (tlv_len < 8) { 761235530Sdelphij return hexdump; 762235530Sdelphij } 763190203Srpaulo printf("\n\t Application type [%s] (0x%02x)", 764190203Srpaulo tok2str(lldp_tia_application_type_values, "none", *(tptr+4)), 765190203Srpaulo *(tptr+4)); 766190203Srpaulo printf(", Flags [%s]", bittok2str( 767190203Srpaulo lldp_tia_network_policy_bits_values, "none", *(tptr+5))); 768190203Srpaulo printf("\n\t Vlan id %u", 769190203Srpaulo LLDP_EXTRACT_NETWORK_POLICY_VLAN(EXTRACT_16BITS(tptr+5))); 770190203Srpaulo printf(", L2 priority %u", 771190203Srpaulo LLDP_EXTRACT_NETWORK_POLICY_L2_PRIORITY(EXTRACT_16BITS(tptr+6))); 772190203Srpaulo printf(", DSCP value %u", 773190203Srpaulo LLDP_EXTRACT_NETWORK_POLICY_DSCP(EXTRACT_16BITS(tptr+6))); 774190203Srpaulo break; 775190203Srpaulo 776190203Srpaulo case LLDP_PRIVATE_TIA_SUBTYPE_LOCAL_ID: 777235530Sdelphij if (tlv_len < 5) { 778235530Sdelphij return hexdump; 779235530Sdelphij } 780190203Srpaulo location_format = *(tptr+4); 781190203Srpaulo printf("\n\t Location data format %s (0x%02x)", 782190203Srpaulo tok2str(lldp_tia_location_data_format_values, "unknown", location_format), 783190203Srpaulo location_format); 784190203Srpaulo 785190203Srpaulo switch (location_format) { 786190203Srpaulo case LLDP_TIA_LOCATION_DATA_FORMAT_COORDINATE_BASED: 787235530Sdelphij if (tlv_len < 21) { 788235530Sdelphij return hexdump; 789235530Sdelphij } 790190203Srpaulo printf("\n\t Latitude resolution %u, latitude value %" PRIu64, 791190203Srpaulo (*(tptr+5)>>2), lldp_extract_latlon(tptr+5)); 792190203Srpaulo printf("\n\t Longitude resolution %u, longitude value %" PRIu64, 793190203Srpaulo (*(tptr+10)>>2), lldp_extract_latlon(tptr+10)); 794190203Srpaulo printf("\n\t Altitude type %s (%u)", 795190203Srpaulo tok2str(lldp_tia_location_altitude_type_values, "unknown",(*(tptr+15)>>4)), 796190203Srpaulo (*(tptr+15)>>4)); 797190203Srpaulo printf("\n\t Altitude resolution %u, altitude value 0x%x", 798190203Srpaulo (EXTRACT_16BITS(tptr+15)>>6)&0x3f, 799190203Srpaulo ((EXTRACT_32BITS(tptr+16)&0x3fffffff))); 800190203Srpaulo printf("\n\t Datum %s (0x%02x)", 801190203Srpaulo tok2str(lldp_tia_location_datum_type_values, "unknown", *(tptr+20)), 802190203Srpaulo *(tptr+20)); 803190203Srpaulo break; 804190203Srpaulo 805190203Srpaulo case LLDP_TIA_LOCATION_DATA_FORMAT_CIVIC_ADDRESS: 806235530Sdelphij if (tlv_len < 6) { 807235530Sdelphij return hexdump; 808235530Sdelphij } 809190203Srpaulo lci_len = *(tptr+5); 810235530Sdelphij if (lci_len < 3) { 811235530Sdelphij return hexdump; 812235530Sdelphij } 813235530Sdelphij if (tlv_len < 7+lci_len) { 814235530Sdelphij return hexdump; 815235530Sdelphij } 816190203Srpaulo printf("\n\t LCI length %u, LCI what %s (0x%02x), Country-code ", 817190203Srpaulo lci_len, 818190203Srpaulo tok2str(lldp_tia_location_lci_what_values, "unknown", *(tptr+6)), 819190203Srpaulo *(tptr+6)); 820190203Srpaulo 821190203Srpaulo /* Country code */ 822190203Srpaulo safeputs((const char *)(tptr+7), 2); 823190203Srpaulo 824190203Srpaulo lci_len = lci_len-3; 825190203Srpaulo tptr = tptr + 9; 826190203Srpaulo 827190203Srpaulo /* Decode each civic address element */ 828190203Srpaulo while (lci_len > 0) { 829235530Sdelphij if (lci_len < 2) { 830235530Sdelphij return hexdump; 831235530Sdelphij } 832190203Srpaulo ca_type = *(tptr); 833190203Srpaulo ca_len = *(tptr+1); 834190203Srpaulo 835190203Srpaulo tptr += 2; 836190203Srpaulo lci_len -= 2; 837190203Srpaulo 838190203Srpaulo printf("\n\t CA type \'%s\' (%u), length %u: ", 839190203Srpaulo tok2str(lldp_tia_location_lci_catype_values, "unknown", ca_type), 840190203Srpaulo ca_type, ca_len); 841190203Srpaulo 842190203Srpaulo /* basic sanity check */ 843190203Srpaulo if ( ca_type == 0 || ca_len == 0) { 844190203Srpaulo return hexdump; 845190203Srpaulo } 846235530Sdelphij if (lci_len < ca_len) { 847235530Sdelphij return hexdump; 848235530Sdelphij } 849190203Srpaulo 850190203Srpaulo safeputs((const char *)tptr, ca_len); 851190203Srpaulo tptr += ca_len; 852190203Srpaulo lci_len -= ca_len; 853190203Srpaulo } 854190203Srpaulo break; 855190203Srpaulo 856190203Srpaulo case LLDP_TIA_LOCATION_DATA_FORMAT_ECS_ELIN: 857190203Srpaulo printf("\n\t ECS ELIN id "); 858190203Srpaulo safeputs((const char *)tptr+5, tlv_len-5); 859190203Srpaulo break; 860190203Srpaulo 861190203Srpaulo default: 862190203Srpaulo printf("\n\t Location ID "); 863190203Srpaulo print_unknown_data(tptr+5, "\n\t ", tlv_len-5); 864190203Srpaulo } 865190203Srpaulo break; 866190203Srpaulo 867190203Srpaulo case LLDP_PRIVATE_TIA_SUBTYPE_EXTENDED_POWER_MDI: 868235530Sdelphij if (tlv_len < 7) { 869235530Sdelphij return hexdump; 870235530Sdelphij } 871190203Srpaulo printf("\n\t Power type [%s]", 872190203Srpaulo (*(tptr+4)&0xC0>>6) ? "PD device" : "PSE device"); 873190203Srpaulo printf(", Power source [%s]", 874190203Srpaulo tok2str(lldp_tia_power_source_values, "none", (*(tptr+4)&0x30)>>4)); 875190203Srpaulo printf("\n\t Power priority [%s] (0x%02x)", 876190203Srpaulo tok2str(lldp_tia_power_priority_values, "none", *(tptr+4)&0x0f), 877190203Srpaulo *(tptr+4)&0x0f); 878190203Srpaulo power_val = EXTRACT_16BITS(tptr+5); 879190203Srpaulo if (power_val < LLDP_TIA_POWER_VAL_MAX) { 880190203Srpaulo printf(", Power %.1f Watts", ((float)power_val)/10); 881190203Srpaulo } else { 882190203Srpaulo printf(", Power %u (Reserved)", power_val); 883190203Srpaulo } 884190203Srpaulo break; 885190203Srpaulo 886190203Srpaulo case LLDP_PRIVATE_TIA_SUBTYPE_INVENTORY_HARDWARE_REV: 887190203Srpaulo case LLDP_PRIVATE_TIA_SUBTYPE_INVENTORY_FIRMWARE_REV: 888190203Srpaulo case LLDP_PRIVATE_TIA_SUBTYPE_INVENTORY_SOFTWARE_REV: 889190203Srpaulo case LLDP_PRIVATE_TIA_SUBTYPE_INVENTORY_SERIAL_NUMBER: 890190203Srpaulo case LLDP_PRIVATE_TIA_SUBTYPE_INVENTORY_MANUFACTURER_NAME: 891190203Srpaulo case LLDP_PRIVATE_TIA_SUBTYPE_INVENTORY_MODEL_NAME: 892190203Srpaulo case LLDP_PRIVATE_TIA_SUBTYPE_INVENTORY_ASSET_ID: 893190203Srpaulo printf("\n\t %s ", 894190203Srpaulo tok2str(lldp_tia_inventory_values, "unknown", subtype)); 895190203Srpaulo safeputs((const char *)tptr+4, tlv_len-4); 896190203Srpaulo break; 897190203Srpaulo 898190203Srpaulo default: 899190203Srpaulo hexdump = TRUE; 900190203Srpaulo break; 901190203Srpaulo } 902190203Srpaulo 903190203Srpaulo return hexdump; 904190203Srpaulo} 905190203Srpaulo 906235530Sdelphij/* 907235530Sdelphij * Print DCBX Protocol fields (V 1.01). 908235530Sdelphij */ 909235530Sdelphijstatic int 910235530Sdelphijlldp_private_dcbx_print(const u_char *pptr, u_int len) 911235530Sdelphij{ 912235530Sdelphij int subtype, hexdump = FALSE; 913235530Sdelphij u_int8_t tval; 914235530Sdelphij u_int16_t tlv; 915235530Sdelphij u_int32_t i, pgval, uval; 916235530Sdelphij u_int tlen, tlv_type, tlv_len; 917235530Sdelphij const u_char *tptr, *mptr; 918235530Sdelphij 919235530Sdelphij if (len < 4) { 920235530Sdelphij return hexdump; 921235530Sdelphij } 922235530Sdelphij subtype = *(pptr+3); 923235530Sdelphij 924235530Sdelphij printf("\n\t %s Subtype (%u)", 925235530Sdelphij tok2str(lldp_dcbx_subtype_values, "unknown", subtype), 926235530Sdelphij subtype); 927235530Sdelphij 928235530Sdelphij /* by passing old version */ 929235530Sdelphij if (subtype == LLDP_DCBX_SUBTYPE_1) 930235530Sdelphij return TRUE; 931235530Sdelphij 932235530Sdelphij tptr = pptr + 4; 933235530Sdelphij tlen = len - 4; 934235530Sdelphij 935235530Sdelphij while (tlen >= sizeof(tlv)) { 936235530Sdelphij 937235530Sdelphij TCHECK2(*tptr, sizeof(tlv)); 938235530Sdelphij 939235530Sdelphij tlv = EXTRACT_16BITS(tptr); 940235530Sdelphij 941235530Sdelphij tlv_type = LLDP_EXTRACT_TYPE(tlv); 942235530Sdelphij tlv_len = LLDP_EXTRACT_LEN(tlv); 943235530Sdelphij hexdump = FALSE; 944235530Sdelphij 945235530Sdelphij tlen -= sizeof(tlv); 946235530Sdelphij tptr += sizeof(tlv); 947235530Sdelphij 948235530Sdelphij /* loop check */ 949235530Sdelphij if (!tlv_type || !tlv_len) { 950235530Sdelphij break; 951235530Sdelphij } 952235530Sdelphij 953235530Sdelphij TCHECK2(*tptr, tlv_len); 954235530Sdelphij if (tlen < tlv_len) { 955235530Sdelphij goto trunc; 956235530Sdelphij } 957235530Sdelphij 958235530Sdelphij /* decode every tlv */ 959235530Sdelphij switch (tlv_type) { 960235530Sdelphij case LLDP_DCBX_CONTROL_TLV: 961235530Sdelphij if (tlv_len < 10) { 962235530Sdelphij goto trunc; 963235530Sdelphij } 964235530Sdelphij printf("\n\t Control - Protocol Control (type 0x%x, length %d)", 965235530Sdelphij LLDP_DCBX_CONTROL_TLV, tlv_len); 966235530Sdelphij printf("\n\t Oper_Version: %d", *tptr); 967235530Sdelphij printf("\n\t Max_Version: %d", *(tptr+1)); 968235530Sdelphij printf("\n\t Sequence Number: %d", EXTRACT_32BITS(tptr+2)); 969235530Sdelphij printf("\n\t Acknowledgement Number: %d", 970235530Sdelphij EXTRACT_32BITS(tptr+6)); 971235530Sdelphij break; 972235530Sdelphij case LLDP_DCBX_PRIORITY_GROUPS_TLV: 973235530Sdelphij if (tlv_len < 17) { 974235530Sdelphij goto trunc; 975235530Sdelphij } 976235530Sdelphij printf("\n\t Feature - Priority Group (type 0x%x, length %d)", 977235530Sdelphij LLDP_DCBX_PRIORITY_GROUPS_TLV, tlv_len); 978235530Sdelphij printf("\n\t Oper_Version: %d", *tptr); 979235530Sdelphij printf("\n\t Max_Version: %d", *(tptr+1)); 980235530Sdelphij printf("\n\t Info block(0x%02X): ", *(tptr+2)); 981235530Sdelphij tval = *(tptr+2); 982235530Sdelphij printf("Enable bit: %d, Willing bit: %d, Error Bit: %d", 983235530Sdelphij (tval & 0x80) ? 1 : 0, (tval & 0x40) ? 1 : 0, 984235530Sdelphij (tval & 0x20) ? 1 : 0); 985235530Sdelphij printf("\n\t SubType: %d", *(tptr+3)); 986235530Sdelphij printf("\n\t Priority Allocation"); 987235530Sdelphij 988235530Sdelphij pgval = EXTRACT_32BITS(tptr+4); 989235530Sdelphij for (i = 0; i <= 7; i++) { 990235530Sdelphij tval = *(tptr+4+(i/2)); 991235530Sdelphij printf("\n\t PgId_%d: %d", 992235530Sdelphij i, (pgval >> (28-4*i)) & 0xF); 993235530Sdelphij } 994235530Sdelphij printf("\n\t Priority Group Allocation"); 995235530Sdelphij for (i = 0; i <= 7; i++) 996235530Sdelphij printf("\n\t Pg percentage[%d]: %d", i, *(tptr+8+i)); 997235530Sdelphij printf("\n\t NumTCsSupported: %d", *(tptr+8+8)); 998235530Sdelphij break; 999235530Sdelphij case LLDP_DCBX_PRIORITY_FLOW_CONTROL_TLV: 1000235530Sdelphij if (tlv_len < 6) { 1001235530Sdelphij goto trunc; 1002235530Sdelphij } 1003235530Sdelphij printf("\n\t Feature - Priority Flow Control"); 1004235530Sdelphij printf(" (type 0x%x, length %d)", 1005235530Sdelphij LLDP_DCBX_PRIORITY_FLOW_CONTROL_TLV, tlv_len); 1006235530Sdelphij printf("\n\t Oper_Version: %d", *tptr); 1007235530Sdelphij printf("\n\t Max_Version: %d", *(tptr+1)); 1008235530Sdelphij printf("\n\t Info block(0x%02X): ", *(tptr+2)); 1009235530Sdelphij tval = *(tptr+2); 1010235530Sdelphij printf("Enable bit: %d, Willing bit: %d, Error Bit: %d", 1011235530Sdelphij (tval & 0x80) ? 1 : 0, (tval & 0x40) ? 1 : 0, 1012235530Sdelphij (tval & 0x20) ? 1 : 0); 1013235530Sdelphij printf("\n\t SubType: %d", *(tptr+3)); 1014235530Sdelphij tval = *(tptr+4); 1015235530Sdelphij printf("\n\t PFC Config (0x%02X)", *(tptr+4)); 1016235530Sdelphij for (i = 0; i <= 7; i++) 1017235530Sdelphij printf("\n\t Priority Bit %d: %s", 1018235530Sdelphij i, (tval & (1 << i)) ? "Enabled" : "Disabled"); 1019235530Sdelphij printf("\n\t NumTCPFCSupported: %d", *(tptr+5)); 1020235530Sdelphij break; 1021235530Sdelphij case LLDP_DCBX_APPLICATION_TLV: 1022235530Sdelphij if (tlv_len < 4) { 1023235530Sdelphij goto trunc; 1024235530Sdelphij } 1025235530Sdelphij printf("\n\t Feature - Application (type 0x%x, length %d)", 1026235530Sdelphij LLDP_DCBX_APPLICATION_TLV, tlv_len); 1027235530Sdelphij printf("\n\t Oper_Version: %d", *tptr); 1028235530Sdelphij printf("\n\t Max_Version: %d", *(tptr+1)); 1029235530Sdelphij printf("\n\t Info block(0x%02X): ", *(tptr+2)); 1030235530Sdelphij tval = *(tptr+2); 1031235530Sdelphij printf("Enable bit: %d, Willing bit: %d, Error Bit: %d", 1032235530Sdelphij (tval & 0x80) ? 1 : 0, (tval & 0x40) ? 1 : 0, 1033235530Sdelphij (tval & 0x20) ? 1 : 0); 1034235530Sdelphij printf("\n\t SubType: %d", *(tptr+3)); 1035235530Sdelphij tval = tlv_len - 4; 1036235530Sdelphij mptr = tptr + 4; 1037235530Sdelphij while (tval >= 6) { 1038235530Sdelphij printf("\n\t Application Value"); 1039235530Sdelphij printf("\n\t Application Protocol ID: 0x%04x", 1040235530Sdelphij EXTRACT_16BITS(mptr)); 1041235530Sdelphij uval = EXTRACT_24BITS(mptr+2); 1042235530Sdelphij printf("\n\t SF (0x%x) Application Protocol ID is %s", 1043235530Sdelphij (uval >> 22), 1044235530Sdelphij (uval >> 22) ? "Socket Number" : "L2 EtherType"); 1045235530Sdelphij printf("\n\t OUI: 0x%06x", uval & 0x3fffff); 1046235530Sdelphij printf("\n\t User Priority Map: 0x%02x", *(mptr+5)); 1047235530Sdelphij tval = tval - 6; 1048235530Sdelphij mptr = mptr + 6; 1049235530Sdelphij } 1050235530Sdelphij break; 1051235530Sdelphij default: 1052235530Sdelphij hexdump = TRUE; 1053235530Sdelphij break; 1054235530Sdelphij } 1055235530Sdelphij 1056235530Sdelphij /* do we also want to see a hex dump ? */ 1057235530Sdelphij if (vflag > 1 || (vflag && hexdump)) { 1058235530Sdelphij print_unknown_data(tptr,"\n\t ", tlv_len); 1059235530Sdelphij } 1060235530Sdelphij 1061235530Sdelphij tlen -= tlv_len; 1062235530Sdelphij tptr += tlv_len; 1063235530Sdelphij } 1064235530Sdelphij 1065235530Sdelphij trunc: 1066235530Sdelphij return hexdump; 1067235530Sdelphij} 1068235530Sdelphij 1069190203Srpaulostatic char * 1070235530Sdelphijlldp_network_addr_print(const u_char *tptr, u_int len) { 1071190203Srpaulo 1072190203Srpaulo u_int8_t af; 1073190203Srpaulo static char buf[BUFSIZE]; 1074190203Srpaulo const char * (*pfunc)(const u_char *); 1075190203Srpaulo 1076235530Sdelphij if (len < 1) 1077235530Sdelphij return NULL; 1078235530Sdelphij len--; 1079190203Srpaulo af = *tptr; 1080190203Srpaulo switch (af) { 1081190203Srpaulo case AFNUM_INET: 1082235530Sdelphij if (len < 4) 1083235530Sdelphij return NULL; 1084190203Srpaulo pfunc = getname; 1085190203Srpaulo break; 1086190203Srpaulo#ifdef INET6 1087190203Srpaulo case AFNUM_INET6: 1088235530Sdelphij if (len < 16) 1089235530Sdelphij return NULL; 1090190203Srpaulo pfunc = getname6; 1091190203Srpaulo break; 1092190203Srpaulo#endif 1093190203Srpaulo case AFNUM_802: 1094235530Sdelphij if (len < 6) 1095235530Sdelphij return NULL; 1096190203Srpaulo pfunc = etheraddr_string; 1097190203Srpaulo break; 1098190203Srpaulo default: 1099190203Srpaulo pfunc = NULL; 1100190203Srpaulo break; 1101190203Srpaulo } 1102190203Srpaulo 1103190203Srpaulo if (!pfunc) { 1104190203Srpaulo snprintf(buf, sizeof(buf), "AFI %s (%u), no AF printer !", 1105190203Srpaulo tok2str(af_values, "Unknown", af), af); 1106190203Srpaulo } else { 1107190203Srpaulo snprintf(buf, sizeof(buf), "AFI %s (%u): %s", 1108190203Srpaulo tok2str(af_values, "Unknown", af), af, (*pfunc)(tptr+1)); 1109190203Srpaulo } 1110190203Srpaulo 1111190203Srpaulo return buf; 1112190203Srpaulo} 1113190203Srpaulo 1114190203Srpaulostatic int 1115190203Srpaulolldp_mgmt_addr_tlv_print(const u_char *pptr, u_int len) { 1116190203Srpaulo 1117190203Srpaulo u_int8_t mgmt_addr_len, intf_num_subtype, oid_len; 1118190203Srpaulo const u_char *tptr; 1119190203Srpaulo u_int tlen; 1120235530Sdelphij char *mgmt_addr; 1121190203Srpaulo 1122190203Srpaulo tlen = len; 1123190203Srpaulo tptr = pptr; 1124190203Srpaulo 1125235530Sdelphij if (tlen < 1) { 1126235530Sdelphij return 0; 1127235530Sdelphij } 1128190203Srpaulo mgmt_addr_len = *tptr++; 1129190203Srpaulo tlen--; 1130190203Srpaulo 1131190203Srpaulo if (tlen < mgmt_addr_len) { 1132190203Srpaulo return 0; 1133190203Srpaulo } 1134190203Srpaulo 1135235530Sdelphij mgmt_addr = lldp_network_addr_print(tptr, mgmt_addr_len); 1136235530Sdelphij if (mgmt_addr == NULL) { 1137235530Sdelphij return 0; 1138235530Sdelphij } 1139190203Srpaulo printf("\n\t Management Address length %u, %s", 1140235530Sdelphij mgmt_addr_len, mgmt_addr); 1141190203Srpaulo tptr += mgmt_addr_len; 1142190203Srpaulo tlen -= mgmt_addr_len; 1143190203Srpaulo 1144190203Srpaulo if (tlen < LLDP_INTF_NUM_LEN) { 1145190203Srpaulo return 0; 1146190203Srpaulo } 1147190203Srpaulo 1148190203Srpaulo intf_num_subtype = *tptr; 1149190203Srpaulo printf("\n\t %s Interface Numbering (%u): %u", 1150190203Srpaulo tok2str(lldp_intf_numb_subtype_values, "Unknown", intf_num_subtype), 1151190203Srpaulo intf_num_subtype, 1152190203Srpaulo EXTRACT_32BITS(tptr+1)); 1153190203Srpaulo 1154190203Srpaulo tptr += LLDP_INTF_NUM_LEN; 1155190203Srpaulo tlen -= LLDP_INTF_NUM_LEN; 1156190203Srpaulo 1157190203Srpaulo /* 1158190203Srpaulo * The OID is optional. 1159190203Srpaulo */ 1160190203Srpaulo if (tlen) { 1161190203Srpaulo oid_len = *tptr; 1162190203Srpaulo 1163235530Sdelphij if (tlen < oid_len) { 1164235530Sdelphij return 0; 1165235530Sdelphij } 1166190203Srpaulo if (oid_len) { 1167190203Srpaulo printf("\n\t OID length %u", oid_len); 1168190203Srpaulo safeputs((const char *)tptr+1, oid_len); 1169190203Srpaulo } 1170190203Srpaulo } 1171190203Srpaulo 1172190203Srpaulo return 1; 1173190203Srpaulo} 1174190203Srpaulo 1175190203Srpaulovoid 1176190203Srpaulolldp_print(register const u_char *pptr, register u_int len) { 1177190203Srpaulo 1178190203Srpaulo u_int8_t subtype; 1179190203Srpaulo u_int16_t tlv, cap, ena_cap; 1180190203Srpaulo u_int oui, tlen, hexdump, tlv_type, tlv_len; 1181190203Srpaulo const u_char *tptr; 1182235530Sdelphij char *network_addr; 1183190203Srpaulo 1184190203Srpaulo tptr = pptr; 1185190203Srpaulo tlen = len; 1186190203Srpaulo 1187251158Sdelphij printf("LLDP, length %u", len); 1188190203Srpaulo 1189190203Srpaulo while (tlen >= sizeof(tlv)) { 1190190203Srpaulo 1191190203Srpaulo TCHECK2(*tptr, sizeof(tlv)); 1192190203Srpaulo 1193190203Srpaulo tlv = EXTRACT_16BITS(tptr); 1194190203Srpaulo 1195190203Srpaulo tlv_type = LLDP_EXTRACT_TYPE(tlv); 1196190203Srpaulo tlv_len = LLDP_EXTRACT_LEN(tlv); 1197190203Srpaulo hexdump = FALSE; 1198190203Srpaulo 1199190203Srpaulo tlen -= sizeof(tlv); 1200190203Srpaulo tptr += sizeof(tlv); 1201190203Srpaulo 1202190203Srpaulo if (vflag) { 1203190203Srpaulo printf("\n\t%s TLV (%u), length %u", 1204190203Srpaulo tok2str(lldp_tlv_values, "Unknown", tlv_type), 1205190203Srpaulo tlv_type, tlv_len); 1206190203Srpaulo } 1207190203Srpaulo 1208190203Srpaulo /* infinite loop check */ 1209190203Srpaulo if (!tlv_type || !tlv_len) { 1210190203Srpaulo break; 1211190203Srpaulo } 1212190203Srpaulo 1213190203Srpaulo TCHECK2(*tptr, tlv_len); 1214235530Sdelphij if (tlen < tlv_len) { 1215235530Sdelphij goto trunc; 1216235530Sdelphij } 1217190203Srpaulo 1218190203Srpaulo switch (tlv_type) { 1219190203Srpaulo 1220190203Srpaulo case LLDP_CHASSIS_ID_TLV: 1221190203Srpaulo if (vflag) { 1222235530Sdelphij if (tlv_len < 2) { 1223235530Sdelphij goto trunc; 1224235530Sdelphij } 1225190203Srpaulo subtype = *tptr; 1226190203Srpaulo printf("\n\t Subtype %s (%u): ", 1227190203Srpaulo tok2str(lldp_chassis_subtype_values, "Unknown", subtype), 1228190203Srpaulo subtype); 1229190203Srpaulo 1230190203Srpaulo switch (subtype) { 1231190203Srpaulo case LLDP_CHASSIS_MAC_ADDR_SUBTYPE: 1232235530Sdelphij if (tlv_len < 1+6) { 1233235530Sdelphij goto trunc; 1234235530Sdelphij } 1235190203Srpaulo printf("%s", etheraddr_string(tptr+1)); 1236190203Srpaulo break; 1237190203Srpaulo 1238190203Srpaulo case LLDP_CHASSIS_INTF_NAME_SUBTYPE: /* fall through */ 1239190203Srpaulo case LLDP_CHASSIS_LOCAL_SUBTYPE: 1240190203Srpaulo case LLDP_CHASSIS_CHASSIS_COMP_SUBTYPE: 1241190203Srpaulo case LLDP_CHASSIS_INTF_ALIAS_SUBTYPE: 1242190203Srpaulo case LLDP_CHASSIS_PORT_COMP_SUBTYPE: 1243190203Srpaulo safeputs((const char *)tptr+1, tlv_len-1); 1244190203Srpaulo break; 1245190203Srpaulo 1246190203Srpaulo case LLDP_CHASSIS_NETWORK_ADDR_SUBTYPE: 1247235530Sdelphij network_addr = lldp_network_addr_print(tptr+1, tlv_len-1); 1248235530Sdelphij if (network_addr == NULL) { 1249235530Sdelphij goto trunc; 1250235530Sdelphij } 1251235530Sdelphij printf("%s", network_addr); 1252190203Srpaulo break; 1253190203Srpaulo 1254190203Srpaulo default: 1255190203Srpaulo hexdump = TRUE; 1256190203Srpaulo break; 1257190203Srpaulo } 1258190203Srpaulo } 1259190203Srpaulo break; 1260190203Srpaulo 1261190203Srpaulo case LLDP_PORT_ID_TLV: 1262190203Srpaulo if (vflag) { 1263235530Sdelphij if (tlv_len < 2) { 1264235530Sdelphij goto trunc; 1265235530Sdelphij } 1266190203Srpaulo subtype = *tptr; 1267190203Srpaulo printf("\n\t Subtype %s (%u): ", 1268190203Srpaulo tok2str(lldp_port_subtype_values, "Unknown", subtype), 1269190203Srpaulo subtype); 1270190203Srpaulo 1271190203Srpaulo switch (subtype) { 1272190203Srpaulo case LLDP_PORT_MAC_ADDR_SUBTYPE: 1273235530Sdelphij if (tlv_len < 1+6) { 1274235530Sdelphij goto trunc; 1275235530Sdelphij } 1276190203Srpaulo printf("%s", etheraddr_string(tptr+1)); 1277190203Srpaulo break; 1278190203Srpaulo 1279190203Srpaulo case LLDP_PORT_INTF_NAME_SUBTYPE: /* fall through */ 1280190203Srpaulo case LLDP_PORT_LOCAL_SUBTYPE: 1281190203Srpaulo case LLDP_PORT_AGENT_CIRC_ID_SUBTYPE: 1282190203Srpaulo case LLDP_PORT_INTF_ALIAS_SUBTYPE: 1283190203Srpaulo case LLDP_PORT_PORT_COMP_SUBTYPE: 1284190203Srpaulo safeputs((const char *)tptr+1, tlv_len-1); 1285190203Srpaulo break; 1286190203Srpaulo 1287190203Srpaulo case LLDP_PORT_NETWORK_ADDR_SUBTYPE: 1288235530Sdelphij network_addr = lldp_network_addr_print(tptr+1, tlv_len-1); 1289235530Sdelphij if (network_addr == NULL) { 1290235530Sdelphij goto trunc; 1291235530Sdelphij } 1292235530Sdelphij printf("%s", network_addr); 1293190203Srpaulo break; 1294190203Srpaulo 1295190203Srpaulo default: 1296190203Srpaulo hexdump = TRUE; 1297190203Srpaulo break; 1298190203Srpaulo } 1299190203Srpaulo } 1300190203Srpaulo break; 1301190203Srpaulo 1302235530Sdelphij case LLDP_TTL_TLV: 1303190203Srpaulo if (vflag) { 1304235530Sdelphij if (tlv_len < 2) { 1305235530Sdelphij goto trunc; 1306190203Srpaulo } 1307235530Sdelphij printf(": TTL %us", EXTRACT_16BITS(tptr)); 1308190203Srpaulo } 1309190203Srpaulo break; 1310190203Srpaulo 1311235530Sdelphij case LLDP_PORT_DESCR_TLV: 1312235530Sdelphij if (vflag) { 1313235530Sdelphij printf(": "); 1314235530Sdelphij safeputs((const char *)tptr, tlv_len); 1315235530Sdelphij } 1316235530Sdelphij break; 1317235530Sdelphij 1318235530Sdelphij case LLDP_SYSTEM_NAME_TLV: 1319235530Sdelphij /* 1320235530Sdelphij * The system name is also print in non-verbose mode 1321235530Sdelphij * similar to the CDP printer. 1322235530Sdelphij */ 1323251158Sdelphij printf(": "); 1324251158Sdelphij safeputs((const char *)tptr, tlv_len); 1325235530Sdelphij break; 1326235530Sdelphij 1327235530Sdelphij case LLDP_SYSTEM_DESCR_TLV: 1328235530Sdelphij if (vflag) { 1329235530Sdelphij printf("\n\t "); 1330235530Sdelphij safeputs((const char *)tptr, tlv_len); 1331235530Sdelphij } 1332235530Sdelphij break; 1333235530Sdelphij 1334190203Srpaulo case LLDP_SYSTEM_CAP_TLV: 1335190203Srpaulo if (vflag) { 1336235530Sdelphij /* 1337235530Sdelphij * XXX - IEEE Std 802.1AB-2009 says the first octet 1338235530Sdelphij * if a chassis ID subtype, with the system 1339235530Sdelphij * capabilities and enabled capabilities following 1340235530Sdelphij * it. 1341235530Sdelphij */ 1342235530Sdelphij if (tlv_len < 4) { 1343235530Sdelphij goto trunc; 1344235530Sdelphij } 1345190203Srpaulo cap = EXTRACT_16BITS(tptr); 1346190203Srpaulo ena_cap = EXTRACT_16BITS(tptr+2); 1347190203Srpaulo printf("\n\t System Capabilities [%s] (0x%04x)", 1348190203Srpaulo bittok2str(lldp_cap_values, "none", cap), cap); 1349190203Srpaulo printf("\n\t Enabled Capabilities [%s] (0x%04x)", 1350190203Srpaulo bittok2str(lldp_cap_values, "none", ena_cap), ena_cap); 1351190203Srpaulo } 1352190203Srpaulo break; 1353190203Srpaulo 1354190203Srpaulo case LLDP_MGMT_ADDR_TLV: 1355190203Srpaulo if (vflag) { 1356235530Sdelphij if (!lldp_mgmt_addr_tlv_print(tptr, tlv_len)) { 1357190203Srpaulo goto trunc; 1358190203Srpaulo } 1359190203Srpaulo } 1360190203Srpaulo break; 1361190203Srpaulo 1362235530Sdelphij case LLDP_PRIVATE_TLV: 1363235530Sdelphij if (vflag) { 1364235530Sdelphij if (tlv_len < 3) { 1365235530Sdelphij goto trunc; 1366235530Sdelphij } 1367235530Sdelphij oui = EXTRACT_24BITS(tptr); 1368235530Sdelphij printf(": OUI %s (0x%06x)", tok2str(oui_values, "Unknown", oui), oui); 1369235530Sdelphij 1370235530Sdelphij switch (oui) { 1371235530Sdelphij case OUI_IEEE_8021_PRIVATE: 1372235530Sdelphij hexdump = lldp_private_8021_print(tptr, tlv_len); 1373235530Sdelphij break; 1374235530Sdelphij case OUI_IEEE_8023_PRIVATE: 1375235530Sdelphij hexdump = lldp_private_8023_print(tptr, tlv_len); 1376235530Sdelphij break; 1377235530Sdelphij case OUI_TIA: 1378235530Sdelphij hexdump = lldp_private_tia_print(tptr, tlv_len); 1379235530Sdelphij break; 1380235530Sdelphij case OUI_DCBX: 1381235530Sdelphij hexdump = lldp_private_dcbx_print(tptr, tlv_len); 1382235530Sdelphij break; 1383235530Sdelphij default: 1384235530Sdelphij hexdump = TRUE; 1385235530Sdelphij break; 1386235530Sdelphij } 1387235530Sdelphij } 1388235530Sdelphij break; 1389235530Sdelphij 1390190203Srpaulo default: 1391190203Srpaulo hexdump = TRUE; 1392190203Srpaulo break; 1393190203Srpaulo } 1394190203Srpaulo 1395190203Srpaulo /* do we also want to see a hex dump ? */ 1396190203Srpaulo if (vflag > 1 || (vflag && hexdump)) { 1397190203Srpaulo print_unknown_data(tptr,"\n\t ", tlv_len); 1398190203Srpaulo } 1399190203Srpaulo 1400190203Srpaulo tlen -= tlv_len; 1401190203Srpaulo tptr += tlv_len; 1402190203Srpaulo } 1403190203Srpaulo return; 1404190203Srpaulo trunc: 1405190203Srpaulo printf("\n\t[|LLDP]"); 1406190203Srpaulo} 1407190203Srpaulo 1408190203Srpaulo/* 1409190203Srpaulo * Local Variables: 1410190203Srpaulo * c-style: whitesmith 1411190203Srpaulo * c-basic-offset: 4 1412190203Srpaulo * End: 1413190203Srpaulo */ 1414