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