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