10f74e101Schristos /* 20f74e101Schristos * Copyright (c) 1998-2007 The TCPDUMP project 30f74e101Schristos * 40f74e101Schristos * Redistribution and use in source and binary forms, with or without 50f74e101Schristos * modification, are permitted provided that: (1) source code 60f74e101Schristos * distributions retain the above copyright notice and this paragraph 70f74e101Schristos * in its entirety, and (2) distributions including binary code include 80f74e101Schristos * the above copyright notice and this paragraph in its entirety in 90f74e101Schristos * the documentation or other materials provided with the distribution. 100f74e101Schristos * THIS SOFTWARE IS PROVIDED ``AS IS'' AND 110f74e101Schristos * WITHOUT ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, WITHOUT 120f74e101Schristos * LIMITATION, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS 130f74e101Schristos * FOR A PARTICULAR PURPOSE. 140f74e101Schristos * 1572c96ff3Schristos * Original code by Hannes Gredler (hannes@gredler.at) 160f74e101Schristos * IEEE and TIA extensions by Carles Kishimoto <carles.kishimoto@gmail.com> 170e9868baSchristos * DCBX extensions by Kaladhar Musunuru <kaladharm@sourceforge.net> 180f74e101Schristos */ 190f74e101Schristos 20dc860a36Sspz /* \summary: IEEE 802.1ab Link Layer Discovery Protocol (LLDP) printer */ 21dc860a36Sspz 2211b3aaa1Schristos #include <sys/cdefs.h> 230f74e101Schristos #ifndef lint 24*26ba0b50Schristos __RCSID("$NetBSD: print-lldp.c,v 1.11 2024/09/02 16:15:31 christos Exp $"); 250f74e101Schristos #endif 260f74e101Schristos 27c74ad251Schristos #include <config.h> 280f74e101Schristos 29c74ad251Schristos #include "netdissect-stdinc.h" 300f74e101Schristos 310f74e101Schristos #include <stdio.h> 320f74e101Schristos 33fdccd7e4Schristos #include "netdissect.h" 340f74e101Schristos #include "extract.h" 350f74e101Schristos #include "addrtoname.h" 360f74e101Schristos #include "af.h" 370f74e101Schristos #include "oui.h" 380f74e101Schristos 390f74e101Schristos #define LLDP_EXTRACT_TYPE(x) (((x)&0xfe00)>>9) 400f74e101Schristos #define LLDP_EXTRACT_LEN(x) ((x)&0x01ff) 410f74e101Schristos 420f74e101Schristos /* 430f74e101Schristos * TLV type codes 440f74e101Schristos */ 450f74e101Schristos #define LLDP_END_TLV 0 460f74e101Schristos #define LLDP_CHASSIS_ID_TLV 1 470f74e101Schristos #define LLDP_PORT_ID_TLV 2 480f74e101Schristos #define LLDP_TTL_TLV 3 490f74e101Schristos #define LLDP_PORT_DESCR_TLV 4 500f74e101Schristos #define LLDP_SYSTEM_NAME_TLV 5 510f74e101Schristos #define LLDP_SYSTEM_DESCR_TLV 6 520f74e101Schristos #define LLDP_SYSTEM_CAP_TLV 7 530f74e101Schristos #define LLDP_MGMT_ADDR_TLV 8 540f74e101Schristos #define LLDP_PRIVATE_TLV 127 550f74e101Schristos 560f74e101Schristos static const struct tok lldp_tlv_values[] = { 570f74e101Schristos { LLDP_END_TLV, "End" }, 580f74e101Schristos { LLDP_CHASSIS_ID_TLV, "Chassis ID" }, 590f74e101Schristos { LLDP_PORT_ID_TLV, "Port ID" }, 600f74e101Schristos { LLDP_TTL_TLV, "Time to Live" }, 610f74e101Schristos { LLDP_PORT_DESCR_TLV, "Port Description" }, 620f74e101Schristos { LLDP_SYSTEM_NAME_TLV, "System Name" }, 630f74e101Schristos { LLDP_SYSTEM_DESCR_TLV, "System Description" }, 640f74e101Schristos { LLDP_SYSTEM_CAP_TLV, "System Capabilities" }, 650f74e101Schristos { LLDP_MGMT_ADDR_TLV, "Management Address" }, 660f74e101Schristos { LLDP_PRIVATE_TLV, "Organization specific" }, 670f74e101Schristos { 0, NULL} 680f74e101Schristos }; 690f74e101Schristos 700f74e101Schristos /* 710f74e101Schristos * Chassis ID subtypes 720f74e101Schristos */ 730f74e101Schristos #define LLDP_CHASSIS_CHASSIS_COMP_SUBTYPE 1 740f74e101Schristos #define LLDP_CHASSIS_INTF_ALIAS_SUBTYPE 2 750f74e101Schristos #define LLDP_CHASSIS_PORT_COMP_SUBTYPE 3 760f74e101Schristos #define LLDP_CHASSIS_MAC_ADDR_SUBTYPE 4 770f74e101Schristos #define LLDP_CHASSIS_NETWORK_ADDR_SUBTYPE 5 780f74e101Schristos #define LLDP_CHASSIS_INTF_NAME_SUBTYPE 6 790f74e101Schristos #define LLDP_CHASSIS_LOCAL_SUBTYPE 7 800f74e101Schristos 810f74e101Schristos static const struct tok lldp_chassis_subtype_values[] = { 820f74e101Schristos { LLDP_CHASSIS_CHASSIS_COMP_SUBTYPE, "Chassis component"}, 830f74e101Schristos { LLDP_CHASSIS_INTF_ALIAS_SUBTYPE, "Interface alias"}, 840f74e101Schristos { LLDP_CHASSIS_PORT_COMP_SUBTYPE, "Port component"}, 850f74e101Schristos { LLDP_CHASSIS_MAC_ADDR_SUBTYPE, "MAC address"}, 860f74e101Schristos { LLDP_CHASSIS_NETWORK_ADDR_SUBTYPE, "Network address"}, 870f74e101Schristos { LLDP_CHASSIS_INTF_NAME_SUBTYPE, "Interface name"}, 880f74e101Schristos { LLDP_CHASSIS_LOCAL_SUBTYPE, "Local"}, 890f74e101Schristos { 0, NULL} 900f74e101Schristos }; 910f74e101Schristos 920f74e101Schristos /* 930f74e101Schristos * Port ID subtypes 940f74e101Schristos */ 950f74e101Schristos #define LLDP_PORT_INTF_ALIAS_SUBTYPE 1 960f74e101Schristos #define LLDP_PORT_PORT_COMP_SUBTYPE 2 970f74e101Schristos #define LLDP_PORT_MAC_ADDR_SUBTYPE 3 980f74e101Schristos #define LLDP_PORT_NETWORK_ADDR_SUBTYPE 4 990f74e101Schristos #define LLDP_PORT_INTF_NAME_SUBTYPE 5 1000f74e101Schristos #define LLDP_PORT_AGENT_CIRC_ID_SUBTYPE 6 1010f74e101Schristos #define LLDP_PORT_LOCAL_SUBTYPE 7 1020f74e101Schristos 1030f74e101Schristos static const struct tok lldp_port_subtype_values[] = { 1040f74e101Schristos { LLDP_PORT_INTF_ALIAS_SUBTYPE, "Interface alias"}, 1050f74e101Schristos { LLDP_PORT_PORT_COMP_SUBTYPE, "Port component"}, 1060f74e101Schristos { LLDP_PORT_MAC_ADDR_SUBTYPE, "MAC address"}, 1070f74e101Schristos { LLDP_PORT_NETWORK_ADDR_SUBTYPE, "Network Address"}, 1080f74e101Schristos { LLDP_PORT_INTF_NAME_SUBTYPE, "Interface Name"}, 1090f74e101Schristos { LLDP_PORT_AGENT_CIRC_ID_SUBTYPE, "Agent circuit ID"}, 1100f74e101Schristos { LLDP_PORT_LOCAL_SUBTYPE, "Local"}, 1110f74e101Schristos { 0, NULL} 1120f74e101Schristos }; 1130f74e101Schristos 1140f74e101Schristos /* 1150f74e101Schristos * System Capabilities 1160f74e101Schristos */ 1170f74e101Schristos #define LLDP_CAP_OTHER (1 << 0) 1180f74e101Schristos #define LLDP_CAP_REPEATER (1 << 1) 1190f74e101Schristos #define LLDP_CAP_BRIDGE (1 << 2) 1200f74e101Schristos #define LLDP_CAP_WLAN_AP (1 << 3) 1210f74e101Schristos #define LLDP_CAP_ROUTER (1 << 4) 1220f74e101Schristos #define LLDP_CAP_PHONE (1 << 5) 1230f74e101Schristos #define LLDP_CAP_DOCSIS (1 << 6) 1240f74e101Schristos #define LLDP_CAP_STATION_ONLY (1 << 7) 1250f74e101Schristos 1260f74e101Schristos static const struct tok lldp_cap_values[] = { 1270f74e101Schristos { LLDP_CAP_OTHER, "Other"}, 1280f74e101Schristos { LLDP_CAP_REPEATER, "Repeater"}, 1290f74e101Schristos { LLDP_CAP_BRIDGE, "Bridge"}, 1300f74e101Schristos { LLDP_CAP_WLAN_AP, "WLAN AP"}, 1310f74e101Schristos { LLDP_CAP_ROUTER, "Router"}, 1320f74e101Schristos { LLDP_CAP_PHONE, "Telephone"}, 1330f74e101Schristos { LLDP_CAP_DOCSIS, "Docsis"}, 1340f74e101Schristos { LLDP_CAP_STATION_ONLY, "Station Only"}, 1350f74e101Schristos { 0, NULL} 1360f74e101Schristos }; 1370f74e101Schristos 1380f74e101Schristos #define LLDP_PRIVATE_8021_SUBTYPE_PORT_VLAN_ID 1 1390f74e101Schristos #define LLDP_PRIVATE_8021_SUBTYPE_PROTOCOL_VLAN_ID 2 1400f74e101Schristos #define LLDP_PRIVATE_8021_SUBTYPE_VLAN_NAME 3 1410f74e101Schristos #define LLDP_PRIVATE_8021_SUBTYPE_PROTOCOL_IDENTITY 4 142c74ad251Schristos #define LLDP_PRIVATE_8021_SUBTYPE_LINKAGGR 7 143870189d2Schristos #define LLDP_PRIVATE_8021_SUBTYPE_CONGESTION_NOTIFICATION 8 144870189d2Schristos #define LLDP_PRIVATE_8021_SUBTYPE_ETS_CONFIGURATION 9 145870189d2Schristos #define LLDP_PRIVATE_8021_SUBTYPE_ETS_RECOMMENDATION 10 146870189d2Schristos #define LLDP_PRIVATE_8021_SUBTYPE_PFC_CONFIGURATION 11 147870189d2Schristos #define LLDP_PRIVATE_8021_SUBTYPE_APPLICATION_PRIORITY 12 148870189d2Schristos #define LLDP_PRIVATE_8021_SUBTYPE_EVB 13 149870189d2Schristos #define LLDP_PRIVATE_8021_SUBTYPE_CDCP 14 1500f74e101Schristos 1510f74e101Schristos static const struct tok lldp_8021_subtype_values[] = { 1520f74e101Schristos { LLDP_PRIVATE_8021_SUBTYPE_PORT_VLAN_ID, "Port VLAN Id"}, 1530f74e101Schristos { LLDP_PRIVATE_8021_SUBTYPE_PROTOCOL_VLAN_ID, "Port and Protocol VLAN ID"}, 1540f74e101Schristos { LLDP_PRIVATE_8021_SUBTYPE_VLAN_NAME, "VLAN name"}, 1550f74e101Schristos { LLDP_PRIVATE_8021_SUBTYPE_PROTOCOL_IDENTITY, "Protocol Identity"}, 156c74ad251Schristos { LLDP_PRIVATE_8021_SUBTYPE_LINKAGGR, "Link aggregation"}, 157870189d2Schristos { LLDP_PRIVATE_8021_SUBTYPE_CONGESTION_NOTIFICATION, "Congestion Notification"}, 158870189d2Schristos { LLDP_PRIVATE_8021_SUBTYPE_ETS_CONFIGURATION, "ETS Configuration"}, 159870189d2Schristos { LLDP_PRIVATE_8021_SUBTYPE_ETS_RECOMMENDATION, "ETS Recommendation"}, 160870189d2Schristos { LLDP_PRIVATE_8021_SUBTYPE_PFC_CONFIGURATION, "Priority Flow Control Configuration"}, 161870189d2Schristos { LLDP_PRIVATE_8021_SUBTYPE_APPLICATION_PRIORITY, "Application Priority"}, 162870189d2Schristos { LLDP_PRIVATE_8021_SUBTYPE_EVB, "EVB"}, 163870189d2Schristos { LLDP_PRIVATE_8021_SUBTYPE_CDCP,"CDCP"}, 1640f74e101Schristos { 0, NULL} 1650f74e101Schristos }; 1660f74e101Schristos 1670f74e101Schristos #define LLDP_8021_PORT_PROTOCOL_VLAN_SUPPORT (1 << 1) 1680f74e101Schristos #define LLDP_8021_PORT_PROTOCOL_VLAN_STATUS (1 << 2) 1690f74e101Schristos 1700f74e101Schristos static const struct tok lldp_8021_port_protocol_id_values[] = { 1710f74e101Schristos { LLDP_8021_PORT_PROTOCOL_VLAN_SUPPORT, "supported"}, 1720f74e101Schristos { LLDP_8021_PORT_PROTOCOL_VLAN_STATUS, "enabled"}, 1730f74e101Schristos { 0, NULL} 1740f74e101Schristos }; 1750f74e101Schristos 1760f74e101Schristos #define LLDP_PRIVATE_8023_SUBTYPE_MACPHY 1 1770f74e101Schristos #define LLDP_PRIVATE_8023_SUBTYPE_MDIPOWER 2 1780f74e101Schristos #define LLDP_PRIVATE_8023_SUBTYPE_LINKAGGR 3 1790f74e101Schristos #define LLDP_PRIVATE_8023_SUBTYPE_MTU 4 1800f74e101Schristos 1810f74e101Schristos static const struct tok lldp_8023_subtype_values[] = { 1820f74e101Schristos { LLDP_PRIVATE_8023_SUBTYPE_MACPHY, "MAC/PHY configuration/status"}, 1830f74e101Schristos { LLDP_PRIVATE_8023_SUBTYPE_MDIPOWER, "Power via MDI"}, 1840f74e101Schristos { LLDP_PRIVATE_8023_SUBTYPE_LINKAGGR, "Link aggregation"}, 1850f74e101Schristos { LLDP_PRIVATE_8023_SUBTYPE_MTU, "Max frame size"}, 1860f74e101Schristos { 0, NULL} 1870f74e101Schristos }; 1880f74e101Schristos 1890f74e101Schristos #define LLDP_PRIVATE_TIA_SUBTYPE_CAPABILITIES 1 1900f74e101Schristos #define LLDP_PRIVATE_TIA_SUBTYPE_NETWORK_POLICY 2 1910f74e101Schristos #define LLDP_PRIVATE_TIA_SUBTYPE_LOCAL_ID 3 1920f74e101Schristos #define LLDP_PRIVATE_TIA_SUBTYPE_EXTENDED_POWER_MDI 4 1930f74e101Schristos #define LLDP_PRIVATE_TIA_SUBTYPE_INVENTORY_HARDWARE_REV 5 1940f74e101Schristos #define LLDP_PRIVATE_TIA_SUBTYPE_INVENTORY_FIRMWARE_REV 6 1950f74e101Schristos #define LLDP_PRIVATE_TIA_SUBTYPE_INVENTORY_SOFTWARE_REV 7 1960f74e101Schristos #define LLDP_PRIVATE_TIA_SUBTYPE_INVENTORY_SERIAL_NUMBER 8 1970f74e101Schristos #define LLDP_PRIVATE_TIA_SUBTYPE_INVENTORY_MANUFACTURER_NAME 9 1980f74e101Schristos #define LLDP_PRIVATE_TIA_SUBTYPE_INVENTORY_MODEL_NAME 10 1990f74e101Schristos #define LLDP_PRIVATE_TIA_SUBTYPE_INVENTORY_ASSET_ID 11 2000f74e101Schristos 2010f74e101Schristos static const struct tok lldp_tia_subtype_values[] = { 2020f74e101Schristos { LLDP_PRIVATE_TIA_SUBTYPE_CAPABILITIES, "LLDP-MED Capabilities" }, 2030f74e101Schristos { LLDP_PRIVATE_TIA_SUBTYPE_NETWORK_POLICY, "Network policy" }, 2040f74e101Schristos { LLDP_PRIVATE_TIA_SUBTYPE_LOCAL_ID, "Location identification" }, 2050f74e101Schristos { LLDP_PRIVATE_TIA_SUBTYPE_EXTENDED_POWER_MDI, "Extended power-via-MDI" }, 2060f74e101Schristos { LLDP_PRIVATE_TIA_SUBTYPE_INVENTORY_HARDWARE_REV, "Inventory - hardware revision" }, 2070f74e101Schristos { LLDP_PRIVATE_TIA_SUBTYPE_INVENTORY_FIRMWARE_REV, "Inventory - firmware revision" }, 2080f74e101Schristos { LLDP_PRIVATE_TIA_SUBTYPE_INVENTORY_SOFTWARE_REV, "Inventory - software revision" }, 2090f74e101Schristos { LLDP_PRIVATE_TIA_SUBTYPE_INVENTORY_SERIAL_NUMBER, "Inventory - serial number" }, 2100f74e101Schristos { LLDP_PRIVATE_TIA_SUBTYPE_INVENTORY_MANUFACTURER_NAME, "Inventory - manufacturer name" }, 2110f74e101Schristos { LLDP_PRIVATE_TIA_SUBTYPE_INVENTORY_MODEL_NAME, "Inventory - model name" }, 2120f74e101Schristos { LLDP_PRIVATE_TIA_SUBTYPE_INVENTORY_ASSET_ID, "Inventory - asset ID" }, 2130f74e101Schristos { 0, NULL} 2140f74e101Schristos }; 2150f74e101Schristos 2160f74e101Schristos #define LLDP_PRIVATE_TIA_LOCATION_ALTITUDE_METERS 1 2170f74e101Schristos #define LLDP_PRIVATE_TIA_LOCATION_ALTITUDE_FLOORS 2 2180f74e101Schristos 2190f74e101Schristos static const struct tok lldp_tia_location_altitude_type_values[] = { 2200f74e101Schristos { LLDP_PRIVATE_TIA_LOCATION_ALTITUDE_METERS, "meters"}, 2210f74e101Schristos { LLDP_PRIVATE_TIA_LOCATION_ALTITUDE_FLOORS, "floors"}, 2220f74e101Schristos { 0, NULL} 2230f74e101Schristos }; 2240f74e101Schristos 2250f74e101Schristos /* ANSI/TIA-1057 - Annex B */ 2260f74e101Schristos #define LLDP_PRIVATE_TIA_LOCATION_LCI_CATYPE_A1 1 2270f74e101Schristos #define LLDP_PRIVATE_TIA_LOCATION_LCI_CATYPE_A2 2 2280f74e101Schristos #define LLDP_PRIVATE_TIA_LOCATION_LCI_CATYPE_A3 3 2290f74e101Schristos #define LLDP_PRIVATE_TIA_LOCATION_LCI_CATYPE_A4 4 2300f74e101Schristos #define LLDP_PRIVATE_TIA_LOCATION_LCI_CATYPE_A5 5 2310f74e101Schristos #define LLDP_PRIVATE_TIA_LOCATION_LCI_CATYPE_A6 6 2320f74e101Schristos 2330f74e101Schristos static const struct tok lldp_tia_location_lci_catype_values[] = { 2340f74e101Schristos { LLDP_PRIVATE_TIA_LOCATION_LCI_CATYPE_A1, "national subdivisions (state,canton,region,province,prefecture)"}, 2350f74e101Schristos { LLDP_PRIVATE_TIA_LOCATION_LCI_CATYPE_A2, "county, parish, gun, district"}, 2360f74e101Schristos { LLDP_PRIVATE_TIA_LOCATION_LCI_CATYPE_A3, "city, township, shi"}, 2370f74e101Schristos { LLDP_PRIVATE_TIA_LOCATION_LCI_CATYPE_A4, "city division, borough, city district, ward chou"}, 2380f74e101Schristos { LLDP_PRIVATE_TIA_LOCATION_LCI_CATYPE_A5, "neighborhood, block"}, 2390f74e101Schristos { LLDP_PRIVATE_TIA_LOCATION_LCI_CATYPE_A6, "street"}, 2400f74e101Schristos { 0, NULL} 2410f74e101Schristos }; 2420f74e101Schristos 2430f74e101Schristos static const struct tok lldp_tia_location_lci_what_values[] = { 2440f74e101Schristos { 0, "location of DHCP server"}, 2450f74e101Schristos { 1, "location of the network element believed to be closest to the client"}, 2460f74e101Schristos { 2, "location of the client"}, 2470f74e101Schristos { 0, NULL} 2480f74e101Schristos }; 2490f74e101Schristos 2500f74e101Schristos /* 2510f74e101Schristos * From RFC 3636 - dot3MauType 2520f74e101Schristos */ 2530f74e101Schristos #define LLDP_MAU_TYPE_UNKNOWN 0 2540f74e101Schristos #define LLDP_MAU_TYPE_AUI 1 2550f74e101Schristos #define LLDP_MAU_TYPE_10BASE_5 2 2560f74e101Schristos #define LLDP_MAU_TYPE_FOIRL 3 2570f74e101Schristos #define LLDP_MAU_TYPE_10BASE_2 4 2580f74e101Schristos #define LLDP_MAU_TYPE_10BASE_T 5 2590f74e101Schristos #define LLDP_MAU_TYPE_10BASE_FP 6 2600f74e101Schristos #define LLDP_MAU_TYPE_10BASE_FB 7 2610f74e101Schristos #define LLDP_MAU_TYPE_10BASE_FL 8 2620f74e101Schristos #define LLDP_MAU_TYPE_10BROAD36 9 2630f74e101Schristos #define LLDP_MAU_TYPE_10BASE_T_HD 10 2640f74e101Schristos #define LLDP_MAU_TYPE_10BASE_T_FD 11 2650f74e101Schristos #define LLDP_MAU_TYPE_10BASE_FL_HD 12 2660f74e101Schristos #define LLDP_MAU_TYPE_10BASE_FL_FD 13 2670f74e101Schristos #define LLDP_MAU_TYPE_100BASE_T4 14 2680f74e101Schristos #define LLDP_MAU_TYPE_100BASE_TX_HD 15 2690f74e101Schristos #define LLDP_MAU_TYPE_100BASE_TX_FD 16 2700f74e101Schristos #define LLDP_MAU_TYPE_100BASE_FX_HD 17 2710f74e101Schristos #define LLDP_MAU_TYPE_100BASE_FX_FD 18 2720f74e101Schristos #define LLDP_MAU_TYPE_100BASE_T2_HD 19 2730f74e101Schristos #define LLDP_MAU_TYPE_100BASE_T2_FD 20 2740f74e101Schristos #define LLDP_MAU_TYPE_1000BASE_X_HD 21 2750f74e101Schristos #define LLDP_MAU_TYPE_1000BASE_X_FD 22 2760f74e101Schristos #define LLDP_MAU_TYPE_1000BASE_LX_HD 23 2770f74e101Schristos #define LLDP_MAU_TYPE_1000BASE_LX_FD 24 2780f74e101Schristos #define LLDP_MAU_TYPE_1000BASE_SX_HD 25 2790f74e101Schristos #define LLDP_MAU_TYPE_1000BASE_SX_FD 26 2800f74e101Schristos #define LLDP_MAU_TYPE_1000BASE_CX_HD 27 2810f74e101Schristos #define LLDP_MAU_TYPE_1000BASE_CX_FD 28 2820f74e101Schristos #define LLDP_MAU_TYPE_1000BASE_T_HD 29 2830f74e101Schristos #define LLDP_MAU_TYPE_1000BASE_T_FD 30 2840f74e101Schristos #define LLDP_MAU_TYPE_10GBASE_X 31 2850f74e101Schristos #define LLDP_MAU_TYPE_10GBASE_LX4 32 2860f74e101Schristos #define LLDP_MAU_TYPE_10GBASE_R 33 2870f74e101Schristos #define LLDP_MAU_TYPE_10GBASE_ER 34 2880f74e101Schristos #define LLDP_MAU_TYPE_10GBASE_LR 35 2890f74e101Schristos #define LLDP_MAU_TYPE_10GBASE_SR 36 2900f74e101Schristos #define LLDP_MAU_TYPE_10GBASE_W 37 2910f74e101Schristos #define LLDP_MAU_TYPE_10GBASE_EW 38 2920f74e101Schristos #define LLDP_MAU_TYPE_10GBASE_LW 39 2930f74e101Schristos #define LLDP_MAU_TYPE_10GBASE_SW 40 2940f74e101Schristos 2950f74e101Schristos static const struct tok lldp_mau_types_values[] = { 2960f74e101Schristos { LLDP_MAU_TYPE_UNKNOWN, "Unknown"}, 2970f74e101Schristos { LLDP_MAU_TYPE_AUI, "AUI"}, 2980f74e101Schristos { LLDP_MAU_TYPE_10BASE_5, "10BASE_5"}, 2990f74e101Schristos { LLDP_MAU_TYPE_FOIRL, "FOIRL"}, 3000f74e101Schristos { LLDP_MAU_TYPE_10BASE_2, "10BASE2"}, 3010f74e101Schristos { LLDP_MAU_TYPE_10BASE_T, "10BASET duplex mode unknown"}, 3020f74e101Schristos { LLDP_MAU_TYPE_10BASE_FP, "10BASEFP"}, 3030f74e101Schristos { LLDP_MAU_TYPE_10BASE_FB, "10BASEFB"}, 3040f74e101Schristos { LLDP_MAU_TYPE_10BASE_FL, "10BASEFL duplex mode unknown"}, 3050f74e101Schristos { LLDP_MAU_TYPE_10BROAD36, "10BROAD36"}, 3060f74e101Schristos { LLDP_MAU_TYPE_10BASE_T_HD, "10BASET hdx"}, 3070f74e101Schristos { LLDP_MAU_TYPE_10BASE_T_FD, "10BASET fdx"}, 3080f74e101Schristos { LLDP_MAU_TYPE_10BASE_FL_HD, "10BASEFL hdx"}, 3090f74e101Schristos { LLDP_MAU_TYPE_10BASE_FL_FD, "10BASEFL fdx"}, 3100f74e101Schristos { LLDP_MAU_TYPE_100BASE_T4, "100BASET4"}, 3110f74e101Schristos { LLDP_MAU_TYPE_100BASE_TX_HD, "100BASETX hdx"}, 3120f74e101Schristos { LLDP_MAU_TYPE_100BASE_TX_FD, "100BASETX fdx"}, 3130f74e101Schristos { LLDP_MAU_TYPE_100BASE_FX_HD, "100BASEFX hdx"}, 3140f74e101Schristos { LLDP_MAU_TYPE_100BASE_FX_FD, "100BASEFX fdx"}, 3150f74e101Schristos { LLDP_MAU_TYPE_100BASE_T2_HD, "100BASET2 hdx"}, 3160f74e101Schristos { LLDP_MAU_TYPE_100BASE_T2_FD, "100BASET2 fdx"}, 3170f74e101Schristos { LLDP_MAU_TYPE_1000BASE_X_HD, "1000BASEX hdx"}, 3180f74e101Schristos { LLDP_MAU_TYPE_1000BASE_X_FD, "1000BASEX fdx"}, 3190f74e101Schristos { LLDP_MAU_TYPE_1000BASE_LX_HD, "1000BASELX hdx"}, 3200f74e101Schristos { LLDP_MAU_TYPE_1000BASE_LX_FD, "1000BASELX fdx"}, 3210f74e101Schristos { LLDP_MAU_TYPE_1000BASE_SX_HD, "1000BASESX hdx"}, 3220f74e101Schristos { LLDP_MAU_TYPE_1000BASE_SX_FD, "1000BASESX fdx"}, 3230f74e101Schristos { LLDP_MAU_TYPE_1000BASE_CX_HD, "1000BASECX hdx"}, 3240f74e101Schristos { LLDP_MAU_TYPE_1000BASE_CX_FD, "1000BASECX fdx"}, 3250f74e101Schristos { LLDP_MAU_TYPE_1000BASE_T_HD, "1000BASET hdx"}, 3260f74e101Schristos { LLDP_MAU_TYPE_1000BASE_T_FD, "1000BASET fdx"}, 3270f74e101Schristos { LLDP_MAU_TYPE_10GBASE_X, "10GBASEX"}, 3280f74e101Schristos { LLDP_MAU_TYPE_10GBASE_LX4, "10GBASELX4"}, 3290f74e101Schristos { LLDP_MAU_TYPE_10GBASE_R, "10GBASER"}, 3300f74e101Schristos { LLDP_MAU_TYPE_10GBASE_ER, "10GBASEER"}, 3310f74e101Schristos { LLDP_MAU_TYPE_10GBASE_LR, "10GBASELR"}, 3320f74e101Schristos { LLDP_MAU_TYPE_10GBASE_SR, "10GBASESR"}, 3330f74e101Schristos { LLDP_MAU_TYPE_10GBASE_W, "10GBASEW"}, 3340f74e101Schristos { LLDP_MAU_TYPE_10GBASE_EW, "10GBASEEW"}, 3350f74e101Schristos { LLDP_MAU_TYPE_10GBASE_LW, "10GBASELW"}, 3360f74e101Schristos { LLDP_MAU_TYPE_10GBASE_SW, "10GBASESW"}, 3370f74e101Schristos { 0, NULL} 3380f74e101Schristos }; 3390f74e101Schristos 3400f74e101Schristos #define LLDP_8023_AUTONEGOTIATION_SUPPORT (1 << 0) 3410f74e101Schristos #define LLDP_8023_AUTONEGOTIATION_STATUS (1 << 1) 3420f74e101Schristos 3430f74e101Schristos static const struct tok lldp_8023_autonegotiation_values[] = { 3440f74e101Schristos { LLDP_8023_AUTONEGOTIATION_SUPPORT, "supported"}, 3450f74e101Schristos { LLDP_8023_AUTONEGOTIATION_STATUS, "enabled"}, 3460f74e101Schristos { 0, NULL} 3470f74e101Schristos }; 3480f74e101Schristos 3490f74e101Schristos #define LLDP_TIA_CAPABILITY_MED (1 << 0) 3500f74e101Schristos #define LLDP_TIA_CAPABILITY_NETWORK_POLICY (1 << 1) 3510f74e101Schristos #define LLDP_TIA_CAPABILITY_LOCATION_IDENTIFICATION (1 << 2) 3520f74e101Schristos #define LLDP_TIA_CAPABILITY_EXTENDED_POWER_MDI_PSE (1 << 3) 3530f74e101Schristos #define LLDP_TIA_CAPABILITY_EXTENDED_POWER_MDI_PD (1 << 4) 3540f74e101Schristos #define LLDP_TIA_CAPABILITY_INVENTORY (1 << 5) 3550f74e101Schristos 3560f74e101Schristos static const struct tok lldp_tia_capabilities_values[] = { 3570f74e101Schristos { LLDP_TIA_CAPABILITY_MED, "LLDP-MED capabilities"}, 3580f74e101Schristos { LLDP_TIA_CAPABILITY_NETWORK_POLICY, "network policy"}, 3590f74e101Schristos { LLDP_TIA_CAPABILITY_LOCATION_IDENTIFICATION, "location identification"}, 3600f74e101Schristos { LLDP_TIA_CAPABILITY_EXTENDED_POWER_MDI_PSE, "extended power via MDI-PSE"}, 3610f74e101Schristos { LLDP_TIA_CAPABILITY_EXTENDED_POWER_MDI_PD, "extended power via MDI-PD"}, 3620f74e101Schristos { LLDP_TIA_CAPABILITY_INVENTORY, "Inventory"}, 3630f74e101Schristos { 0, NULL} 3640f74e101Schristos }; 3650f74e101Schristos 3660f74e101Schristos #define LLDP_TIA_DEVICE_TYPE_ENDPOINT_CLASS_1 1 3670f74e101Schristos #define LLDP_TIA_DEVICE_TYPE_ENDPOINT_CLASS_2 2 3680f74e101Schristos #define LLDP_TIA_DEVICE_TYPE_ENDPOINT_CLASS_3 3 3690f74e101Schristos #define LLDP_TIA_DEVICE_TYPE_NETWORK_CONNECTIVITY 4 3700f74e101Schristos 3710f74e101Schristos static const struct tok lldp_tia_device_type_values[] = { 3720f74e101Schristos { LLDP_TIA_DEVICE_TYPE_ENDPOINT_CLASS_1, "endpoint class 1"}, 3730f74e101Schristos { LLDP_TIA_DEVICE_TYPE_ENDPOINT_CLASS_2, "endpoint class 2"}, 3740f74e101Schristos { LLDP_TIA_DEVICE_TYPE_ENDPOINT_CLASS_3, "endpoint class 3"}, 3750f74e101Schristos { LLDP_TIA_DEVICE_TYPE_NETWORK_CONNECTIVITY, "network connectivity"}, 3760f74e101Schristos { 0, NULL} 3770f74e101Schristos }; 3780f74e101Schristos 3790f74e101Schristos #define LLDP_TIA_APPLICATION_TYPE_VOICE 1 3800f74e101Schristos #define LLDP_TIA_APPLICATION_TYPE_VOICE_SIGNALING 2 3810f74e101Schristos #define LLDP_TIA_APPLICATION_TYPE_GUEST_VOICE 3 3820f74e101Schristos #define LLDP_TIA_APPLICATION_TYPE_GUEST_VOICE_SIGNALING 4 3830f74e101Schristos #define LLDP_TIA_APPLICATION_TYPE_SOFTPHONE_VOICE 5 3840f74e101Schristos #define LLDP_TIA_APPLICATION_TYPE_VIDEO_CONFERENCING 6 3850f74e101Schristos #define LLDP_TIA_APPLICATION_TYPE_STREAMING_VIDEO 7 3860f74e101Schristos #define LLDP_TIA_APPLICATION_TYPE_VIDEO_SIGNALING 8 3870f74e101Schristos 3880f74e101Schristos static const struct tok lldp_tia_application_type_values[] = { 3890f74e101Schristos { LLDP_TIA_APPLICATION_TYPE_VOICE, "voice"}, 3900f74e101Schristos { LLDP_TIA_APPLICATION_TYPE_VOICE_SIGNALING, "voice signaling"}, 3910f74e101Schristos { LLDP_TIA_APPLICATION_TYPE_GUEST_VOICE, "guest voice"}, 3920f74e101Schristos { LLDP_TIA_APPLICATION_TYPE_GUEST_VOICE_SIGNALING, "guest voice signaling"}, 3930f74e101Schristos { LLDP_TIA_APPLICATION_TYPE_SOFTPHONE_VOICE, "softphone voice"}, 3940f74e101Schristos { LLDP_TIA_APPLICATION_TYPE_VIDEO_CONFERENCING, "video conferencing"}, 3950f74e101Schristos { LLDP_TIA_APPLICATION_TYPE_STREAMING_VIDEO, "streaming video"}, 3960f74e101Schristos { LLDP_TIA_APPLICATION_TYPE_VIDEO_SIGNALING, "video signaling"}, 3970f74e101Schristos { 0, NULL} 3980f74e101Schristos }; 3990f74e101Schristos 4000e9868baSchristos #define LLDP_TIA_NETWORK_POLICY_X_BIT (1 << 5) 4010f74e101Schristos #define LLDP_TIA_NETWORK_POLICY_T_BIT (1 << 6) 4020e9868baSchristos #define LLDP_TIA_NETWORK_POLICY_U_BIT (1 << 7) 4030f74e101Schristos 4040f74e101Schristos static const struct tok lldp_tia_network_policy_bits_values[] = { 4050f74e101Schristos { LLDP_TIA_NETWORK_POLICY_U_BIT, "Unknown"}, 4060f74e101Schristos { LLDP_TIA_NETWORK_POLICY_T_BIT, "Tagged"}, 4070f74e101Schristos { LLDP_TIA_NETWORK_POLICY_X_BIT, "reserved"}, 4080f74e101Schristos { 0, NULL} 4090f74e101Schristos }; 4100f74e101Schristos 4110f74e101Schristos #define LLDP_EXTRACT_NETWORK_POLICY_VLAN(x) (((x)&0x1ffe)>>1) 4120f74e101Schristos #define LLDP_EXTRACT_NETWORK_POLICY_L2_PRIORITY(x) (((x)&0x01ff)>>6) 4130f74e101Schristos #define LLDP_EXTRACT_NETWORK_POLICY_DSCP(x) ((x)&0x003f) 4140f74e101Schristos 4150f74e101Schristos #define LLDP_TIA_LOCATION_DATA_FORMAT_COORDINATE_BASED 1 4160f74e101Schristos #define LLDP_TIA_LOCATION_DATA_FORMAT_CIVIC_ADDRESS 2 4170f74e101Schristos #define LLDP_TIA_LOCATION_DATA_FORMAT_ECS_ELIN 3 4180f74e101Schristos 4190f74e101Schristos static const struct tok lldp_tia_location_data_format_values[] = { 4200f74e101Schristos { LLDP_TIA_LOCATION_DATA_FORMAT_COORDINATE_BASED, "coordinate-based LCI"}, 4210f74e101Schristos { LLDP_TIA_LOCATION_DATA_FORMAT_CIVIC_ADDRESS, "civic address LCI"}, 4220f74e101Schristos { LLDP_TIA_LOCATION_DATA_FORMAT_ECS_ELIN, "ECS ELIN"}, 4230f74e101Schristos { 0, NULL} 4240f74e101Schristos }; 4250f74e101Schristos 4260f74e101Schristos #define LLDP_TIA_LOCATION_DATUM_WGS_84 1 4270f74e101Schristos #define LLDP_TIA_LOCATION_DATUM_NAD_83_NAVD_88 2 4280f74e101Schristos #define LLDP_TIA_LOCATION_DATUM_NAD_83_MLLW 3 4290f74e101Schristos 4300f74e101Schristos static const struct tok lldp_tia_location_datum_type_values[] = { 4310f74e101Schristos { LLDP_TIA_LOCATION_DATUM_WGS_84, "World Geodesic System 1984"}, 4320f74e101Schristos { LLDP_TIA_LOCATION_DATUM_NAD_83_NAVD_88, "North American Datum 1983 (NAVD88)"}, 4330f74e101Schristos { LLDP_TIA_LOCATION_DATUM_NAD_83_MLLW, "North American Datum 1983 (MLLW)"}, 4340f74e101Schristos { 0, NULL} 4350f74e101Schristos }; 4360f74e101Schristos 4370f74e101Schristos #define LLDP_TIA_POWER_SOURCE_PSE 1 4380f74e101Schristos #define LLDP_TIA_POWER_SOURCE_LOCAL 2 4390f74e101Schristos #define LLDP_TIA_POWER_SOURCE_PSE_AND_LOCAL 3 4400f74e101Schristos 4410f74e101Schristos static const struct tok lldp_tia_power_source_values[] = { 4420f74e101Schristos { LLDP_TIA_POWER_SOURCE_PSE, "PSE - primary power source"}, 4430f74e101Schristos { LLDP_TIA_POWER_SOURCE_LOCAL, "local - backup power source"}, 4440f74e101Schristos { LLDP_TIA_POWER_SOURCE_PSE_AND_LOCAL, "PSE+local - reserved"}, 4450f74e101Schristos { 0, NULL} 4460f74e101Schristos }; 4470f74e101Schristos 4480f74e101Schristos #define LLDP_TIA_POWER_PRIORITY_CRITICAL 1 4490f74e101Schristos #define LLDP_TIA_POWER_PRIORITY_HIGH 2 4500f74e101Schristos #define LLDP_TIA_POWER_PRIORITY_LOW 3 4510f74e101Schristos 4520f74e101Schristos static const struct tok lldp_tia_power_priority_values[] = { 4530f74e101Schristos { LLDP_TIA_POWER_PRIORITY_CRITICAL, "critical"}, 4540f74e101Schristos { LLDP_TIA_POWER_PRIORITY_HIGH, "high"}, 4550f74e101Schristos { LLDP_TIA_POWER_PRIORITY_LOW, "low"}, 4560f74e101Schristos { 0, NULL} 4570f74e101Schristos }; 4580f74e101Schristos 4590f74e101Schristos #define LLDP_TIA_POWER_VAL_MAX 1024 4600f74e101Schristos 4610f74e101Schristos static const struct tok lldp_tia_inventory_values[] = { 4620f74e101Schristos { LLDP_PRIVATE_TIA_SUBTYPE_INVENTORY_HARDWARE_REV, "Hardware revision" }, 4630f74e101Schristos { LLDP_PRIVATE_TIA_SUBTYPE_INVENTORY_FIRMWARE_REV, "Firmware revision" }, 4640f74e101Schristos { LLDP_PRIVATE_TIA_SUBTYPE_INVENTORY_SOFTWARE_REV, "Software revision" }, 4650f74e101Schristos { LLDP_PRIVATE_TIA_SUBTYPE_INVENTORY_SERIAL_NUMBER, "Serial number" }, 4660f74e101Schristos { LLDP_PRIVATE_TIA_SUBTYPE_INVENTORY_MANUFACTURER_NAME, "Manufacturer name" }, 4670f74e101Schristos { LLDP_PRIVATE_TIA_SUBTYPE_INVENTORY_MODEL_NAME, "Model name" }, 4680f74e101Schristos { LLDP_PRIVATE_TIA_SUBTYPE_INVENTORY_ASSET_ID, "Asset ID" }, 4690f74e101Schristos { 0, NULL} 4700f74e101Schristos }; 4710f74e101Schristos 4720f74e101Schristos /* 4730f74e101Schristos * From RFC 3636 - ifMauAutoNegCapAdvertisedBits 4740f74e101Schristos */ 4750f74e101Schristos #define LLDP_MAU_PMD_OTHER (1 << 15) 4760f74e101Schristos #define LLDP_MAU_PMD_10BASE_T (1 << 14) 4770f74e101Schristos #define LLDP_MAU_PMD_10BASE_T_FD (1 << 13) 4780f74e101Schristos #define LLDP_MAU_PMD_100BASE_T4 (1 << 12) 4790f74e101Schristos #define LLDP_MAU_PMD_100BASE_TX (1 << 11) 4800f74e101Schristos #define LLDP_MAU_PMD_100BASE_TX_FD (1 << 10) 4810f74e101Schristos #define LLDP_MAU_PMD_100BASE_T2 (1 << 9) 4820f74e101Schristos #define LLDP_MAU_PMD_100BASE_T2_FD (1 << 8) 4830f74e101Schristos #define LLDP_MAU_PMD_FDXPAUSE (1 << 7) 4840f74e101Schristos #define LLDP_MAU_PMD_FDXAPAUSE (1 << 6) 4850f74e101Schristos #define LLDP_MAU_PMD_FDXSPAUSE (1 << 5) 4860f74e101Schristos #define LLDP_MAU_PMD_FDXBPAUSE (1 << 4) 4870f74e101Schristos #define LLDP_MAU_PMD_1000BASE_X (1 << 3) 4880f74e101Schristos #define LLDP_MAU_PMD_1000BASE_X_FD (1 << 2) 4890f74e101Schristos #define LLDP_MAU_PMD_1000BASE_T (1 << 1) 4900f74e101Schristos #define LLDP_MAU_PMD_1000BASE_T_FD (1 << 0) 4910f74e101Schristos 4920f74e101Schristos static const struct tok lldp_pmd_capability_values[] = { 4930f74e101Schristos { LLDP_MAU_PMD_10BASE_T, "10BASE-T hdx"}, 4940f74e101Schristos { LLDP_MAU_PMD_10BASE_T_FD, "10BASE-T fdx"}, 4950f74e101Schristos { LLDP_MAU_PMD_100BASE_T4, "100BASE-T4"}, 4960f74e101Schristos { LLDP_MAU_PMD_100BASE_TX, "100BASE-TX hdx"}, 4970f74e101Schristos { LLDP_MAU_PMD_100BASE_TX_FD, "100BASE-TX fdx"}, 4980f74e101Schristos { LLDP_MAU_PMD_100BASE_T2, "100BASE-T2 hdx"}, 4990f74e101Schristos { LLDP_MAU_PMD_100BASE_T2_FD, "100BASE-T2 fdx"}, 5000f74e101Schristos { LLDP_MAU_PMD_FDXPAUSE, "Pause for fdx links"}, 5010f74e101Schristos { LLDP_MAU_PMD_FDXAPAUSE, "Asym PAUSE for fdx"}, 5020f74e101Schristos { LLDP_MAU_PMD_FDXSPAUSE, "Sym PAUSE for fdx"}, 5030f74e101Schristos { LLDP_MAU_PMD_FDXBPAUSE, "Asym and Sym PAUSE for fdx"}, 5040f74e101Schristos { LLDP_MAU_PMD_1000BASE_X, "1000BASE-{X LX SX CX} hdx"}, 5050f74e101Schristos { LLDP_MAU_PMD_1000BASE_X_FD, "1000BASE-{X LX SX CX} fdx"}, 5060f74e101Schristos { LLDP_MAU_PMD_1000BASE_T, "1000BASE-T hdx"}, 5070f74e101Schristos { LLDP_MAU_PMD_1000BASE_T_FD, "1000BASE-T fdx"}, 5080f74e101Schristos { 0, NULL} 5090f74e101Schristos }; 5100f74e101Schristos 5110f74e101Schristos #define LLDP_MDI_PORT_CLASS (1 << 0) 5120f74e101Schristos #define LLDP_MDI_POWER_SUPPORT (1 << 1) 5130f74e101Schristos #define LLDP_MDI_POWER_STATE (1 << 2) 5140f74e101Schristos #define LLDP_MDI_PAIR_CONTROL_ABILITY (1 << 3) 5150f74e101Schristos 5160f74e101Schristos static const struct tok lldp_mdi_values[] = { 5170f74e101Schristos { LLDP_MDI_PORT_CLASS, "PSE"}, 5180f74e101Schristos { LLDP_MDI_POWER_SUPPORT, "supported"}, 5190f74e101Schristos { LLDP_MDI_POWER_STATE, "enabled"}, 5200f74e101Schristos { LLDP_MDI_PAIR_CONTROL_ABILITY, "can be controlled"}, 5210f74e101Schristos { 0, NULL} 5220f74e101Schristos }; 5230f74e101Schristos 5240f74e101Schristos #define LLDP_MDI_PSE_PORT_POWER_PAIRS_SIGNAL 1 5250f74e101Schristos #define LLDP_MDI_PSE_PORT_POWER_PAIRS_SPARE 2 5260f74e101Schristos 5270f74e101Schristos static const struct tok lldp_mdi_power_pairs_values[] = { 5280f74e101Schristos { LLDP_MDI_PSE_PORT_POWER_PAIRS_SIGNAL, "signal"}, 5290f74e101Schristos { LLDP_MDI_PSE_PORT_POWER_PAIRS_SPARE, "spare"}, 5300f74e101Schristos { 0, NULL} 5310f74e101Schristos }; 5320f74e101Schristos 5330f74e101Schristos #define LLDP_MDI_POWER_CLASS0 1 5340f74e101Schristos #define LLDP_MDI_POWER_CLASS1 2 5350f74e101Schristos #define LLDP_MDI_POWER_CLASS2 3 5360f74e101Schristos #define LLDP_MDI_POWER_CLASS3 4 5370f74e101Schristos #define LLDP_MDI_POWER_CLASS4 5 5380f74e101Schristos 5390f74e101Schristos static const struct tok lldp_mdi_power_class_values[] = { 5400f74e101Schristos { LLDP_MDI_POWER_CLASS0, "class0"}, 5410f74e101Schristos { LLDP_MDI_POWER_CLASS1, "class1"}, 5420f74e101Schristos { LLDP_MDI_POWER_CLASS2, "class2"}, 5430f74e101Schristos { LLDP_MDI_POWER_CLASS3, "class3"}, 5440f74e101Schristos { LLDP_MDI_POWER_CLASS4, "class4"}, 5450f74e101Schristos { 0, NULL} 5460f74e101Schristos }; 5470f74e101Schristos 548c74ad251Schristos #define LLDP_AGGREGATION_CAPABILITY (1 << 0) 5490f74e101Schristos #define LLDP_AGGREGATION_STATUS (1 << 1) 5500f74e101Schristos 5510f74e101Schristos static const struct tok lldp_aggregation_values[] = { 552c74ad251Schristos { LLDP_AGGREGATION_CAPABILITY, "supported"}, 5530f74e101Schristos { LLDP_AGGREGATION_STATUS, "enabled"}, 5540f74e101Schristos { 0, NULL} 5550f74e101Schristos }; 5560f74e101Schristos 5570f74e101Schristos /* 5580e9868baSchristos * DCBX protocol subtypes. 5590e9868baSchristos */ 5600e9868baSchristos #define LLDP_DCBX_SUBTYPE_1 1 5610e9868baSchristos #define LLDP_DCBX_SUBTYPE_2 2 5620e9868baSchristos 5630e9868baSchristos static const struct tok lldp_dcbx_subtype_values[] = { 5640e9868baSchristos { LLDP_DCBX_SUBTYPE_1, "DCB Capability Exchange Protocol Rev 1" }, 5650e9868baSchristos { LLDP_DCBX_SUBTYPE_2, "DCB Capability Exchange Protocol Rev 1.01" }, 5660e9868baSchristos { 0, NULL} 5670e9868baSchristos }; 5680e9868baSchristos 5690e9868baSchristos #define LLDP_DCBX_CONTROL_TLV 1 5700e9868baSchristos #define LLDP_DCBX_PRIORITY_GROUPS_TLV 2 5710e9868baSchristos #define LLDP_DCBX_PRIORITY_FLOW_CONTROL_TLV 3 5720e9868baSchristos #define LLDP_DCBX_APPLICATION_TLV 4 5730e9868baSchristos 5740e9868baSchristos /* 5750f74e101Schristos * Interface numbering subtypes. 5760f74e101Schristos */ 5770f74e101Schristos #define LLDP_INTF_NUMB_IFX_SUBTYPE 2 5780f74e101Schristos #define LLDP_INTF_NUMB_SYSPORT_SUBTYPE 3 5790f74e101Schristos 5800f74e101Schristos static const struct tok lldp_intf_numb_subtype_values[] = { 5810f74e101Schristos { LLDP_INTF_NUMB_IFX_SUBTYPE, "Interface Index" }, 5820f74e101Schristos { LLDP_INTF_NUMB_SYSPORT_SUBTYPE, "System Port Number" }, 5830f74e101Schristos { 0, NULL} 5840f74e101Schristos }; 5850f74e101Schristos 5860f74e101Schristos #define LLDP_INTF_NUM_LEN 5 5870f74e101Schristos 588870189d2Schristos #define LLDP_EVB_MODE_NOT_SUPPORTED 0 589870189d2Schristos #define LLDP_EVB_MODE_EVB_BRIDGE 1 590870189d2Schristos #define LLDP_EVB_MODE_EVB_STATION 2 591870189d2Schristos #define LLDP_EVB_MODE_RESERVED 3 592870189d2Schristos 593870189d2Schristos static const struct tok lldp_evb_mode_values[]={ 594870189d2Schristos { LLDP_EVB_MODE_NOT_SUPPORTED, "Not Supported"}, 595870189d2Schristos { LLDP_EVB_MODE_EVB_BRIDGE, "EVB Bridge"}, 596c74ad251Schristos { LLDP_EVB_MODE_EVB_STATION, "EVB Station"}, 597870189d2Schristos { LLDP_EVB_MODE_RESERVED, "Reserved for future Standardization"}, 59872c96ff3Schristos { 0, NULL}, 599870189d2Schristos }; 600870189d2Schristos 601870189d2Schristos #define NO_OF_BITS 8 602870189d2Schristos #define LLDP_PRIVATE_8021_SUBTYPE_CONGESTION_NOTIFICATION_LENGTH 6 603870189d2Schristos #define LLDP_PRIVATE_8021_SUBTYPE_ETS_CONFIGURATION_LENGTH 25 604870189d2Schristos #define LLDP_PRIVATE_8021_SUBTYPE_ETS_RECOMMENDATION_LENGTH 25 605870189d2Schristos #define LLDP_PRIVATE_8021_SUBTYPE_PFC_CONFIGURATION_LENGTH 6 606870189d2Schristos #define LLDP_PRIVATE_8021_SUBTYPE_APPLICATION_PRIORITY_MIN_LENGTH 5 607870189d2Schristos #define LLDP_PRIVATE_8021_SUBTYPE_EVB_LENGTH 9 608870189d2Schristos #define LLDP_PRIVATE_8021_SUBTYPE_CDCP_MIN_LENGTH 8 609870189d2Schristos 610dc860a36Sspz #define LLDP_IANA_SUBTYPE_MUDURL 1 611dc860a36Sspz 612dc860a36Sspz static const struct tok lldp_iana_subtype_values[] = { 613dc860a36Sspz { LLDP_IANA_SUBTYPE_MUDURL, "MUD-URL" }, 614dc860a36Sspz { 0, NULL } 615dc860a36Sspz }; 616dc860a36Sspz 617dc860a36Sspz 618b3a00663Schristos static void 619b3a00663Schristos print_ets_priority_assignment_table(netdissect_options *ndo, 620b3a00663Schristos const u_char *ptr) 621870189d2Schristos { 622c74ad251Schristos ND_PRINT("\n\t Priority Assignment Table"); 623c74ad251Schristos ND_PRINT("\n\t Priority : 0 1 2 3 4 5 6 7"); 624c74ad251Schristos ND_PRINT("\n\t Value : %-3d %-3d %-3d %-3d %-3d %-3d %-3d %-3d", 625c74ad251Schristos GET_U_1(ptr) >> 4, GET_U_1(ptr) & 0x0f, 626c74ad251Schristos GET_U_1(ptr + 1) >> 4, GET_U_1(ptr + 1) & 0x0f, 627c74ad251Schristos GET_U_1(ptr + 2) >> 4, GET_U_1(ptr + 2) & 0x0f, 628c74ad251Schristos GET_U_1(ptr + 3) >> 4, GET_U_1(ptr + 3) & 0x0f); 629870189d2Schristos } 630870189d2Schristos 631b3a00663Schristos static void 632b3a00663Schristos print_tc_bandwidth_table(netdissect_options *ndo, 633b3a00663Schristos const u_char *ptr) 634870189d2Schristos { 635c74ad251Schristos ND_PRINT("\n\t TC Bandwidth Table"); 636c74ad251Schristos ND_PRINT("\n\t TC%% : 0 1 2 3 4 5 6 7"); 637c74ad251Schristos ND_PRINT("\n\t Value : %-3d %-3d %-3d %-3d %-3d %-3d %-3d %-3d", 638c74ad251Schristos GET_U_1(ptr), GET_U_1(ptr + 1), GET_U_1(ptr + 2), 639c74ad251Schristos GET_U_1(ptr + 3), GET_U_1(ptr + 4), GET_U_1(ptr + 5), 640c74ad251Schristos GET_U_1(ptr + 6), GET_U_1(ptr + 7)); 641870189d2Schristos } 642870189d2Schristos 643b3a00663Schristos static void 644b3a00663Schristos print_tsa_assignment_table(netdissect_options *ndo, 645b3a00663Schristos const u_char *ptr) 646870189d2Schristos { 647c74ad251Schristos ND_PRINT("\n\t TSA Assignment Table"); 648c74ad251Schristos ND_PRINT("\n\t Traffic Class: 0 1 2 3 4 5 6 7"); 649c74ad251Schristos ND_PRINT("\n\t Value : %-3d %-3d %-3d %-3d %-3d %-3d %-3d %-3d", 650c74ad251Schristos GET_U_1(ptr), GET_U_1(ptr + 1), GET_U_1(ptr + 2), 651c74ad251Schristos GET_U_1(ptr + 3), GET_U_1(ptr + 4), GET_U_1(ptr + 5), 652c74ad251Schristos GET_U_1(ptr + 6), GET_U_1(ptr + 7)); 653870189d2Schristos } 654870189d2Schristos 6550f74e101Schristos /* 6560e9868baSchristos * Print IEEE 802.1 private extensions. (802.1AB annex E) 6570f74e101Schristos */ 6580f74e101Schristos static int 659b3a00663Schristos lldp_private_8021_print(netdissect_options *ndo, 660b3a00663Schristos const u_char *tptr, u_int tlv_len) 6610f74e101Schristos { 662c74ad251Schristos int hexdump = FALSE; 663c74ad251Schristos u_int subtype; 6640e9868baSchristos u_int sublen; 665870189d2Schristos u_int tval; 66672c96ff3Schristos u_int i; 6670f74e101Schristos 6680e9868baSchristos if (tlv_len < 4) { 6690e9868baSchristos return hexdump; 6700e9868baSchristos } 671c74ad251Schristos subtype = GET_U_1(tptr + 3); 6720f74e101Schristos 673c74ad251Schristos ND_PRINT("\n\t %s Subtype (%u)", 6740f74e101Schristos tok2str(lldp_8021_subtype_values, "unknown", subtype), 675c74ad251Schristos subtype); 6760f74e101Schristos 6770f74e101Schristos switch (subtype) { 6780f74e101Schristos case LLDP_PRIVATE_8021_SUBTYPE_PORT_VLAN_ID: 6790e9868baSchristos if (tlv_len < 6) { 6800e9868baSchristos return hexdump; 6810e9868baSchristos } 682c74ad251Schristos ND_PRINT("\n\t port vlan id (PVID): %u", 683c74ad251Schristos GET_BE_U_2(tptr + 4)); 6840f74e101Schristos break; 6850f74e101Schristos case LLDP_PRIVATE_8021_SUBTYPE_PROTOCOL_VLAN_ID: 6860e9868baSchristos if (tlv_len < 7) { 6870e9868baSchristos return hexdump; 6880e9868baSchristos } 689c74ad251Schristos ND_PRINT("\n\t port and protocol vlan id (PPVID): %u, flags [%s] (0x%02x)", 690c74ad251Schristos GET_BE_U_2(tptr + 5), 691c74ad251Schristos bittok2str(lldp_8021_port_protocol_id_values, "none", GET_U_1(tptr + 4)), 692c74ad251Schristos GET_U_1(tptr + 4)); 6930f74e101Schristos break; 6940f74e101Schristos case LLDP_PRIVATE_8021_SUBTYPE_VLAN_NAME: 6950e9868baSchristos if (tlv_len < 6) { 6960e9868baSchristos return hexdump; 6970e9868baSchristos } 698c74ad251Schristos ND_PRINT("\n\t vlan id (VID): %u", GET_BE_U_2(tptr + 4)); 6990e9868baSchristos if (tlv_len < 7) { 7000e9868baSchristos return hexdump; 7010e9868baSchristos } 702c74ad251Schristos sublen = GET_U_1(tptr + 6); 7030e9868baSchristos if (tlv_len < 7+sublen) { 7040e9868baSchristos return hexdump; 7050e9868baSchristos } 706c74ad251Schristos ND_PRINT("\n\t vlan name: "); 707c74ad251Schristos nd_printjnp(ndo, tptr + 7, sublen); 7080f74e101Schristos break; 7090f74e101Schristos case LLDP_PRIVATE_8021_SUBTYPE_PROTOCOL_IDENTITY: 7100e9868baSchristos if (tlv_len < 5) { 7110e9868baSchristos return hexdump; 7120e9868baSchristos } 713c74ad251Schristos sublen = GET_U_1(tptr + 4); 7140e9868baSchristos if (tlv_len < 5+sublen) { 7150e9868baSchristos return hexdump; 7160e9868baSchristos } 717c74ad251Schristos ND_PRINT("\n\t protocol identity: "); 718c74ad251Schristos nd_printjnp(ndo, tptr + 5, sublen); 7190f74e101Schristos break; 720c74ad251Schristos 721c74ad251Schristos case LLDP_PRIVATE_8021_SUBTYPE_LINKAGGR: 722c74ad251Schristos if (tlv_len < 9) { 723c74ad251Schristos return hexdump; 724c74ad251Schristos } 725c74ad251Schristos ND_PRINT("\n\t aggregation status [%s], aggregation port ID %u", 726c74ad251Schristos bittok2str(lldp_aggregation_values, "none", GET_U_1((tptr + 4))), 727c74ad251Schristos GET_BE_U_4(tptr + 5)); 728c74ad251Schristos break; 729c74ad251Schristos 730870189d2Schristos case LLDP_PRIVATE_8021_SUBTYPE_CONGESTION_NOTIFICATION: 731870189d2Schristos if(tlv_len<LLDP_PRIVATE_8021_SUBTYPE_CONGESTION_NOTIFICATION_LENGTH){ 732870189d2Schristos return hexdump; 733870189d2Schristos } 734c74ad251Schristos tval=GET_U_1(tptr + 4); 735c74ad251Schristos ND_PRINT("\n\t Pre-Priority CNPV Indicator"); 736c74ad251Schristos ND_PRINT("\n\t Priority : 0 1 2 3 4 5 6 7"); 737c74ad251Schristos ND_PRINT("\n\t Value : "); 738870189d2Schristos for(i=0;i<NO_OF_BITS;i++) 739c74ad251Schristos ND_PRINT("%-2d ", (tval >> i) & 0x01); 740c74ad251Schristos tval=GET_U_1(tptr + 5); 741c74ad251Schristos ND_PRINT("\n\t Pre-Priority Ready Indicator"); 742c74ad251Schristos ND_PRINT("\n\t Priority : 0 1 2 3 4 5 6 7"); 743c74ad251Schristos ND_PRINT("\n\t Value : "); 744870189d2Schristos for(i=0;i<NO_OF_BITS;i++) 745c74ad251Schristos ND_PRINT("%-2d ", (tval >> i) & 0x01); 746870189d2Schristos break; 747870189d2Schristos 748870189d2Schristos case LLDP_PRIVATE_8021_SUBTYPE_ETS_CONFIGURATION: 749870189d2Schristos if(tlv_len<LLDP_PRIVATE_8021_SUBTYPE_ETS_CONFIGURATION_LENGTH) { 750870189d2Schristos return hexdump; 751870189d2Schristos } 752c74ad251Schristos tval=GET_U_1(tptr + 4); 753c74ad251Schristos ND_PRINT("\n\t Willing:%u, CBS:%u, RES:%u, Max TCs:%u", 754c74ad251Schristos tval >> 7, (tval >> 6) & 0x02, (tval >> 3) & 0x07, tval & 0x07); 755870189d2Schristos 756870189d2Schristos /*Print Priority Assignment Table*/ 757b3a00663Schristos print_ets_priority_assignment_table(ndo, tptr + 5); 758870189d2Schristos 759870189d2Schristos /*Print TC Bandwidth Table*/ 760b3a00663Schristos print_tc_bandwidth_table(ndo, tptr + 9); 761870189d2Schristos 762870189d2Schristos /* Print TSA Assignment Table */ 763b3a00663Schristos print_tsa_assignment_table(ndo, tptr + 17); 764870189d2Schristos 765870189d2Schristos break; 766870189d2Schristos 767870189d2Schristos case LLDP_PRIVATE_8021_SUBTYPE_ETS_RECOMMENDATION: 768870189d2Schristos if(tlv_len<LLDP_PRIVATE_8021_SUBTYPE_ETS_RECOMMENDATION_LENGTH) { 769870189d2Schristos return hexdump; 770870189d2Schristos } 771c74ad251Schristos ND_PRINT("\n\t RES: %u", GET_U_1(tptr + 4)); 772870189d2Schristos /*Print Priority Assignment Table */ 773b3a00663Schristos print_ets_priority_assignment_table(ndo, tptr + 5); 774870189d2Schristos /*Print TC Bandwidth Table */ 775b3a00663Schristos print_tc_bandwidth_table(ndo, tptr + 9); 776870189d2Schristos /* Print TSA Assignment Table */ 777b3a00663Schristos print_tsa_assignment_table(ndo, tptr + 17); 778870189d2Schristos break; 779870189d2Schristos 780870189d2Schristos case LLDP_PRIVATE_8021_SUBTYPE_PFC_CONFIGURATION: 781870189d2Schristos if(tlv_len<LLDP_PRIVATE_8021_SUBTYPE_PFC_CONFIGURATION_LENGTH) { 782870189d2Schristos return hexdump; 783870189d2Schristos } 784c74ad251Schristos tval=GET_U_1(tptr + 4); 785c74ad251Schristos ND_PRINT("\n\t Willing: %u, MBC: %u, RES: %u, PFC cap:%u ", 786c74ad251Schristos tval >> 7, (tval >> 6) & 0x01, (tval >> 4) & 0x03, (tval & 0x0f)); 787c74ad251Schristos ND_PRINT("\n\t PFC Enable"); 788c74ad251Schristos tval=GET_U_1(tptr + 5); 789c74ad251Schristos ND_PRINT("\n\t Priority : 0 1 2 3 4 5 6 7"); 790c74ad251Schristos ND_PRINT("\n\t Value : "); 791870189d2Schristos for(i=0;i<NO_OF_BITS;i++) 792c74ad251Schristos ND_PRINT("%-2d ", (tval >> i) & 0x01); 793870189d2Schristos break; 794870189d2Schristos 795870189d2Schristos case LLDP_PRIVATE_8021_SUBTYPE_APPLICATION_PRIORITY: 796870189d2Schristos if(tlv_len<LLDP_PRIVATE_8021_SUBTYPE_APPLICATION_PRIORITY_MIN_LENGTH) { 797870189d2Schristos return hexdump; 798870189d2Schristos } 799c74ad251Schristos ND_PRINT("\n\t RES: %u", GET_U_1(tptr + 4)); 800870189d2Schristos if(tlv_len<=LLDP_PRIVATE_8021_SUBTYPE_APPLICATION_PRIORITY_MIN_LENGTH){ 801870189d2Schristos return hexdump; 802870189d2Schristos } 803870189d2Schristos /* Length of Application Priority Table */ 804870189d2Schristos sublen=tlv_len-5; 805870189d2Schristos if(sublen%3!=0){ 806870189d2Schristos return hexdump; 807870189d2Schristos } 808870189d2Schristos i=0; 809c74ad251Schristos ND_PRINT("\n\t Application Priority Table"); 810870189d2Schristos while(i<sublen) { 811c74ad251Schristos tval=GET_U_1(tptr + i + 5); 812c74ad251Schristos ND_PRINT("\n\t Priority: %u, RES: %u, Sel: %u, Protocol ID: %u", 81372c96ff3Schristos tval >> 5, (tval >> 3) & 0x03, (tval & 0x07), 814c74ad251Schristos GET_BE_U_2(tptr + i + 6)); 815870189d2Schristos i=i+3; 816870189d2Schristos } 817870189d2Schristos break; 818870189d2Schristos case LLDP_PRIVATE_8021_SUBTYPE_EVB: 819870189d2Schristos if(tlv_len<LLDP_PRIVATE_8021_SUBTYPE_EVB_LENGTH){ 820870189d2Schristos return hexdump; 821870189d2Schristos } 822c74ad251Schristos ND_PRINT("\n\t EVB Bridge Status"); 823c74ad251Schristos tval=GET_U_1(tptr + 4); 824c74ad251Schristos ND_PRINT("\n\t RES: %u, BGID: %u, RRCAP: %u, RRCTR: %u", 825c74ad251Schristos tval >> 3, (tval >> 2) & 0x01, (tval >> 1) & 0x01, tval & 0x01); 826c74ad251Schristos ND_PRINT("\n\t EVB Station Status"); 827c74ad251Schristos tval=GET_U_1(tptr + 5); 828c74ad251Schristos ND_PRINT("\n\t RES: %u, SGID: %u, RRREQ: %u,RRSTAT: %u", 829c74ad251Schristos tval >> 4, (tval >> 3) & 0x01, (tval >> 2) & 0x01, tval & 0x03); 830c74ad251Schristos tval=GET_U_1(tptr + 6); 831c74ad251Schristos ND_PRINT("\n\t R: %u, RTE: %u, ",tval >> 5, tval & 0x1f); 832c74ad251Schristos tval=GET_U_1(tptr + 7); 833c74ad251Schristos ND_PRINT("EVB Mode: %s [%u]", 834c74ad251Schristos tok2str(lldp_evb_mode_values, "unknown", tval >> 6), tval >> 6); 835c74ad251Schristos ND_PRINT("\n\t ROL: %u, RWD: %u, ", (tval >> 5) & 0x01, tval & 0x1f); 836c74ad251Schristos tval=GET_U_1(tptr + 8); 837c74ad251Schristos ND_PRINT("RES: %u, ROL: %u, RKA: %u", tval >> 6, (tval >> 5) & 0x01, tval & 0x1f); 838870189d2Schristos break; 839870189d2Schristos 840870189d2Schristos case LLDP_PRIVATE_8021_SUBTYPE_CDCP: 841870189d2Schristos if(tlv_len<LLDP_PRIVATE_8021_SUBTYPE_CDCP_MIN_LENGTH){ 842870189d2Schristos return hexdump; 843870189d2Schristos } 844c74ad251Schristos tval=GET_U_1(tptr + 4); 845c74ad251Schristos ND_PRINT("\n\t Role: %u, RES: %u, Scomp: %u ", 846c74ad251Schristos tval >> 7, (tval >> 4) & 0x07, (tval >> 3) & 0x01); 847c74ad251Schristos ND_PRINT("ChnCap: %u", GET_BE_U_2(tptr + 6) & 0x0fff); 848870189d2Schristos sublen=tlv_len-8; 849870189d2Schristos if(sublen%3!=0) { 850870189d2Schristos return hexdump; 851870189d2Schristos } 852870189d2Schristos i=0; 853870189d2Schristos while(i<sublen) { 854c74ad251Schristos tval=GET_BE_U_3(tptr + i + 8); 855c74ad251Schristos ND_PRINT("\n\t SCID: %u, SVID: %u", 856c74ad251Schristos tval >> 12, tval & 0x000fff); 857870189d2Schristos i=i+3; 858870189d2Schristos } 859870189d2Schristos break; 8600f74e101Schristos 8610f74e101Schristos default: 8620f74e101Schristos hexdump = TRUE; 8630f74e101Schristos break; 8640f74e101Schristos } 8650f74e101Schristos 8660f74e101Schristos return hexdump; 8670f74e101Schristos } 8680f74e101Schristos 8690f74e101Schristos /* 8700e9868baSchristos * Print IEEE 802.3 private extensions. (802.3bc) 8710f74e101Schristos */ 8720f74e101Schristos static int 873b3a00663Schristos lldp_private_8023_print(netdissect_options *ndo, 874b3a00663Schristos const u_char *tptr, u_int tlv_len) 8750f74e101Schristos { 876c74ad251Schristos int hexdump = FALSE; 877c74ad251Schristos u_int subtype; 8780f74e101Schristos 8790e9868baSchristos if (tlv_len < 4) { 8800e9868baSchristos return hexdump; 8810e9868baSchristos } 882c74ad251Schristos subtype = GET_U_1(tptr + 3); 8830f74e101Schristos 884c74ad251Schristos ND_PRINT("\n\t %s Subtype (%u)", 8850f74e101Schristos tok2str(lldp_8023_subtype_values, "unknown", subtype), 886c74ad251Schristos subtype); 8870f74e101Schristos 8880f74e101Schristos switch (subtype) { 8890f74e101Schristos case LLDP_PRIVATE_8023_SUBTYPE_MACPHY: 8900e9868baSchristos if (tlv_len < 9) { 8910e9868baSchristos return hexdump; 8920e9868baSchristos } 893c74ad251Schristos ND_PRINT("\n\t autonegotiation [%s] (0x%02x)", 894c74ad251Schristos bittok2str(lldp_8023_autonegotiation_values, "none", GET_U_1(tptr + 4)), 895c74ad251Schristos GET_U_1(tptr + 4)); 896c74ad251Schristos ND_PRINT("\n\t PMD autoneg capability [%s] (0x%04x)", 897c74ad251Schristos bittok2str(lldp_pmd_capability_values,"unknown", GET_BE_U_2(tptr + 5)), 898c74ad251Schristos GET_BE_U_2(tptr + 5)); 899c74ad251Schristos ND_PRINT("\n\t MAU type %s (0x%04x)", 900c74ad251Schristos tok2str(lldp_mau_types_values, "unknown", GET_BE_U_2(tptr + 7)), 901c74ad251Schristos GET_BE_U_2(tptr + 7)); 9020f74e101Schristos break; 9030f74e101Schristos 9040f74e101Schristos case LLDP_PRIVATE_8023_SUBTYPE_MDIPOWER: 9050e9868baSchristos if (tlv_len < 7) { 9060e9868baSchristos return hexdump; 9070e9868baSchristos } 908c74ad251Schristos ND_PRINT("\n\t MDI power support [%s], power pair %s, power class %s", 909c74ad251Schristos bittok2str(lldp_mdi_values, "none", GET_U_1((tptr + 4))), 910c74ad251Schristos tok2str(lldp_mdi_power_pairs_values, "unknown", GET_U_1((tptr + 5))), 911c74ad251Schristos tok2str(lldp_mdi_power_class_values, "unknown", GET_U_1((tptr + 6)))); 9120f74e101Schristos break; 9130f74e101Schristos 9140f74e101Schristos case LLDP_PRIVATE_8023_SUBTYPE_LINKAGGR: 9150e9868baSchristos if (tlv_len < 9) { 9160e9868baSchristos return hexdump; 9170e9868baSchristos } 918c74ad251Schristos ND_PRINT("\n\t aggregation status [%s], aggregation port ID %u", 919c74ad251Schristos bittok2str(lldp_aggregation_values, "none", GET_U_1((tptr + 4))), 920c74ad251Schristos GET_BE_U_4(tptr + 5)); 9210f74e101Schristos break; 9220f74e101Schristos 9230f74e101Schristos case LLDP_PRIVATE_8023_SUBTYPE_MTU: 92472c96ff3Schristos if (tlv_len < 6) { 92572c96ff3Schristos return hexdump; 92672c96ff3Schristos } 927c74ad251Schristos ND_PRINT("\n\t MTU size %u", GET_BE_U_2(tptr + 4)); 9280f74e101Schristos break; 9290f74e101Schristos 9300f74e101Schristos default: 9310f74e101Schristos hexdump = TRUE; 9320f74e101Schristos break; 9330f74e101Schristos } 9340f74e101Schristos 9350f74e101Schristos return hexdump; 9360f74e101Schristos } 9370f74e101Schristos 9380f74e101Schristos /* 9390f74e101Schristos * Extract 34bits of latitude/longitude coordinates. 9400f74e101Schristos */ 941b3a00663Schristos static uint64_t 942c74ad251Schristos lldp_extract_latlon(netdissect_options *ndo, const u_char *tptr) 9430f74e101Schristos { 944b3a00663Schristos uint64_t latlon; 9450f74e101Schristos 946c74ad251Schristos latlon = GET_U_1(tptr) & 0x3; 947c74ad251Schristos latlon = (latlon << 32) | GET_BE_U_4(tptr + 1); 9480f74e101Schristos 9490f74e101Schristos return latlon; 9500f74e101Schristos } 9510f74e101Schristos 952dc860a36Sspz /* objects defined in IANA subtype 00 00 5e 953dc860a36Sspz * (right now there is only one) 954dc860a36Sspz */ 955dc860a36Sspz 956dc860a36Sspz 957dc860a36Sspz static int 958dc860a36Sspz lldp_private_iana_print(netdissect_options *ndo, 959dc860a36Sspz const u_char *tptr, u_int tlv_len) 960dc860a36Sspz { 961c74ad251Schristos int hexdump = FALSE; 962c74ad251Schristos u_int subtype; 963dc860a36Sspz 964dc860a36Sspz if (tlv_len < 8) { 965dc860a36Sspz return hexdump; 966dc860a36Sspz } 967c74ad251Schristos subtype = GET_U_1(tptr + 3); 968dc860a36Sspz 969c74ad251Schristos ND_PRINT("\n\t %s Subtype (%u)", 970dc860a36Sspz tok2str(lldp_iana_subtype_values, "unknown", subtype), 971c74ad251Schristos subtype); 972dc860a36Sspz 973dc860a36Sspz switch (subtype) { 974dc860a36Sspz case LLDP_IANA_SUBTYPE_MUDURL: 975c74ad251Schristos ND_PRINT("\n\t MUD-URL="); 976c74ad251Schristos (void)nd_printn(ndo, tptr+4, tlv_len-4, NULL); 977dc860a36Sspz break; 978dc860a36Sspz default: 979dc860a36Sspz hexdump=TRUE; 980dc860a36Sspz } 981dc860a36Sspz 982dc860a36Sspz return hexdump; 983dc860a36Sspz } 984dc860a36Sspz 985dc860a36Sspz 986dc860a36Sspz 9870f74e101Schristos /* 9880f74e101Schristos * Print private TIA extensions. 9890f74e101Schristos */ 9900f74e101Schristos static int 991b3a00663Schristos lldp_private_tia_print(netdissect_options *ndo, 992b3a00663Schristos const u_char *tptr, u_int tlv_len) 9930f74e101Schristos { 994c74ad251Schristos int hexdump = FALSE; 995c74ad251Schristos u_int subtype; 996b3a00663Schristos uint8_t location_format; 997b3a00663Schristos uint16_t power_val; 9980e9868baSchristos u_int lci_len; 999b3a00663Schristos uint8_t ca_type, ca_len; 10000f74e101Schristos 10010e9868baSchristos if (tlv_len < 4) { 10020e9868baSchristos return hexdump; 10030e9868baSchristos } 1004c74ad251Schristos subtype = GET_U_1(tptr + 3); 10050f74e101Schristos 1006c74ad251Schristos ND_PRINT("\n\t %s Subtype (%u)", 10070f74e101Schristos tok2str(lldp_tia_subtype_values, "unknown", subtype), 1008c74ad251Schristos subtype); 10090f74e101Schristos 10100f74e101Schristos switch (subtype) { 10110f74e101Schristos case LLDP_PRIVATE_TIA_SUBTYPE_CAPABILITIES: 10120e9868baSchristos if (tlv_len < 7) { 10130e9868baSchristos return hexdump; 10140e9868baSchristos } 1015c74ad251Schristos ND_PRINT("\n\t Media capabilities [%s] (0x%04x)", 10160f74e101Schristos bittok2str(lldp_tia_capabilities_values, "none", 1017c74ad251Schristos GET_BE_U_2(tptr + 4)), GET_BE_U_2(tptr + 4)); 1018c74ad251Schristos ND_PRINT("\n\t Device type [%s] (0x%02x)", 1019c74ad251Schristos tok2str(lldp_tia_device_type_values, "unknown", GET_U_1(tptr + 6)), 1020c74ad251Schristos GET_U_1(tptr + 6)); 10210f74e101Schristos break; 10220f74e101Schristos 10230f74e101Schristos case LLDP_PRIVATE_TIA_SUBTYPE_NETWORK_POLICY: 10240e9868baSchristos if (tlv_len < 8) { 10250e9868baSchristos return hexdump; 10260e9868baSchristos } 1027c74ad251Schristos ND_PRINT("\n\t Application type [%s] (0x%02x)", 1028c74ad251Schristos tok2str(lldp_tia_application_type_values, "none", GET_U_1(tptr + 4)), 1029c74ad251Schristos GET_U_1(tptr + 4)); 1030c74ad251Schristos ND_PRINT(", Flags [%s]", bittok2str( 1031c74ad251Schristos lldp_tia_network_policy_bits_values, "none", GET_U_1((tptr + 5)))); 1032c74ad251Schristos ND_PRINT("\n\t Vlan id %u", 1033c74ad251Schristos LLDP_EXTRACT_NETWORK_POLICY_VLAN(GET_BE_U_2(tptr + 5))); 1034c74ad251Schristos ND_PRINT(", L2 priority %u", 1035c74ad251Schristos LLDP_EXTRACT_NETWORK_POLICY_L2_PRIORITY(GET_BE_U_2(tptr + 6))); 1036c74ad251Schristos ND_PRINT(", DSCP value %u", 1037c74ad251Schristos LLDP_EXTRACT_NETWORK_POLICY_DSCP(GET_BE_U_2(tptr + 6))); 10380f74e101Schristos break; 10390f74e101Schristos 10400f74e101Schristos case LLDP_PRIVATE_TIA_SUBTYPE_LOCAL_ID: 10410e9868baSchristos if (tlv_len < 5) { 10420e9868baSchristos return hexdump; 10430e9868baSchristos } 1044c74ad251Schristos location_format = GET_U_1(tptr + 4); 1045c74ad251Schristos ND_PRINT("\n\t Location data format %s (0x%02x)", 10460f74e101Schristos tok2str(lldp_tia_location_data_format_values, "unknown", location_format), 1047c74ad251Schristos location_format); 10480f74e101Schristos 10490f74e101Schristos switch (location_format) { 10500f74e101Schristos case LLDP_TIA_LOCATION_DATA_FORMAT_COORDINATE_BASED: 10510e9868baSchristos if (tlv_len < 21) { 10520e9868baSchristos return hexdump; 10530e9868baSchristos } 1054c74ad251Schristos ND_PRINT("\n\t Latitude resolution %u, latitude value %" PRIu64, 1055c74ad251Schristos (GET_U_1(tptr + 5) >> 2), 1056c74ad251Schristos lldp_extract_latlon(ndo, tptr + 5)); 1057c74ad251Schristos ND_PRINT("\n\t Longitude resolution %u, longitude value %" PRIu64, 1058c74ad251Schristos (GET_U_1(tptr + 10) >> 2), 1059c74ad251Schristos lldp_extract_latlon(ndo, tptr + 10)); 1060c74ad251Schristos ND_PRINT("\n\t Altitude type %s (%u)", 1061c74ad251Schristos tok2str(lldp_tia_location_altitude_type_values, "unknown",GET_U_1(tptr + 15) >> 4), 1062c74ad251Schristos (GET_U_1(tptr + 15) >> 4)); 1063c74ad251Schristos ND_PRINT("\n\t Altitude resolution %u, altitude value 0x%x", 1064c74ad251Schristos (GET_BE_U_2(tptr + 15)>>6)&0x3f, 1065c74ad251Schristos (GET_BE_U_4(tptr + 16) & 0x3fffffff)); 1066c74ad251Schristos ND_PRINT("\n\t Datum %s (0x%02x)", 1067c74ad251Schristos tok2str(lldp_tia_location_datum_type_values, "unknown", GET_U_1(tptr + 20)), 1068c74ad251Schristos GET_U_1(tptr + 20)); 10690f74e101Schristos break; 10700f74e101Schristos 10710f74e101Schristos case LLDP_TIA_LOCATION_DATA_FORMAT_CIVIC_ADDRESS: 10720e9868baSchristos if (tlv_len < 6) { 10730e9868baSchristos return hexdump; 10740e9868baSchristos } 1075c74ad251Schristos lci_len = GET_U_1(tptr + 5); 10760e9868baSchristos if (lci_len < 3) { 10770e9868baSchristos return hexdump; 10780e9868baSchristos } 10790e9868baSchristos if (tlv_len < 7+lci_len) { 10800e9868baSchristos return hexdump; 10810e9868baSchristos } 1082c74ad251Schristos ND_PRINT("\n\t LCI length %u, LCI what %s (0x%02x), Country-code ", 10830f74e101Schristos lci_len, 1084c74ad251Schristos tok2str(lldp_tia_location_lci_what_values, "unknown", GET_U_1(tptr + 6)), 1085c74ad251Schristos GET_U_1(tptr + 6)); 10860f74e101Schristos 10870f74e101Schristos /* Country code */ 1088c74ad251Schristos nd_printjnp(ndo, tptr + 7, 2); 10890f74e101Schristos 10900f74e101Schristos lci_len = lci_len-3; 10910f74e101Schristos tptr = tptr + 9; 10920f74e101Schristos 10930f74e101Schristos /* Decode each civic address element */ 10940f74e101Schristos while (lci_len > 0) { 10950e9868baSchristos if (lci_len < 2) { 10960e9868baSchristos return hexdump; 10970e9868baSchristos } 1098c74ad251Schristos ca_type = GET_U_1(tptr); 1099c74ad251Schristos ca_len = GET_U_1(tptr + 1); 11000f74e101Schristos 11010f74e101Schristos tptr += 2; 11020f74e101Schristos lci_len -= 2; 11030f74e101Schristos 1104*26ba0b50Schristos ND_PRINT("\n\t CA type '%s' (%u), length %u: ", 11050f74e101Schristos tok2str(lldp_tia_location_lci_catype_values, "unknown", ca_type), 1106c74ad251Schristos ca_type, ca_len); 11070f74e101Schristos 11080f74e101Schristos /* basic sanity check */ 11090f74e101Schristos if ( ca_type == 0 || ca_len == 0) { 11100f74e101Schristos return hexdump; 11110f74e101Schristos } 11120e9868baSchristos if (lci_len < ca_len) { 11130e9868baSchristos return hexdump; 11140e9868baSchristos } 11150f74e101Schristos 1116c74ad251Schristos nd_printjnp(ndo, tptr, ca_len); 11170f74e101Schristos tptr += ca_len; 11180f74e101Schristos lci_len -= ca_len; 11190f74e101Schristos } 11200f74e101Schristos break; 11210f74e101Schristos 11220f74e101Schristos case LLDP_TIA_LOCATION_DATA_FORMAT_ECS_ELIN: 1123c74ad251Schristos ND_PRINT("\n\t ECS ELIN id "); 1124c74ad251Schristos nd_printjnp(ndo, tptr + 5, tlv_len - 5); 11250f74e101Schristos break; 11260f74e101Schristos 11270f74e101Schristos default: 1128c74ad251Schristos ND_PRINT("\n\t Location ID "); 1129b3a00663Schristos print_unknown_data(ndo, tptr + 5, "\n\t ", tlv_len - 5); 11300f74e101Schristos } 11310f74e101Schristos break; 11320f74e101Schristos 11330f74e101Schristos case LLDP_PRIVATE_TIA_SUBTYPE_EXTENDED_POWER_MDI: 11340e9868baSchristos if (tlv_len < 7) { 11350e9868baSchristos return hexdump; 11360e9868baSchristos } 1137c74ad251Schristos ND_PRINT("\n\t Power type [%s]", 1138c74ad251Schristos (GET_U_1(tptr + 4) & 0xC0 >> 6) ? "PD device" : "PSE device"); 1139c74ad251Schristos ND_PRINT(", Power source [%s]", 1140c74ad251Schristos tok2str(lldp_tia_power_source_values, "none", (GET_U_1((tptr + 4)) & 0x30) >> 4)); 1141c74ad251Schristos ND_PRINT("\n\t Power priority [%s] (0x%02x)", 1142c74ad251Schristos tok2str(lldp_tia_power_priority_values, "none", GET_U_1(tptr + 4) & 0x0f), 1143c74ad251Schristos GET_U_1(tptr + 4) & 0x0f); 1144c74ad251Schristos power_val = GET_BE_U_2(tptr + 5); 11450f74e101Schristos if (power_val < LLDP_TIA_POWER_VAL_MAX) { 1146c74ad251Schristos ND_PRINT(", Power %.1f Watts", ((float)power_val) / 10); 11470f74e101Schristos } else { 1148c74ad251Schristos ND_PRINT(", Power %u (Reserved)", power_val); 11490f74e101Schristos } 11500f74e101Schristos break; 11510f74e101Schristos 11520f74e101Schristos case LLDP_PRIVATE_TIA_SUBTYPE_INVENTORY_HARDWARE_REV: 11530f74e101Schristos case LLDP_PRIVATE_TIA_SUBTYPE_INVENTORY_FIRMWARE_REV: 11540f74e101Schristos case LLDP_PRIVATE_TIA_SUBTYPE_INVENTORY_SOFTWARE_REV: 11550f74e101Schristos case LLDP_PRIVATE_TIA_SUBTYPE_INVENTORY_SERIAL_NUMBER: 11560f74e101Schristos case LLDP_PRIVATE_TIA_SUBTYPE_INVENTORY_MANUFACTURER_NAME: 11570f74e101Schristos case LLDP_PRIVATE_TIA_SUBTYPE_INVENTORY_MODEL_NAME: 11580f74e101Schristos case LLDP_PRIVATE_TIA_SUBTYPE_INVENTORY_ASSET_ID: 1159c74ad251Schristos ND_PRINT("\n\t %s ", 1160c74ad251Schristos tok2str(lldp_tia_inventory_values, "unknown", subtype)); 1161c74ad251Schristos nd_printjnp(ndo, tptr + 4, tlv_len - 4); 11620f74e101Schristos break; 11630f74e101Schristos 11640f74e101Schristos default: 11650f74e101Schristos hexdump = TRUE; 11660f74e101Schristos break; 11670f74e101Schristos } 11680f74e101Schristos 11690f74e101Schristos return hexdump; 11700f74e101Schristos } 11710f74e101Schristos 11720e9868baSchristos /* 11730e9868baSchristos * Print DCBX Protocol fields (V 1.01). 11740e9868baSchristos */ 11750e9868baSchristos static int 1176b3a00663Schristos lldp_private_dcbx_print(netdissect_options *ndo, 1177b3a00663Schristos const u_char *pptr, u_int len) 11780e9868baSchristos { 1179c74ad251Schristos int hexdump = FALSE; 1180c74ad251Schristos u_int subtype; 1181c74ad251Schristos uint16_t tval; 1182b3a00663Schristos uint16_t tlv; 1183b3a00663Schristos uint32_t i, pgval, uval; 1184c74ad251Schristos u_int tlen, tlv_type; 1185c74ad251Schristos uint16_t tlv_len; 11860e9868baSchristos const u_char *tptr, *mptr; 11870e9868baSchristos 11880e9868baSchristos if (len < 4) { 11890e9868baSchristos return hexdump; 11900e9868baSchristos } 1191c74ad251Schristos subtype = GET_U_1(pptr + 3); 11920e9868baSchristos 1193c74ad251Schristos ND_PRINT("\n\t %s Subtype (%u)", 11940e9868baSchristos tok2str(lldp_dcbx_subtype_values, "unknown", subtype), 1195c74ad251Schristos subtype); 11960e9868baSchristos 11970e9868baSchristos /* by passing old version */ 11980e9868baSchristos if (subtype == LLDP_DCBX_SUBTYPE_1) 11990e9868baSchristos return TRUE; 12000e9868baSchristos 12010e9868baSchristos tptr = pptr + 4; 12020e9868baSchristos tlen = len - 4; 12030e9868baSchristos 12040e9868baSchristos while (tlen >= sizeof(tlv)) { 12050e9868baSchristos 1206c74ad251Schristos ND_TCHECK_LEN(tptr, sizeof(tlv)); 12070e9868baSchristos 1208c74ad251Schristos tlv = GET_BE_U_2(tptr); 12090e9868baSchristos 12100e9868baSchristos tlv_type = LLDP_EXTRACT_TYPE(tlv); 12110e9868baSchristos tlv_len = LLDP_EXTRACT_LEN(tlv); 12120e9868baSchristos hexdump = FALSE; 12130e9868baSchristos 12140e9868baSchristos tlen -= sizeof(tlv); 12150e9868baSchristos tptr += sizeof(tlv); 12160e9868baSchristos 12170e9868baSchristos /* loop check */ 12180e9868baSchristos if (!tlv_type || !tlv_len) { 12190e9868baSchristos break; 12200e9868baSchristos } 12210e9868baSchristos 1222c74ad251Schristos ND_TCHECK_LEN(tptr, tlv_len); 12230e9868baSchristos if (tlen < tlv_len) { 12240e9868baSchristos goto trunc; 12250e9868baSchristos } 12260e9868baSchristos 12270e9868baSchristos /* decode every tlv */ 12280e9868baSchristos switch (tlv_type) { 12290e9868baSchristos case LLDP_DCBX_CONTROL_TLV: 12300e9868baSchristos if (tlv_len < 10) { 12310e9868baSchristos goto trunc; 12320e9868baSchristos } 1233c74ad251Schristos ND_PRINT("\n\t Control - Protocol Control (type 0x%x, length %u)", 1234c74ad251Schristos LLDP_DCBX_CONTROL_TLV, tlv_len); 1235c74ad251Schristos ND_PRINT("\n\t Oper_Version: %u", GET_U_1(tptr)); 1236c74ad251Schristos ND_PRINT("\n\t Max_Version: %u", GET_U_1(tptr + 1)); 1237c74ad251Schristos ND_PRINT("\n\t Sequence Number: %u", GET_BE_U_4(tptr + 2)); 1238c74ad251Schristos ND_PRINT("\n\t Acknowledgement Number: %u", 1239c74ad251Schristos GET_BE_U_4(tptr + 6)); 12400e9868baSchristos break; 12410e9868baSchristos case LLDP_DCBX_PRIORITY_GROUPS_TLV: 12420e9868baSchristos if (tlv_len < 17) { 12430e9868baSchristos goto trunc; 12440e9868baSchristos } 1245c74ad251Schristos ND_PRINT("\n\t Feature - Priority Group (type 0x%x, length %u)", 1246c74ad251Schristos LLDP_DCBX_PRIORITY_GROUPS_TLV, tlv_len); 1247c74ad251Schristos ND_PRINT("\n\t Oper_Version: %u", GET_U_1(tptr)); 1248c74ad251Schristos ND_PRINT("\n\t Max_Version: %u", GET_U_1(tptr + 1)); 1249c74ad251Schristos ND_PRINT("\n\t Info block(0x%02X): ", GET_U_1(tptr + 2)); 1250c74ad251Schristos tval = GET_U_1(tptr + 2); 1251c74ad251Schristos ND_PRINT("Enable bit: %u, Willing bit: %u, Error Bit: %u", 12520e9868baSchristos (tval & 0x80) ? 1 : 0, (tval & 0x40) ? 1 : 0, 1253c74ad251Schristos (tval & 0x20) ? 1 : 0); 1254c74ad251Schristos ND_PRINT("\n\t SubType: %u", GET_U_1(tptr + 3)); 1255c74ad251Schristos ND_PRINT("\n\t Priority Allocation"); 12560e9868baSchristos 1257b3a00663Schristos /* 1258b3a00663Schristos * Array of 8 4-bit priority group ID values; we fetch all 1259b3a00663Schristos * 32 bits and extract each nibble. 1260b3a00663Schristos */ 1261c74ad251Schristos pgval = GET_BE_U_4(tptr + 4); 12620e9868baSchristos for (i = 0; i <= 7; i++) { 1263c74ad251Schristos ND_PRINT("\n\t PgId_%u: %u", 1264c74ad251Schristos i, (pgval >> (28 - 4 * i)) & 0xF); 12650e9868baSchristos } 1266c74ad251Schristos ND_PRINT("\n\t Priority Group Allocation"); 12670e9868baSchristos for (i = 0; i <= 7; i++) 1268c74ad251Schristos ND_PRINT("\n\t Pg percentage[%u]: %u", i, 1269c74ad251Schristos GET_U_1(tptr + 8 + i)); 1270c74ad251Schristos ND_PRINT("\n\t NumTCsSupported: %u", GET_U_1(tptr + 8 + 8)); 12710e9868baSchristos break; 12720e9868baSchristos case LLDP_DCBX_PRIORITY_FLOW_CONTROL_TLV: 12730e9868baSchristos if (tlv_len < 6) { 12740e9868baSchristos goto trunc; 12750e9868baSchristos } 1276c74ad251Schristos ND_PRINT("\n\t Feature - Priority Flow Control"); 1277c74ad251Schristos ND_PRINT(" (type 0x%x, length %u)", 1278c74ad251Schristos LLDP_DCBX_PRIORITY_FLOW_CONTROL_TLV, tlv_len); 1279c74ad251Schristos ND_PRINT("\n\t Oper_Version: %u", GET_U_1(tptr)); 1280c74ad251Schristos ND_PRINT("\n\t Max_Version: %u", GET_U_1(tptr + 1)); 1281c74ad251Schristos ND_PRINT("\n\t Info block(0x%02X): ", GET_U_1(tptr + 2)); 1282c74ad251Schristos tval = GET_U_1(tptr + 2); 1283c74ad251Schristos ND_PRINT("Enable bit: %u, Willing bit: %u, Error Bit: %u", 12840e9868baSchristos (tval & 0x80) ? 1 : 0, (tval & 0x40) ? 1 : 0, 1285c74ad251Schristos (tval & 0x20) ? 1 : 0); 1286c74ad251Schristos ND_PRINT("\n\t SubType: %u", GET_U_1(tptr + 3)); 1287c74ad251Schristos tval = GET_U_1(tptr + 4); 1288c74ad251Schristos ND_PRINT("\n\t PFC Config (0x%02X)", GET_U_1(tptr + 4)); 12890e9868baSchristos for (i = 0; i <= 7; i++) 1290c74ad251Schristos ND_PRINT("\n\t Priority Bit %u: %s", 1291c74ad251Schristos i, (tval & (1 << i)) ? "Enabled" : "Disabled"); 1292c74ad251Schristos ND_PRINT("\n\t NumTCPFCSupported: %u", GET_U_1(tptr + 5)); 12930e9868baSchristos break; 12940e9868baSchristos case LLDP_DCBX_APPLICATION_TLV: 12950e9868baSchristos if (tlv_len < 4) { 12960e9868baSchristos goto trunc; 12970e9868baSchristos } 1298c74ad251Schristos ND_PRINT("\n\t Feature - Application (type 0x%x, length %u)", 1299c74ad251Schristos LLDP_DCBX_APPLICATION_TLV, tlv_len); 1300c74ad251Schristos ND_PRINT("\n\t Oper_Version: %u", GET_U_1(tptr)); 1301c74ad251Schristos ND_PRINT("\n\t Max_Version: %u", GET_U_1(tptr + 1)); 1302c74ad251Schristos ND_PRINT("\n\t Info block(0x%02X): ", GET_U_1(tptr + 2)); 1303c74ad251Schristos tval = GET_U_1(tptr + 2); 1304c74ad251Schristos ND_PRINT("Enable bit: %u, Willing bit: %u, Error Bit: %u", 13050e9868baSchristos (tval & 0x80) ? 1 : 0, (tval & 0x40) ? 1 : 0, 1306c74ad251Schristos (tval & 0x20) ? 1 : 0); 1307c74ad251Schristos ND_PRINT("\n\t SubType: %u", GET_U_1(tptr + 3)); 13080e9868baSchristos tval = tlv_len - 4; 13090e9868baSchristos mptr = tptr + 4; 13100e9868baSchristos while (tval >= 6) { 1311c74ad251Schristos ND_PRINT("\n\t Application Value"); 1312c74ad251Schristos ND_PRINT("\n\t Application Protocol ID: 0x%04x", 1313c74ad251Schristos GET_BE_U_2(mptr)); 1314c74ad251Schristos uval = GET_BE_U_3(mptr + 2); 1315c74ad251Schristos ND_PRINT("\n\t SF (0x%x) Application Protocol ID is %s", 13160e9868baSchristos (uval >> 22), 1317c74ad251Schristos (uval >> 22) ? "Socket Number" : "L2 EtherType"); 1318c74ad251Schristos ND_PRINT("\n\t OUI: 0x%06x", uval & 0x3fffff); 1319c74ad251Schristos ND_PRINT("\n\t User Priority Map: 0x%02x", 1320c74ad251Schristos GET_U_1(mptr + 5)); 13210e9868baSchristos tval = tval - 6; 13220e9868baSchristos mptr = mptr + 6; 13230e9868baSchristos } 13240e9868baSchristos break; 13250e9868baSchristos default: 13260e9868baSchristos hexdump = TRUE; 13270e9868baSchristos break; 13280e9868baSchristos } 13290e9868baSchristos 13300e9868baSchristos /* do we also want to see a hex dump ? */ 1331b3a00663Schristos if (ndo->ndo_vflag > 1 || (ndo->ndo_vflag && hexdump)) { 1332b3a00663Schristos print_unknown_data(ndo, tptr, "\n\t ", tlv_len); 13330e9868baSchristos } 13340e9868baSchristos 13350e9868baSchristos tlen -= tlv_len; 13360e9868baSchristos tptr += tlv_len; 13370e9868baSchristos } 13380e9868baSchristos 13390e9868baSchristos trunc: 13400e9868baSchristos return hexdump; 13410e9868baSchristos } 13420e9868baSchristos 13430f74e101Schristos static char * 1344ba2ff121Schristos lldp_network_addr_print(netdissect_options *ndo, const u_char *tptr, u_int len) 1345ba2ff121Schristos { 1346b3a00663Schristos uint8_t af; 13470f74e101Schristos static char buf[BUFSIZE]; 1348b3a00663Schristos const char * (*pfunc)(netdissect_options *, const u_char *); 13490f74e101Schristos 13500e9868baSchristos if (len < 1) 13510e9868baSchristos return NULL; 13520e9868baSchristos len--; 1353c74ad251Schristos af = GET_U_1(tptr); 13540f74e101Schristos switch (af) { 13550f74e101Schristos case AFNUM_INET: 1356c74ad251Schristos if (len < sizeof(nd_ipv4)) 13570e9868baSchristos return NULL; 1358c74ad251Schristos pfunc = ipaddr_string; 13590f74e101Schristos break; 13600f74e101Schristos case AFNUM_INET6: 1361c74ad251Schristos if (len < sizeof(nd_ipv6)) 13620e9868baSchristos return NULL; 1363c74ad251Schristos pfunc = ip6addr_string; 13640f74e101Schristos break; 13650f74e101Schristos case AFNUM_802: 1366c74ad251Schristos if (len < MAC_ADDR_LEN) 13670e9868baSchristos return NULL; 13680f74e101Schristos pfunc = etheraddr_string; 13690f74e101Schristos break; 13700f74e101Schristos default: 13710f74e101Schristos pfunc = NULL; 13720f74e101Schristos break; 13730f74e101Schristos } 13740f74e101Schristos 13750f74e101Schristos if (!pfunc) { 13760f74e101Schristos snprintf(buf, sizeof(buf), "AFI %s (%u), no AF printer !", 13770f74e101Schristos tok2str(af_values, "Unknown", af), af); 13780f74e101Schristos } else { 13790f74e101Schristos snprintf(buf, sizeof(buf), "AFI %s (%u): %s", 1380b3a00663Schristos tok2str(af_values, "Unknown", af), af, (*pfunc)(ndo, tptr+1)); 13810f74e101Schristos } 13820f74e101Schristos 13830f74e101Schristos return buf; 13840f74e101Schristos } 13850f74e101Schristos 13860f74e101Schristos static int 1387b3a00663Schristos lldp_mgmt_addr_tlv_print(netdissect_options *ndo, 1388ba2ff121Schristos const u_char *pptr, u_int len) 1389ba2ff121Schristos { 1390b3a00663Schristos uint8_t mgmt_addr_len, intf_num_subtype, oid_len; 13910f74e101Schristos const u_char *tptr; 13920f74e101Schristos u_int tlen; 13930e9868baSchristos char *mgmt_addr; 13940f74e101Schristos 13950f74e101Schristos tlen = len; 13960f74e101Schristos tptr = pptr; 13970f74e101Schristos 13980e9868baSchristos if (tlen < 1) { 13990e9868baSchristos return 0; 14000e9868baSchristos } 1401c74ad251Schristos mgmt_addr_len = GET_U_1(tptr); 1402c74ad251Schristos tptr++; 14030f74e101Schristos tlen--; 14040f74e101Schristos 14050f74e101Schristos if (tlen < mgmt_addr_len) { 14060f74e101Schristos return 0; 14070f74e101Schristos } 14080f74e101Schristos 1409b3a00663Schristos mgmt_addr = lldp_network_addr_print(ndo, tptr, mgmt_addr_len); 14100e9868baSchristos if (mgmt_addr == NULL) { 14110e9868baSchristos return 0; 14120e9868baSchristos } 1413c74ad251Schristos ND_PRINT("\n\t Management Address length %u, %s", 1414c74ad251Schristos mgmt_addr_len, mgmt_addr); 14150f74e101Schristos tptr += mgmt_addr_len; 14160f74e101Schristos tlen -= mgmt_addr_len; 14170f74e101Schristos 14180f74e101Schristos if (tlen < LLDP_INTF_NUM_LEN) { 14190f74e101Schristos return 0; 14200f74e101Schristos } 14210f74e101Schristos 1422c74ad251Schristos intf_num_subtype = GET_U_1(tptr); 1423c74ad251Schristos ND_PRINT("\n\t %s Interface Numbering (%u): %u", 14240f74e101Schristos tok2str(lldp_intf_numb_subtype_values, "Unknown", intf_num_subtype), 14250f74e101Schristos intf_num_subtype, 1426c74ad251Schristos GET_BE_U_4(tptr + 1)); 14270f74e101Schristos 14280f74e101Schristos tptr += LLDP_INTF_NUM_LEN; 14290f74e101Schristos tlen -= LLDP_INTF_NUM_LEN; 14300f74e101Schristos 14310f74e101Schristos /* 14320f74e101Schristos * The OID is optional. 14330f74e101Schristos */ 14340f74e101Schristos if (tlen) { 1435c74ad251Schristos oid_len = GET_U_1(tptr); 14360f74e101Schristos 143772c96ff3Schristos if (tlen < 1U + oid_len) { 14380e9868baSchristos return 0; 14390e9868baSchristos } 14400f74e101Schristos if (oid_len) { 1441c74ad251Schristos ND_PRINT("\n\t OID length %u", oid_len); 1442c74ad251Schristos nd_printjnp(ndo, tptr + 1, oid_len); 14430f74e101Schristos } 14440f74e101Schristos } 14450f74e101Schristos 14460f74e101Schristos return 1; 14470f74e101Schristos } 14480f74e101Schristos 14490f74e101Schristos void 1450b3a00663Schristos lldp_print(netdissect_options *ndo, 1451c74ad251Schristos const u_char *pptr, u_int len) 1452ba2ff121Schristos { 1453b3a00663Schristos uint8_t subtype; 1454b3a00663Schristos uint16_t tlv, cap, ena_cap; 14550f74e101Schristos u_int oui, tlen, hexdump, tlv_type, tlv_len; 14560f74e101Schristos const u_char *tptr; 14570e9868baSchristos char *network_addr; 14580f74e101Schristos 1459c74ad251Schristos ndo->ndo_protocol = "lldp"; 14600f74e101Schristos tptr = pptr; 14610f74e101Schristos tlen = len; 14620f74e101Schristos 1463c74ad251Schristos ND_PRINT("LLDP, length %u", len); 14640f74e101Schristos 14650f74e101Schristos while (tlen >= sizeof(tlv)) { 14660f74e101Schristos 1467c74ad251Schristos ND_TCHECK_LEN(tptr, sizeof(tlv)); 14680f74e101Schristos 1469c74ad251Schristos tlv = GET_BE_U_2(tptr); 14700f74e101Schristos 14710f74e101Schristos tlv_type = LLDP_EXTRACT_TYPE(tlv); 14720f74e101Schristos tlv_len = LLDP_EXTRACT_LEN(tlv); 14730f74e101Schristos hexdump = FALSE; 14740f74e101Schristos 14750f74e101Schristos tlen -= sizeof(tlv); 14760f74e101Schristos tptr += sizeof(tlv); 14770f74e101Schristos 1478b3a00663Schristos if (ndo->ndo_vflag) { 1479c74ad251Schristos ND_PRINT("\n\t%s TLV (%u), length %u", 14800f74e101Schristos tok2str(lldp_tlv_values, "Unknown", tlv_type), 1481c74ad251Schristos tlv_type, tlv_len); 14820f74e101Schristos } 14830f74e101Schristos 14840f74e101Schristos /* infinite loop check */ 14850f74e101Schristos if (!tlv_type || !tlv_len) { 14860f74e101Schristos break; 14870f74e101Schristos } 14880f74e101Schristos 1489c74ad251Schristos ND_TCHECK_LEN(tptr, tlv_len); 14900e9868baSchristos if (tlen < tlv_len) { 14910e9868baSchristos goto trunc; 14920e9868baSchristos } 14930f74e101Schristos 14940f74e101Schristos switch (tlv_type) { 14950e9868baSchristos 14960e9868baSchristos case LLDP_CHASSIS_ID_TLV: 1497b3a00663Schristos if (ndo->ndo_vflag) { 14980e9868baSchristos if (tlv_len < 2) { 14990e9868baSchristos goto trunc; 15000e9868baSchristos } 1501c74ad251Schristos subtype = GET_U_1(tptr); 1502c74ad251Schristos ND_PRINT("\n\t Subtype %s (%u): ", 15030e9868baSchristos tok2str(lldp_chassis_subtype_values, "Unknown", subtype), 1504c74ad251Schristos subtype); 15050e9868baSchristos 15060e9868baSchristos switch (subtype) { 15070e9868baSchristos case LLDP_CHASSIS_MAC_ADDR_SUBTYPE: 15080e9868baSchristos if (tlv_len < 1+6) { 15090e9868baSchristos goto trunc; 15100e9868baSchristos } 1511c74ad251Schristos ND_PRINT("%s", GET_ETHERADDR_STRING(tptr + 1)); 15120e9868baSchristos break; 15130e9868baSchristos 15140e9868baSchristos case LLDP_CHASSIS_INTF_NAME_SUBTYPE: /* fall through */ 15150e9868baSchristos case LLDP_CHASSIS_LOCAL_SUBTYPE: 15160e9868baSchristos case LLDP_CHASSIS_CHASSIS_COMP_SUBTYPE: 15170e9868baSchristos case LLDP_CHASSIS_INTF_ALIAS_SUBTYPE: 15180e9868baSchristos case LLDP_CHASSIS_PORT_COMP_SUBTYPE: 1519c74ad251Schristos nd_printjnp(ndo, tptr + 1, tlv_len - 1); 15200e9868baSchristos break; 15210e9868baSchristos 15220e9868baSchristos case LLDP_CHASSIS_NETWORK_ADDR_SUBTYPE: 1523b3a00663Schristos network_addr = lldp_network_addr_print(ndo, tptr+1, tlv_len-1); 15240e9868baSchristos if (network_addr == NULL) { 15250e9868baSchristos goto trunc; 15260e9868baSchristos } 1527c74ad251Schristos ND_PRINT("%s", network_addr); 15280e9868baSchristos break; 15290e9868baSchristos 15300e9868baSchristos default: 15310e9868baSchristos hexdump = TRUE; 15320e9868baSchristos break; 15330e9868baSchristos } 15340e9868baSchristos } 15350e9868baSchristos break; 15360e9868baSchristos 15370e9868baSchristos case LLDP_PORT_ID_TLV: 1538b3a00663Schristos if (ndo->ndo_vflag) { 15390e9868baSchristos if (tlv_len < 2) { 15400e9868baSchristos goto trunc; 15410e9868baSchristos } 1542c74ad251Schristos subtype = GET_U_1(tptr); 1543c74ad251Schristos ND_PRINT("\n\t Subtype %s (%u): ", 15440e9868baSchristos tok2str(lldp_port_subtype_values, "Unknown", subtype), 1545c74ad251Schristos subtype); 15460e9868baSchristos 15470e9868baSchristos switch (subtype) { 15480e9868baSchristos case LLDP_PORT_MAC_ADDR_SUBTYPE: 15490e9868baSchristos if (tlv_len < 1+6) { 15500e9868baSchristos goto trunc; 15510e9868baSchristos } 1552c74ad251Schristos ND_PRINT("%s", GET_ETHERADDR_STRING(tptr + 1)); 15530e9868baSchristos break; 15540e9868baSchristos 15550e9868baSchristos case LLDP_PORT_INTF_NAME_SUBTYPE: /* fall through */ 15560e9868baSchristos case LLDP_PORT_LOCAL_SUBTYPE: 15570e9868baSchristos case LLDP_PORT_AGENT_CIRC_ID_SUBTYPE: 15580e9868baSchristos case LLDP_PORT_INTF_ALIAS_SUBTYPE: 15590e9868baSchristos case LLDP_PORT_PORT_COMP_SUBTYPE: 1560c74ad251Schristos nd_printjnp(ndo, tptr + 1, tlv_len - 1); 15610e9868baSchristos break; 15620e9868baSchristos 15630e9868baSchristos case LLDP_PORT_NETWORK_ADDR_SUBTYPE: 1564b3a00663Schristos network_addr = lldp_network_addr_print(ndo, tptr+1, tlv_len-1); 15650e9868baSchristos if (network_addr == NULL) { 15660e9868baSchristos goto trunc; 15670e9868baSchristos } 1568c74ad251Schristos ND_PRINT("%s", network_addr); 15690e9868baSchristos break; 15700e9868baSchristos 15710e9868baSchristos default: 15720e9868baSchristos hexdump = TRUE; 15730e9868baSchristos break; 15740e9868baSchristos } 15750e9868baSchristos } 15760e9868baSchristos break; 15770e9868baSchristos 15780f74e101Schristos case LLDP_TTL_TLV: 1579b3a00663Schristos if (ndo->ndo_vflag) { 15800e9868baSchristos if (tlv_len < 2) { 15810e9868baSchristos goto trunc; 15820e9868baSchristos } 1583c74ad251Schristos ND_PRINT(": TTL %us", GET_BE_U_2(tptr)); 15840f74e101Schristos } 15850f74e101Schristos break; 15860f74e101Schristos 15870e9868baSchristos case LLDP_PORT_DESCR_TLV: 1588b3a00663Schristos if (ndo->ndo_vflag) { 1589c74ad251Schristos ND_PRINT(": "); 1590c74ad251Schristos nd_printjnp(ndo, tptr, tlv_len); 15910e9868baSchristos } 15920e9868baSchristos break; 15930f74e101Schristos 15940e9868baSchristos case LLDP_SYSTEM_NAME_TLV: 15950f74e101Schristos /* 15960f74e101Schristos * The system name is also print in non-verbose mode 15970f74e101Schristos * similar to the CDP printer. 15980f74e101Schristos */ 1599c74ad251Schristos ND_PRINT(": "); 1600c74ad251Schristos nd_printjnp(ndo, tptr, tlv_len); 16010f74e101Schristos break; 16020f74e101Schristos 16030f74e101Schristos case LLDP_SYSTEM_DESCR_TLV: 1604b3a00663Schristos if (ndo->ndo_vflag) { 1605c74ad251Schristos ND_PRINT("\n\t "); 1606c74ad251Schristos nd_printjnp(ndo, tptr, tlv_len); 16070f74e101Schristos } 16080f74e101Schristos break; 16090f74e101Schristos 16100f74e101Schristos case LLDP_SYSTEM_CAP_TLV: 1611b3a00663Schristos if (ndo->ndo_vflag) { 16120e9868baSchristos /* 16130e9868baSchristos * XXX - IEEE Std 802.1AB-2009 says the first octet 16140e9868baSchristos * if a chassis ID subtype, with the system 16150e9868baSchristos * capabilities and enabled capabilities following 16160e9868baSchristos * it. 16170e9868baSchristos */ 16180e9868baSchristos if (tlv_len < 4) { 16190e9868baSchristos goto trunc; 16200e9868baSchristos } 1621c74ad251Schristos cap = GET_BE_U_2(tptr); 1622c74ad251Schristos ena_cap = GET_BE_U_2(tptr + 2); 1623c74ad251Schristos ND_PRINT("\n\t System Capabilities [%s] (0x%04x)", 1624c74ad251Schristos bittok2str(lldp_cap_values, "none", cap), cap); 1625c74ad251Schristos ND_PRINT("\n\t Enabled Capabilities [%s] (0x%04x)", 1626c74ad251Schristos bittok2str(lldp_cap_values, "none", ena_cap), ena_cap); 16270f74e101Schristos } 16280f74e101Schristos break; 16290f74e101Schristos 16300f74e101Schristos case LLDP_MGMT_ADDR_TLV: 1631b3a00663Schristos if (ndo->ndo_vflag) { 1632b3a00663Schristos if (!lldp_mgmt_addr_tlv_print(ndo, tptr, tlv_len)) { 16330f74e101Schristos goto trunc; 16340f74e101Schristos } 16350f74e101Schristos } 16360f74e101Schristos break; 16370f74e101Schristos 16380e9868baSchristos case LLDP_PRIVATE_TLV: 1639b3a00663Schristos if (ndo->ndo_vflag) { 16400e9868baSchristos if (tlv_len < 3) { 16410e9868baSchristos goto trunc; 16420e9868baSchristos } 1643c74ad251Schristos oui = GET_BE_U_3(tptr); 1644c74ad251Schristos ND_PRINT(": OUI %s (0x%06x)", tok2str(oui_values, "Unknown", oui), oui); 16450e9868baSchristos 16460e9868baSchristos switch (oui) { 16470e9868baSchristos case OUI_IEEE_8021_PRIVATE: 1648b3a00663Schristos hexdump = lldp_private_8021_print(ndo, tptr, tlv_len); 16490e9868baSchristos break; 16500e9868baSchristos case OUI_IEEE_8023_PRIVATE: 1651b3a00663Schristos hexdump = lldp_private_8023_print(ndo, tptr, tlv_len); 16520e9868baSchristos break; 1653dc860a36Sspz case OUI_IANA: 1654dc860a36Sspz hexdump = lldp_private_iana_print(ndo, tptr, tlv_len); 1655dc860a36Sspz break; 16560e9868baSchristos case OUI_TIA: 1657b3a00663Schristos hexdump = lldp_private_tia_print(ndo, tptr, tlv_len); 16580e9868baSchristos break; 16590e9868baSchristos case OUI_DCBX: 1660b3a00663Schristos hexdump = lldp_private_dcbx_print(ndo, tptr, tlv_len); 16610e9868baSchristos break; 16620e9868baSchristos default: 16630e9868baSchristos hexdump = TRUE; 16640e9868baSchristos break; 16650e9868baSchristos } 16660e9868baSchristos } 16670e9868baSchristos break; 16680e9868baSchristos 16690f74e101Schristos default: 16700f74e101Schristos hexdump = TRUE; 16710f74e101Schristos break; 16720f74e101Schristos } 16730f74e101Schristos 16740f74e101Schristos /* do we also want to see a hex dump ? */ 1675b3a00663Schristos if (ndo->ndo_vflag > 1 || (ndo->ndo_vflag && hexdump)) { 1676b3a00663Schristos print_unknown_data(ndo, tptr, "\n\t ", tlv_len); 16770f74e101Schristos } 16780f74e101Schristos 16790f74e101Schristos tlen -= tlv_len; 16800f74e101Schristos tptr += tlv_len; 16810f74e101Schristos } 16820f74e101Schristos return; 16830f74e101Schristos trunc: 1684c74ad251Schristos nd_print_trunc(ndo); 16850f74e101Schristos } 1686