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