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