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