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