Home | History | Annotate | Download | only in tcpdump
      1 /*
      2  * Copyright (c) 1998-2007 The TCPDUMP project
      3  *
      4  * Redistribution and use in source and binary forms, with or without
      5  * modification, are permitted provided that: (1) source code
      6  * distributions retain the above copyright notice and this paragraph
      7  * in its entirety, and (2) distributions including binary code include
      8  * the above copyright notice and this paragraph in its entirety in
      9  * the documentation or other materials provided with the distribution.
     10  * THIS SOFTWARE IS PROVIDED ``AS IS'' AND
     11  * WITHOUT ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, WITHOUT
     12  * LIMITATION, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
     13  * FOR A PARTICULAR PURPOSE.
     14  *
     15  * support for the IEEE Link Discovery Protocol as per 802.1AB
     16  *
     17  * Original code by Hannes Gredler (hannes (at) juniper.net)
     18  * IEEE and TIA extensions by Carles Kishimoto <carles.kishimoto (at) gmail.com>
     19  * DCBX extensions by Kaladhar Musunuru <kaladharm (at) sourceforge.net>
     20  */
     21 
     22 #define NETDISSECT_REWORKED
     23 #ifdef HAVE_CONFIG_H
     24 #include "config.h"
     25 #endif
     26 
     27 #include <tcpdump-stdinc.h>
     28 
     29 #include <stdio.h>
     30 
     31 #include "interface.h"
     32 #include "extract.h"
     33 #include "addrtoname.h"
     34 #include "af.h"
     35 #include "oui.h"
     36 
     37 #define	LLDP_EXTRACT_TYPE(x) (((x)&0xfe00)>>9)
     38 #define	LLDP_EXTRACT_LEN(x) ((x)&0x01ff)
     39 
     40 /*
     41  * TLV type codes
     42  */
     43 #define LLDP_END_TLV             0
     44 #define LLDP_CHASSIS_ID_TLV      1
     45 #define LLDP_PORT_ID_TLV         2
     46 #define LLDP_TTL_TLV             3
     47 #define LLDP_PORT_DESCR_TLV      4
     48 #define LLDP_SYSTEM_NAME_TLV     5
     49 #define LLDP_SYSTEM_DESCR_TLV    6
     50 #define LLDP_SYSTEM_CAP_TLV      7
     51 #define LLDP_MGMT_ADDR_TLV       8
     52 #define LLDP_PRIVATE_TLV       127
     53 
     54 static const struct tok lldp_tlv_values[] = {
     55     { LLDP_END_TLV, "End" },
     56     { LLDP_CHASSIS_ID_TLV, "Chassis ID" },
     57     { LLDP_PORT_ID_TLV, "Port ID" },
     58     { LLDP_TTL_TLV, "Time to Live" },
     59     { LLDP_PORT_DESCR_TLV, "Port Description" },
     60     { LLDP_SYSTEM_NAME_TLV, "System Name" },
     61     { LLDP_SYSTEM_DESCR_TLV, "System Description" },
     62     { LLDP_SYSTEM_CAP_TLV, "System Capabilities" },
     63     { LLDP_MGMT_ADDR_TLV, "Management Address" },
     64     { LLDP_PRIVATE_TLV, "Organization specific" },
     65     { 0, NULL}
     66 };
     67 
     68 /*
     69  * Chassis ID subtypes
     70  */
     71 #define LLDP_CHASSIS_CHASSIS_COMP_SUBTYPE  1
     72 #define LLDP_CHASSIS_INTF_ALIAS_SUBTYPE    2
     73 #define LLDP_CHASSIS_PORT_COMP_SUBTYPE     3
     74 #define LLDP_CHASSIS_MAC_ADDR_SUBTYPE      4
     75 #define LLDP_CHASSIS_NETWORK_ADDR_SUBTYPE  5
     76 #define LLDP_CHASSIS_INTF_NAME_SUBTYPE     6
     77 #define LLDP_CHASSIS_LOCAL_SUBTYPE         7
     78 
     79 static const struct tok lldp_chassis_subtype_values[] = {
     80     { LLDP_CHASSIS_CHASSIS_COMP_SUBTYPE, "Chassis component"},
     81     { LLDP_CHASSIS_INTF_ALIAS_SUBTYPE, "Interface alias"},
     82     { LLDP_CHASSIS_PORT_COMP_SUBTYPE, "Port component"},
     83     { LLDP_CHASSIS_MAC_ADDR_SUBTYPE, "MAC address"},
     84     { LLDP_CHASSIS_NETWORK_ADDR_SUBTYPE, "Network address"},
     85     { LLDP_CHASSIS_INTF_NAME_SUBTYPE, "Interface name"},
     86     { LLDP_CHASSIS_LOCAL_SUBTYPE, "Local"},
     87     { 0, NULL}
     88 };
     89 
     90 /*
     91  * Port ID subtypes
     92  */
     93 #define LLDP_PORT_INTF_ALIAS_SUBTYPE       1
     94 #define LLDP_PORT_PORT_COMP_SUBTYPE        2
     95 #define LLDP_PORT_MAC_ADDR_SUBTYPE         3
     96 #define LLDP_PORT_NETWORK_ADDR_SUBTYPE     4
     97 #define LLDP_PORT_INTF_NAME_SUBTYPE        5
     98 #define LLDP_PORT_AGENT_CIRC_ID_SUBTYPE    6
     99 #define LLDP_PORT_LOCAL_SUBTYPE            7
    100 
    101 static const struct tok lldp_port_subtype_values[] = {
    102     { LLDP_PORT_INTF_ALIAS_SUBTYPE, "Interface alias"},
    103     { LLDP_PORT_PORT_COMP_SUBTYPE, "Port component"},
    104     { LLDP_PORT_MAC_ADDR_SUBTYPE, "MAC address"},
    105     { LLDP_PORT_NETWORK_ADDR_SUBTYPE, "Network Address"},
    106     { LLDP_PORT_INTF_NAME_SUBTYPE, "Interface Name"},
    107     { LLDP_PORT_AGENT_CIRC_ID_SUBTYPE, "Agent circuit ID"},
    108     { LLDP_PORT_LOCAL_SUBTYPE, "Local"},
    109     { 0, NULL}
    110 };
    111 
    112 /*
    113  * System Capabilities
    114  */
    115 #define LLDP_CAP_OTHER              (1 <<  0)
    116 #define LLDP_CAP_REPEATER           (1 <<  1)
    117 #define LLDP_CAP_BRIDGE             (1 <<  2)
    118 #define LLDP_CAP_WLAN_AP            (1 <<  3)
    119 #define LLDP_CAP_ROUTER             (1 <<  4)
    120 #define LLDP_CAP_PHONE              (1 <<  5)
    121 #define LLDP_CAP_DOCSIS             (1 <<  6)
    122 #define LLDP_CAP_STATION_ONLY       (1 <<  7)
    123 
    124 static const struct tok lldp_cap_values[] = {
    125     { LLDP_CAP_OTHER, "Other"},
    126     { LLDP_CAP_REPEATER, "Repeater"},
    127     { LLDP_CAP_BRIDGE, "Bridge"},
    128     { LLDP_CAP_WLAN_AP, "WLAN AP"},
    129     { LLDP_CAP_ROUTER, "Router"},
    130     { LLDP_CAP_PHONE, "Telephone"},
    131     { LLDP_CAP_DOCSIS, "Docsis"},
    132     { LLDP_CAP_STATION_ONLY, "Station Only"},
    133     { 0, NULL}
    134 };
    135 
    136 #define LLDP_PRIVATE_8021_SUBTYPE_PORT_VLAN_ID		1
    137 #define LLDP_PRIVATE_8021_SUBTYPE_PROTOCOL_VLAN_ID	2
    138 #define LLDP_PRIVATE_8021_SUBTYPE_VLAN_NAME		3
    139 #define LLDP_PRIVATE_8021_SUBTYPE_PROTOCOL_IDENTITY	4
    140 #define LLDP_PRIVATE_8021_SUBTYPE_CONGESTION_NOTIFICATION 8
    141 #define LLDP_PRIVATE_8021_SUBTYPE_ETS_CONFIGURATION       9
    142 #define LLDP_PRIVATE_8021_SUBTYPE_ETS_RECOMMENDATION     10
    143 #define LLDP_PRIVATE_8021_SUBTYPE_PFC_CONFIGURATION      11
    144 #define LLDP_PRIVATE_8021_SUBTYPE_APPLICATION_PRIORITY   12
    145 #define LLDP_PRIVATE_8021_SUBTYPE_EVB                    13
    146 #define LLDP_PRIVATE_8021_SUBTYPE_CDCP 			 14
    147 
    148 static const struct tok lldp_8021_subtype_values[] = {
    149     { LLDP_PRIVATE_8021_SUBTYPE_PORT_VLAN_ID, "Port VLAN Id"},
    150     { LLDP_PRIVATE_8021_SUBTYPE_PROTOCOL_VLAN_ID, "Port and Protocol VLAN ID"},
    151     { LLDP_PRIVATE_8021_SUBTYPE_VLAN_NAME, "VLAN name"},
    152     { LLDP_PRIVATE_8021_SUBTYPE_PROTOCOL_IDENTITY, "Protocol Identity"},
    153     { LLDP_PRIVATE_8021_SUBTYPE_CONGESTION_NOTIFICATION, "Congestion Notification"},
    154     { LLDP_PRIVATE_8021_SUBTYPE_ETS_CONFIGURATION, "ETS Configuration"},
    155     { LLDP_PRIVATE_8021_SUBTYPE_ETS_RECOMMENDATION, "ETS Recommendation"},
    156     { LLDP_PRIVATE_8021_SUBTYPE_PFC_CONFIGURATION, "Priority Flow Control Configuration"},
    157     { LLDP_PRIVATE_8021_SUBTYPE_APPLICATION_PRIORITY, "Application Priority"},
    158     { LLDP_PRIVATE_8021_SUBTYPE_EVB, "EVB"},
    159     { LLDP_PRIVATE_8021_SUBTYPE_CDCP,"CDCP"},
    160     { 0, NULL}
    161 };
    162 
    163 #define LLDP_8021_PORT_PROTOCOL_VLAN_SUPPORT       (1 <<  1)
    164 #define LLDP_8021_PORT_PROTOCOL_VLAN_STATUS        (1 <<  2)
    165 
    166 static const struct tok lldp_8021_port_protocol_id_values[] = {
    167     { LLDP_8021_PORT_PROTOCOL_VLAN_SUPPORT, "supported"},
    168     { LLDP_8021_PORT_PROTOCOL_VLAN_STATUS, "enabled"},
    169     { 0, NULL}
    170 };
    171 
    172 #define LLDP_PRIVATE_8023_SUBTYPE_MACPHY        1
    173 #define LLDP_PRIVATE_8023_SUBTYPE_MDIPOWER      2
    174 #define LLDP_PRIVATE_8023_SUBTYPE_LINKAGGR      3
    175 #define LLDP_PRIVATE_8023_SUBTYPE_MTU           4
    176 
    177 static const struct tok lldp_8023_subtype_values[] = {
    178     { LLDP_PRIVATE_8023_SUBTYPE_MACPHY,	"MAC/PHY configuration/status"},
    179     { LLDP_PRIVATE_8023_SUBTYPE_MDIPOWER, "Power via MDI"},
    180     { LLDP_PRIVATE_8023_SUBTYPE_LINKAGGR, "Link aggregation"},
    181     { LLDP_PRIVATE_8023_SUBTYPE_MTU, "Max frame size"},
    182     { 0, NULL}
    183 };
    184 
    185 #define LLDP_PRIVATE_TIA_SUBTYPE_CAPABILITIES                   1
    186 #define LLDP_PRIVATE_TIA_SUBTYPE_NETWORK_POLICY                 2
    187 #define LLDP_PRIVATE_TIA_SUBTYPE_LOCAL_ID                       3
    188 #define LLDP_PRIVATE_TIA_SUBTYPE_EXTENDED_POWER_MDI             4
    189 #define LLDP_PRIVATE_TIA_SUBTYPE_INVENTORY_HARDWARE_REV         5
    190 #define LLDP_PRIVATE_TIA_SUBTYPE_INVENTORY_FIRMWARE_REV         6
    191 #define LLDP_PRIVATE_TIA_SUBTYPE_INVENTORY_SOFTWARE_REV         7
    192 #define LLDP_PRIVATE_TIA_SUBTYPE_INVENTORY_SERIAL_NUMBER        8
    193 #define LLDP_PRIVATE_TIA_SUBTYPE_INVENTORY_MANUFACTURER_NAME    9
    194 #define LLDP_PRIVATE_TIA_SUBTYPE_INVENTORY_MODEL_NAME           10
    195 #define LLDP_PRIVATE_TIA_SUBTYPE_INVENTORY_ASSET_ID             11
    196 
    197 static const struct tok lldp_tia_subtype_values[] = {
    198     { LLDP_PRIVATE_TIA_SUBTYPE_CAPABILITIES, "LLDP-MED Capabilities" },
    199     { LLDP_PRIVATE_TIA_SUBTYPE_NETWORK_POLICY, "Network policy" },
    200     { LLDP_PRIVATE_TIA_SUBTYPE_LOCAL_ID, "Location identification" },
    201     { LLDP_PRIVATE_TIA_SUBTYPE_EXTENDED_POWER_MDI, "Extended power-via-MDI" },
    202     { LLDP_PRIVATE_TIA_SUBTYPE_INVENTORY_HARDWARE_REV, "Inventory - hardware revision" },
    203     { LLDP_PRIVATE_TIA_SUBTYPE_INVENTORY_FIRMWARE_REV, "Inventory - firmware revision" },
    204     { LLDP_PRIVATE_TIA_SUBTYPE_INVENTORY_SOFTWARE_REV, "Inventory - software revision" },
    205     { LLDP_PRIVATE_TIA_SUBTYPE_INVENTORY_SERIAL_NUMBER, "Inventory - serial number" },
    206     { LLDP_PRIVATE_TIA_SUBTYPE_INVENTORY_MANUFACTURER_NAME, "Inventory - manufacturer name" },
    207     { LLDP_PRIVATE_TIA_SUBTYPE_INVENTORY_MODEL_NAME, "Inventory - model name" },
    208     { LLDP_PRIVATE_TIA_SUBTYPE_INVENTORY_ASSET_ID, "Inventory - asset ID" },
    209     { 0, NULL}
    210 };
    211 
    212 #define LLDP_PRIVATE_TIA_LOCATION_ALTITUDE_METERS       1
    213 #define LLDP_PRIVATE_TIA_LOCATION_ALTITUDE_FLOORS       2
    214 
    215 static const struct tok lldp_tia_location_altitude_type_values[] = {
    216     { LLDP_PRIVATE_TIA_LOCATION_ALTITUDE_METERS, "meters"},
    217     { LLDP_PRIVATE_TIA_LOCATION_ALTITUDE_FLOORS, "floors"},
    218     { 0, NULL}
    219 };
    220 
    221 /* ANSI/TIA-1057 - Annex B */
    222 #define LLDP_PRIVATE_TIA_LOCATION_LCI_CATYPE_A1		1
    223 #define LLDP_PRIVATE_TIA_LOCATION_LCI_CATYPE_A2		2
    224 #define LLDP_PRIVATE_TIA_LOCATION_LCI_CATYPE_A3		3
    225 #define LLDP_PRIVATE_TIA_LOCATION_LCI_CATYPE_A4		4
    226 #define LLDP_PRIVATE_TIA_LOCATION_LCI_CATYPE_A5		5
    227 #define LLDP_PRIVATE_TIA_LOCATION_LCI_CATYPE_A6		6
    228 
    229 static const struct tok lldp_tia_location_lci_catype_values[] = {
    230     { LLDP_PRIVATE_TIA_LOCATION_LCI_CATYPE_A1, "national subdivisions (state,canton,region,province,prefecture)"},
    231     { LLDP_PRIVATE_TIA_LOCATION_LCI_CATYPE_A2, "county, parish, gun, district"},
    232     { LLDP_PRIVATE_TIA_LOCATION_LCI_CATYPE_A3, "city, township, shi"},
    233     { LLDP_PRIVATE_TIA_LOCATION_LCI_CATYPE_A4, "city division, borough, city district, ward chou"},
    234     { LLDP_PRIVATE_TIA_LOCATION_LCI_CATYPE_A5, "neighborhood, block"},
    235     { LLDP_PRIVATE_TIA_LOCATION_LCI_CATYPE_A6, "street"},
    236     { 0, NULL}
    237 };
    238 
    239 static const struct tok lldp_tia_location_lci_what_values[] = {
    240     { 0, "location of DHCP server"},
    241     { 1, "location of the network element believed to be closest to the client"},
    242     { 2, "location of the client"},
    243     { 0, NULL}
    244 };
    245 
    246 /*
    247  * From RFC 3636 - dot3MauType
    248  */
    249 #define		LLDP_MAU_TYPE_UNKNOWN		0
    250 #define		LLDP_MAU_TYPE_AUI		1
    251 #define		LLDP_MAU_TYPE_10BASE_5		2
    252 #define		LLDP_MAU_TYPE_FOIRL		3
    253 #define		LLDP_MAU_TYPE_10BASE_2		4
    254 #define		LLDP_MAU_TYPE_10BASE_T		5
    255 #define		LLDP_MAU_TYPE_10BASE_FP		6
    256 #define		LLDP_MAU_TYPE_10BASE_FB		7
    257 #define		LLDP_MAU_TYPE_10BASE_FL		8
    258 #define		LLDP_MAU_TYPE_10BROAD36		9
    259 #define		LLDP_MAU_TYPE_10BASE_T_HD	10
    260 #define		LLDP_MAU_TYPE_10BASE_T_FD	11
    261 #define		LLDP_MAU_TYPE_10BASE_FL_HD	12
    262 #define		LLDP_MAU_TYPE_10BASE_FL_FD	13
    263 #define		LLDP_MAU_TYPE_100BASE_T4	14
    264 #define		LLDP_MAU_TYPE_100BASE_TX_HD	15
    265 #define		LLDP_MAU_TYPE_100BASE_TX_FD	16
    266 #define		LLDP_MAU_TYPE_100BASE_FX_HD	17
    267 #define		LLDP_MAU_TYPE_100BASE_FX_FD	18
    268 #define		LLDP_MAU_TYPE_100BASE_T2_HD	19
    269 #define		LLDP_MAU_TYPE_100BASE_T2_FD	20
    270 #define		LLDP_MAU_TYPE_1000BASE_X_HD	21
    271 #define		LLDP_MAU_TYPE_1000BASE_X_FD	22
    272 #define		LLDP_MAU_TYPE_1000BASE_LX_HD	23
    273 #define		LLDP_MAU_TYPE_1000BASE_LX_FD	24
    274 #define		LLDP_MAU_TYPE_1000BASE_SX_HD	25
    275 #define		LLDP_MAU_TYPE_1000BASE_SX_FD	26
    276 #define		LLDP_MAU_TYPE_1000BASE_CX_HD	27
    277 #define		LLDP_MAU_TYPE_1000BASE_CX_FD	28
    278 #define		LLDP_MAU_TYPE_1000BASE_T_HD	29
    279 #define		LLDP_MAU_TYPE_1000BASE_T_FD	30
    280 #define		LLDP_MAU_TYPE_10GBASE_X		31
    281 #define		LLDP_MAU_TYPE_10GBASE_LX4	32
    282 #define		LLDP_MAU_TYPE_10GBASE_R		33
    283 #define		LLDP_MAU_TYPE_10GBASE_ER	34
    284 #define		LLDP_MAU_TYPE_10GBASE_LR	35
    285 #define		LLDP_MAU_TYPE_10GBASE_SR	36
    286 #define		LLDP_MAU_TYPE_10GBASE_W		37
    287 #define		LLDP_MAU_TYPE_10GBASE_EW	38
    288 #define		LLDP_MAU_TYPE_10GBASE_LW	39
    289 #define		LLDP_MAU_TYPE_10GBASE_SW	40
    290 
    291 static const struct tok lldp_mau_types_values[] = {
    292     { LLDP_MAU_TYPE_UNKNOWN,            "Unknown"},
    293     { LLDP_MAU_TYPE_AUI,                "AUI"},
    294     { LLDP_MAU_TYPE_10BASE_5,           "10BASE_5"},
    295     { LLDP_MAU_TYPE_FOIRL,              "FOIRL"},
    296     { LLDP_MAU_TYPE_10BASE_2,           "10BASE2"},
    297     { LLDP_MAU_TYPE_10BASE_T,           "10BASET duplex mode unknown"},
    298     { LLDP_MAU_TYPE_10BASE_FP,          "10BASEFP"},
    299     { LLDP_MAU_TYPE_10BASE_FB,          "10BASEFB"},
    300     { LLDP_MAU_TYPE_10BASE_FL,          "10BASEFL duplex mode unknown"},
    301     { LLDP_MAU_TYPE_10BROAD36,          "10BROAD36"},
    302     { LLDP_MAU_TYPE_10BASE_T_HD,        "10BASET hdx"},
    303     { LLDP_MAU_TYPE_10BASE_T_FD,        "10BASET fdx"},
    304     { LLDP_MAU_TYPE_10BASE_FL_HD,       "10BASEFL hdx"},
    305     { LLDP_MAU_TYPE_10BASE_FL_FD,       "10BASEFL fdx"},
    306     { LLDP_MAU_TYPE_100BASE_T4,         "100BASET4"},
    307     { LLDP_MAU_TYPE_100BASE_TX_HD,      "100BASETX hdx"},
    308     { LLDP_MAU_TYPE_100BASE_TX_FD,      "100BASETX fdx"},
    309     { LLDP_MAU_TYPE_100BASE_FX_HD,      "100BASEFX hdx"},
    310     { LLDP_MAU_TYPE_100BASE_FX_FD,      "100BASEFX fdx"},
    311     { LLDP_MAU_TYPE_100BASE_T2_HD,      "100BASET2 hdx"},
    312     { LLDP_MAU_TYPE_100BASE_T2_FD,      "100BASET2 fdx"},
    313     { LLDP_MAU_TYPE_1000BASE_X_HD,      "1000BASEX hdx"},
    314     { LLDP_MAU_TYPE_1000BASE_X_FD,      "1000BASEX fdx"},
    315     { LLDP_MAU_TYPE_1000BASE_LX_HD,     "1000BASELX hdx"},
    316     { LLDP_MAU_TYPE_1000BASE_LX_FD,     "1000BASELX fdx"},
    317     { LLDP_MAU_TYPE_1000BASE_SX_HD,     "1000BASESX hdx"},
    318     { LLDP_MAU_TYPE_1000BASE_SX_FD,     "1000BASESX fdx"},
    319     { LLDP_MAU_TYPE_1000BASE_CX_HD,     "1000BASECX hdx"},
    320     { LLDP_MAU_TYPE_1000BASE_CX_FD,     "1000BASECX fdx"},
    321     { LLDP_MAU_TYPE_1000BASE_T_HD,      "1000BASET hdx"},
    322     { LLDP_MAU_TYPE_1000BASE_T_FD,      "1000BASET fdx"},
    323     { LLDP_MAU_TYPE_10GBASE_X,          "10GBASEX"},
    324     { LLDP_MAU_TYPE_10GBASE_LX4,        "10GBASELX4"},
    325     { LLDP_MAU_TYPE_10GBASE_R,          "10GBASER"},
    326     { LLDP_MAU_TYPE_10GBASE_ER,         "10GBASEER"},
    327     { LLDP_MAU_TYPE_10GBASE_LR,         "10GBASELR"},
    328     { LLDP_MAU_TYPE_10GBASE_SR,         "10GBASESR"},
    329     { LLDP_MAU_TYPE_10GBASE_W,          "10GBASEW"},
    330     { LLDP_MAU_TYPE_10GBASE_EW,         "10GBASEEW"},
    331     { LLDP_MAU_TYPE_10GBASE_LW,         "10GBASELW"},
    332     { LLDP_MAU_TYPE_10GBASE_SW,         "10GBASESW"},
    333     { 0, NULL}
    334 };
    335 
    336 #define LLDP_8023_AUTONEGOTIATION_SUPPORT       (1 <<  0)
    337 #define LLDP_8023_AUTONEGOTIATION_STATUS        (1 <<  1)
    338 
    339 static const struct tok lldp_8023_autonegotiation_values[] = {
    340     { LLDP_8023_AUTONEGOTIATION_SUPPORT, "supported"},
    341     { LLDP_8023_AUTONEGOTIATION_STATUS, "enabled"},
    342     { 0, NULL}
    343 };
    344 
    345 #define LLDP_TIA_CAPABILITY_MED                         (1 <<  0)
    346 #define LLDP_TIA_CAPABILITY_NETWORK_POLICY              (1 <<  1)
    347 #define LLDP_TIA_CAPABILITY_LOCATION_IDENTIFICATION     (1 <<  2)
    348 #define LLDP_TIA_CAPABILITY_EXTENDED_POWER_MDI_PSE      (1 <<  3)
    349 #define LLDP_TIA_CAPABILITY_EXTENDED_POWER_MDI_PD       (1 <<  4)
    350 #define LLDP_TIA_CAPABILITY_INVENTORY                   (1 <<  5)
    351 
    352 static const struct tok lldp_tia_capabilities_values[] = {
    353     { LLDP_TIA_CAPABILITY_MED, "LLDP-MED capabilities"},
    354     { LLDP_TIA_CAPABILITY_NETWORK_POLICY, "network policy"},
    355     { LLDP_TIA_CAPABILITY_LOCATION_IDENTIFICATION, "location identification"},
    356     { LLDP_TIA_CAPABILITY_EXTENDED_POWER_MDI_PSE, "extended power via MDI-PSE"},
    357     { LLDP_TIA_CAPABILITY_EXTENDED_POWER_MDI_PD, "extended power via MDI-PD"},
    358     { LLDP_TIA_CAPABILITY_INVENTORY, "Inventory"},
    359     { 0, NULL}
    360 };
    361 
    362 #define LLDP_TIA_DEVICE_TYPE_ENDPOINT_CLASS_1           1
    363 #define LLDP_TIA_DEVICE_TYPE_ENDPOINT_CLASS_2           2
    364 #define LLDP_TIA_DEVICE_TYPE_ENDPOINT_CLASS_3           3
    365 #define LLDP_TIA_DEVICE_TYPE_NETWORK_CONNECTIVITY       4
    366 
    367 static const struct tok lldp_tia_device_type_values[] = {
    368     { LLDP_TIA_DEVICE_TYPE_ENDPOINT_CLASS_1, "endpoint class 1"},
    369     { LLDP_TIA_DEVICE_TYPE_ENDPOINT_CLASS_2, "endpoint class 2"},
    370     { LLDP_TIA_DEVICE_TYPE_ENDPOINT_CLASS_3, "endpoint class 3"},
    371     { LLDP_TIA_DEVICE_TYPE_NETWORK_CONNECTIVITY, "network connectivity"},
    372     { 0, NULL}
    373 };
    374 
    375 #define LLDP_TIA_APPLICATION_TYPE_VOICE                 1
    376 #define LLDP_TIA_APPLICATION_TYPE_VOICE_SIGNALING       2
    377 #define LLDP_TIA_APPLICATION_TYPE_GUEST_VOICE           3
    378 #define LLDP_TIA_APPLICATION_TYPE_GUEST_VOICE_SIGNALING 4
    379 #define LLDP_TIA_APPLICATION_TYPE_SOFTPHONE_VOICE       5
    380 #define LLDP_TIA_APPLICATION_TYPE_VIDEO_CONFERENCING    6
    381 #define LLDP_TIA_APPLICATION_TYPE_STREAMING_VIDEO       7
    382 #define LLDP_TIA_APPLICATION_TYPE_VIDEO_SIGNALING       8
    383 
    384 static const struct tok lldp_tia_application_type_values[] = {
    385     { LLDP_TIA_APPLICATION_TYPE_VOICE, "voice"},
    386     { LLDP_TIA_APPLICATION_TYPE_VOICE_SIGNALING, "voice signaling"},
    387     { LLDP_TIA_APPLICATION_TYPE_GUEST_VOICE, "guest voice"},
    388     { LLDP_TIA_APPLICATION_TYPE_GUEST_VOICE_SIGNALING, "guest voice signaling"},
    389     { LLDP_TIA_APPLICATION_TYPE_SOFTPHONE_VOICE, "softphone voice"},
    390     { LLDP_TIA_APPLICATION_TYPE_VIDEO_CONFERENCING, "video conferencing"},
    391     { LLDP_TIA_APPLICATION_TYPE_STREAMING_VIDEO, "streaming video"},
    392     { LLDP_TIA_APPLICATION_TYPE_VIDEO_SIGNALING, "video signaling"},
    393     { 0, NULL}
    394 };
    395 
    396 #define LLDP_TIA_NETWORK_POLICY_X_BIT           (1 << 5)
    397 #define LLDP_TIA_NETWORK_POLICY_T_BIT           (1 << 6)
    398 #define LLDP_TIA_NETWORK_POLICY_U_BIT           (1 << 7)
    399 
    400 static const struct tok lldp_tia_network_policy_bits_values[] = {
    401     { LLDP_TIA_NETWORK_POLICY_U_BIT, "Unknown"},
    402     { LLDP_TIA_NETWORK_POLICY_T_BIT, "Tagged"},
    403     { LLDP_TIA_NETWORK_POLICY_X_BIT, "reserved"},
    404     { 0, NULL}
    405 };
    406 
    407 #define LLDP_EXTRACT_NETWORK_POLICY_VLAN(x)           (((x)&0x1ffe)>>1)
    408 #define LLDP_EXTRACT_NETWORK_POLICY_L2_PRIORITY(x)    (((x)&0x01ff)>>6)
    409 #define LLDP_EXTRACT_NETWORK_POLICY_DSCP(x)           ((x)&0x003f)
    410 
    411 #define LLDP_TIA_LOCATION_DATA_FORMAT_COORDINATE_BASED  1
    412 #define LLDP_TIA_LOCATION_DATA_FORMAT_CIVIC_ADDRESS     2
    413 #define LLDP_TIA_LOCATION_DATA_FORMAT_ECS_ELIN          3
    414 
    415 static const struct tok lldp_tia_location_data_format_values[] = {
    416     { LLDP_TIA_LOCATION_DATA_FORMAT_COORDINATE_BASED, "coordinate-based LCI"},
    417     { LLDP_TIA_LOCATION_DATA_FORMAT_CIVIC_ADDRESS, "civic address LCI"},
    418     { LLDP_TIA_LOCATION_DATA_FORMAT_ECS_ELIN, "ECS ELIN"},
    419     { 0, NULL}
    420 };
    421 
    422 #define LLDP_TIA_LOCATION_DATUM_WGS_84          1
    423 #define LLDP_TIA_LOCATION_DATUM_NAD_83_NAVD_88  2
    424 #define LLDP_TIA_LOCATION_DATUM_NAD_83_MLLW     3
    425 
    426 static const struct tok lldp_tia_location_datum_type_values[] = {
    427     { LLDP_TIA_LOCATION_DATUM_WGS_84, "World Geodesic System 1984"},
    428     { LLDP_TIA_LOCATION_DATUM_NAD_83_NAVD_88, "North American Datum 1983 (NAVD88)"},
    429     { LLDP_TIA_LOCATION_DATUM_NAD_83_MLLW, "North American Datum 1983 (MLLW)"},
    430     { 0, NULL}
    431 };
    432 
    433 #define LLDP_TIA_POWER_SOURCE_PSE               1
    434 #define LLDP_TIA_POWER_SOURCE_LOCAL             2
    435 #define LLDP_TIA_POWER_SOURCE_PSE_AND_LOCAL     3
    436 
    437 static const struct tok lldp_tia_power_source_values[] = {
    438     { LLDP_TIA_POWER_SOURCE_PSE, "PSE - primary power source"},
    439     { LLDP_TIA_POWER_SOURCE_LOCAL, "local - backup power source"},
    440     { LLDP_TIA_POWER_SOURCE_PSE_AND_LOCAL, "PSE+local - reserved"},
    441     { 0, NULL}
    442 };
    443 
    444 #define LLDP_TIA_POWER_PRIORITY_CRITICAL        1
    445 #define LLDP_TIA_POWER_PRIORITY_HIGH            2
    446 #define LLDP_TIA_POWER_PRIORITY_LOW             3
    447 
    448 static const struct tok lldp_tia_power_priority_values[] = {
    449     { LLDP_TIA_POWER_PRIORITY_CRITICAL, "critical"},
    450     { LLDP_TIA_POWER_PRIORITY_HIGH, "high"},
    451     { LLDP_TIA_POWER_PRIORITY_LOW, "low"},
    452     { 0, NULL}
    453 };
    454 
    455 #define LLDP_TIA_POWER_VAL_MAX               1024
    456 
    457 static const struct tok lldp_tia_inventory_values[] = {
    458     { LLDP_PRIVATE_TIA_SUBTYPE_INVENTORY_HARDWARE_REV, "Hardware revision" },
    459     { LLDP_PRIVATE_TIA_SUBTYPE_INVENTORY_FIRMWARE_REV, "Firmware revision" },
    460     { LLDP_PRIVATE_TIA_SUBTYPE_INVENTORY_SOFTWARE_REV, "Software revision" },
    461     { LLDP_PRIVATE_TIA_SUBTYPE_INVENTORY_SERIAL_NUMBER, "Serial number" },
    462     { LLDP_PRIVATE_TIA_SUBTYPE_INVENTORY_MANUFACTURER_NAME, "Manufacturer name" },
    463     { LLDP_PRIVATE_TIA_SUBTYPE_INVENTORY_MODEL_NAME, "Model name" },
    464     { LLDP_PRIVATE_TIA_SUBTYPE_INVENTORY_ASSET_ID, "Asset ID" },
    465     { 0, NULL}
    466 };
    467 
    468 /*
    469  * From RFC 3636 - ifMauAutoNegCapAdvertisedBits
    470  */
    471 #define	 LLDP_MAU_PMD_OTHER			(1 <<  15)
    472 #define	 LLDP_MAU_PMD_10BASE_T			(1 <<  14)
    473 #define	 LLDP_MAU_PMD_10BASE_T_FD		(1 <<  13)
    474 #define	 LLDP_MAU_PMD_100BASE_T4		(1 <<  12)
    475 #define	 LLDP_MAU_PMD_100BASE_TX		(1 <<  11)
    476 #define	 LLDP_MAU_PMD_100BASE_TX_FD		(1 <<  10)
    477 #define	 LLDP_MAU_PMD_100BASE_T2		(1 <<  9)
    478 #define	 LLDP_MAU_PMD_100BASE_T2_FD		(1 <<  8)
    479 #define	 LLDP_MAU_PMD_FDXPAUSE			(1 <<  7)
    480 #define	 LLDP_MAU_PMD_FDXAPAUSE			(1 <<  6)
    481 #define	 LLDP_MAU_PMD_FDXSPAUSE			(1 <<  5)
    482 #define	 LLDP_MAU_PMD_FDXBPAUSE			(1 <<  4)
    483 #define	 LLDP_MAU_PMD_1000BASE_X		(1 <<  3)
    484 #define	 LLDP_MAU_PMD_1000BASE_X_FD		(1 <<  2)
    485 #define	 LLDP_MAU_PMD_1000BASE_T		(1 <<  1)
    486 #define	 LLDP_MAU_PMD_1000BASE_T_FD		(1 <<  0)
    487 
    488 static const struct tok lldp_pmd_capability_values[] = {
    489     { LLDP_MAU_PMD_10BASE_T,		"10BASE-T hdx"},
    490     { LLDP_MAU_PMD_10BASE_T_FD,	        "10BASE-T fdx"},
    491     { LLDP_MAU_PMD_100BASE_T4,		"100BASE-T4"},
    492     { LLDP_MAU_PMD_100BASE_TX,		"100BASE-TX hdx"},
    493     { LLDP_MAU_PMD_100BASE_TX_FD,	"100BASE-TX fdx"},
    494     { LLDP_MAU_PMD_100BASE_T2,		"100BASE-T2 hdx"},
    495     { LLDP_MAU_PMD_100BASE_T2_FD,	"100BASE-T2 fdx"},
    496     { LLDP_MAU_PMD_FDXPAUSE,		"Pause for fdx links"},
    497     { LLDP_MAU_PMD_FDXAPAUSE,		"Asym PAUSE for fdx"},
    498     { LLDP_MAU_PMD_FDXSPAUSE,		"Sym PAUSE for fdx"},
    499     { LLDP_MAU_PMD_FDXBPAUSE,		"Asym and Sym PAUSE for fdx"},
    500     { LLDP_MAU_PMD_1000BASE_X,		"1000BASE-{X LX SX CX} hdx"},
    501     { LLDP_MAU_PMD_1000BASE_X_FD,	"1000BASE-{X LX SX CX} fdx"},
    502     { LLDP_MAU_PMD_1000BASE_T,		"1000BASE-T hdx"},
    503     { LLDP_MAU_PMD_1000BASE_T_FD,	"1000BASE-T fdx"},
    504     { 0, NULL}
    505 };
    506 
    507 #define	LLDP_MDI_PORT_CLASS			(1 <<  0)
    508 #define	LLDP_MDI_POWER_SUPPORT			(1 <<  1)
    509 #define LLDP_MDI_POWER_STATE			(1 <<  2)
    510 #define LLDP_MDI_PAIR_CONTROL_ABILITY		(1 <<  3)
    511 
    512 static const struct tok lldp_mdi_values[] = {
    513     { LLDP_MDI_PORT_CLASS, 		"PSE"},
    514     { LLDP_MDI_POWER_SUPPORT, 		"supported"},
    515     { LLDP_MDI_POWER_STATE, 		"enabled"},
    516     { LLDP_MDI_PAIR_CONTROL_ABILITY, 	"can be controlled"},
    517     { 0, NULL}
    518 };
    519 
    520 #define LLDP_MDI_PSE_PORT_POWER_PAIRS_SIGNAL	1
    521 #define LLDP_MDI_PSE_PORT_POWER_PAIRS_SPARE	2
    522 
    523 static const struct tok lldp_mdi_power_pairs_values[] = {
    524     { LLDP_MDI_PSE_PORT_POWER_PAIRS_SIGNAL,	"signal"},
    525     { LLDP_MDI_PSE_PORT_POWER_PAIRS_SPARE,	"spare"},
    526     { 0, NULL}
    527 };
    528 
    529 #define LLDP_MDI_POWER_CLASS0		1
    530 #define LLDP_MDI_POWER_CLASS1		2
    531 #define LLDP_MDI_POWER_CLASS2		3
    532 #define LLDP_MDI_POWER_CLASS3		4
    533 #define LLDP_MDI_POWER_CLASS4		5
    534 
    535 static const struct tok lldp_mdi_power_class_values[] = {
    536     { LLDP_MDI_POWER_CLASS0,     "class0"},
    537     { LLDP_MDI_POWER_CLASS1,     "class1"},
    538     { LLDP_MDI_POWER_CLASS2,     "class2"},
    539     { LLDP_MDI_POWER_CLASS3,     "class3"},
    540     { LLDP_MDI_POWER_CLASS4,     "class4"},
    541     { 0, NULL}
    542 };
    543 
    544 #define LLDP_AGGREGATION_CAPABILTIY     (1 <<  0)
    545 #define LLDP_AGGREGATION_STATUS         (1 <<  1)
    546 
    547 static const struct tok lldp_aggregation_values[] = {
    548     { LLDP_AGGREGATION_CAPABILTIY, "supported"},
    549     { LLDP_AGGREGATION_STATUS, "enabled"},
    550     { 0, NULL}
    551 };
    552 
    553 /*
    554  * DCBX protocol subtypes.
    555  */
    556 #define LLDP_DCBX_SUBTYPE_1                1
    557 #define LLDP_DCBX_SUBTYPE_2                2
    558 
    559 static const struct tok lldp_dcbx_subtype_values[] = {
    560     { LLDP_DCBX_SUBTYPE_1, "DCB Capability Exchange Protocol Rev 1" },
    561     { LLDP_DCBX_SUBTYPE_2, "DCB Capability Exchange Protocol Rev 1.01" },
    562     { 0, NULL}
    563 };
    564 
    565 #define LLDP_DCBX_CONTROL_TLV                1
    566 #define LLDP_DCBX_PRIORITY_GROUPS_TLV        2
    567 #define LLDP_DCBX_PRIORITY_FLOW_CONTROL_TLV  3
    568 #define LLDP_DCBX_APPLICATION_TLV            4
    569 
    570 /*
    571  * Interface numbering subtypes.
    572  */
    573 #define LLDP_INTF_NUMB_IFX_SUBTYPE         2
    574 #define LLDP_INTF_NUMB_SYSPORT_SUBTYPE     3
    575 
    576 static const struct tok lldp_intf_numb_subtype_values[] = {
    577     { LLDP_INTF_NUMB_IFX_SUBTYPE, "Interface Index" },
    578     { LLDP_INTF_NUMB_SYSPORT_SUBTYPE, "System Port Number" },
    579     { 0, NULL}
    580 };
    581 
    582 #define LLDP_INTF_NUM_LEN                  5
    583 
    584 #define LLDP_EVB_MODE_NOT_SUPPORTED	0
    585 #define LLDP_EVB_MODE_EVB_BRIDGE	1
    586 #define LLDP_EVB_MODE_EVB_STATION	2
    587 #define LLDP_EVB_MODE_RESERVED		3
    588 
    589 static const struct tok lldp_evb_mode_values[]={
    590     { LLDP_EVB_MODE_NOT_SUPPORTED, "Not Supported"},
    591     { LLDP_EVB_MODE_EVB_BRIDGE, "EVB Bridge"},
    592     { LLDP_EVB_MODE_EVB_STATION, "EVB Staion"},
    593     { LLDP_EVB_MODE_RESERVED, "Reserved for future Standardization"},
    594 };
    595 
    596 #define NO_OF_BITS 8
    597 #define LLDP_PRIVATE_8021_SUBTYPE_CONGESTION_NOTIFICATION_LENGTH  6
    598 #define LLDP_PRIVATE_8021_SUBTYPE_ETS_CONFIGURATION_LENGTH       25
    599 #define LLDP_PRIVATE_8021_SUBTYPE_ETS_RECOMMENDATION_LENGTH      25
    600 #define LLDP_PRIVATE_8021_SUBTYPE_PFC_CONFIGURATION_LENGTH        6
    601 #define LLDP_PRIVATE_8021_SUBTYPE_APPLICATION_PRIORITY_MIN_LENGTH 5
    602 #define LLDP_PRIVATE_8021_SUBTYPE_EVB_LENGTH                      9
    603 #define LLDP_PRIVATE_8021_SUBTYPE_CDCP_MIN_LENGTH                 8
    604 
    605 static void
    606 print_ets_priority_assignment_table(netdissect_options *ndo,
    607                                     const u_char *ptr)
    608 {
    609     ND_PRINT((ndo, "\n\t    Priority Assignment Table"));
    610     ND_PRINT((ndo, "\n\t     Priority : 0   1   2   3   4   5   6   7"));
    611     ND_PRINT((ndo, "\n\t     Value    : %-3d %-3d %-3d %-3d %-3d %-3d %-3d %-3d",
    612             ptr[0]>>4,ptr[0]&0x0f,ptr[1]>>4,ptr[1]&0x0f,ptr[2]>>4,
    613             ptr[2] & 0x0f, ptr[3] >> 4, ptr[3] & 0x0f));
    614 }
    615 
    616 static void
    617 print_tc_bandwidth_table(netdissect_options *ndo,
    618                          const u_char *ptr)
    619 {
    620     ND_PRINT((ndo, "\n\t    TC Bandwidth Table"));
    621     ND_PRINT((ndo, "\n\t     TC%%   : 0   1   2   3   4   5   6   7"));
    622     ND_PRINT((ndo, "\n\t     Value : %-3d %-3d %-3d %-3d %-3d %-3d %-3d %-3d",
    623              ptr[0], ptr[1], ptr[2], ptr[3], ptr[4], ptr[5], ptr[6], ptr[7]));
    624 }
    625 
    626 static void
    627 print_tsa_assignment_table(netdissect_options *ndo,
    628                            const u_char *ptr)
    629 {
    630     ND_PRINT((ndo, "\n\t    TSA Assignment Table"));
    631     ND_PRINT((ndo, "\n\t     Traffic Class: 0   1   2   3   4   5   6   7"));
    632     ND_PRINT((ndo, "\n\t     Value        : %-3d %-3d %-3d %-3d %-3d %-3d %-3d %-3d",
    633              ptr[0], ptr[1], ptr[2], ptr[3], ptr[4], ptr[5], ptr[6], ptr[7]));
    634 }
    635 
    636 /*
    637  * Print IEEE 802.1 private extensions. (802.1AB annex E)
    638  */
    639 static int
    640 lldp_private_8021_print(netdissect_options *ndo,
    641                         const u_char *tptr, u_int tlv_len)
    642 {
    643     int subtype, hexdump = FALSE;
    644     u_int sublen;
    645     u_int tval;
    646     uint8_t i;
    647 
    648     if (tlv_len < 4) {
    649         return hexdump;
    650     }
    651     subtype = *(tptr+3);
    652 
    653     ND_PRINT((ndo, "\n\t  %s Subtype (%u)",
    654            tok2str(lldp_8021_subtype_values, "unknown", subtype),
    655            subtype));
    656 
    657     switch (subtype) {
    658     case LLDP_PRIVATE_8021_SUBTYPE_PORT_VLAN_ID:
    659         if (tlv_len < 6) {
    660             return hexdump;
    661         }
    662         ND_PRINT((ndo, "\n\t    port vlan id (PVID): %u",
    663                EXTRACT_16BITS(tptr + 4)));
    664         break;
    665     case LLDP_PRIVATE_8021_SUBTYPE_PROTOCOL_VLAN_ID:
    666         if (tlv_len < 7) {
    667             return hexdump;
    668         }
    669         ND_PRINT((ndo, "\n\t    port and protocol vlan id (PPVID): %u, flags [%s] (0x%02x)",
    670                EXTRACT_16BITS(tptr+5),
    671 	       bittok2str(lldp_8021_port_protocol_id_values, "none", *(tptr+4)),
    672 	       *(tptr + 4)));
    673         break;
    674     case LLDP_PRIVATE_8021_SUBTYPE_VLAN_NAME:
    675         if (tlv_len < 6) {
    676             return hexdump;
    677         }
    678         ND_PRINT((ndo, "\n\t    vlan id (VID): %u", EXTRACT_16BITS(tptr + 4)));
    679         if (tlv_len < 7) {
    680             return hexdump;
    681         }
    682         sublen = *(tptr+6);
    683         if (tlv_len < 7+sublen) {
    684             return hexdump;
    685         }
    686         ND_PRINT((ndo, "\n\t    vlan name: "));
    687         safeputs(ndo, tptr + 7, sublen);
    688         break;
    689     case LLDP_PRIVATE_8021_SUBTYPE_PROTOCOL_IDENTITY:
    690         if (tlv_len < 5) {
    691             return hexdump;
    692         }
    693         sublen = *(tptr+4);
    694         if (tlv_len < 5+sublen) {
    695             return hexdump;
    696         }
    697         ND_PRINT((ndo, "\n\t    protocol identity: "));
    698         safeputs(ndo, tptr + 5, sublen);
    699         break;
    700     case LLDP_PRIVATE_8021_SUBTYPE_CONGESTION_NOTIFICATION:
    701         if(tlv_len<LLDP_PRIVATE_8021_SUBTYPE_CONGESTION_NOTIFICATION_LENGTH){
    702         	return hexdump;
    703         }
    704         tval=*(tptr+4);
    705         ND_PRINT((ndo, "\n\t    Pre-Priority CNPV Indicator"));
    706         ND_PRINT((ndo, "\n\t     Priority : 0  1  2  3  4  5  6  7"));
    707         ND_PRINT((ndo, "\n\t     Value    : "));
    708         for(i=0;i<NO_OF_BITS;i++)
    709             ND_PRINT((ndo, "%-2d ", (tval >> i) & 0x01));
    710         tval=*(tptr+5);
    711         ND_PRINT((ndo, "\n\t    Pre-Priority Ready Indicator"));
    712         ND_PRINT((ndo, "\n\t     Priority : 0  1  2  3  4  5  6  7"));
    713         ND_PRINT((ndo, "\n\t     Value    : "));
    714         for(i=0;i<NO_OF_BITS;i++)
    715             ND_PRINT((ndo, "%-2d ", (tval >> i) & 0x01));
    716         break;
    717 
    718     case LLDP_PRIVATE_8021_SUBTYPE_ETS_CONFIGURATION:
    719         if(tlv_len<LLDP_PRIVATE_8021_SUBTYPE_ETS_CONFIGURATION_LENGTH) {
    720             return hexdump;
    721         }
    722         tval=*(tptr+4);
    723         ND_PRINT((ndo, "\n\t    Willing:%d, CBS:%d, RES:%d, Max TCs:%d",
    724         	tval >> 7, (tval >> 6) & 0x02, (tval >> 3) & 0x07, tval & 0x07));
    725 
    726         /*Print Priority Assignment Table*/
    727         print_ets_priority_assignment_table(ndo, tptr + 5);
    728 
    729         /*Print TC Bandwidth Table*/
    730         print_tc_bandwidth_table(ndo, tptr + 9);
    731 
    732         /* Print TSA Assignment Table */
    733         print_tsa_assignment_table(ndo, tptr + 17);
    734 
    735         break;
    736 
    737     case LLDP_PRIVATE_8021_SUBTYPE_ETS_RECOMMENDATION:
    738         if(tlv_len<LLDP_PRIVATE_8021_SUBTYPE_ETS_RECOMMENDATION_LENGTH) {
    739         	return hexdump;
    740         }
    741         ND_PRINT((ndo, "\n\t    RES: %d", *(tptr + 4)));
    742         /*Print Priority Assignment Table */
    743         print_ets_priority_assignment_table(ndo, tptr + 5);
    744         /*Print TC Bandwidth Table */
    745         print_tc_bandwidth_table(ndo, tptr + 9);
    746         /* Print TSA Assignment Table */
    747         print_tsa_assignment_table(ndo, tptr + 17);
    748         break;
    749 
    750     case LLDP_PRIVATE_8021_SUBTYPE_PFC_CONFIGURATION:
    751         if(tlv_len<LLDP_PRIVATE_8021_SUBTYPE_PFC_CONFIGURATION_LENGTH) {
    752             return hexdump;
    753         }
    754         tval=*(tptr+4);
    755         ND_PRINT((ndo, "\n\t    Willing: %d, MBC: %d, RES: %d, PFC cap:%d ",
    756         	tval >> 7, (tval >> 6) & 0x01, (tval >> 4) & 0x03, (tval & 0x0f)));
    757         ND_PRINT((ndo, "\n\t    PFC Enable"));
    758         tval=*(tptr+5);
    759         ND_PRINT((ndo, "\n\t     Priority : 0  1  2  3  4  5  6  7"));
    760         ND_PRINT((ndo, "\n\t     Value    : "));
    761         for(i=0;i<NO_OF_BITS;i++)
    762             ND_PRINT((ndo, "%-2d ", (tval >> i) & 0x01));
    763         break;
    764 
    765     case LLDP_PRIVATE_8021_SUBTYPE_APPLICATION_PRIORITY:
    766         if(tlv_len<LLDP_PRIVATE_8021_SUBTYPE_APPLICATION_PRIORITY_MIN_LENGTH) {
    767             return hexdump;
    768         }
    769         ND_PRINT((ndo, "\n\t    RES: %d", *(tptr + 4)));
    770         if(tlv_len<=LLDP_PRIVATE_8021_SUBTYPE_APPLICATION_PRIORITY_MIN_LENGTH){
    771         	return hexdump;
    772         }
    773         /*  Length of Application Priority Table */
    774         sublen=tlv_len-5;
    775         if(sublen%3!=0){
    776         	return hexdump;
    777         }
    778         i=0;
    779         ND_PRINT((ndo, "\n\t    Application Priority Table"));
    780         while(i<sublen) {
    781         	tval=*(tptr+i+5);
    782         	ND_PRINT((ndo, "\n\t      Priority: %d, RES: %d, Sel: %d",
    783         		 tval >> 5, (tval >> 3) & 0x03, (tval & 0x07)));
    784         	ND_PRINT((ndo, "Protocol ID: %d", EXTRACT_16BITS(tptr + i + 5)));
    785         	i=i+3;
    786         }
    787         break;
    788     case LLDP_PRIVATE_8021_SUBTYPE_EVB:
    789         if(tlv_len<LLDP_PRIVATE_8021_SUBTYPE_EVB_LENGTH){
    790         	return hexdump;
    791         }
    792         ND_PRINT((ndo, "\n\t    EVB Bridge Status"));
    793         tval=*(tptr+4);
    794         ND_PRINT((ndo, "\n\t      RES: %d, BGID: %d, RRCAP: %d, RRCTR: %d",
    795         	tval >> 3, (tval >> 2) & 0x01, (tval >> 1) & 0x01, tval & 0x01));
    796         ND_PRINT((ndo, "\n\t    EVB Station Status"));
    797         tval=*(tptr+5);
    798         ND_PRINT((ndo, "\n\t      RES: %d, SGID: %d, RRREQ: %d,RRSTAT: %d",
    799         	tval >> 4, (tval >> 3) & 0x01, (tval >> 2) & 0x01, tval & 0x03));
    800         tval=*(tptr+6);
    801         ND_PRINT((ndo, "\n\t    R: %d, RTE: %d, ",tval >> 5, tval & 0x1f));
    802         tval=*(tptr+7);
    803         ND_PRINT((ndo, "EVB Mode: %s [%d]",
    804         	tok2str(lldp_evb_mode_values, "unknown", tval >> 6), tval >> 6));
    805         ND_PRINT((ndo, "\n\t    ROL: %d, RWD: %d, ", (tval >> 5) & 0x01, tval & 0x1f));
    806         tval=*(tptr+8);
    807         ND_PRINT((ndo, "RES: %d, ROL: %d, RKA: %d", tval >> 6, (tval >> 5) & 0x01, tval & 0x1f));
    808         break;
    809 
    810     case LLDP_PRIVATE_8021_SUBTYPE_CDCP:
    811         if(tlv_len<LLDP_PRIVATE_8021_SUBTYPE_CDCP_MIN_LENGTH){
    812         	return hexdump;
    813         }
    814         tval=*(tptr+4);
    815         ND_PRINT((ndo, "\n\t    Role: %d, RES: %d, Scomp: %d ",
    816         	tval >> 7, (tval >> 4) & 0x07, (tval >> 3) & 0x01));
    817         ND_PRINT((ndo, "ChnCap: %d", EXTRACT_16BITS(tptr + 6) & 0x0fff));
    818         sublen=tlv_len-8;
    819         if(sublen%3!=0) {
    820         	return hexdump;
    821         }
    822         i=0;
    823         while(i<sublen) {
    824         	tval=EXTRACT_24BITS(tptr+i+8);
    825         	ND_PRINT((ndo, "\n\t    SCID: %d, SVID: %d",
    826         		tval >> 12, tval & 0x000fff));
    827         	i=i+3;
    828         }
    829         break;
    830 
    831     default:
    832         hexdump = TRUE;
    833         break;
    834     }
    835 
    836     return hexdump;
    837 }
    838 
    839 /*
    840  * Print IEEE 802.3 private extensions. (802.3bc)
    841  */
    842 static int
    843 lldp_private_8023_print(netdissect_options *ndo,
    844                         const u_char *tptr, u_int tlv_len)
    845 {
    846     int subtype, hexdump = FALSE;
    847 
    848     if (tlv_len < 4) {
    849         return hexdump;
    850     }
    851     subtype = *(tptr+3);
    852 
    853     ND_PRINT((ndo, "\n\t  %s Subtype (%u)",
    854            tok2str(lldp_8023_subtype_values, "unknown", subtype),
    855            subtype));
    856 
    857     switch (subtype) {
    858     case LLDP_PRIVATE_8023_SUBTYPE_MACPHY:
    859         if (tlv_len < 9) {
    860             return hexdump;
    861         }
    862         ND_PRINT((ndo, "\n\t    autonegotiation [%s] (0x%02x)",
    863                bittok2str(lldp_8023_autonegotiation_values, "none", *(tptr+4)),
    864                *(tptr + 4)));
    865         ND_PRINT((ndo, "\n\t    PMD autoneg capability [%s] (0x%04x)",
    866                bittok2str(lldp_pmd_capability_values,"unknown", EXTRACT_16BITS(tptr+5)),
    867                EXTRACT_16BITS(tptr + 5)));
    868         ND_PRINT((ndo, "\n\t    MAU type %s (0x%04x)",
    869                tok2str(lldp_mau_types_values, "unknown", EXTRACT_16BITS(tptr+7)),
    870                EXTRACT_16BITS(tptr + 7)));
    871         break;
    872 
    873     case LLDP_PRIVATE_8023_SUBTYPE_MDIPOWER:
    874         if (tlv_len < 7) {
    875             return hexdump;
    876         }
    877         ND_PRINT((ndo, "\n\t    MDI power support [%s], power pair %s, power class %s",
    878                bittok2str(lldp_mdi_values, "none", *(tptr+4)),
    879                tok2str(lldp_mdi_power_pairs_values, "unknown", *(tptr+5)),
    880                tok2str(lldp_mdi_power_class_values, "unknown", *(tptr + 6))));
    881         break;
    882 
    883     case LLDP_PRIVATE_8023_SUBTYPE_LINKAGGR:
    884         if (tlv_len < 9) {
    885             return hexdump;
    886         }
    887         ND_PRINT((ndo, "\n\t    aggregation status [%s], aggregation port ID %u",
    888                bittok2str(lldp_aggregation_values, "none", *(tptr+4)),
    889                EXTRACT_32BITS(tptr + 5)));
    890         break;
    891 
    892     case LLDP_PRIVATE_8023_SUBTYPE_MTU:
    893         ND_PRINT((ndo, "\n\t    MTU size %u", EXTRACT_16BITS(tptr + 4)));
    894         break;
    895 
    896     default:
    897         hexdump = TRUE;
    898         break;
    899     }
    900 
    901     return hexdump;
    902 }
    903 
    904 /*
    905  * Extract 34bits of latitude/longitude coordinates.
    906  */
    907 static uint64_t
    908 lldp_extract_latlon(const u_char *tptr)
    909 {
    910     uint64_t latlon;
    911 
    912     latlon = *tptr & 0x3;
    913     latlon = (latlon << 32) | EXTRACT_32BITS(tptr+1);
    914 
    915     return latlon;
    916 }
    917 
    918 /*
    919  * Print private TIA extensions.
    920  */
    921 static int
    922 lldp_private_tia_print(netdissect_options *ndo,
    923                        const u_char *tptr, u_int tlv_len)
    924 {
    925     int subtype, hexdump = FALSE;
    926     uint8_t location_format;
    927     uint16_t power_val;
    928     u_int lci_len;
    929     uint8_t ca_type, ca_len;
    930 
    931     if (tlv_len < 4) {
    932         return hexdump;
    933     }
    934     subtype = *(tptr+3);
    935 
    936     ND_PRINT((ndo, "\n\t  %s Subtype (%u)",
    937            tok2str(lldp_tia_subtype_values, "unknown", subtype),
    938            subtype));
    939 
    940     switch (subtype) {
    941     case LLDP_PRIVATE_TIA_SUBTYPE_CAPABILITIES:
    942         if (tlv_len < 7) {
    943             return hexdump;
    944         }
    945         ND_PRINT((ndo, "\n\t    Media capabilities [%s] (0x%04x)",
    946                bittok2str(lldp_tia_capabilities_values, "none",
    947                           EXTRACT_16BITS(tptr + 4)), EXTRACT_16BITS(tptr + 4)));
    948         ND_PRINT((ndo, "\n\t    Device type [%s] (0x%02x)",
    949                tok2str(lldp_tia_device_type_values, "unknown", *(tptr+6)),
    950                *(tptr + 6)));
    951         break;
    952 
    953     case LLDP_PRIVATE_TIA_SUBTYPE_NETWORK_POLICY:
    954         if (tlv_len < 8) {
    955             return hexdump;
    956         }
    957         ND_PRINT((ndo, "\n\t    Application type [%s] (0x%02x)",
    958                tok2str(lldp_tia_application_type_values, "none", *(tptr+4)),
    959                *(tptr + 4)));
    960         ND_PRINT((ndo, ", Flags [%s]", bittok2str(
    961                    lldp_tia_network_policy_bits_values, "none", *(tptr + 5))));
    962         ND_PRINT((ndo, "\n\t    Vlan id %u",
    963                LLDP_EXTRACT_NETWORK_POLICY_VLAN(EXTRACT_16BITS(tptr + 5))));
    964         ND_PRINT((ndo, ", L2 priority %u",
    965                LLDP_EXTRACT_NETWORK_POLICY_L2_PRIORITY(EXTRACT_16BITS(tptr + 6))));
    966         ND_PRINT((ndo, ", DSCP value %u",
    967                LLDP_EXTRACT_NETWORK_POLICY_DSCP(EXTRACT_16BITS(tptr + 6))));
    968         break;
    969 
    970     case LLDP_PRIVATE_TIA_SUBTYPE_LOCAL_ID:
    971         if (tlv_len < 5) {
    972             return hexdump;
    973         }
    974         location_format = *(tptr+4);
    975         ND_PRINT((ndo, "\n\t    Location data format %s (0x%02x)",
    976                tok2str(lldp_tia_location_data_format_values, "unknown", location_format),
    977                location_format));
    978 
    979         switch (location_format) {
    980         case LLDP_TIA_LOCATION_DATA_FORMAT_COORDINATE_BASED:
    981             if (tlv_len < 21) {
    982                 return hexdump;
    983             }
    984             ND_PRINT((ndo, "\n\t    Latitude resolution %u, latitude value %" PRIu64,
    985                    (*(tptr + 5) >> 2), lldp_extract_latlon(tptr + 5)));
    986             ND_PRINT((ndo, "\n\t    Longitude resolution %u, longitude value %" PRIu64,
    987                    (*(tptr + 10) >> 2), lldp_extract_latlon(tptr + 10)));
    988             ND_PRINT((ndo, "\n\t    Altitude type %s (%u)",
    989                    tok2str(lldp_tia_location_altitude_type_values, "unknown",(*(tptr+15)>>4)),
    990                    (*(tptr + 15) >> 4)));
    991             ND_PRINT((ndo, "\n\t    Altitude resolution %u, altitude value 0x%x",
    992                    (EXTRACT_16BITS(tptr+15)>>6)&0x3f,
    993                    ((EXTRACT_32BITS(tptr + 16) & 0x3fffffff))));
    994             ND_PRINT((ndo, "\n\t    Datum %s (0x%02x)",
    995                    tok2str(lldp_tia_location_datum_type_values, "unknown", *(tptr+20)),
    996                    *(tptr + 20)));
    997             break;
    998 
    999         case LLDP_TIA_LOCATION_DATA_FORMAT_CIVIC_ADDRESS:
   1000             if (tlv_len < 6) {
   1001                 return hexdump;
   1002             }
   1003             lci_len = *(tptr+5);
   1004             if (lci_len < 3) {
   1005                 return hexdump;
   1006             }
   1007             if (tlv_len < 7+lci_len) {
   1008                 return hexdump;
   1009             }
   1010             ND_PRINT((ndo, "\n\t    LCI length %u, LCI what %s (0x%02x), Country-code ",
   1011                    lci_len,
   1012                    tok2str(lldp_tia_location_lci_what_values, "unknown", *(tptr+6)),
   1013                    *(tptr + 6)));
   1014 
   1015             /* Country code */
   1016             safeputs(ndo, tptr + 7, 2);
   1017 
   1018             lci_len = lci_len-3;
   1019             tptr = tptr + 9;
   1020 
   1021             /* Decode each civic address element */
   1022             while (lci_len > 0) {
   1023                 if (lci_len < 2) {
   1024                     return hexdump;
   1025                 }
   1026 		ca_type = *(tptr);
   1027                 ca_len = *(tptr+1);
   1028 
   1029 		tptr += 2;
   1030                 lci_len -= 2;
   1031 
   1032                 ND_PRINT((ndo, "\n\t      CA type \'%s\' (%u), length %u: ",
   1033                        tok2str(lldp_tia_location_lci_catype_values, "unknown", ca_type),
   1034                        ca_type, ca_len));
   1035 
   1036 		/* basic sanity check */
   1037 		if ( ca_type == 0 || ca_len == 0) {
   1038                     return hexdump;
   1039 		}
   1040 		if (lci_len < ca_len) {
   1041 		    return hexdump;
   1042 		}
   1043 
   1044                 safeputs(ndo, tptr, ca_len);
   1045                 tptr += ca_len;
   1046                 lci_len -= ca_len;
   1047             }
   1048             break;
   1049 
   1050         case LLDP_TIA_LOCATION_DATA_FORMAT_ECS_ELIN:
   1051             ND_PRINT((ndo, "\n\t    ECS ELIN id "));
   1052             safeputs(ndo, tptr + 5, tlv_len - 5);
   1053             break;
   1054 
   1055         default:
   1056             ND_PRINT((ndo, "\n\t    Location ID "));
   1057             print_unknown_data(ndo, tptr + 5, "\n\t      ", tlv_len - 5);
   1058         }
   1059         break;
   1060 
   1061     case LLDP_PRIVATE_TIA_SUBTYPE_EXTENDED_POWER_MDI:
   1062         if (tlv_len < 7) {
   1063             return hexdump;
   1064         }
   1065         ND_PRINT((ndo, "\n\t    Power type [%s]",
   1066                (*(tptr + 4) & 0xC0 >> 6) ? "PD device" : "PSE device"));
   1067         ND_PRINT((ndo, ", Power source [%s]",
   1068                tok2str(lldp_tia_power_source_values, "none", (*(tptr + 4) & 0x30) >> 4)));
   1069         ND_PRINT((ndo, "\n\t    Power priority [%s] (0x%02x)",
   1070                tok2str(lldp_tia_power_priority_values, "none", *(tptr+4)&0x0f),
   1071                *(tptr + 4) & 0x0f));
   1072         power_val = EXTRACT_16BITS(tptr+5);
   1073         if (power_val < LLDP_TIA_POWER_VAL_MAX) {
   1074             ND_PRINT((ndo, ", Power %.1f Watts", ((float)power_val) / 10));
   1075         } else {
   1076             ND_PRINT((ndo, ", Power %u (Reserved)", power_val));
   1077         }
   1078         break;
   1079 
   1080     case LLDP_PRIVATE_TIA_SUBTYPE_INVENTORY_HARDWARE_REV:
   1081     case LLDP_PRIVATE_TIA_SUBTYPE_INVENTORY_FIRMWARE_REV:
   1082     case LLDP_PRIVATE_TIA_SUBTYPE_INVENTORY_SOFTWARE_REV:
   1083     case LLDP_PRIVATE_TIA_SUBTYPE_INVENTORY_SERIAL_NUMBER:
   1084     case LLDP_PRIVATE_TIA_SUBTYPE_INVENTORY_MANUFACTURER_NAME:
   1085     case LLDP_PRIVATE_TIA_SUBTYPE_INVENTORY_MODEL_NAME:
   1086     case LLDP_PRIVATE_TIA_SUBTYPE_INVENTORY_ASSET_ID:
   1087         ND_PRINT((ndo, "\n\t  %s ",
   1088                tok2str(lldp_tia_inventory_values, "unknown", subtype)));
   1089         safeputs(ndo, tptr + 4, tlv_len - 4);
   1090         break;
   1091 
   1092     default:
   1093         hexdump = TRUE;
   1094         break;
   1095     }
   1096 
   1097     return hexdump;
   1098 }
   1099 
   1100 /*
   1101  * Print DCBX Protocol fields (V 1.01).
   1102  */
   1103 static int
   1104 lldp_private_dcbx_print(netdissect_options *ndo,
   1105                         const u_char *pptr, u_int len)
   1106 {
   1107     int subtype, hexdump = FALSE;
   1108     uint8_t tval;
   1109     uint16_t tlv;
   1110     uint32_t i, pgval, uval;
   1111     u_int tlen, tlv_type, tlv_len;
   1112     const u_char *tptr, *mptr;
   1113 
   1114     if (len < 4) {
   1115         return hexdump;
   1116     }
   1117     subtype = *(pptr+3);
   1118 
   1119     ND_PRINT((ndo, "\n\t  %s Subtype (%u)",
   1120            tok2str(lldp_dcbx_subtype_values, "unknown", subtype),
   1121            subtype));
   1122 
   1123     /* by passing old version */
   1124     if (subtype == LLDP_DCBX_SUBTYPE_1)
   1125 	return TRUE;
   1126 
   1127     tptr = pptr + 4;
   1128     tlen = len - 4;
   1129 
   1130     while (tlen >= sizeof(tlv)) {
   1131 
   1132         ND_TCHECK2(*tptr, sizeof(tlv));
   1133 
   1134         tlv = EXTRACT_16BITS(tptr);
   1135 
   1136         tlv_type = LLDP_EXTRACT_TYPE(tlv);
   1137         tlv_len = LLDP_EXTRACT_LEN(tlv);
   1138         hexdump = FALSE;
   1139 
   1140         tlen -= sizeof(tlv);
   1141         tptr += sizeof(tlv);
   1142 
   1143         /* loop check */
   1144         if (!tlv_type || !tlv_len) {
   1145             break;
   1146         }
   1147 
   1148         ND_TCHECK2(*tptr, tlv_len);
   1149         if (tlen < tlv_len) {
   1150             goto trunc;
   1151         }
   1152 
   1153 	/* decode every tlv */
   1154         switch (tlv_type) {
   1155         case LLDP_DCBX_CONTROL_TLV:
   1156             if (tlv_len < 10) {
   1157                 goto trunc;
   1158             }
   1159 	    ND_PRINT((ndo, "\n\t    Control - Protocol Control (type 0x%x, length %d)",
   1160 		LLDP_DCBX_CONTROL_TLV, tlv_len));
   1161 	    ND_PRINT((ndo, "\n\t      Oper_Version: %d", *tptr));
   1162 	    ND_PRINT((ndo, "\n\t      Max_Version: %d", *(tptr + 1)));
   1163 	    ND_PRINT((ndo, "\n\t      Sequence Number: %d", EXTRACT_32BITS(tptr + 2)));
   1164 	    ND_PRINT((ndo, "\n\t      Acknowledgement Number: %d",
   1165 					EXTRACT_32BITS(tptr + 6)));
   1166 	    break;
   1167         case LLDP_DCBX_PRIORITY_GROUPS_TLV:
   1168             if (tlv_len < 17) {
   1169                 goto trunc;
   1170             }
   1171 	    ND_PRINT((ndo, "\n\t    Feature - Priority Group (type 0x%x, length %d)",
   1172 		LLDP_DCBX_PRIORITY_GROUPS_TLV, tlv_len));
   1173 	    ND_PRINT((ndo, "\n\t      Oper_Version: %d", *tptr));
   1174 	    ND_PRINT((ndo, "\n\t      Max_Version: %d", *(tptr + 1)));
   1175 	    ND_PRINT((ndo, "\n\t      Info block(0x%02X): ", *(tptr + 2)));
   1176 	    tval = *(tptr+2);
   1177 	    ND_PRINT((ndo, "Enable bit: %d, Willing bit: %d, Error Bit: %d",
   1178 		(tval &  0x80) ? 1 : 0, (tval &  0x40) ? 1 : 0,
   1179 		(tval &  0x20) ? 1 : 0));
   1180 	    ND_PRINT((ndo, "\n\t      SubType: %d", *(tptr + 3)));
   1181 	    ND_PRINT((ndo, "\n\t      Priority Allocation"));
   1182 
   1183 	    /*
   1184 	     * Array of 8 4-bit priority group ID values; we fetch all
   1185 	     * 32 bits and extract each nibble.
   1186 	     */
   1187 	    pgval = EXTRACT_32BITS(tptr+4);
   1188 	    for (i = 0; i <= 7; i++) {
   1189 		ND_PRINT((ndo, "\n\t          PgId_%d: %d",
   1190 			i, (pgval >> (28 - 4 * i)) & 0xF));
   1191 	    }
   1192 	    ND_PRINT((ndo, "\n\t      Priority Group Allocation"));
   1193 	    for (i = 0; i <= 7; i++)
   1194 		ND_PRINT((ndo, "\n\t          Pg percentage[%d]: %d", i, *(tptr + 8 + i)));
   1195 	    ND_PRINT((ndo, "\n\t      NumTCsSupported: %d", *(tptr + 8 + 8)));
   1196 	    break;
   1197         case LLDP_DCBX_PRIORITY_FLOW_CONTROL_TLV:
   1198             if (tlv_len < 6) {
   1199                 goto trunc;
   1200             }
   1201 	    ND_PRINT((ndo, "\n\t    Feature - Priority Flow Control"));
   1202 	    ND_PRINT((ndo, " (type 0x%x, length %d)",
   1203 		LLDP_DCBX_PRIORITY_FLOW_CONTROL_TLV, tlv_len));
   1204 	    ND_PRINT((ndo, "\n\t      Oper_Version: %d", *tptr));
   1205 	    ND_PRINT((ndo, "\n\t      Max_Version: %d", *(tptr + 1)));
   1206 	    ND_PRINT((ndo, "\n\t      Info block(0x%02X): ", *(tptr + 2)));
   1207 	    tval = *(tptr+2);
   1208 	    ND_PRINT((ndo, "Enable bit: %d, Willing bit: %d, Error Bit: %d",
   1209 		(tval &  0x80) ? 1 : 0, (tval &  0x40) ? 1 : 0,
   1210 		(tval &  0x20) ? 1 : 0));
   1211 	    ND_PRINT((ndo, "\n\t      SubType: %d", *(tptr + 3)));
   1212 	    tval = *(tptr+4);
   1213 	    ND_PRINT((ndo, "\n\t      PFC Config (0x%02X)", *(tptr + 4)));
   1214 	    for (i = 0; i <= 7; i++)
   1215 		ND_PRINT((ndo, "\n\t          Priority Bit %d: %s",
   1216 		    i, (tval & (1 << i)) ? "Enabled" : "Disabled"));
   1217 	    ND_PRINT((ndo, "\n\t      NumTCPFCSupported: %d", *(tptr + 5)));
   1218 	    break;
   1219         case LLDP_DCBX_APPLICATION_TLV:
   1220             if (tlv_len < 4) {
   1221                 goto trunc;
   1222             }
   1223 	    ND_PRINT((ndo, "\n\t    Feature - Application (type 0x%x, length %d)",
   1224 		LLDP_DCBX_APPLICATION_TLV, tlv_len));
   1225 	    ND_PRINT((ndo, "\n\t      Oper_Version: %d", *tptr));
   1226 	    ND_PRINT((ndo, "\n\t      Max_Version: %d", *(tptr + 1)));
   1227 	    ND_PRINT((ndo, "\n\t      Info block(0x%02X): ", *(tptr + 2)));
   1228 	    tval = *(tptr+2);
   1229 	    ND_PRINT((ndo, "Enable bit: %d, Willing bit: %d, Error Bit: %d",
   1230 		(tval &  0x80) ? 1 : 0, (tval &  0x40) ? 1 : 0,
   1231 		(tval &  0x20) ? 1 : 0));
   1232 	    ND_PRINT((ndo, "\n\t      SubType: %d", *(tptr + 3)));
   1233 	    tval = tlv_len - 4;
   1234 	    mptr = tptr + 4;
   1235 	    while (tval >= 6) {
   1236 		ND_PRINT((ndo, "\n\t      Application Value"));
   1237 		ND_PRINT((ndo, "\n\t          Application Protocol ID: 0x%04x",
   1238 			EXTRACT_16BITS(mptr)));
   1239 		uval = EXTRACT_24BITS(mptr+2);
   1240 		ND_PRINT((ndo, "\n\t          SF (0x%x) Application Protocol ID is %s",
   1241 			(uval >> 22),
   1242 			(uval >> 22) ? "Socket Number" : "L2 EtherType"));
   1243 		ND_PRINT((ndo, "\n\t          OUI: 0x%06x", uval & 0x3fffff));
   1244 		ND_PRINT((ndo, "\n\t          User Priority Map: 0x%02x", *(mptr + 5)));
   1245 		tval = tval - 6;
   1246 		mptr = mptr + 6;
   1247 	    }
   1248 	    break;
   1249 	default:
   1250 	    hexdump = TRUE;
   1251 	    break;
   1252 	}
   1253 
   1254         /* do we also want to see a hex dump ? */
   1255         if (ndo->ndo_vflag > 1 || (ndo->ndo_vflag && hexdump)) {
   1256 	    print_unknown_data(ndo, tptr, "\n\t    ", tlv_len);
   1257         }
   1258 
   1259         tlen -= tlv_len;
   1260         tptr += tlv_len;
   1261     }
   1262 
   1263  trunc:
   1264     return hexdump;
   1265 }
   1266 
   1267 static char *
   1268 lldp_network_addr_print(netdissect_options *ndo, const u_char *tptr, u_int len)
   1269 {
   1270     uint8_t af;
   1271     static char buf[BUFSIZE];
   1272     const char * (*pfunc)(netdissect_options *, const u_char *);
   1273 
   1274     if (len < 1)
   1275       return NULL;
   1276     len--;
   1277     af = *tptr;
   1278     switch (af) {
   1279     case AFNUM_INET:
   1280         if (len < 4)
   1281           return NULL;
   1282         pfunc = getname;
   1283         break;
   1284 #ifdef INET6
   1285     case AFNUM_INET6:
   1286         if (len < 16)
   1287           return NULL;
   1288         pfunc = getname6;
   1289         break;
   1290 #endif
   1291     case AFNUM_802:
   1292         if (len < 6)
   1293           return NULL;
   1294         pfunc = etheraddr_string;
   1295         break;
   1296     default:
   1297         pfunc = NULL;
   1298         break;
   1299     }
   1300 
   1301     if (!pfunc) {
   1302         snprintf(buf, sizeof(buf), "AFI %s (%u), no AF printer !",
   1303                  tok2str(af_values, "Unknown", af), af);
   1304     } else {
   1305         snprintf(buf, sizeof(buf), "AFI %s (%u): %s",
   1306                  tok2str(af_values, "Unknown", af), af, (*pfunc)(ndo, tptr+1));
   1307     }
   1308 
   1309     return buf;
   1310 }
   1311 
   1312 static int
   1313 lldp_mgmt_addr_tlv_print(netdissect_options *ndo,
   1314                          const u_char *pptr, u_int len)
   1315 {
   1316     uint8_t mgmt_addr_len, intf_num_subtype, oid_len;
   1317     const u_char *tptr;
   1318     u_int tlen;
   1319     char *mgmt_addr;
   1320 
   1321     tlen = len;
   1322     tptr = pptr;
   1323 
   1324     if (tlen < 1) {
   1325         return 0;
   1326     }
   1327     mgmt_addr_len = *tptr++;
   1328     tlen--;
   1329 
   1330     if (tlen < mgmt_addr_len) {
   1331         return 0;
   1332     }
   1333 
   1334     mgmt_addr = lldp_network_addr_print(ndo, tptr, mgmt_addr_len);
   1335     if (mgmt_addr == NULL) {
   1336         return 0;
   1337     }
   1338     ND_PRINT((ndo, "\n\t  Management Address length %u, %s",
   1339            mgmt_addr_len, mgmt_addr));
   1340     tptr += mgmt_addr_len;
   1341     tlen -= mgmt_addr_len;
   1342 
   1343     if (tlen < LLDP_INTF_NUM_LEN) {
   1344         return 0;
   1345     }
   1346 
   1347     intf_num_subtype = *tptr;
   1348     ND_PRINT((ndo, "\n\t  %s Interface Numbering (%u): %u",
   1349            tok2str(lldp_intf_numb_subtype_values, "Unknown", intf_num_subtype),
   1350            intf_num_subtype,
   1351            EXTRACT_32BITS(tptr + 1)));
   1352 
   1353     tptr += LLDP_INTF_NUM_LEN;
   1354     tlen -= LLDP_INTF_NUM_LEN;
   1355 
   1356     /*
   1357      * The OID is optional.
   1358      */
   1359     if (tlen) {
   1360         oid_len = *tptr;
   1361 
   1362         if (tlen < oid_len) {
   1363             return 0;
   1364         }
   1365         if (oid_len) {
   1366             ND_PRINT((ndo, "\n\t  OID length %u", oid_len));
   1367             safeputs(ndo, tptr + 1, oid_len);
   1368         }
   1369     }
   1370 
   1371     return 1;
   1372 }
   1373 
   1374 void
   1375 lldp_print(netdissect_options *ndo,
   1376            register const u_char *pptr, register u_int len)
   1377 {
   1378     uint8_t subtype;
   1379     uint16_t tlv, cap, ena_cap;
   1380     u_int oui, tlen, hexdump, tlv_type, tlv_len;
   1381     const u_char *tptr;
   1382     char *network_addr;
   1383 
   1384     tptr = pptr;
   1385     tlen = len;
   1386 
   1387     ND_PRINT((ndo, "LLDP, length %u", len));
   1388 
   1389     while (tlen >= sizeof(tlv)) {
   1390 
   1391         ND_TCHECK2(*tptr, sizeof(tlv));
   1392 
   1393         tlv = EXTRACT_16BITS(tptr);
   1394 
   1395         tlv_type = LLDP_EXTRACT_TYPE(tlv);
   1396         tlv_len = LLDP_EXTRACT_LEN(tlv);
   1397         hexdump = FALSE;
   1398 
   1399         tlen -= sizeof(tlv);
   1400         tptr += sizeof(tlv);
   1401 
   1402         if (ndo->ndo_vflag) {
   1403             ND_PRINT((ndo, "\n\t%s TLV (%u), length %u",
   1404                    tok2str(lldp_tlv_values, "Unknown", tlv_type),
   1405                    tlv_type, tlv_len));
   1406         }
   1407 
   1408         /* infinite loop check */
   1409         if (!tlv_type || !tlv_len) {
   1410             break;
   1411         }
   1412 
   1413         ND_TCHECK2(*tptr, tlv_len);
   1414         if (tlen < tlv_len) {
   1415             goto trunc;
   1416         }
   1417 
   1418         switch (tlv_type) {
   1419 
   1420         case LLDP_CHASSIS_ID_TLV:
   1421             if (ndo->ndo_vflag) {
   1422                 if (tlv_len < 2) {
   1423                     goto trunc;
   1424                 }
   1425                 subtype = *tptr;
   1426                 ND_PRINT((ndo, "\n\t  Subtype %s (%u): ",
   1427                        tok2str(lldp_chassis_subtype_values, "Unknown", subtype),
   1428                        subtype));
   1429 
   1430                 switch (subtype) {
   1431                 case LLDP_CHASSIS_MAC_ADDR_SUBTYPE:
   1432                     if (tlv_len < 1+6) {
   1433                         goto trunc;
   1434                     }
   1435                     ND_PRINT((ndo, "%s", etheraddr_string(ndo, tptr + 1)));
   1436                     break;
   1437 
   1438                 case LLDP_CHASSIS_INTF_NAME_SUBTYPE: /* fall through */
   1439                 case LLDP_CHASSIS_LOCAL_SUBTYPE:
   1440                 case LLDP_CHASSIS_CHASSIS_COMP_SUBTYPE:
   1441                 case LLDP_CHASSIS_INTF_ALIAS_SUBTYPE:
   1442                 case LLDP_CHASSIS_PORT_COMP_SUBTYPE:
   1443                     safeputs(ndo, tptr + 1, tlv_len - 1);
   1444                     break;
   1445 
   1446                 case LLDP_CHASSIS_NETWORK_ADDR_SUBTYPE:
   1447                     network_addr = lldp_network_addr_print(ndo, tptr+1, tlv_len-1);
   1448                     if (network_addr == NULL) {
   1449                         goto trunc;
   1450                     }
   1451                     ND_PRINT((ndo, "%s", network_addr));
   1452                     break;
   1453 
   1454                 default:
   1455                     hexdump = TRUE;
   1456                     break;
   1457                 }
   1458             }
   1459             break;
   1460 
   1461         case LLDP_PORT_ID_TLV:
   1462             if (ndo->ndo_vflag) {
   1463                 if (tlv_len < 2) {
   1464                     goto trunc;
   1465                 }
   1466                 subtype = *tptr;
   1467                 ND_PRINT((ndo, "\n\t  Subtype %s (%u): ",
   1468                        tok2str(lldp_port_subtype_values, "Unknown", subtype),
   1469                        subtype));
   1470 
   1471                 switch (subtype) {
   1472                 case LLDP_PORT_MAC_ADDR_SUBTYPE:
   1473                     if (tlv_len < 1+6) {
   1474                         goto trunc;
   1475                     }
   1476                     ND_PRINT((ndo, "%s", etheraddr_string(ndo, tptr + 1)));
   1477                     break;
   1478 
   1479                 case LLDP_PORT_INTF_NAME_SUBTYPE: /* fall through */
   1480                 case LLDP_PORT_LOCAL_SUBTYPE:
   1481                 case LLDP_PORT_AGENT_CIRC_ID_SUBTYPE:
   1482                 case LLDP_PORT_INTF_ALIAS_SUBTYPE:
   1483                 case LLDP_PORT_PORT_COMP_SUBTYPE:
   1484                     safeputs(ndo, tptr + 1, tlv_len - 1);
   1485                     break;
   1486 
   1487                 case LLDP_PORT_NETWORK_ADDR_SUBTYPE:
   1488                     network_addr = lldp_network_addr_print(ndo, tptr+1, tlv_len-1);
   1489                     if (network_addr == NULL) {
   1490                         goto trunc;
   1491                     }
   1492                     ND_PRINT((ndo, "%s", network_addr));
   1493                     break;
   1494 
   1495                 default:
   1496                     hexdump = TRUE;
   1497                     break;
   1498                 }
   1499             }
   1500             break;
   1501 
   1502         case LLDP_TTL_TLV:
   1503             if (ndo->ndo_vflag) {
   1504                 if (tlv_len < 2) {
   1505                     goto trunc;
   1506                 }
   1507                 ND_PRINT((ndo, ": TTL %us", EXTRACT_16BITS(tptr)));
   1508             }
   1509             break;
   1510 
   1511         case LLDP_PORT_DESCR_TLV:
   1512             if (ndo->ndo_vflag) {
   1513                 ND_PRINT((ndo, ": "));
   1514                 safeputs(ndo, tptr, tlv_len);
   1515             }
   1516             break;
   1517 
   1518         case LLDP_SYSTEM_NAME_TLV:
   1519             /*
   1520              * The system name is also print in non-verbose mode
   1521              * similar to the CDP printer.
   1522              */
   1523             ND_PRINT((ndo, ": "));
   1524             safeputs(ndo, tptr, tlv_len);
   1525             break;
   1526 
   1527         case LLDP_SYSTEM_DESCR_TLV:
   1528             if (ndo->ndo_vflag) {
   1529                 ND_PRINT((ndo, "\n\t  "));
   1530                 safeputs(ndo, tptr, tlv_len);
   1531             }
   1532             break;
   1533 
   1534         case LLDP_SYSTEM_CAP_TLV:
   1535             if (ndo->ndo_vflag) {
   1536                 /*
   1537                  * XXX - IEEE Std 802.1AB-2009 says the first octet
   1538                  * if a chassis ID subtype, with the system
   1539                  * capabilities and enabled capabilities following
   1540                  * it.
   1541                  */
   1542                 if (tlv_len < 4) {
   1543                     goto trunc;
   1544                 }
   1545                 cap = EXTRACT_16BITS(tptr);
   1546                 ena_cap = EXTRACT_16BITS(tptr+2);
   1547                 ND_PRINT((ndo, "\n\t  System  Capabilities [%s] (0x%04x)",
   1548                        bittok2str(lldp_cap_values, "none", cap), cap));
   1549                 ND_PRINT((ndo, "\n\t  Enabled Capabilities [%s] (0x%04x)",
   1550                        bittok2str(lldp_cap_values, "none", ena_cap), ena_cap));
   1551             }
   1552             break;
   1553 
   1554         case LLDP_MGMT_ADDR_TLV:
   1555             if (ndo->ndo_vflag) {
   1556                 if (!lldp_mgmt_addr_tlv_print(ndo, tptr, tlv_len)) {
   1557                     goto trunc;
   1558                 }
   1559             }
   1560             break;
   1561 
   1562         case LLDP_PRIVATE_TLV:
   1563             if (ndo->ndo_vflag) {
   1564                 if (tlv_len < 3) {
   1565                     goto trunc;
   1566                 }
   1567                 oui = EXTRACT_24BITS(tptr);
   1568                 ND_PRINT((ndo, ": OUI %s (0x%06x)", tok2str(oui_values, "Unknown", oui), oui));
   1569 
   1570                 switch (oui) {
   1571                 case OUI_IEEE_8021_PRIVATE:
   1572                     hexdump = lldp_private_8021_print(ndo, tptr, tlv_len);
   1573                     break;
   1574                 case OUI_IEEE_8023_PRIVATE:
   1575                     hexdump = lldp_private_8023_print(ndo, tptr, tlv_len);
   1576                     break;
   1577                 case OUI_TIA:
   1578                     hexdump = lldp_private_tia_print(ndo, tptr, tlv_len);
   1579                     break;
   1580                 case OUI_DCBX:
   1581                     hexdump = lldp_private_dcbx_print(ndo, tptr, tlv_len);
   1582                     break;
   1583                 default:
   1584                     hexdump = TRUE;
   1585                     break;
   1586                 }
   1587             }
   1588             break;
   1589 
   1590         default:
   1591             hexdump = TRUE;
   1592             break;
   1593         }
   1594 
   1595         /* do we also want to see a hex dump ? */
   1596         if (ndo->ndo_vflag > 1 || (ndo->ndo_vflag && hexdump)) {
   1597             print_unknown_data(ndo, tptr, "\n\t  ", tlv_len);
   1598         }
   1599 
   1600         tlen -= tlv_len;
   1601         tptr += tlv_len;
   1602     }
   1603     return;
   1604  trunc:
   1605     ND_PRINT((ndo, "\n\t[|LLDP]"));
   1606 }
   1607 
   1608 /*
   1609  * Local Variables:
   1610  * c-style: whitesmith
   1611  * c-basic-offset: 4
   1612  * End:
   1613  */
   1614