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