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