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