xref: /netbsd-src/external/bsd/tcpdump/dist/print-lldp.c (revision e89934bbf778a6d6d6894877c4da59d0c7835b0f)
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@juniper.net)
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.8 2017/02/05 04:05:05 spz Exp $");
25 #endif
26 
27 #ifdef HAVE_CONFIG_H
28 #include "config.h"
29 #endif
30 
31 #include <netdissect-stdinc.h>
32 
33 #include <stdio.h>
34 
35 #include "netdissect.h"
36 #include "extract.h"
37 #include "addrtoname.h"
38 #include "af.h"
39 #include "oui.h"
40 
41 #define	LLDP_EXTRACT_TYPE(x) (((x)&0xfe00)>>9)
42 #define	LLDP_EXTRACT_LEN(x) ((x)&0x01ff)
43 
44 /*
45  * TLV type codes
46  */
47 #define LLDP_END_TLV             0
48 #define LLDP_CHASSIS_ID_TLV      1
49 #define LLDP_PORT_ID_TLV         2
50 #define LLDP_TTL_TLV             3
51 #define LLDP_PORT_DESCR_TLV      4
52 #define LLDP_SYSTEM_NAME_TLV     5
53 #define LLDP_SYSTEM_DESCR_TLV    6
54 #define LLDP_SYSTEM_CAP_TLV      7
55 #define LLDP_MGMT_ADDR_TLV       8
56 #define LLDP_PRIVATE_TLV       127
57 
58 static const struct tok lldp_tlv_values[] = {
59     { LLDP_END_TLV, "End" },
60     { LLDP_CHASSIS_ID_TLV, "Chassis ID" },
61     { LLDP_PORT_ID_TLV, "Port ID" },
62     { LLDP_TTL_TLV, "Time to Live" },
63     { LLDP_PORT_DESCR_TLV, "Port Description" },
64     { LLDP_SYSTEM_NAME_TLV, "System Name" },
65     { LLDP_SYSTEM_DESCR_TLV, "System Description" },
66     { LLDP_SYSTEM_CAP_TLV, "System Capabilities" },
67     { LLDP_MGMT_ADDR_TLV, "Management Address" },
68     { LLDP_PRIVATE_TLV, "Organization specific" },
69     { 0, NULL}
70 };
71 
72 /*
73  * Chassis ID subtypes
74  */
75 #define LLDP_CHASSIS_CHASSIS_COMP_SUBTYPE  1
76 #define LLDP_CHASSIS_INTF_ALIAS_SUBTYPE    2
77 #define LLDP_CHASSIS_PORT_COMP_SUBTYPE     3
78 #define LLDP_CHASSIS_MAC_ADDR_SUBTYPE      4
79 #define LLDP_CHASSIS_NETWORK_ADDR_SUBTYPE  5
80 #define LLDP_CHASSIS_INTF_NAME_SUBTYPE     6
81 #define LLDP_CHASSIS_LOCAL_SUBTYPE         7
82 
83 static const struct tok lldp_chassis_subtype_values[] = {
84     { LLDP_CHASSIS_CHASSIS_COMP_SUBTYPE, "Chassis component"},
85     { LLDP_CHASSIS_INTF_ALIAS_SUBTYPE, "Interface alias"},
86     { LLDP_CHASSIS_PORT_COMP_SUBTYPE, "Port component"},
87     { LLDP_CHASSIS_MAC_ADDR_SUBTYPE, "MAC address"},
88     { LLDP_CHASSIS_NETWORK_ADDR_SUBTYPE, "Network address"},
89     { LLDP_CHASSIS_INTF_NAME_SUBTYPE, "Interface name"},
90     { LLDP_CHASSIS_LOCAL_SUBTYPE, "Local"},
91     { 0, NULL}
92 };
93 
94 /*
95  * Port ID subtypes
96  */
97 #define LLDP_PORT_INTF_ALIAS_SUBTYPE       1
98 #define LLDP_PORT_PORT_COMP_SUBTYPE        2
99 #define LLDP_PORT_MAC_ADDR_SUBTYPE         3
100 #define LLDP_PORT_NETWORK_ADDR_SUBTYPE     4
101 #define LLDP_PORT_INTF_NAME_SUBTYPE        5
102 #define LLDP_PORT_AGENT_CIRC_ID_SUBTYPE    6
103 #define LLDP_PORT_LOCAL_SUBTYPE            7
104 
105 static const struct tok lldp_port_subtype_values[] = {
106     { LLDP_PORT_INTF_ALIAS_SUBTYPE, "Interface alias"},
107     { LLDP_PORT_PORT_COMP_SUBTYPE, "Port component"},
108     { LLDP_PORT_MAC_ADDR_SUBTYPE, "MAC address"},
109     { LLDP_PORT_NETWORK_ADDR_SUBTYPE, "Network Address"},
110     { LLDP_PORT_INTF_NAME_SUBTYPE, "Interface Name"},
111     { LLDP_PORT_AGENT_CIRC_ID_SUBTYPE, "Agent circuit ID"},
112     { LLDP_PORT_LOCAL_SUBTYPE, "Local"},
113     { 0, NULL}
114 };
115 
116 /*
117  * System Capabilities
118  */
119 #define LLDP_CAP_OTHER              (1 <<  0)
120 #define LLDP_CAP_REPEATER           (1 <<  1)
121 #define LLDP_CAP_BRIDGE             (1 <<  2)
122 #define LLDP_CAP_WLAN_AP            (1 <<  3)
123 #define LLDP_CAP_ROUTER             (1 <<  4)
124 #define LLDP_CAP_PHONE              (1 <<  5)
125 #define LLDP_CAP_DOCSIS             (1 <<  6)
126 #define LLDP_CAP_STATION_ONLY       (1 <<  7)
127 
128 static const struct tok lldp_cap_values[] = {
129     { LLDP_CAP_OTHER, "Other"},
130     { LLDP_CAP_REPEATER, "Repeater"},
131     { LLDP_CAP_BRIDGE, "Bridge"},
132     { LLDP_CAP_WLAN_AP, "WLAN AP"},
133     { LLDP_CAP_ROUTER, "Router"},
134     { LLDP_CAP_PHONE, "Telephone"},
135     { LLDP_CAP_DOCSIS, "Docsis"},
136     { LLDP_CAP_STATION_ONLY, "Station Only"},
137     { 0, NULL}
138 };
139 
140 #define LLDP_PRIVATE_8021_SUBTYPE_PORT_VLAN_ID		1
141 #define LLDP_PRIVATE_8021_SUBTYPE_PROTOCOL_VLAN_ID	2
142 #define LLDP_PRIVATE_8021_SUBTYPE_VLAN_NAME		3
143 #define LLDP_PRIVATE_8021_SUBTYPE_PROTOCOL_IDENTITY	4
144 #define LLDP_PRIVATE_8021_SUBTYPE_CONGESTION_NOTIFICATION 8
145 #define LLDP_PRIVATE_8021_SUBTYPE_ETS_CONFIGURATION       9
146 #define LLDP_PRIVATE_8021_SUBTYPE_ETS_RECOMMENDATION     10
147 #define LLDP_PRIVATE_8021_SUBTYPE_PFC_CONFIGURATION      11
148 #define LLDP_PRIVATE_8021_SUBTYPE_APPLICATION_PRIORITY   12
149 #define LLDP_PRIVATE_8021_SUBTYPE_EVB                    13
150 #define LLDP_PRIVATE_8021_SUBTYPE_CDCP 			 14
151 
152 static const struct tok lldp_8021_subtype_values[] = {
153     { LLDP_PRIVATE_8021_SUBTYPE_PORT_VLAN_ID, "Port VLAN Id"},
154     { LLDP_PRIVATE_8021_SUBTYPE_PROTOCOL_VLAN_ID, "Port and Protocol VLAN ID"},
155     { LLDP_PRIVATE_8021_SUBTYPE_VLAN_NAME, "VLAN name"},
156     { LLDP_PRIVATE_8021_SUBTYPE_PROTOCOL_IDENTITY, "Protocol Identity"},
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_CAPABILTIY     (1 <<  0)
549 #define LLDP_AGGREGATION_STATUS         (1 <<  1)
550 
551 static const struct tok lldp_aggregation_values[] = {
552     { LLDP_AGGREGATION_CAPABILTIY, "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 Staion"},
597     { LLDP_EVB_MODE_RESERVED, "Reserved for future Standardization"},
598 };
599 
600 #define NO_OF_BITS 8
601 #define LLDP_PRIVATE_8021_SUBTYPE_CONGESTION_NOTIFICATION_LENGTH  6
602 #define LLDP_PRIVATE_8021_SUBTYPE_ETS_CONFIGURATION_LENGTH       25
603 #define LLDP_PRIVATE_8021_SUBTYPE_ETS_RECOMMENDATION_LENGTH      25
604 #define LLDP_PRIVATE_8021_SUBTYPE_PFC_CONFIGURATION_LENGTH        6
605 #define LLDP_PRIVATE_8021_SUBTYPE_APPLICATION_PRIORITY_MIN_LENGTH 5
606 #define LLDP_PRIVATE_8021_SUBTYPE_EVB_LENGTH                      9
607 #define LLDP_PRIVATE_8021_SUBTYPE_CDCP_MIN_LENGTH                 8
608 
609 #define LLDP_IANA_SUBTYPE_MUDURL 1
610 
611 static const struct tok lldp_iana_subtype_values[] =   {
612     { LLDP_IANA_SUBTYPE_MUDURL, "MUD-URL" },
613     { 0, NULL }
614 };
615 
616 
617 static void
618 print_ets_priority_assignment_table(netdissect_options *ndo,
619                                     const u_char *ptr)
620 {
621     ND_PRINT((ndo, "\n\t    Priority Assignment Table"));
622     ND_PRINT((ndo, "\n\t     Priority : 0   1   2   3   4   5   6   7"));
623     ND_PRINT((ndo, "\n\t     Value    : %-3d %-3d %-3d %-3d %-3d %-3d %-3d %-3d",
624             ptr[0]>>4,ptr[0]&0x0f,ptr[1]>>4,ptr[1]&0x0f,ptr[2]>>4,
625             ptr[2] & 0x0f, ptr[3] >> 4, ptr[3] & 0x0f));
626 }
627 
628 static void
629 print_tc_bandwidth_table(netdissect_options *ndo,
630                          const u_char *ptr)
631 {
632     ND_PRINT((ndo, "\n\t    TC Bandwidth Table"));
633     ND_PRINT((ndo, "\n\t     TC%%   : 0   1   2   3   4   5   6   7"));
634     ND_PRINT((ndo, "\n\t     Value : %-3d %-3d %-3d %-3d %-3d %-3d %-3d %-3d",
635              ptr[0], ptr[1], ptr[2], ptr[3], ptr[4], ptr[5], ptr[6], ptr[7]));
636 }
637 
638 static void
639 print_tsa_assignment_table(netdissect_options *ndo,
640                            const u_char *ptr)
641 {
642     ND_PRINT((ndo, "\n\t    TSA Assignment Table"));
643     ND_PRINT((ndo, "\n\t     Traffic Class: 0   1   2   3   4   5   6   7"));
644     ND_PRINT((ndo, "\n\t     Value        : %-3d %-3d %-3d %-3d %-3d %-3d %-3d %-3d",
645              ptr[0], ptr[1], ptr[2], ptr[3], ptr[4], ptr[5], ptr[6], ptr[7]));
646 }
647 
648 /*
649  * Print IEEE 802.1 private extensions. (802.1AB annex E)
650  */
651 static int
652 lldp_private_8021_print(netdissect_options *ndo,
653                         const u_char *tptr, u_int tlv_len)
654 {
655     int subtype, hexdump = FALSE;
656     u_int sublen;
657     u_int tval;
658     uint8_t i;
659 
660     if (tlv_len < 4) {
661         return hexdump;
662     }
663     subtype = *(tptr+3);
664 
665     ND_PRINT((ndo, "\n\t  %s Subtype (%u)",
666            tok2str(lldp_8021_subtype_values, "unknown", subtype),
667            subtype));
668 
669     switch (subtype) {
670     case LLDP_PRIVATE_8021_SUBTYPE_PORT_VLAN_ID:
671         if (tlv_len < 6) {
672             return hexdump;
673         }
674         ND_PRINT((ndo, "\n\t    port vlan id (PVID): %u",
675                EXTRACT_16BITS(tptr + 4)));
676         break;
677     case LLDP_PRIVATE_8021_SUBTYPE_PROTOCOL_VLAN_ID:
678         if (tlv_len < 7) {
679             return hexdump;
680         }
681         ND_PRINT((ndo, "\n\t    port and protocol vlan id (PPVID): %u, flags [%s] (0x%02x)",
682                EXTRACT_16BITS(tptr+5),
683 	       bittok2str(lldp_8021_port_protocol_id_values, "none", *(tptr+4)),
684 	       *(tptr + 4)));
685         break;
686     case LLDP_PRIVATE_8021_SUBTYPE_VLAN_NAME:
687         if (tlv_len < 6) {
688             return hexdump;
689         }
690         ND_PRINT((ndo, "\n\t    vlan id (VID): %u", EXTRACT_16BITS(tptr + 4)));
691         if (tlv_len < 7) {
692             return hexdump;
693         }
694         sublen = *(tptr+6);
695         if (tlv_len < 7+sublen) {
696             return hexdump;
697         }
698         ND_PRINT((ndo, "\n\t    vlan name: "));
699         safeputs(ndo, tptr + 7, sublen);
700         break;
701     case LLDP_PRIVATE_8021_SUBTYPE_PROTOCOL_IDENTITY:
702         if (tlv_len < 5) {
703             return hexdump;
704         }
705         sublen = *(tptr+4);
706         if (tlv_len < 5+sublen) {
707             return hexdump;
708         }
709         ND_PRINT((ndo, "\n\t    protocol identity: "));
710         safeputs(ndo, tptr + 5, sublen);
711         break;
712     case LLDP_PRIVATE_8021_SUBTYPE_CONGESTION_NOTIFICATION:
713         if(tlv_len<LLDP_PRIVATE_8021_SUBTYPE_CONGESTION_NOTIFICATION_LENGTH){
714         	return hexdump;
715         }
716         tval=*(tptr+4);
717         ND_PRINT((ndo, "\n\t    Pre-Priority CNPV Indicator"));
718         ND_PRINT((ndo, "\n\t     Priority : 0  1  2  3  4  5  6  7"));
719         ND_PRINT((ndo, "\n\t     Value    : "));
720         for(i=0;i<NO_OF_BITS;i++)
721             ND_PRINT((ndo, "%-2d ", (tval >> i) & 0x01));
722         tval=*(tptr+5);
723         ND_PRINT((ndo, "\n\t    Pre-Priority Ready Indicator"));
724         ND_PRINT((ndo, "\n\t     Priority : 0  1  2  3  4  5  6  7"));
725         ND_PRINT((ndo, "\n\t     Value    : "));
726         for(i=0;i<NO_OF_BITS;i++)
727             ND_PRINT((ndo, "%-2d ", (tval >> i) & 0x01));
728         break;
729 
730     case LLDP_PRIVATE_8021_SUBTYPE_ETS_CONFIGURATION:
731         if(tlv_len<LLDP_PRIVATE_8021_SUBTYPE_ETS_CONFIGURATION_LENGTH) {
732             return hexdump;
733         }
734         tval=*(tptr+4);
735         ND_PRINT((ndo, "\n\t    Willing:%d, CBS:%d, RES:%d, Max TCs:%d",
736         	tval >> 7, (tval >> 6) & 0x02, (tval >> 3) & 0x07, tval & 0x07));
737 
738         /*Print Priority Assignment Table*/
739         print_ets_priority_assignment_table(ndo, tptr + 5);
740 
741         /*Print TC Bandwidth Table*/
742         print_tc_bandwidth_table(ndo, tptr + 9);
743 
744         /* Print TSA Assignment Table */
745         print_tsa_assignment_table(ndo, tptr + 17);
746 
747         break;
748 
749     case LLDP_PRIVATE_8021_SUBTYPE_ETS_RECOMMENDATION:
750         if(tlv_len<LLDP_PRIVATE_8021_SUBTYPE_ETS_RECOMMENDATION_LENGTH) {
751         	return hexdump;
752         }
753         ND_PRINT((ndo, "\n\t    RES: %d", *(tptr + 4)));
754         /*Print Priority Assignment Table */
755         print_ets_priority_assignment_table(ndo, tptr + 5);
756         /*Print TC Bandwidth Table */
757         print_tc_bandwidth_table(ndo, tptr + 9);
758         /* Print TSA Assignment Table */
759         print_tsa_assignment_table(ndo, tptr + 17);
760         break;
761 
762     case LLDP_PRIVATE_8021_SUBTYPE_PFC_CONFIGURATION:
763         if(tlv_len<LLDP_PRIVATE_8021_SUBTYPE_PFC_CONFIGURATION_LENGTH) {
764             return hexdump;
765         }
766         tval=*(tptr+4);
767         ND_PRINT((ndo, "\n\t    Willing: %d, MBC: %d, RES: %d, PFC cap:%d ",
768         	tval >> 7, (tval >> 6) & 0x01, (tval >> 4) & 0x03, (tval & 0x0f)));
769         ND_PRINT((ndo, "\n\t    PFC Enable"));
770         tval=*(tptr+5);
771         ND_PRINT((ndo, "\n\t     Priority : 0  1  2  3  4  5  6  7"));
772         ND_PRINT((ndo, "\n\t     Value    : "));
773         for(i=0;i<NO_OF_BITS;i++)
774             ND_PRINT((ndo, "%-2d ", (tval >> i) & 0x01));
775         break;
776 
777     case LLDP_PRIVATE_8021_SUBTYPE_APPLICATION_PRIORITY:
778         if(tlv_len<LLDP_PRIVATE_8021_SUBTYPE_APPLICATION_PRIORITY_MIN_LENGTH) {
779             return hexdump;
780         }
781         ND_PRINT((ndo, "\n\t    RES: %d", *(tptr + 4)));
782         if(tlv_len<=LLDP_PRIVATE_8021_SUBTYPE_APPLICATION_PRIORITY_MIN_LENGTH){
783         	return hexdump;
784         }
785         /*  Length of Application Priority Table */
786         sublen=tlv_len-5;
787         if(sublen%3!=0){
788         	return hexdump;
789         }
790         i=0;
791         ND_PRINT((ndo, "\n\t    Application Priority Table"));
792         while(i<sublen) {
793         	tval=*(tptr+i+5);
794         	ND_PRINT((ndo, "\n\t      Priority: %d, RES: %d, Sel: %d",
795         		 tval >> 5, (tval >> 3) & 0x03, (tval & 0x07)));
796         	ND_PRINT((ndo, "Protocol ID: %d", EXTRACT_16BITS(tptr + i + 5)));
797         	i=i+3;
798         }
799         break;
800     case LLDP_PRIVATE_8021_SUBTYPE_EVB:
801         if(tlv_len<LLDP_PRIVATE_8021_SUBTYPE_EVB_LENGTH){
802         	return hexdump;
803         }
804         ND_PRINT((ndo, "\n\t    EVB Bridge Status"));
805         tval=*(tptr+4);
806         ND_PRINT((ndo, "\n\t      RES: %d, BGID: %d, RRCAP: %d, RRCTR: %d",
807         	tval >> 3, (tval >> 2) & 0x01, (tval >> 1) & 0x01, tval & 0x01));
808         ND_PRINT((ndo, "\n\t    EVB Station Status"));
809         tval=*(tptr+5);
810         ND_PRINT((ndo, "\n\t      RES: %d, SGID: %d, RRREQ: %d,RRSTAT: %d",
811         	tval >> 4, (tval >> 3) & 0x01, (tval >> 2) & 0x01, tval & 0x03));
812         tval=*(tptr+6);
813         ND_PRINT((ndo, "\n\t    R: %d, RTE: %d, ",tval >> 5, tval & 0x1f));
814         tval=*(tptr+7);
815         ND_PRINT((ndo, "EVB Mode: %s [%d]",
816         	tok2str(lldp_evb_mode_values, "unknown", tval >> 6), tval >> 6));
817         ND_PRINT((ndo, "\n\t    ROL: %d, RWD: %d, ", (tval >> 5) & 0x01, tval & 0x1f));
818         tval=*(tptr+8);
819         ND_PRINT((ndo, "RES: %d, ROL: %d, RKA: %d", tval >> 6, (tval >> 5) & 0x01, tval & 0x1f));
820         break;
821 
822     case LLDP_PRIVATE_8021_SUBTYPE_CDCP:
823         if(tlv_len<LLDP_PRIVATE_8021_SUBTYPE_CDCP_MIN_LENGTH){
824         	return hexdump;
825         }
826         tval=*(tptr+4);
827         ND_PRINT((ndo, "\n\t    Role: %d, RES: %d, Scomp: %d ",
828         	tval >> 7, (tval >> 4) & 0x07, (tval >> 3) & 0x01));
829         ND_PRINT((ndo, "ChnCap: %d", EXTRACT_16BITS(tptr + 6) & 0x0fff));
830         sublen=tlv_len-8;
831         if(sublen%3!=0) {
832         	return hexdump;
833         }
834         i=0;
835         while(i<sublen) {
836         	tval=EXTRACT_24BITS(tptr+i+8);
837         	ND_PRINT((ndo, "\n\t    SCID: %d, SVID: %d",
838         		tval >> 12, tval & 0x000fff));
839         	i=i+3;
840         }
841         break;
842 
843     default:
844         hexdump = TRUE;
845         break;
846     }
847 
848     return hexdump;
849 }
850 
851 /*
852  * Print IEEE 802.3 private extensions. (802.3bc)
853  */
854 static int
855 lldp_private_8023_print(netdissect_options *ndo,
856                         const u_char *tptr, u_int tlv_len)
857 {
858     int subtype, hexdump = FALSE;
859 
860     if (tlv_len < 4) {
861         return hexdump;
862     }
863     subtype = *(tptr+3);
864 
865     ND_PRINT((ndo, "\n\t  %s Subtype (%u)",
866            tok2str(lldp_8023_subtype_values, "unknown", subtype),
867            subtype));
868 
869     switch (subtype) {
870     case LLDP_PRIVATE_8023_SUBTYPE_MACPHY:
871         if (tlv_len < 9) {
872             return hexdump;
873         }
874         ND_PRINT((ndo, "\n\t    autonegotiation [%s] (0x%02x)",
875                bittok2str(lldp_8023_autonegotiation_values, "none", *(tptr+4)),
876                *(tptr + 4)));
877         ND_PRINT((ndo, "\n\t    PMD autoneg capability [%s] (0x%04x)",
878                bittok2str(lldp_pmd_capability_values,"unknown", EXTRACT_16BITS(tptr+5)),
879                EXTRACT_16BITS(tptr + 5)));
880         ND_PRINT((ndo, "\n\t    MAU type %s (0x%04x)",
881                tok2str(lldp_mau_types_values, "unknown", EXTRACT_16BITS(tptr+7)),
882                EXTRACT_16BITS(tptr + 7)));
883         break;
884 
885     case LLDP_PRIVATE_8023_SUBTYPE_MDIPOWER:
886         if (tlv_len < 7) {
887             return hexdump;
888         }
889         ND_PRINT((ndo, "\n\t    MDI power support [%s], power pair %s, power class %s",
890                bittok2str(lldp_mdi_values, "none", *(tptr+4)),
891                tok2str(lldp_mdi_power_pairs_values, "unknown", *(tptr+5)),
892                tok2str(lldp_mdi_power_class_values, "unknown", *(tptr + 6))));
893         break;
894 
895     case LLDP_PRIVATE_8023_SUBTYPE_LINKAGGR:
896         if (tlv_len < 9) {
897             return hexdump;
898         }
899         ND_PRINT((ndo, "\n\t    aggregation status [%s], aggregation port ID %u",
900                bittok2str(lldp_aggregation_values, "none", *(tptr+4)),
901                EXTRACT_32BITS(tptr + 5)));
902         break;
903 
904     case LLDP_PRIVATE_8023_SUBTYPE_MTU:
905         ND_PRINT((ndo, "\n\t    MTU size %u", EXTRACT_16BITS(tptr + 4)));
906         break;
907 
908     default:
909         hexdump = TRUE;
910         break;
911     }
912 
913     return hexdump;
914 }
915 
916 /*
917  * Extract 34bits of latitude/longitude coordinates.
918  */
919 static uint64_t
920 lldp_extract_latlon(const u_char *tptr)
921 {
922     uint64_t latlon;
923 
924     latlon = *tptr & 0x3;
925     latlon = (latlon << 32) | EXTRACT_32BITS(tptr+1);
926 
927     return latlon;
928 }
929 
930 /* objects defined in IANA subtype 00 00 5e
931  * (right now there is only one)
932  */
933 
934 
935 static int
936 lldp_private_iana_print(netdissect_options *ndo,
937                         const u_char *tptr, u_int tlv_len)
938 {
939     int subtype, hexdump = FALSE;
940 
941     if (tlv_len < 8) {
942         return hexdump;
943     }
944     subtype = *(tptr+3);
945 
946     ND_PRINT((ndo, "\n\t  %s Subtype (%u)",
947            tok2str(lldp_iana_subtype_values, "unknown", subtype),
948            subtype));
949 
950     switch (subtype) {
951     case LLDP_IANA_SUBTYPE_MUDURL:
952         ND_PRINT((ndo, "\n\t  MUD-URL="));
953         (void)fn_printn(ndo, tptr+4, tlv_len-4, NULL);
954         break;
955     default:
956         hexdump=TRUE;
957     }
958 
959     return hexdump;
960 }
961 
962 
963 
964 /*
965  * Print private TIA extensions.
966  */
967 static int
968 lldp_private_tia_print(netdissect_options *ndo,
969                        const u_char *tptr, u_int tlv_len)
970 {
971     int subtype, hexdump = FALSE;
972     uint8_t location_format;
973     uint16_t power_val;
974     u_int lci_len;
975     uint8_t ca_type, ca_len;
976 
977     if (tlv_len < 4) {
978         return hexdump;
979     }
980     subtype = *(tptr+3);
981 
982     ND_PRINT((ndo, "\n\t  %s Subtype (%u)",
983            tok2str(lldp_tia_subtype_values, "unknown", subtype),
984            subtype));
985 
986     switch (subtype) {
987     case LLDP_PRIVATE_TIA_SUBTYPE_CAPABILITIES:
988         if (tlv_len < 7) {
989             return hexdump;
990         }
991         ND_PRINT((ndo, "\n\t    Media capabilities [%s] (0x%04x)",
992                bittok2str(lldp_tia_capabilities_values, "none",
993                           EXTRACT_16BITS(tptr + 4)), EXTRACT_16BITS(tptr + 4)));
994         ND_PRINT((ndo, "\n\t    Device type [%s] (0x%02x)",
995                tok2str(lldp_tia_device_type_values, "unknown", *(tptr+6)),
996                *(tptr + 6)));
997         break;
998 
999     case LLDP_PRIVATE_TIA_SUBTYPE_NETWORK_POLICY:
1000         if (tlv_len < 8) {
1001             return hexdump;
1002         }
1003         ND_PRINT((ndo, "\n\t    Application type [%s] (0x%02x)",
1004                tok2str(lldp_tia_application_type_values, "none", *(tptr+4)),
1005                *(tptr + 4)));
1006         ND_PRINT((ndo, ", Flags [%s]", bittok2str(
1007                    lldp_tia_network_policy_bits_values, "none", *(tptr + 5))));
1008         ND_PRINT((ndo, "\n\t    Vlan id %u",
1009                LLDP_EXTRACT_NETWORK_POLICY_VLAN(EXTRACT_16BITS(tptr + 5))));
1010         ND_PRINT((ndo, ", L2 priority %u",
1011                LLDP_EXTRACT_NETWORK_POLICY_L2_PRIORITY(EXTRACT_16BITS(tptr + 6))));
1012         ND_PRINT((ndo, ", DSCP value %u",
1013                LLDP_EXTRACT_NETWORK_POLICY_DSCP(EXTRACT_16BITS(tptr + 6))));
1014         break;
1015 
1016     case LLDP_PRIVATE_TIA_SUBTYPE_LOCAL_ID:
1017         if (tlv_len < 5) {
1018             return hexdump;
1019         }
1020         location_format = *(tptr+4);
1021         ND_PRINT((ndo, "\n\t    Location data format %s (0x%02x)",
1022                tok2str(lldp_tia_location_data_format_values, "unknown", location_format),
1023                location_format));
1024 
1025         switch (location_format) {
1026         case LLDP_TIA_LOCATION_DATA_FORMAT_COORDINATE_BASED:
1027             if (tlv_len < 21) {
1028                 return hexdump;
1029             }
1030             ND_PRINT((ndo, "\n\t    Latitude resolution %u, latitude value %" PRIu64,
1031                    (*(tptr + 5) >> 2), lldp_extract_latlon(tptr + 5)));
1032             ND_PRINT((ndo, "\n\t    Longitude resolution %u, longitude value %" PRIu64,
1033                    (*(tptr + 10) >> 2), lldp_extract_latlon(tptr + 10)));
1034             ND_PRINT((ndo, "\n\t    Altitude type %s (%u)",
1035                    tok2str(lldp_tia_location_altitude_type_values, "unknown",(*(tptr+15)>>4)),
1036                    (*(tptr + 15) >> 4)));
1037             ND_PRINT((ndo, "\n\t    Altitude resolution %u, altitude value 0x%x",
1038                    (EXTRACT_16BITS(tptr+15)>>6)&0x3f,
1039                    ((EXTRACT_32BITS(tptr + 16) & 0x3fffffff))));
1040             ND_PRINT((ndo, "\n\t    Datum %s (0x%02x)",
1041                    tok2str(lldp_tia_location_datum_type_values, "unknown", *(tptr+20)),
1042                    *(tptr + 20)));
1043             break;
1044 
1045         case LLDP_TIA_LOCATION_DATA_FORMAT_CIVIC_ADDRESS:
1046             if (tlv_len < 6) {
1047                 return hexdump;
1048             }
1049             lci_len = *(tptr+5);
1050             if (lci_len < 3) {
1051                 return hexdump;
1052             }
1053             if (tlv_len < 7+lci_len) {
1054                 return hexdump;
1055             }
1056             ND_PRINT((ndo, "\n\t    LCI length %u, LCI what %s (0x%02x), Country-code ",
1057                    lci_len,
1058                    tok2str(lldp_tia_location_lci_what_values, "unknown", *(tptr+6)),
1059                    *(tptr + 6)));
1060 
1061             /* Country code */
1062             safeputs(ndo, tptr + 7, 2);
1063 
1064             lci_len = lci_len-3;
1065             tptr = tptr + 9;
1066 
1067             /* Decode each civic address element */
1068             while (lci_len > 0) {
1069                 if (lci_len < 2) {
1070                     return hexdump;
1071                 }
1072 		ca_type = *(tptr);
1073                 ca_len = *(tptr+1);
1074 
1075 		tptr += 2;
1076                 lci_len -= 2;
1077 
1078                 ND_PRINT((ndo, "\n\t      CA type \'%s\' (%u), length %u: ",
1079                        tok2str(lldp_tia_location_lci_catype_values, "unknown", ca_type),
1080                        ca_type, ca_len));
1081 
1082 		/* basic sanity check */
1083 		if ( ca_type == 0 || ca_len == 0) {
1084                     return hexdump;
1085 		}
1086 		if (lci_len < ca_len) {
1087 		    return hexdump;
1088 		}
1089 
1090                 safeputs(ndo, tptr, ca_len);
1091                 tptr += ca_len;
1092                 lci_len -= ca_len;
1093             }
1094             break;
1095 
1096         case LLDP_TIA_LOCATION_DATA_FORMAT_ECS_ELIN:
1097             ND_PRINT((ndo, "\n\t    ECS ELIN id "));
1098             safeputs(ndo, tptr + 5, tlv_len - 5);
1099             break;
1100 
1101         default:
1102             ND_PRINT((ndo, "\n\t    Location ID "));
1103             print_unknown_data(ndo, tptr + 5, "\n\t      ", tlv_len - 5);
1104         }
1105         break;
1106 
1107     case LLDP_PRIVATE_TIA_SUBTYPE_EXTENDED_POWER_MDI:
1108         if (tlv_len < 7) {
1109             return hexdump;
1110         }
1111         ND_PRINT((ndo, "\n\t    Power type [%s]",
1112                (*(tptr + 4) & 0xC0 >> 6) ? "PD device" : "PSE device"));
1113         ND_PRINT((ndo, ", Power source [%s]",
1114                tok2str(lldp_tia_power_source_values, "none", (*(tptr + 4) & 0x30) >> 4)));
1115         ND_PRINT((ndo, "\n\t    Power priority [%s] (0x%02x)",
1116                tok2str(lldp_tia_power_priority_values, "none", *(tptr+4)&0x0f),
1117                *(tptr + 4) & 0x0f));
1118         power_val = EXTRACT_16BITS(tptr+5);
1119         if (power_val < LLDP_TIA_POWER_VAL_MAX) {
1120             ND_PRINT((ndo, ", Power %.1f Watts", ((float)power_val) / 10));
1121         } else {
1122             ND_PRINT((ndo, ", Power %u (Reserved)", power_val));
1123         }
1124         break;
1125 
1126     case LLDP_PRIVATE_TIA_SUBTYPE_INVENTORY_HARDWARE_REV:
1127     case LLDP_PRIVATE_TIA_SUBTYPE_INVENTORY_FIRMWARE_REV:
1128     case LLDP_PRIVATE_TIA_SUBTYPE_INVENTORY_SOFTWARE_REV:
1129     case LLDP_PRIVATE_TIA_SUBTYPE_INVENTORY_SERIAL_NUMBER:
1130     case LLDP_PRIVATE_TIA_SUBTYPE_INVENTORY_MANUFACTURER_NAME:
1131     case LLDP_PRIVATE_TIA_SUBTYPE_INVENTORY_MODEL_NAME:
1132     case LLDP_PRIVATE_TIA_SUBTYPE_INVENTORY_ASSET_ID:
1133         ND_PRINT((ndo, "\n\t  %s ",
1134                tok2str(lldp_tia_inventory_values, "unknown", subtype)));
1135         safeputs(ndo, tptr + 4, tlv_len - 4);
1136         break;
1137 
1138     default:
1139         hexdump = TRUE;
1140         break;
1141     }
1142 
1143     return hexdump;
1144 }
1145 
1146 /*
1147  * Print DCBX Protocol fields (V 1.01).
1148  */
1149 static int
1150 lldp_private_dcbx_print(netdissect_options *ndo,
1151                         const u_char *pptr, u_int len)
1152 {
1153     int subtype, hexdump = FALSE;
1154     uint8_t tval;
1155     uint16_t tlv;
1156     uint32_t i, pgval, uval;
1157     u_int tlen, tlv_type, tlv_len;
1158     const u_char *tptr, *mptr;
1159 
1160     if (len < 4) {
1161         return hexdump;
1162     }
1163     subtype = *(pptr+3);
1164 
1165     ND_PRINT((ndo, "\n\t  %s Subtype (%u)",
1166            tok2str(lldp_dcbx_subtype_values, "unknown", subtype),
1167            subtype));
1168 
1169     /* by passing old version */
1170     if (subtype == LLDP_DCBX_SUBTYPE_1)
1171 	return TRUE;
1172 
1173     tptr = pptr + 4;
1174     tlen = len - 4;
1175 
1176     while (tlen >= sizeof(tlv)) {
1177 
1178         ND_TCHECK2(*tptr, sizeof(tlv));
1179 
1180         tlv = EXTRACT_16BITS(tptr);
1181 
1182         tlv_type = LLDP_EXTRACT_TYPE(tlv);
1183         tlv_len = LLDP_EXTRACT_LEN(tlv);
1184         hexdump = FALSE;
1185 
1186         tlen -= sizeof(tlv);
1187         tptr += sizeof(tlv);
1188 
1189         /* loop check */
1190         if (!tlv_type || !tlv_len) {
1191             break;
1192         }
1193 
1194         ND_TCHECK2(*tptr, tlv_len);
1195         if (tlen < tlv_len) {
1196             goto trunc;
1197         }
1198 
1199 	/* decode every tlv */
1200         switch (tlv_type) {
1201         case LLDP_DCBX_CONTROL_TLV:
1202             if (tlv_len < 10) {
1203                 goto trunc;
1204             }
1205 	    ND_PRINT((ndo, "\n\t    Control - Protocol Control (type 0x%x, length %d)",
1206 		LLDP_DCBX_CONTROL_TLV, tlv_len));
1207 	    ND_PRINT((ndo, "\n\t      Oper_Version: %d", *tptr));
1208 	    ND_PRINT((ndo, "\n\t      Max_Version: %d", *(tptr + 1)));
1209 	    ND_PRINT((ndo, "\n\t      Sequence Number: %d", EXTRACT_32BITS(tptr + 2)));
1210 	    ND_PRINT((ndo, "\n\t      Acknowledgement Number: %d",
1211 					EXTRACT_32BITS(tptr + 6)));
1212 	    break;
1213         case LLDP_DCBX_PRIORITY_GROUPS_TLV:
1214             if (tlv_len < 17) {
1215                 goto trunc;
1216             }
1217 	    ND_PRINT((ndo, "\n\t    Feature - Priority Group (type 0x%x, length %d)",
1218 		LLDP_DCBX_PRIORITY_GROUPS_TLV, tlv_len));
1219 	    ND_PRINT((ndo, "\n\t      Oper_Version: %d", *tptr));
1220 	    ND_PRINT((ndo, "\n\t      Max_Version: %d", *(tptr + 1)));
1221 	    ND_PRINT((ndo, "\n\t      Info block(0x%02X): ", *(tptr + 2)));
1222 	    tval = *(tptr+2);
1223 	    ND_PRINT((ndo, "Enable bit: %d, Willing bit: %d, Error Bit: %d",
1224 		(tval &  0x80) ? 1 : 0, (tval &  0x40) ? 1 : 0,
1225 		(tval &  0x20) ? 1 : 0));
1226 	    ND_PRINT((ndo, "\n\t      SubType: %d", *(tptr + 3)));
1227 	    ND_PRINT((ndo, "\n\t      Priority Allocation"));
1228 
1229 	    /*
1230 	     * Array of 8 4-bit priority group ID values; we fetch all
1231 	     * 32 bits and extract each nibble.
1232 	     */
1233 	    pgval = EXTRACT_32BITS(tptr+4);
1234 	    for (i = 0; i <= 7; i++) {
1235 		ND_PRINT((ndo, "\n\t          PgId_%d: %d",
1236 			i, (pgval >> (28 - 4 * i)) & 0xF));
1237 	    }
1238 	    ND_PRINT((ndo, "\n\t      Priority Group Allocation"));
1239 	    for (i = 0; i <= 7; i++)
1240 		ND_PRINT((ndo, "\n\t          Pg percentage[%d]: %d", i, *(tptr + 8 + i)));
1241 	    ND_PRINT((ndo, "\n\t      NumTCsSupported: %d", *(tptr + 8 + 8)));
1242 	    break;
1243         case LLDP_DCBX_PRIORITY_FLOW_CONTROL_TLV:
1244             if (tlv_len < 6) {
1245                 goto trunc;
1246             }
1247 	    ND_PRINT((ndo, "\n\t    Feature - Priority Flow Control"));
1248 	    ND_PRINT((ndo, " (type 0x%x, length %d)",
1249 		LLDP_DCBX_PRIORITY_FLOW_CONTROL_TLV, tlv_len));
1250 	    ND_PRINT((ndo, "\n\t      Oper_Version: %d", *tptr));
1251 	    ND_PRINT((ndo, "\n\t      Max_Version: %d", *(tptr + 1)));
1252 	    ND_PRINT((ndo, "\n\t      Info block(0x%02X): ", *(tptr + 2)));
1253 	    tval = *(tptr+2);
1254 	    ND_PRINT((ndo, "Enable bit: %d, Willing bit: %d, Error Bit: %d",
1255 		(tval &  0x80) ? 1 : 0, (tval &  0x40) ? 1 : 0,
1256 		(tval &  0x20) ? 1 : 0));
1257 	    ND_PRINT((ndo, "\n\t      SubType: %d", *(tptr + 3)));
1258 	    tval = *(tptr+4);
1259 	    ND_PRINT((ndo, "\n\t      PFC Config (0x%02X)", *(tptr + 4)));
1260 	    for (i = 0; i <= 7; i++)
1261 		ND_PRINT((ndo, "\n\t          Priority Bit %d: %s",
1262 		    i, (tval & (1 << i)) ? "Enabled" : "Disabled"));
1263 	    ND_PRINT((ndo, "\n\t      NumTCPFCSupported: %d", *(tptr + 5)));
1264 	    break;
1265         case LLDP_DCBX_APPLICATION_TLV:
1266             if (tlv_len < 4) {
1267                 goto trunc;
1268             }
1269 	    ND_PRINT((ndo, "\n\t    Feature - Application (type 0x%x, length %d)",
1270 		LLDP_DCBX_APPLICATION_TLV, tlv_len));
1271 	    ND_PRINT((ndo, "\n\t      Oper_Version: %d", *tptr));
1272 	    ND_PRINT((ndo, "\n\t      Max_Version: %d", *(tptr + 1)));
1273 	    ND_PRINT((ndo, "\n\t      Info block(0x%02X): ", *(tptr + 2)));
1274 	    tval = *(tptr+2);
1275 	    ND_PRINT((ndo, "Enable bit: %d, Willing bit: %d, Error Bit: %d",
1276 		(tval &  0x80) ? 1 : 0, (tval &  0x40) ? 1 : 0,
1277 		(tval &  0x20) ? 1 : 0));
1278 	    ND_PRINT((ndo, "\n\t      SubType: %d", *(tptr + 3)));
1279 	    tval = tlv_len - 4;
1280 	    mptr = tptr + 4;
1281 	    while (tval >= 6) {
1282 		ND_PRINT((ndo, "\n\t      Application Value"));
1283 		ND_PRINT((ndo, "\n\t          Application Protocol ID: 0x%04x",
1284 			EXTRACT_16BITS(mptr)));
1285 		uval = EXTRACT_24BITS(mptr+2);
1286 		ND_PRINT((ndo, "\n\t          SF (0x%x) Application Protocol ID is %s",
1287 			(uval >> 22),
1288 			(uval >> 22) ? "Socket Number" : "L2 EtherType"));
1289 		ND_PRINT((ndo, "\n\t          OUI: 0x%06x", uval & 0x3fffff));
1290 		ND_PRINT((ndo, "\n\t          User Priority Map: 0x%02x", *(mptr + 5)));
1291 		tval = tval - 6;
1292 		mptr = mptr + 6;
1293 	    }
1294 	    break;
1295 	default:
1296 	    hexdump = TRUE;
1297 	    break;
1298 	}
1299 
1300         /* do we also want to see a hex dump ? */
1301         if (ndo->ndo_vflag > 1 || (ndo->ndo_vflag && hexdump)) {
1302 	    print_unknown_data(ndo, tptr, "\n\t    ", tlv_len);
1303         }
1304 
1305         tlen -= tlv_len;
1306         tptr += tlv_len;
1307     }
1308 
1309  trunc:
1310     return hexdump;
1311 }
1312 
1313 static char *
1314 lldp_network_addr_print(netdissect_options *ndo, const u_char *tptr, u_int len)
1315 {
1316     uint8_t af;
1317     static char buf[BUFSIZE];
1318     const char * (*pfunc)(netdissect_options *, const u_char *);
1319 
1320     if (len < 1)
1321       return NULL;
1322     len--;
1323     af = *tptr;
1324     switch (af) {
1325     case AFNUM_INET:
1326         if (len < 4)
1327           return NULL;
1328         /* This cannot be assigned to ipaddr_string(), which is a macro. */
1329         pfunc = getname;
1330         break;
1331     case AFNUM_INET6:
1332         if (len < 16)
1333           return NULL;
1334         /* This cannot be assigned to ip6addr_string(), which is a macro. */
1335         pfunc = getname6;
1336         break;
1337     case AFNUM_802:
1338         if (len < 6)
1339           return NULL;
1340         pfunc = etheraddr_string;
1341         break;
1342     default:
1343         pfunc = NULL;
1344         break;
1345     }
1346 
1347     if (!pfunc) {
1348         snprintf(buf, sizeof(buf), "AFI %s (%u), no AF printer !",
1349                  tok2str(af_values, "Unknown", af), af);
1350     } else {
1351         snprintf(buf, sizeof(buf), "AFI %s (%u): %s",
1352                  tok2str(af_values, "Unknown", af), af, (*pfunc)(ndo, tptr+1));
1353     }
1354 
1355     return buf;
1356 }
1357 
1358 static int
1359 lldp_mgmt_addr_tlv_print(netdissect_options *ndo,
1360                          const u_char *pptr, u_int len)
1361 {
1362     uint8_t mgmt_addr_len, intf_num_subtype, oid_len;
1363     const u_char *tptr;
1364     u_int tlen;
1365     char *mgmt_addr;
1366 
1367     tlen = len;
1368     tptr = pptr;
1369 
1370     if (tlen < 1) {
1371         return 0;
1372     }
1373     mgmt_addr_len = *tptr++;
1374     tlen--;
1375 
1376     if (tlen < mgmt_addr_len) {
1377         return 0;
1378     }
1379 
1380     mgmt_addr = lldp_network_addr_print(ndo, tptr, mgmt_addr_len);
1381     if (mgmt_addr == NULL) {
1382         return 0;
1383     }
1384     ND_PRINT((ndo, "\n\t  Management Address length %u, %s",
1385            mgmt_addr_len, mgmt_addr));
1386     tptr += mgmt_addr_len;
1387     tlen -= mgmt_addr_len;
1388 
1389     if (tlen < LLDP_INTF_NUM_LEN) {
1390         return 0;
1391     }
1392 
1393     intf_num_subtype = *tptr;
1394     ND_PRINT((ndo, "\n\t  %s Interface Numbering (%u): %u",
1395            tok2str(lldp_intf_numb_subtype_values, "Unknown", intf_num_subtype),
1396            intf_num_subtype,
1397            EXTRACT_32BITS(tptr + 1)));
1398 
1399     tptr += LLDP_INTF_NUM_LEN;
1400     tlen -= LLDP_INTF_NUM_LEN;
1401 
1402     /*
1403      * The OID is optional.
1404      */
1405     if (tlen) {
1406         oid_len = *tptr;
1407 
1408         if (tlen < oid_len) {
1409             return 0;
1410         }
1411         if (oid_len) {
1412             ND_PRINT((ndo, "\n\t  OID length %u", oid_len));
1413             safeputs(ndo, tptr + 1, oid_len);
1414         }
1415     }
1416 
1417     return 1;
1418 }
1419 
1420 void
1421 lldp_print(netdissect_options *ndo,
1422            register const u_char *pptr, register u_int len)
1423 {
1424     uint8_t subtype;
1425     uint16_t tlv, cap, ena_cap;
1426     u_int oui, tlen, hexdump, tlv_type, tlv_len;
1427     const u_char *tptr;
1428     char *network_addr;
1429 
1430     tptr = pptr;
1431     tlen = len;
1432 
1433     ND_PRINT((ndo, "LLDP, length %u", len));
1434 
1435     while (tlen >= sizeof(tlv)) {
1436 
1437         ND_TCHECK2(*tptr, sizeof(tlv));
1438 
1439         tlv = EXTRACT_16BITS(tptr);
1440 
1441         tlv_type = LLDP_EXTRACT_TYPE(tlv);
1442         tlv_len = LLDP_EXTRACT_LEN(tlv);
1443         hexdump = FALSE;
1444 
1445         tlen -= sizeof(tlv);
1446         tptr += sizeof(tlv);
1447 
1448         if (ndo->ndo_vflag) {
1449             ND_PRINT((ndo, "\n\t%s TLV (%u), length %u",
1450                    tok2str(lldp_tlv_values, "Unknown", tlv_type),
1451                    tlv_type, tlv_len));
1452         }
1453 
1454         /* infinite loop check */
1455         if (!tlv_type || !tlv_len) {
1456             break;
1457         }
1458 
1459         ND_TCHECK2(*tptr, tlv_len);
1460         if (tlen < tlv_len) {
1461             goto trunc;
1462         }
1463 
1464         switch (tlv_type) {
1465 
1466         case LLDP_CHASSIS_ID_TLV:
1467             if (ndo->ndo_vflag) {
1468                 if (tlv_len < 2) {
1469                     goto trunc;
1470                 }
1471                 subtype = *tptr;
1472                 ND_PRINT((ndo, "\n\t  Subtype %s (%u): ",
1473                        tok2str(lldp_chassis_subtype_values, "Unknown", subtype),
1474                        subtype));
1475 
1476                 switch (subtype) {
1477                 case LLDP_CHASSIS_MAC_ADDR_SUBTYPE:
1478                     if (tlv_len < 1+6) {
1479                         goto trunc;
1480                     }
1481                     ND_PRINT((ndo, "%s", etheraddr_string(ndo, tptr + 1)));
1482                     break;
1483 
1484                 case LLDP_CHASSIS_INTF_NAME_SUBTYPE: /* fall through */
1485                 case LLDP_CHASSIS_LOCAL_SUBTYPE:
1486                 case LLDP_CHASSIS_CHASSIS_COMP_SUBTYPE:
1487                 case LLDP_CHASSIS_INTF_ALIAS_SUBTYPE:
1488                 case LLDP_CHASSIS_PORT_COMP_SUBTYPE:
1489                     safeputs(ndo, tptr + 1, tlv_len - 1);
1490                     break;
1491 
1492                 case LLDP_CHASSIS_NETWORK_ADDR_SUBTYPE:
1493                     network_addr = lldp_network_addr_print(ndo, tptr+1, tlv_len-1);
1494                     if (network_addr == NULL) {
1495                         goto trunc;
1496                     }
1497                     ND_PRINT((ndo, "%s", network_addr));
1498                     break;
1499 
1500                 default:
1501                     hexdump = TRUE;
1502                     break;
1503                 }
1504             }
1505             break;
1506 
1507         case LLDP_PORT_ID_TLV:
1508             if (ndo->ndo_vflag) {
1509                 if (tlv_len < 2) {
1510                     goto trunc;
1511                 }
1512                 subtype = *tptr;
1513                 ND_PRINT((ndo, "\n\t  Subtype %s (%u): ",
1514                        tok2str(lldp_port_subtype_values, "Unknown", subtype),
1515                        subtype));
1516 
1517                 switch (subtype) {
1518                 case LLDP_PORT_MAC_ADDR_SUBTYPE:
1519                     if (tlv_len < 1+6) {
1520                         goto trunc;
1521                     }
1522                     ND_PRINT((ndo, "%s", etheraddr_string(ndo, tptr + 1)));
1523                     break;
1524 
1525                 case LLDP_PORT_INTF_NAME_SUBTYPE: /* fall through */
1526                 case LLDP_PORT_LOCAL_SUBTYPE:
1527                 case LLDP_PORT_AGENT_CIRC_ID_SUBTYPE:
1528                 case LLDP_PORT_INTF_ALIAS_SUBTYPE:
1529                 case LLDP_PORT_PORT_COMP_SUBTYPE:
1530                     safeputs(ndo, tptr + 1, tlv_len - 1);
1531                     break;
1532 
1533                 case LLDP_PORT_NETWORK_ADDR_SUBTYPE:
1534                     network_addr = lldp_network_addr_print(ndo, tptr+1, tlv_len-1);
1535                     if (network_addr == NULL) {
1536                         goto trunc;
1537                     }
1538                     ND_PRINT((ndo, "%s", network_addr));
1539                     break;
1540 
1541                 default:
1542                     hexdump = TRUE;
1543                     break;
1544                 }
1545             }
1546             break;
1547 
1548         case LLDP_TTL_TLV:
1549             if (ndo->ndo_vflag) {
1550                 if (tlv_len < 2) {
1551                     goto trunc;
1552                 }
1553                 ND_PRINT((ndo, ": TTL %us", EXTRACT_16BITS(tptr)));
1554             }
1555             break;
1556 
1557         case LLDP_PORT_DESCR_TLV:
1558             if (ndo->ndo_vflag) {
1559                 ND_PRINT((ndo, ": "));
1560                 safeputs(ndo, tptr, tlv_len);
1561             }
1562             break;
1563 
1564         case LLDP_SYSTEM_NAME_TLV:
1565             /*
1566              * The system name is also print in non-verbose mode
1567              * similar to the CDP printer.
1568              */
1569             ND_PRINT((ndo, ": "));
1570             safeputs(ndo, tptr, tlv_len);
1571             break;
1572 
1573         case LLDP_SYSTEM_DESCR_TLV:
1574             if (ndo->ndo_vflag) {
1575                 ND_PRINT((ndo, "\n\t  "));
1576                 safeputs(ndo, tptr, tlv_len);
1577             }
1578             break;
1579 
1580         case LLDP_SYSTEM_CAP_TLV:
1581             if (ndo->ndo_vflag) {
1582                 /*
1583                  * XXX - IEEE Std 802.1AB-2009 says the first octet
1584                  * if a chassis ID subtype, with the system
1585                  * capabilities and enabled capabilities following
1586                  * it.
1587                  */
1588                 if (tlv_len < 4) {
1589                     goto trunc;
1590                 }
1591                 cap = EXTRACT_16BITS(tptr);
1592                 ena_cap = EXTRACT_16BITS(tptr+2);
1593                 ND_PRINT((ndo, "\n\t  System  Capabilities [%s] (0x%04x)",
1594                        bittok2str(lldp_cap_values, "none", cap), cap));
1595                 ND_PRINT((ndo, "\n\t  Enabled Capabilities [%s] (0x%04x)",
1596                        bittok2str(lldp_cap_values, "none", ena_cap), ena_cap));
1597             }
1598             break;
1599 
1600         case LLDP_MGMT_ADDR_TLV:
1601             if (ndo->ndo_vflag) {
1602                 if (!lldp_mgmt_addr_tlv_print(ndo, tptr, tlv_len)) {
1603                     goto trunc;
1604                 }
1605             }
1606             break;
1607 
1608         case LLDP_PRIVATE_TLV:
1609             if (ndo->ndo_vflag) {
1610                 if (tlv_len < 3) {
1611                     goto trunc;
1612                 }
1613                 oui = EXTRACT_24BITS(tptr);
1614                 ND_PRINT((ndo, ": OUI %s (0x%06x)", tok2str(oui_values, "Unknown", oui), oui));
1615 
1616                 switch (oui) {
1617                 case OUI_IEEE_8021_PRIVATE:
1618                     hexdump = lldp_private_8021_print(ndo, tptr, tlv_len);
1619                     break;
1620                 case OUI_IEEE_8023_PRIVATE:
1621                     hexdump = lldp_private_8023_print(ndo, tptr, tlv_len);
1622                     break;
1623 		case OUI_IANA:
1624                     hexdump = lldp_private_iana_print(ndo, tptr, tlv_len);
1625                     break;
1626                 case OUI_TIA:
1627                     hexdump = lldp_private_tia_print(ndo, tptr, tlv_len);
1628                     break;
1629                 case OUI_DCBX:
1630                     hexdump = lldp_private_dcbx_print(ndo, tptr, tlv_len);
1631                     break;
1632                 default:
1633                     hexdump = TRUE;
1634                     break;
1635                 }
1636             }
1637             break;
1638 
1639         default:
1640             hexdump = TRUE;
1641             break;
1642         }
1643 
1644         /* do we also want to see a hex dump ? */
1645         if (ndo->ndo_vflag > 1 || (ndo->ndo_vflag && hexdump)) {
1646             print_unknown_data(ndo, tptr, "\n\t  ", tlv_len);
1647         }
1648 
1649         tlen -= tlv_len;
1650         tptr += tlv_len;
1651     }
1652     return;
1653  trunc:
1654     ND_PRINT((ndo, "\n\t[|LLDP]"));
1655 }
1656 
1657 /*
1658  * Local Variables:
1659  * c-style: whitesmith
1660  * c-basic-offset: 4
1661  * End:
1662  */
1663