]> git.ipfire.org Git - thirdparty/lldpd.git/blame - src/client/display.c
build: bump cross-platform-actions/action from 0.27.0 to 0.28.0
[thirdparty/lldpd.git] / src / client / display.c
CommitLineData
4b292b55
VB
1/* -*- mode: c; c-file-style: "openbsd" -*- */
2/*
3 * Copyright (c) 2008 Vincent Bernat <bernat@luffy.cx>
4 *
5 * Permission to use, copy, modify, and/or distribute this software for any
6 * purpose with or without fee is hereby granted, provided that the above
7 * copyright notice and this permission notice appear in all copies.
8 *
9 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
10 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
11 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
12 * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
13 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
14 * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
15 * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
16 */
17
18#include <stdio.h>
19#include <stdlib.h>
20#include <unistd.h>
21#include <ctype.h>
22#include <time.h>
23#include <errno.h>
54c057d1 24#include <sys/param.h>
4b292b55
VB
25#include <sys/types.h>
26#include <sys/socket.h>
27#include <sys/un.h>
28#include <arpa/inet.h>
4e5f34c5 29#include <string.h>
4b292b55
VB
30
31#include "../log.h"
32#include "client.h"
33
34static void
9f181945
PD
35display_cap(struct writer *w, lldpctl_atom_t *chassis, u_int16_t bit,
36 const char *symbol)
4b292b55
VB
37{
38 if (lldpctl_atom_get_int(chassis, lldpctl_k_chassis_cap_available) & bit) {
39 tag_start(w, "capability", "Capability");
8b549648
VB
40 tag_attr(w, "type", "", symbol);
41 tag_attr(w, "enabled", "",
42 (lldpctl_atom_get_int(chassis, lldpctl_k_chassis_cap_enabled) &
43 bit) ?
44 "on" :
45 "off");
46 tag_end(w);
4b292b55
VB
47 }
48}
49
50static void
51display_med_capability(struct writer *w, long int available, int cap,
52 const char *symbol)
53{
54 if (available & cap) {
55 tag_start(w, "capability", "Capability");
56 tag_attr(w, "type", "", symbol);
1f8742dd 57 tag_attr(w, "available", "", "yes");
4b292b55
VB
58 tag_end(w);
59 }
60}
61
4b292b55 62static void
9439b950 63display_med(struct writer *w, lldpctl_atom_t *port, lldpctl_atom_t *chassis)
4b292b55
VB
64{
65 lldpctl_atom_t *medpolicies, *medpolicy;
66 lldpctl_atom_t *medlocations, *medlocation;
67 lldpctl_atom_t *caelements, *caelement;
60ad2804 68 lldpctl_atom_t *medpower;
9439b950 69 long int cap = lldpctl_atom_get_int(chassis, lldpctl_k_chassis_med_cap);
4b292b55
VB
70 const char *type;
71
8b549648 72 if (lldpctl_atom_get_int(chassis, lldpctl_k_chassis_med_type) <= 0) return;
4b292b55
VB
73
74 tag_start(w, "lldp-med", "LLDP-MED");
75
76 tag_datatag(w, "device-type", "Device Type",
9439b950 77 lldpctl_atom_get_str(chassis, lldpctl_k_chassis_med_type));
4b292b55
VB
78
79 display_med_capability(w, cap, LLDP_MED_CAP_CAP, "Capabilities");
80 display_med_capability(w, cap, LLDP_MED_CAP_POLICY, "Policy");
81 display_med_capability(w, cap, LLDP_MED_CAP_LOCATION, "Location");
82 display_med_capability(w, cap, LLDP_MED_CAP_MDI_PSE, "MDI/PSE");
83 display_med_capability(w, cap, LLDP_MED_CAP_MDI_PD, "MDI/PD");
84 display_med_capability(w, cap, LLDP_MED_CAP_IV, "Inventory");
85
86 /* LLDP MED policies */
87 medpolicies = lldpctl_atom_get(port, lldpctl_k_port_med_policies);
8b549648
VB
88 lldpctl_atom_foreach(medpolicies, medpolicy)
89 {
90 if (lldpctl_atom_get_int(medpolicy, lldpctl_k_med_policy_type) <= 0)
91 continue;
4b292b55
VB
92
93 tag_start(w, "policy", "LLDP-MED Network Policy for");
8b549648
VB
94 tag_attr(w, "apptype", "",
95 lldpctl_atom_get_str(medpolicy, lldpctl_k_med_policy_type));
4b292b55 96 tag_attr(w, "defined", "Defined",
8b549648
VB
97 (lldpctl_atom_get_int(medpolicy, lldpctl_k_med_policy_unknown) >
98 0) ?
99 "no" :
100 "yes");
101
102 if (lldpctl_atom_get_int(medpolicy, lldpctl_k_med_policy_tagged) > 0) {
103 int vid =
104 lldpctl_atom_get_int(medpolicy, lldpctl_k_med_policy_vid);
4b292b55
VB
105 tag_start(w, "vlan", "VLAN");
106 if (vid == 0) {
107 tag_attr(w, "vid", "", "priority");
108 } else if (vid == 4095) {
109 tag_attr(w, "vid", "", "reserved");
110 } else {
111 tag_attr(w, "vid", "",
112 lldpctl_atom_get_str(medpolicy,
113 lldpctl_k_med_policy_vid));
114 }
115 tag_end(w);
116 }
117
118 tag_datatag(w, "priority", "Priority",
8b549648 119 lldpctl_atom_get_str(medpolicy, lldpctl_k_med_policy_priority));
5b12cbac 120 /* Also give a numeric value */
8b549648
VB
121 int pcp =
122 lldpctl_atom_get_int(medpolicy, lldpctl_k_med_policy_priority);
5b12cbac
VB
123 char spcp[2] = { pcp + '0', '\0' };
124 tag_datatag(w, "pcp", "PCP", spcp);
4b292b55 125 tag_datatag(w, "dscp", "DSCP Value",
8b549648 126 lldpctl_atom_get_str(medpolicy, lldpctl_k_med_policy_dscp));
4b292b55
VB
127
128 tag_end(w);
129 }
130 lldpctl_atom_dec_ref(medpolicies);
131
132 /* LLDP MED locations */
133 medlocations = lldpctl_atom_get(port, lldpctl_k_port_med_locations);
8b549648
VB
134 lldpctl_atom_foreach(medlocations, medlocation)
135 {
136 int format =
137 lldpctl_atom_get_int(medlocation, lldpctl_k_med_location_format);
4b292b55
VB
138 if (format <= 0) continue;
139 tag_start(w, "location", "LLDP-MED Location Identification");
140 tag_attr(w, "type", "Type",
8b549648 141 lldpctl_atom_get_str(medlocation, lldpctl_k_med_location_format));
4b292b55
VB
142
143 switch (format) {
144 case LLDP_MED_LOCFORMAT_COORD:
145 tag_attr(w, "geoid", "Geoid",
146 lldpctl_atom_get_str(medlocation,
147 lldpctl_k_med_location_geoid));
148 tag_datatag(w, "lat", "Latitude",
149 lldpctl_atom_get_str(medlocation,
150 lldpctl_k_med_location_latitude));
151 tag_datatag(w, "lon", "Longitude",
152 lldpctl_atom_get_str(medlocation,
153 lldpctl_k_med_location_longitude));
154 tag_start(w, "altitude", "Altitude");
8b549648
VB
155 tag_attr(w, "unit", "",
156 lldpctl_atom_get_str(medlocation,
4b292b55 157 lldpctl_k_med_location_altitude_unit));
8b549648
VB
158 tag_data(w,
159 lldpctl_atom_get_str(medlocation,
4b292b55
VB
160 lldpctl_k_med_location_altitude));
161 tag_end(w);
162 break;
163 case LLDP_MED_LOCFORMAT_CIVIC:
164 tag_datatag(w, "country", "Country",
165 lldpctl_atom_get_str(medlocation,
166 lldpctl_k_med_location_country));
167 caelements = lldpctl_atom_get(medlocation,
168 lldpctl_k_med_location_ca_elements);
8b549648
VB
169 lldpctl_atom_foreach(caelements, caelement)
170 {
4b292b55
VB
171 type = lldpctl_atom_get_str(caelement,
172 lldpctl_k_med_civicaddress_type);
173 tag_datatag(w, totag(type), type,
174 lldpctl_atom_get_str(caelement,
175 lldpctl_k_med_civicaddress_value));
176 }
177 lldpctl_atom_dec_ref(caelements);
178 break;
179 case LLDP_MED_LOCFORMAT_ELIN:
180 tag_datatag(w, "ecs", "ECS ELIN",
181 lldpctl_atom_get_str(medlocation,
182 lldpctl_k_med_location_elin));
183 break;
184 }
185
186 tag_end(w);
187 }
188 lldpctl_atom_dec_ref(medlocations);
189
190 /* LLDP MED power */
60ad2804
VB
191 medpower = lldpctl_atom_get(port, lldpctl_k_port_med_power);
192 if (lldpctl_atom_get_int(medpower, lldpctl_k_med_power_type) > 0) {
8b549648 193 tag_start(w, "poe", "Extended Power-over-Ethernet");
4b292b55
VB
194
195 tag_datatag(w, "device-type", "Power Type & Source",
60ad2804 196 lldpctl_atom_get_str(medpower, lldpctl_k_med_power_type));
4b292b55 197 tag_datatag(w, "source", "Power Source",
60ad2804 198 lldpctl_atom_get_str(medpower, lldpctl_k_med_power_source));
4b292b55 199 tag_datatag(w, "priority", "Power priority",
60ad2804 200 lldpctl_atom_get_str(medpower, lldpctl_k_med_power_priority));
4b292b55 201 tag_datatag(w, "power", "Power Value",
60ad2804
VB
202 lldpctl_atom_get_str(medpower, lldpctl_k_med_power_val));
203
204 tag_end(w);
4b292b55 205 }
60ad2804 206 lldpctl_atom_dec_ref(medpower);
4b292b55
VB
207
208 /* LLDP MED inventory */
209 do {
8b549648
VB
210 const char *hw =
211 lldpctl_atom_get_str(chassis, lldpctl_k_chassis_med_inventory_hw);
212 const char *sw =
213 lldpctl_atom_get_str(chassis, lldpctl_k_chassis_med_inventory_sw);
214 const char *fw =
215 lldpctl_atom_get_str(chassis, lldpctl_k_chassis_med_inventory_fw);
216 const char *sn =
217 lldpctl_atom_get_str(chassis, lldpctl_k_chassis_med_inventory_sn);
9439b950 218 const char *manuf = lldpctl_atom_get_str(chassis,
4b292b55 219 lldpctl_k_chassis_med_inventory_manuf);
9439b950 220 const char *model = lldpctl_atom_get_str(chassis,
4b292b55 221 lldpctl_k_chassis_med_inventory_model);
9439b950 222 const char *asset = lldpctl_atom_get_str(chassis,
4b292b55 223 lldpctl_k_chassis_med_inventory_asset);
8b549648 224 if (!(hw || sw || fw || sn || manuf || model || asset)) break;
4b292b55
VB
225
226 tag_start(w, "inventory", "Inventory");
227 tag_datatag(w, "hardware", "Hardware Revision", hw);
228 tag_datatag(w, "software", "Software Revision", sw);
229 tag_datatag(w, "firmware", "Firmware Revision", fw);
230 tag_datatag(w, "serial", "Serial Number", sn);
231 tag_datatag(w, "manufacturer", "Manufacturer", manuf);
232 tag_datatag(w, "model", "Model", model);
233 tag_datatag(w, "asset", "Asset ID", asset);
234 tag_end(w);
8b549648 235 } while (0);
4b292b55
VB
236
237 tag_end(w);
238}
239
240static void
8b549648 241display_chassis(struct writer *w, lldpctl_atom_t *chassis, int details)
4b292b55
VB
242{
243 lldpctl_atom_t *mgmts, *mgmt;
244
245 tag_start(w, "chassis", "Chassis");
246 tag_start(w, "id", "ChassisID");
8b549648
VB
247 tag_attr(w, "type", "",
248 lldpctl_atom_get_str(chassis, lldpctl_k_chassis_id_subtype));
249 tag_data(w, lldpctl_atom_get_str(chassis, lldpctl_k_chassis_id));
4b292b55
VB
250 tag_end(w);
251 tag_datatag(w, "name", "SysName",
9439b950 252 lldpctl_atom_get_str(chassis, lldpctl_k_chassis_name));
9a775667
VB
253 if (details == DISPLAY_BRIEF) {
254 tag_end(w);
255 return;
256 }
4b292b55 257 tag_datatag(w, "descr", "SysDescr",
9439b950 258 lldpctl_atom_get_str(chassis, lldpctl_k_chassis_descr));
4b292b55
VB
259
260 /* Management addresses */
9439b950 261 mgmts = lldpctl_atom_get(chassis, lldpctl_k_chassis_mgmt);
8b549648
VB
262 lldpctl_atom_foreach(mgmts, mgmt)
263 {
4b292b55
VB
264 tag_datatag(w, "mgmt-ip", "MgmtIP",
265 lldpctl_atom_get_str(mgmt, lldpctl_k_mgmt_ip));
30fca74b
VB
266 if (lldpctl_atom_get_int(mgmt, lldpctl_k_mgmt_iface_index))
267 tag_datatag(w, "mgmt-iface", "MgmtIface",
268 lldpctl_atom_get_str(mgmt, lldpctl_k_mgmt_iface_index));
4b292b55
VB
269 }
270 lldpctl_atom_dec_ref(mgmts);
271
272 /* Capabilities */
9439b950
VB
273 display_cap(w, chassis, LLDP_CAP_OTHER, "Other");
274 display_cap(w, chassis, LLDP_CAP_REPEATER, "Repeater");
275 display_cap(w, chassis, LLDP_CAP_BRIDGE, "Bridge");
276 display_cap(w, chassis, LLDP_CAP_ROUTER, "Router");
277 display_cap(w, chassis, LLDP_CAP_WLAN, "Wlan");
278 display_cap(w, chassis, LLDP_CAP_TELEPHONE, "Tel");
279 display_cap(w, chassis, LLDP_CAP_DOCSIS, "Docsis");
280 display_cap(w, chassis, LLDP_CAP_STATION, "Station");
9f181945
PD
281 display_cap(w, chassis, LLDP_CAP_CVLAN, "CVLAN");
282 display_cap(w, chassis, LLDP_CAP_SVLAN, "SVLAN");
283 display_cap(w, chassis, LLDP_CAP_TPMRCOMP, "TPMR");
4b292b55
VB
284
285 tag_end(w);
286}
287
26331a26 288static void
8b549648 289display_custom_tlvs(struct writer *w, lldpctl_atom_t *neighbor)
26331a26
AA
290{
291 lldpctl_atom_t *custom_list, *custom;
292 int have_custom_tlvs = 0;
293 size_t i, len, slen;
294 const uint8_t *oui, *oui_info;
295 char buf[1600]; /* should be enough for printing */
296
297 custom_list = lldpctl_atom_get(neighbor, lldpctl_k_custom_tlvs);
8b549648
VB
298 lldpctl_atom_foreach(custom_list, custom)
299 {
26331a26
AA
300 /* This tag gets added only once, if there are any custom TLVs */
301 if (!have_custom_tlvs) {
877f7db8 302 tag_start(w, "unknown-tlvs", "Unknown TLVs");
26331a26
AA
303 have_custom_tlvs++;
304 }
305 len = 0;
306 oui = lldpctl_atom_get_buffer(custom, lldpctl_k_custom_tlv_oui, &len);
307 len = 0;
8b549648
VB
308 oui_info = lldpctl_atom_get_buffer(custom,
309 lldpctl_k_custom_tlv_oui_info_string, &len);
310 if (!oui) continue;
26331a26
AA
311 tag_start(w, "unknown-tlv", "TLV");
312
313 /* Add OUI as attribute */
314 snprintf(buf, sizeof(buf), "%02X,%02X,%02X", oui[0], oui[1], oui[2]);
315 tag_attr(w, "oui", "OUI", buf);
316 snprintf(buf, sizeof(buf), "%d",
8b549648
VB
317 (int)lldpctl_atom_get_int(custom,
318 lldpctl_k_custom_tlv_oui_subtype));
26331a26
AA
319 tag_attr(w, "subtype", "SubType", buf);
320 snprintf(buf, sizeof(buf), "%d", (int)len);
321 tag_attr(w, "len", "Len", buf);
322 if (len > 0) {
8b549648
VB
323 for (slen = 0, i = 0; i < len; ++i)
324 slen += snprintf(buf + slen,
325 sizeof(buf) > slen ? sizeof(buf) - slen : 0,
326 "%02X%s", oui_info[i], ((i < len - 1) ? "," : ""));
26331a26
AA
327 tag_data(w, buf);
328 }
329 tag_end(w);
330 }
331 lldpctl_atom_dec_ref(custom_list);
332
8b549648 333 if (have_custom_tlvs) tag_end(w);
26331a26
AA
334}
335
4b292b55 336static void
f540397c
GS
337display_autoneg(struct writer *w, int advertised, int bithd, int bitfd,
338 const char *desc)
4b292b55 339{
8b549648 340 if (!((advertised & bithd) || (advertised & bitfd))) return;
4b292b55
VB
341
342 tag_start(w, "advertised", "Adv");
343 tag_attr(w, "type", "", desc);
20264473 344 if (bitfd != bithd) {
8b549648
VB
345 tag_attr(w, "hd", "HD", (advertised & bithd) ? "yes" : "no");
346 tag_attr(w, "fd", "FD", (advertised & bitfd) ? "yes" : "no");
20264473 347 }
8b549648 348 tag_end(w);
4b292b55
VB
349}
350
351static void
9a775667 352display_port(struct writer *w, lldpctl_atom_t *port, int details)
4b292b55 353{
1e85286a
MW
354 int vlan_tx_tag;
355 char buf[5]; /* should be enough for printing */
356
4b292b55
VB
357 tag_start(w, "port", "Port");
358 tag_start(w, "id", "PortID");
8b549648 359 tag_attr(w, "type", "", lldpctl_atom_get_str(port, lldpctl_k_port_id_subtype));
4b292b55
VB
360 tag_data(w, lldpctl_atom_get_str(port, lldpctl_k_port_id));
361 tag_end(w);
362
363 tag_datatag(w, "descr", "PortDescr",
364 lldpctl_atom_get_str(port, lldpctl_k_port_descr));
1e85286a
MW
365
366 if ((vlan_tx_tag = lldpctl_atom_get_int(port, lldpctl_k_port_vlan_tx)) != -1) {
367 tag_start(w, "vlanTX", "VlanTX");
368 snprintf(buf, sizeof(buf), "%d", vlan_tx_tag & 0xfff);
8b549648 369 tag_attr(w, "id", "VID", buf);
1e85286a 370 snprintf(buf, sizeof(buf), "%d", (vlan_tx_tag >> 13) & 0x7);
8b549648 371 tag_attr(w, "prio", "Prio", buf);
1e85286a 372 snprintf(buf, sizeof(buf), "%d", (vlan_tx_tag >> 12) & 0x1);
8b549648 373 tag_attr(w, "dei", "DEI", buf);
1e85286a
MW
374 tag_end(w);
375 }
376
8b549648 377 if (details && lldpctl_atom_get_int(port, lldpctl_k_port_ttl) > 0)
78346c89
VB
378 tag_datatag(w, "ttl", "TTL",
379 lldpctl_atom_get_str(port, lldpctl_k_port_ttl));
4b292b55
VB
380
381 /* Dot3 */
9a775667
VB
382 if (details == DISPLAY_DETAILS) {
383 tag_datatag(w, "mfs", "MFS",
384 lldpctl_atom_get_str(port, lldpctl_k_port_dot3_mfs));
a519a7e4 385 tag_datatag(w, "aggregation", "Port is aggregated. PortAggregID",
9a775667 386 lldpctl_atom_get_str(port, lldpctl_k_port_dot3_aggregid));
4b292b55 387
72cf4bba 388 long int autoneg_support, autoneg_enabled, autoneg_advertised, mautype;
8b549648
VB
389 autoneg_support =
390 lldpctl_atom_get_int(port, lldpctl_k_port_dot3_autoneg_support);
391 autoneg_enabled =
392 lldpctl_atom_get_int(port, lldpctl_k_port_dot3_autoneg_enabled);
393 autoneg_advertised =
394 lldpctl_atom_get_int(port, lldpctl_k_port_dot3_autoneg_advertised);
72cf4bba
VB
395 mautype = lldpctl_atom_get_int(port, lldpctl_k_port_dot3_mautype);
396 if (autoneg_support > 0 || autoneg_enabled > 0 || mautype > 0) {
4b292b55 397 tag_start(w, "auto-negotiation", "PMD autoneg");
8b549648
VB
398 tag_attr(w, "supported", "supported",
399 (autoneg_support > 0) ? "yes" : "no");
400 tag_attr(w, "enabled", "enabled",
401 (autoneg_enabled > 0) ? "yes" : "no");
4b292b55
VB
402
403 if (autoneg_enabled > 0) {
8b549648 404 if (autoneg_advertised < 0) autoneg_advertised = 0;
4b292b55
VB
405 display_autoneg(w, autoneg_advertised,
406 LLDP_DOT3_LINK_AUTONEG_10BASE_T,
8b549648 407 LLDP_DOT3_LINK_AUTONEG_10BASET_FD, "10Base-T");
4b292b55
VB
408 display_autoneg(w, autoneg_advertised,
409 LLDP_DOT3_LINK_AUTONEG_100BASE_TX,
8b549648 410 LLDP_DOT3_LINK_AUTONEG_100BASE_TXFD, "100Base-TX");
4b292b55
VB
411 display_autoneg(w, autoneg_advertised,
412 LLDP_DOT3_LINK_AUTONEG_100BASE_T2,
8b549648 413 LLDP_DOT3_LINK_AUTONEG_100BASE_T2FD, "100Base-T2");
20264473
VB
414 display_autoneg(w, autoneg_advertised,
415 LLDP_DOT3_LINK_AUTONEG_100BASE_T4,
8b549648 416 LLDP_DOT3_LINK_AUTONEG_100BASE_T4, "100Base-T4");
4b292b55
VB
417 display_autoneg(w, autoneg_advertised,
418 LLDP_DOT3_LINK_AUTONEG_1000BASE_X,
8b549648 419 LLDP_DOT3_LINK_AUTONEG_1000BASE_XFD, "1000Base-X");
4b292b55
VB
420 display_autoneg(w, autoneg_advertised,
421 LLDP_DOT3_LINK_AUTONEG_1000BASE_T,
8b549648 422 LLDP_DOT3_LINK_AUTONEG_1000BASE_TFD, "1000Base-T");
4b292b55
VB
423 }
424 tag_datatag(w, "current", "MAU oper type",
425 lldpctl_atom_get_str(port, lldpctl_k_port_dot3_mautype));
426 tag_end(w);
427 }
4b292b55 428
8b549648
VB
429 lldpctl_atom_t *dot3_power =
430 lldpctl_atom_get(port, lldpctl_k_port_dot3_power);
431 int devicetype =
432 lldpctl_atom_get_int(dot3_power, lldpctl_k_dot3_power_devicetype);
4b292b55
VB
433 if (devicetype > 0) {
434 tag_start(w, "power", "MDI Power");
b6541a9a 435 tag_attr(w, "supported", "Supported",
4b292b55 436 (lldpctl_atom_get_int(dot3_power,
8b549648
VB
437 lldpctl_k_dot3_power_supported) > 0) ?
438 "yes" :
439 "no");
b6541a9a 440 tag_attr(w, "enabled", "Enabled",
4b292b55 441 (lldpctl_atom_get_int(dot3_power,
8b549648
VB
442 lldpctl_k_dot3_power_enabled) > 0) ?
443 "yes" :
444 "no");
b6541a9a 445 tag_attr(w, "paircontrol", "Pair control",
4b292b55 446 (lldpctl_atom_get_int(dot3_power,
8b549648
VB
447 lldpctl_k_dot3_power_paircontrol) > 0) ?
448 "yes" :
449 "no");
4b292b55 450 tag_start(w, "device-type", "Device type");
8b549648
VB
451 tag_data(w,
452 lldpctl_atom_get_str(dot3_power,
453 lldpctl_k_dot3_power_devicetype));
454 ;
4b292b55 455 tag_end(w);
0e05b829 456 tag_start(w, "pairs", "Power pairs");
8b549648
VB
457 tag_data(w,
458 lldpctl_atom_get_str(dot3_power,
0e05b829
VB
459 lldpctl_k_dot3_power_pairs));
460 tag_end(w);
4b292b55 461 tag_start(w, "class", "Class");
8b549648
VB
462 tag_data(w,
463 lldpctl_atom_get_str(dot3_power,
4b292b55
VB
464 lldpctl_k_dot3_power_class));
465 tag_end(w);
466
467 /* 802.3at */
468 if (lldpctl_atom_get_int(dot3_power,
8b549648
VB
469 lldpctl_k_dot3_power_type) >
470 LLDP_DOT3_POWER_8023AT_OFF) {
4b292b55 471 tag_start(w, "power-type", "Power type");
8b549648
VB
472 tag_data(w,
473 lldpctl_atom_get_str(dot3_power,
4b292b55
VB
474 lldpctl_k_dot3_power_type));
475 tag_end(w);
476
477 tag_start(w, "source", "Power Source");
8b549648
VB
478 tag_data(w,
479 lldpctl_atom_get_str(dot3_power,
4b292b55
VB
480 lldpctl_k_dot3_power_source));
481 tag_end(w);
482
483 tag_start(w, "priority", "Power Priority");
8b549648
VB
484 tag_data(w,
485 lldpctl_atom_get_str(dot3_power,
4b292b55
VB
486 lldpctl_k_dot3_power_priority));
487 tag_end(w);
488
489 tag_start(w, "requested", "PD requested power Value");
8b549648
VB
490 tag_data(w,
491 lldpctl_atom_get_str(dot3_power,
4b292b55
VB
492 lldpctl_k_dot3_power_requested));
493 tag_end(w);
494
495 tag_start(w, "allocated", "PSE allocated power Value");
8b549648
VB
496 tag_data(w,
497 lldpctl_atom_get_str(dot3_power,
4b292b55
VB
498 lldpctl_k_dot3_power_allocated));
499 tag_end(w);
500 }
501
551717c6
VB
502 /* 802.3bt */
503 if (lldpctl_atom_get_int(dot3_power,
504 lldpctl_k_dot3_power_type_ext) >
505 LLDP_DOT3_POWER_8023BT_OFF) {
506 tag_start(w, "requested-a", "Requested mode A");
507 tag_data(w,
508 lldpctl_atom_get_str(dot3_power,
509 lldpctl_k_dot3_power_requested_a));
510 tag_end(w);
511 tag_start(w, "requested-b", "Requested mode B");
512 tag_data(w,
513 lldpctl_atom_get_str(dot3_power,
514 lldpctl_k_dot3_power_requested_b));
515 tag_end(w);
516 tag_start(w, "allocated-a", "Allocated alternative A");
517 tag_data(w,
518 lldpctl_atom_get_str(dot3_power,
519 lldpctl_k_dot3_power_allocated_a));
520 tag_end(w);
521 tag_start(w, "allocated-b", "Allocated alternative B");
522 tag_data(w,
523 lldpctl_atom_get_str(dot3_power,
524 lldpctl_k_dot3_power_allocated_b));
525 tag_end(w);
526 tag_start(w, "pse-powering-status",
527 "PSE powering status");
528 tag_data(w,
529 lldpctl_atom_get_str(dot3_power,
530 lldpctl_k_dot3_power_pse_status));
531 tag_end(w);
532 tag_start(w, "pd-powering-status",
533 "PD powering status");
534 tag_data(w,
535 lldpctl_atom_get_str(dot3_power,
536 lldpctl_k_dot3_power_pd_status));
537 tag_end(w);
538 tag_start(w, "power-pairs-ext", "Power pairs extra");
539 tag_data(w,
540 lldpctl_atom_get_str(dot3_power,
541 lldpctl_k_dot3_power_pse_pairs_ext));
542 tag_end(w);
543 tag_start(w, "power-class-ext-a", "Class extra A");
544 tag_data(w,
545 lldpctl_atom_get_str(dot3_power,
546 lldpctl_k_dot3_power_class_a));
547 tag_end(w);
548 tag_start(w, "power-class-ext-b", "Class extra B");
549 tag_data(w,
550 lldpctl_atom_get_str(dot3_power,
551 lldpctl_k_dot3_power_class_b));
552 tag_end(w);
553 tag_start(w, "power-class-ext", "Class extra");
554 tag_data(w,
555 lldpctl_atom_get_str(dot3_power,
556 lldpctl_k_dot3_power_class_ext));
557 tag_end(w);
558 tag_start(w, "power-type-ext", "Power type extra");
559 tag_data(w,
560 lldpctl_atom_get_str(dot3_power,
561 lldpctl_k_dot3_power_type_ext));
562 tag_end(w);
563 tag_start(w, "pd-load", "PD load");
564 tag_data(w,
565 lldpctl_atom_get_str(dot3_power,
566 lldpctl_k_dot3_power_pd_load));
567 tag_end(w);
568 tag_start(w, "max-power",
569 "PSE maximum available power");
570 tag_data(w,
571 lldpctl_atom_get_str(dot3_power,
572 lldpctl_k_dot3_power_pse_max));
573 tag_end(w);
574 }
575
4b292b55
VB
576 tag_end(w);
577 }
578 lldpctl_atom_dec_ref(dot3_power);
9a775667 579 }
4b292b55
VB
580
581 tag_end(w);
582}
583
a54f6012
SW
584static void
585display_local_ttl(struct writer *w, lldpctl_conn_t *conn, int details)
586{
587 char *ttl;
588 long int tx_hold;
589 long int tx_interval;
590
591 lldpctl_atom_t *configuration;
592 configuration = lldpctl_get_configuration(conn);
593 if (!configuration) {
594 log_warnx("lldpctl", "not able to get configuration. %s",
595 lldpctl_last_strerror(conn));
596 return;
597 }
598
599 tx_hold = lldpctl_atom_get_int(configuration, lldpctl_k_config_tx_hold);
8b549648
VB
600 tx_interval =
601 lldpctl_atom_get_int(configuration, lldpctl_k_config_tx_interval_ms);
a54f6012 602
54c057d1 603 tx_interval = MIN((tx_interval * tx_hold + 999) / 1000, 65535);
74f55c2e
JPT
604
605 if (asprintf(&ttl, "%lu", tx_interval) == -1) {
a54f6012
SW
606 log_warnx("lldpctl", "not enough memory to build TTL.");
607 goto end;
608 }
609
610 tag_start(w, "ttl", "TTL");
611 tag_attr(w, "ttl", "", ttl);
612 tag_end(w);
613 free(ttl);
614end:
615 lldpctl_atom_dec_ref(configuration);
a54f6012
SW
616}
617
4b292b55
VB
618static void
619display_vlans(struct writer *w, lldpctl_atom_t *port)
620{
621 lldpctl_atom_t *vlans, *vlan;
622 int foundpvid = 0;
623 int pvid, vid;
624
8b549648 625 pvid = lldpctl_atom_get_int(port, lldpctl_k_port_vlan_pvid);
4b292b55
VB
626
627 vlans = lldpctl_atom_get(port, lldpctl_k_port_vlans);
8b549648
VB
628 lldpctl_atom_foreach(vlans, vlan)
629 {
630 vid = lldpctl_atom_get_int(vlan, lldpctl_k_vlan_id);
4b292b55
VB
631
632 tag_start(w, "vlan", "VLAN");
633 tag_attr(w, "vlan-id", "",
634 lldpctl_atom_get_str(vlan, lldpctl_k_vlan_id));
011056b3 635 if (pvid == vid) {
4b292b55 636 tag_attr(w, "pvid", "pvid", "yes");
011056b3
VB
637 foundpvid = 1;
638 } else {
639 tag_attr(w, "pvid", "pvid", "no");
640 }
8b549648 641 tag_data(w, lldpctl_atom_get_str(vlan, lldpctl_k_vlan_name));
4b292b55
VB
642 tag_end(w);
643 }
644 lldpctl_atom_dec_ref(vlans);
645
646 if (!foundpvid && pvid > 0) {
647 tag_start(w, "vlan", "VLAN");
648 tag_attr(w, "vlan-id", "",
8b549648 649 lldpctl_atom_get_str(port, lldpctl_k_port_vlan_pvid));
4b292b55
VB
650 tag_attr(w, "pvid", "pvid", "yes");
651 tag_end(w);
652 }
653}
654
655static void
656display_ppvids(struct writer *w, lldpctl_atom_t *port)
657{
658 lldpctl_atom_t *ppvids, *ppvid;
659 ppvids = lldpctl_atom_get(port, lldpctl_k_port_ppvids);
8b549648
VB
660 lldpctl_atom_foreach(ppvids, ppvid)
661 {
662 int status = lldpctl_atom_get_int(ppvid, lldpctl_k_ppvid_status);
4b292b55 663 tag_start(w, "ppvid", "PPVID");
8b549648 664 if (lldpctl_atom_get_int(ppvid, lldpctl_k_ppvid_id) > 0)
4b292b55 665 tag_attr(w, "value", "",
8b549648 666 lldpctl_atom_get_str(ppvid, lldpctl_k_ppvid_id));
4b292b55 667 tag_attr(w, "supported", "supported",
8b549648 668 (status & LLDP_PPVID_CAP_SUPPORTED) ? "yes" : "no");
4b292b55 669 tag_attr(w, "enabled", "enabled",
8b549648 670 (status & LLDP_PPVID_CAP_ENABLED) ? "yes" : "no");
4b292b55
VB
671 tag_end(w);
672 }
673 lldpctl_atom_dec_ref(ppvids);
674}
675
676static void
677display_pids(struct writer *w, lldpctl_atom_t *port)
678{
679 lldpctl_atom_t *pids, *pid;
680 pids = lldpctl_atom_get(port, lldpctl_k_port_pis);
8b549648
VB
681 lldpctl_atom_foreach(pids, pid)
682 {
4b292b55 683 const char *pi = lldpctl_atom_get_str(pid, lldpctl_k_pi_id);
8b549648 684 if (pi && strlen(pi) > 0) tag_datatag(w, "pi", "PI", pi);
4b292b55
VB
685 }
686 lldpctl_atom_dec_ref(pids);
687}
688
8b549648 689static const char *
4b292b55
VB
690display_age(time_t lastchange)
691{
692 static char sage[30];
693 int age = (int)(time(NULL) - lastchange);
8b549648
VB
694 if (snprintf(sage, sizeof(sage), "%d day%s, %02d:%02d:%02d",
695 age / (60 * 60 * 24), (age / (60 * 60 * 24) > 1) ? "s" : "",
696 (age / (60 * 60)) % 24, (age / 60) % 60, age % 60) >= sizeof(sage))
4b292b55
VB
697 return "too much";
698 else
699 return sage;
700}
701
3407e638 702void
8b549648
VB
703display_local_chassis(lldpctl_conn_t *conn, struct writer *w, struct cmd_env *env,
704 int details)
3407e638
VB
705{
706 tag_start(w, "local-chassis", "Local chassis");
707
708 lldpctl_atom_t *chassis = lldpctl_get_local_chassis(conn);
709 display_chassis(w, chassis, details);
710 if (details == DISPLAY_DETAILS) {
711 display_med(w, NULL, chassis);
712 }
713 lldpctl_atom_dec_ref(chassis);
714
715 tag_end(w);
716}
717
4b292b55 718void
4e90a9e0 719display_interface(lldpctl_conn_t *conn, struct writer *w, int hidden,
a54f6012 720 lldpctl_atom_t *iface, lldpctl_atom_t *port, int details, int protocol)
4e90a9e0 721{
a54f6012
SW
722 int local = 0;
723
8b549648 724 if (!hidden && lldpctl_atom_get_int(port, lldpctl_k_port_hidden)) return;
4e90a9e0 725
494264f0
ST
726 /* user might have specified protocol to filter on display */
727 if ((protocol != LLDPD_MODE_MAX) &&
a54f6012 728 (protocol != lldpctl_atom_get_int(port, lldpctl_k_port_protocol)))
8b549648 729 return;
494264f0 730
a54f6012 731 /* Infer local / remote port from the port index (remote == 0) */
8b549648 732 local = lldpctl_atom_get_int(port, lldpctl_k_port_index) > 0 ? 1 : 0;
a54f6012
SW
733
734 lldpctl_atom_t *chassis = lldpctl_atom_get(port, lldpctl_k_port_chassis);
9439b950 735
4e90a9e0 736 tag_start(w, "interface", "Interface");
8b549648 737 tag_attr(w, "name", "", lldpctl_atom_get_str(iface, lldpctl_k_interface_name));
50b79a84 738 if (!local) {
8b549648 739 tag_attr(w, "via", "via",
50b79a84
VB
740 lldpctl_atom_get_str(port, lldpctl_k_port_protocol));
741 if (details > DISPLAY_BRIEF) {
8b549648 742 tag_attr(w, "rid", "RID",
a54f6012 743 lldpctl_atom_get_str(chassis, lldpctl_k_chassis_index));
8b549648
VB
744 tag_attr(w, "age", "Time",
745 display_age(
746 lldpctl_atom_get_int(port, lldpctl_k_port_age)));
50b79a84
VB
747 }
748 } else {
546a5280
VB
749 tag_datatag(w, "status", "Administrative status",
750 lldpctl_atom_get_str(port, lldpctl_k_port_status));
751 }
9a775667 752
9439b950 753 display_chassis(w, chassis, details);
a54f6012 754 display_port(w, port, details);
8b549648 755 if (details && local && conn) display_local_ttl(w, conn, details);
9a775667 756 if (details == DISPLAY_DETAILS) {
a54f6012
SW
757 display_vlans(w, port);
758 display_ppvids(w, port);
759 display_pids(w, port);
760 display_med(w, port, chassis);
9a775667 761 }
4e90a9e0 762
9439b950
VB
763 lldpctl_atom_dec_ref(chassis);
764
a54f6012 765 display_custom_tlvs(w, port);
26331a26 766
4e90a9e0
VB
767 tag_end(w);
768}
769
9a775667
VB
770/**
771 * Display information about interfaces.
772 *
773 * @param conn Connection to lldpd.
774 * @param w Writer.
9cac8fed 775 * @param env Environment from which we may find the list of ports.
92014c58 776 * @param hidden Whatever to show hidden ports.
9a775667
VB
777 * @param details Level of details we need (DISPLAY_*).
778 */
4e90a9e0 779void
8b549648 780display_interfaces(lldpctl_conn_t *conn, struct writer *w, struct cmd_env *env,
9a775667 781 int hidden, int details)
4b292b55 782{
4b292b55 783 lldpctl_atom_t *iface;
494264f0 784 int protocol = LLDPD_MODE_MAX;
7efa65c1 785 const char *proto_str;
494264f0
ST
786
787 /* user might have specified protocol to filter display results */
788 proto_str = cmdenv_get(env, "protocol");
789
790 if (proto_str) {
791 log_debug("display", "filter protocol: %s ", proto_str);
792
7efa65c1
VB
793 protocol = 0;
794 for (lldpctl_map_t *protocol_map =
795 lldpctl_key_get_map(lldpctl_k_port_protocol);
8b549648 796 protocol_map->string; protocol_map++) {
7efa65c1
VB
797 if (!strcasecmp(proto_str, protocol_map->string)) {
798 protocol = protocol_map->value;
799 break;
800 }
494264f0
ST
801 }
802 }
4b292b55 803
4b292b55 804 tag_start(w, "lldp", "LLDP neighbors");
9a775667
VB
805 while ((iface = cmd_iterate_on_interfaces(conn, env))) {
806 lldpctl_atom_t *port;
807 lldpctl_atom_t *neighbors;
808 lldpctl_atom_t *neighbor;
8b549648 809 port = lldpctl_get_port(iface);
4b292b55 810 neighbors = lldpctl_atom_get(port, lldpctl_k_port_neighbors);
8b549648
VB
811 lldpctl_atom_foreach(neighbors, neighbor)
812 {
813 display_interface(conn, w, hidden, iface, neighbor, details,
814 protocol);
4b292b55
VB
815 }
816 lldpctl_atom_dec_ref(neighbors);
817 lldpctl_atom_dec_ref(port);
818 }
4b292b55 819 tag_end(w);
4b292b55 820}
8729d69f 821
a54f6012
SW
822/**
823 * Display information about local interfaces.
824 *
825 * @param conn Connection to lldpd.
826 * @param w Writer.
827 * @param hidden Whatever to show hidden ports.
828 * @param env Environment from which we may find the list of ports.
829 * @param details Level of details we need (DISPLAY_*).
830 */
831void
8b549648 832display_local_interfaces(lldpctl_conn_t *conn, struct writer *w, struct cmd_env *env,
a54f6012
SW
833 int hidden, int details)
834{
835 lldpctl_atom_t *iface;
836 int protocol = LLDPD_MODE_MAX;
837
838 tag_start(w, "lldp", "LLDP interfaces");
839 while ((iface = cmd_iterate_on_interfaces(conn, env))) {
840 lldpctl_atom_t *port;
546a5280 841 port = lldpctl_get_port(iface);
a54f6012
SW
842 display_interface(conn, w, hidden, iface, port, details, protocol);
843 lldpctl_atom_dec_ref(port);
844 }
845 tag_end(w);
8b549648 846}
a54f6012 847
f540397c 848static void
5331eb2d 849display_stat(struct writer *w, const char *tag, const char *descr,
8b549648 850 long unsigned int cnt)
78356144 851{
b0cb07f7 852 char buf[20] = {};
78356144 853
5331eb2d 854 tag_start(w, tag, descr);
a769e9cb 855 snprintf(buf, sizeof(buf), "%lu", cnt);
5331eb2d 856 tag_attr(w, tag, "", buf);
857 tag_end(w);
858}
859
860void
8b549648 861display_interface_stats(lldpctl_conn_t *conn, struct writer *w, lldpctl_atom_t *port)
5331eb2d 862{
78356144 863 tag_start(w, "interface", "Interface");
8b549648 864 tag_attr(w, "name", "", lldpctl_atom_get_str(port, lldpctl_k_port_name));
78356144 865
5331eb2d 866 display_stat(w, "tx", "Transmitted",
8b549648
VB
867 lldpctl_atom_get_int(port, lldpctl_k_tx_cnt));
868 display_stat(w, "rx", "Received", lldpctl_atom_get_int(port, lldpctl_k_rx_cnt));
78356144 869
5331eb2d 870 display_stat(w, "rx_discarded_cnt", "Discarded",
8b549648 871 lldpctl_atom_get_int(port, lldpctl_k_rx_discarded_cnt));
78356144 872
5331eb2d 873 display_stat(w, "rx_unrecognized_cnt", "Unrecognized",
8b549648 874 lldpctl_atom_get_int(port, lldpctl_k_rx_unrecognized_cnt));
78356144 875
5331eb2d 876 display_stat(w, "ageout_cnt", "Ageout",
8b549648 877 lldpctl_atom_get_int(port, lldpctl_k_ageout_cnt));
78356144 878
5331eb2d 879 display_stat(w, "insert_cnt", "Inserted",
8b549648 880 lldpctl_atom_get_int(port, lldpctl_k_insert_cnt));
78356144 881
5331eb2d 882 display_stat(w, "delete_cnt", "Deleted",
8b549648 883 lldpctl_atom_get_int(port, lldpctl_k_delete_cnt));
78356144 884
885 tag_end(w);
886}
887
888/**
889 * Display interface stats
890 *
891 * @param conn Connection to lldpd.
892 * @param w Writer.
78356144 893 * @param env Environment from which we may find the list of ports.
78356144 894 */
895void
8b549648 896display_interfaces_stats(lldpctl_conn_t *conn, struct writer *w, struct cmd_env *env)
78356144 897{
898 lldpctl_atom_t *iface;
5331eb2d 899 int summary = 0;
900 u_int64_t h_tx_cnt = 0;
901 u_int64_t h_rx_cnt = 0;
902 u_int64_t h_rx_discarded_cnt = 0;
903 u_int64_t h_rx_unrecognized_cnt = 0;
904 u_int64_t h_ageout_cnt = 0;
905 u_int64_t h_insert_cnt = 0;
906 u_int64_t h_delete_cnt = 0;
5331eb2d 907
8b549648 908 if (cmdenv_get(env, "summary")) summary = 1;
78356144 909
8b549648 910 tag_start(w, "lldp", (summary ? "LLDP Global statistics" : "LLDP statistics"));
78356144 911 while ((iface = cmd_iterate_on_interfaces(conn, env))) {
912 lldpctl_atom_t *port;
8b549648 913 port = lldpctl_get_port(iface);
5331eb2d 914 if (!summary)
915 display_interface_stats(conn, w, port);
916 else {
8b549648
VB
917 h_tx_cnt += lldpctl_atom_get_int(port, lldpctl_k_tx_cnt);
918 h_rx_cnt += lldpctl_atom_get_int(port, lldpctl_k_rx_cnt);
919 h_rx_discarded_cnt +=
920 lldpctl_atom_get_int(port, lldpctl_k_rx_discarded_cnt);
921 h_rx_unrecognized_cnt +=
922 lldpctl_atom_get_int(port, lldpctl_k_rx_unrecognized_cnt);
923 h_ageout_cnt +=
924 lldpctl_atom_get_int(port, lldpctl_k_ageout_cnt);
925 h_insert_cnt +=
926 lldpctl_atom_get_int(port, lldpctl_k_insert_cnt);
927 h_delete_cnt +=
928 lldpctl_atom_get_int(port, lldpctl_k_delete_cnt);
5331eb2d 929 }
39a39abf 930 lldpctl_atom_dec_ref(port);
5331eb2d 931 }
932
933 if (summary) {
d947819d 934 tag_start(w, "summary", "Summary of stats");
5331eb2d 935 display_stat(w, "tx", "Transmitted", h_tx_cnt);
936 display_stat(w, "rx", "Received", h_rx_cnt);
8b549648 937 display_stat(w, "rx_discarded_cnt", "Discarded", h_rx_discarded_cnt);
5331eb2d 938
939 display_stat(w, "rx_unrecognized_cnt", "Unrecognized",
8b549648 940 h_rx_unrecognized_cnt);
5331eb2d 941
942 display_stat(w, "ageout_cnt", "Ageout", h_ageout_cnt);
943
944 display_stat(w, "insert_cnt", "Inserted", h_insert_cnt);
945
946 display_stat(w, "delete_cnt", "Deleted", h_delete_cnt);
947 tag_end(w);
78356144 948 }
949 tag_end(w);
950}
951
9a775667 952static const char *
8b549648
VB
953N(const char *str)
954{
8729d69f
VB
955 if (str == NULL || strlen(str) == 0) return "(none)";
956 return str;
957}
958
959void
960display_configuration(lldpctl_conn_t *conn, struct writer *w)
961{
962 lldpctl_atom_t *configuration;
963
964 configuration = lldpctl_get_configuration(conn);
965 if (!configuration) {
9a775667 966 log_warnx("lldpctl", "not able to get configuration. %s",
8729d69f
VB
967 lldpctl_last_strerror(conn));
968 return;
969 }
970
971 tag_start(w, "configuration", "Global configuration");
972 tag_start(w, "config", "Configuration");
973
974 tag_datatag(w, "tx-delay", "Transmit delay",
8843f168 975 lldpctl_atom_get_str(configuration, lldpctl_k_config_tx_interval));
74f55c2e
JPT
976 tag_datatag(w, "tx-delay-ms", "Transmit delay in milliseconds",
977 lldpctl_atom_get_str(configuration, lldpctl_k_config_tx_interval_ms));
c10302a3 978 tag_datatag(w, "tx-hold", "Transmit hold",
979 lldpctl_atom_get_str(configuration, lldpctl_k_config_tx_hold));
ba1bdf6a
VB
980 tag_datatag(w, "max-neighbors", "Maximum number of neighbors",
981 lldpctl_atom_get_str(configuration, lldpctl_k_config_max_neighbors));
8729d69f 982 tag_datatag(w, "rx-only", "Receive mode",
8b549648
VB
983 lldpctl_atom_get_int(configuration, lldpctl_k_config_receiveonly) ? "yes" :
984 "no");
8729d69f
VB
985 tag_datatag(w, "mgmt-pattern", "Pattern for management addresses",
986 N(lldpctl_atom_get_str(configuration, lldpctl_k_config_mgmt_pattern)));
987 tag_datatag(w, "iface-pattern", "Interface pattern",
988 N(lldpctl_atom_get_str(configuration, lldpctl_k_config_iface_pattern)));
0a78e14f 989 tag_datatag(w, "perm-iface-pattern", "Permanent interface pattern",
8b549648
VB
990 N(lldpctl_atom_get_str(configuration,
991 lldpctl_k_config_perm_iface_pattern)));
8729d69f
VB
992 tag_datatag(w, "cid-pattern", "Interface pattern for chassis ID",
993 N(lldpctl_atom_get_str(configuration, lldpctl_k_config_cid_pattern)));
0e5197c8 994 tag_datatag(w, "cid-string", "Override chassis ID with",
5660759b 995 N(lldpctl_atom_get_str(configuration, lldpctl_k_config_cid_string)));
8729d69f
VB
996 tag_datatag(w, "description", "Override description with",
997 N(lldpctl_atom_get_str(configuration, lldpctl_k_config_description)));
998 tag_datatag(w, "platform", "Override platform with",
999 N(lldpctl_atom_get_str(configuration, lldpctl_k_config_platform)));
ce347d29
JJ
1000 tag_datatag(w, "hostname", "Override system name with",
1001 N(lldpctl_atom_get_str(configuration, lldpctl_k_config_hostname)));
4c8e6e37 1002 tag_datatag(w, "capabilities", "Override system capabilities",
8b549648
VB
1003 lldpctl_atom_get_int(configuration, lldpctl_k_config_chassis_cap_override) ?
1004 "yes" :
1005 "no");
8729d69f 1006 tag_datatag(w, "advertise-version", "Advertise version",
8b549648
VB
1007 lldpctl_atom_get_int(configuration, lldpctl_k_config_advertise_version) ?
1008 "yes" :
1009 "no");
bb37268d 1010 tag_datatag(w, "ifdescr-update", "Update interface descriptions",
8b549648
VB
1011 lldpctl_atom_get_int(configuration, lldpctl_k_config_ifdescr_update) ?
1012 "yes" :
1013 "no");
f84199dd 1014 tag_datatag(w, "iface-promisc", "Promiscuous mode on managed interfaces",
8b549648
VB
1015 lldpctl_atom_get_int(configuration, lldpctl_k_config_iface_promisc) ?
1016 "yes" :
1017 "no");
8729d69f 1018 tag_datatag(w, "lldpmed-no-inventory", "Disable LLDP-MED inventory",
8b549648
VB
1019 (lldpctl_atom_get_int(configuration,
1020 lldpctl_k_config_lldpmed_noinventory) == 0) ?
1021 "no" :
1022 "yes");
486a6133 1023 tag_datatag(w, "lldpmed-faststart", "LLDP-MED fast start mechanism",
8b549648
VB
1024 (lldpctl_atom_get_int(configuration, lldpctl_k_config_fast_start_enabled) ==
1025 0) ?
1026 "no" :
1027 "yes");
486a6133 1028 tag_datatag(w, "lldpmed-faststart-interval", "LLDP-MED fast start interval",
8b549648
VB
1029 N(lldpctl_atom_get_str(configuration,
1030 lldpctl_k_config_fast_start_interval)));
dfbd7185 1031 tag_datatag(w, "bond-slave-src-mac-type",
8b549648
VB
1032 "Source MAC for LLDP frames on bond slaves",
1033 lldpctl_atom_get_str(configuration,
1034 lldpctl_k_config_bond_slave_src_mac_type));
1035 tag_datatag(w, "lldp-portid-type", "Port ID TLV subtype for LLDP frames",
1036 lldpctl_atom_get_str(configuration, lldpctl_k_config_lldp_portid_type));
1037 tag_datatag(w, "lldp-agent-type", "Agent type",
1038 lldpctl_atom_get_str(configuration, lldpctl_k_config_lldp_agent_type));
8729d69f
VB
1039
1040 tag_end(w);
1041 tag_end(w);
1042
1043 lldpctl_atom_dec_ref(configuration);
1044}