'networkctl-dump-util.c',
'networkctl-journal.c',
'networkctl-link-info.c',
+ 'networkctl-link-info-json.c',
'networkctl-list.c',
'networkctl-lldp.c',
'networkctl-misc.c',
#include "sd-netlink.h"
#include "alloc-util.h"
+#include "dhcp-protocol.h"
#include "ether-addr-util.h"
#include "format-ifname.h"
#include "format-table.h"
int dump_addresses(
sd_netlink *rtnl,
+ sd_dhcp_message *message,
sd_dhcp_lease *lease,
Table *table,
int ifindex) {
_cleanup_free_ struct local_address *local_addrs = NULL;
_cleanup_strv_free_ char **buf = NULL;
- struct in_addr dhcp4_address = {};
+ struct in_addr dhcp4_address = {}, server_address = {};
int r, n;
assert(rtnl);
if (n <= 0)
return n;
- if (lease)
+ if (message) {
+ dhcp4_address.s_addr = message->header.yiaddr;
+ if (dhcp_message_get_option_address(message, SD_DHCP_OPTION_SERVER_IDENTIFIER, &server_address) < 0)
+ /* The message should be BOOTP, let's fallback to the siaddr field. */
+ server_address.s_addr = message->header.siaddr;
+ } else if (lease) {
(void) sd_dhcp_lease_get_address(lease, &dhcp4_address);
+ (void) sd_dhcp_lease_get_server_identifier(lease, &server_address);
+ }
FOREACH_ARRAY(local, local_addrs, n) {
- struct in_addr server_address;
- bool dhcp4 = false;
-
- if (local->family == AF_INET && in4_addr_equal(&local->address.in, &dhcp4_address))
- dhcp4 = sd_dhcp_lease_get_server_identifier(lease, &server_address) >= 0;
+ bool dhcp4 = local->family == AF_INET && in4_addr_equal(&local->address.in, &dhcp4_address);
r = strv_extendf(&buf, "%s%s%s%s%s%s",
IN_ADDR_TO_STRING(local->family, &local->address),
#include "shared-forward.h"
+#include "dhcp-message.h"
+
int dump_list(Table *table, const char *key, char * const *l);
int ieee_oui(sd_hwdb *hwdb, const struct ether_addr *mac, char **ret);
int dump_gateways(sd_netlink *rtnl, sd_hwdb *hwdb, Table *table, int ifindex);
-int dump_addresses(sd_netlink *rtnl, sd_dhcp_lease *lease, Table *table, int ifindex);
+int dump_addresses(sd_netlink *rtnl, sd_dhcp_message *message, sd_dhcp_lease *lease, Table *table, int ifindex);
--- /dev/null
+/* SPDX-License-Identifier: LGPL-2.1-or-later */
+
+#include "sd-dhcp-client-id.h"
+#include "sd-json.h"
+
+#include "iovec-util.h"
+#include "json-util.h"
+#include "networkctl-link-info.h"
+#include "networkctl-link-info-json.h"
+#include "networkctl-util.h"
+
+static int acquire_link_bitrates(LinkInfo *link) {
+ int r;
+
+ assert(link);
+
+ sd_json_variant *v;
+ r = json_variant_find_object(link->description, STRV_MAKE("Interface", "BitRates"), &v);
+ if (r == -ENODATA)
+ return 0;
+ if (r < 0)
+ return r;
+
+ static const sd_json_dispatch_field dispatch_table[] = {
+ { "TxBitRate", _SD_JSON_VARIANT_TYPE_INVALID, sd_json_dispatch_uint64, offsetof(LinkInfo, tx_bitrate), SD_JSON_MANDATORY },
+ { "RxBitRate", _SD_JSON_VARIANT_TYPE_INVALID, sd_json_dispatch_uint64, offsetof(LinkInfo, rx_bitrate), SD_JSON_MANDATORY },
+ {}
+ };
+
+ r = sd_json_dispatch(v, dispatch_table,
+ SD_JSON_LOG | SD_JSON_WARNING | SD_JSON_ALLOW_EXTENSIONS,
+ link);
+ if (r < 0)
+ return r;
+
+ link->has_bitrates = true;
+ return 0;
+}
+
+static int acquire_link_dhcp_client(LinkInfo *link) {
+ int r;
+
+ assert(link);
+
+ sd_json_variant *v;
+ r = json_variant_find_object(link->description, STRV_MAKE("Interface", "DHCPv4Client", "ClientIdentifier"), &v);
+ if (r == -ENODATA)
+ return 0;
+ if (r < 0)
+ return r;
+
+ _cleanup_(iovec_done) struct iovec iov = {};
+ r = json_dispatch_byte_array_iovec("ClientIdentifier", v, /* flags= */ 0, &iov);
+ if (r < 0)
+ return r;
+
+ return sd_dhcp_client_id_set_raw(&link->dhcp_client_id, iov.iov_base, iov.iov_len);
+}
+
+static int acquire_link_dhcp_message(LinkInfo *link) {
+ int r;
+
+ assert(link);
+
+ sd_json_variant *v;
+ r = json_variant_find_object(link->description, STRV_MAKE("Interface", "DHCPv4Client", "Lease", "Message"), &v);
+ if (r == -ENODATA)
+ return 0;
+ if (r < 0)
+ return r;
+
+ return dhcp_message_parse_json(v, &link->dhcp_message);
+}
+
+int link_info_parse_description(LinkInfo *link, sd_varlink *vl) {
+ int r;
+
+ assert(link);
+
+ if (!vl)
+ return 0;
+
+ r = acquire_link_description(vl, link->ifindex, &link->description);
+ if (r < 0)
+ return r;
+
+ (void) acquire_link_bitrates(link);
+ (void) acquire_link_dhcp_client(link);
+ (void) acquire_link_dhcp_message(link);
+
+ return 0;
+}
--- /dev/null
+/* SPDX-License-Identifier: LGPL-2.1-or-later */
+#pragma once
+
+#include "shared-forward.h"
+
+typedef struct LinkInfo LinkInfo;
+
+int link_info_parse_description(LinkInfo *link, sd_varlink *vl);
#include "glob-util.h"
#include "netlink-util.h"
#include "networkctl-link-info.h"
-#include "networkctl-util.h"
+#include "networkctl-link-info-json.h"
#include "sort-util.h"
#include "stdio-util.h"
#include "string-util.h"
for (unsigned i = 0; array && array[i].needs_freeing; i++) {
sd_device_unref(array[i].sd_device);
sd_json_variant_unref(array[i].description);
+ sd_dhcp_message_unref(array[i].dhcp_message);
free(array[i].netdev_kind);
free(array[i].ssid);
free(array[i].qdisc);
return 1;
}
-static int acquire_link_bitrates(LinkInfo *link) {
- int r;
-
- assert(link);
-
- sd_json_variant *v;
- r = json_variant_find_object(link->description, STRV_MAKE("Interface", "BitRates"), &v);
- if (r == -ENODATA)
- return 0;
- if (r < 0)
- return r;
-
- static const sd_json_dispatch_field dispatch_table[] = {
- { "TxBitRate", _SD_JSON_VARIANT_TYPE_INVALID, sd_json_dispatch_uint64, offsetof(LinkInfo, tx_bitrate), SD_JSON_MANDATORY },
- { "RxBitRate", _SD_JSON_VARIANT_TYPE_INVALID, sd_json_dispatch_uint64, offsetof(LinkInfo, rx_bitrate), SD_JSON_MANDATORY },
- {}
- };
-
- r = sd_json_dispatch(v, dispatch_table,
- SD_JSON_LOG | SD_JSON_WARNING | SD_JSON_ALLOW_EXTENSIONS,
- link);
- if (r < 0)
- return r;
-
- link->has_bitrates = true;
- return 0;
-}
-
static void acquire_ether_link_info(int *fd, LinkInfo *link) {
assert(fd);
assert(link);
acquire_ether_link_info(&fd, &links[c]);
acquire_wlan_link_info(&links[c]);
- if (vl)
- (void) acquire_link_description(vl, links[c].ifindex, &links[c].description);
- (void) acquire_link_bitrates(&links[c]);
+ (void) link_info_parse_description(&links[c], vl);
c++;
}
#include <linux/if_link.h>
#include <linux/nl80211.h>
+#include "dhcp-client-id-internal.h"
+#include "dhcp-message.h"
#include "ether-addr-util.h"
#include "ethtool-util.h"
#include "shared-forward.h"
uint64_t tx_bitrate;
uint64_t rx_bitrate;
+ /* DHCPv4 */
+ sd_dhcp_message *dhcp_message;
+ sd_dhcp_client_id dhcp_client_id;
+
/* bridge info */
uint32_t forward_delay;
uint32_t hello_time;
#include "sd-device.h"
#include "sd-dhcp-client-id.h"
#include "sd-dhcp-lease.h"
+#include "sd-dhcp-protocol.h"
#include "sd-hwdb.h"
#include "sd-netlink.h"
#include "sd-network.h"
return r;
}
- r = dump_addresses(rtnl, lease, table, info->ifindex);
+ r = dump_addresses(rtnl, info->dhcp_message, lease, table, info->ifindex);
if (r < 0)
return r;
return table_log_add_error(r);
}
- if (lease) {
- const sd_dhcp_client_id *client_id;
+ if (info->dhcp_message) {
+ _cleanup_free_ char *tz = NULL;
+
+ if (dhcp_message_get_option_string(info->dhcp_message, SD_DHCP_OPTION_TZDB_TIMEZONE, &tz) >= 0
+ && timezone_is_valid(tz, LOG_DEBUG)) {
+ r = table_add_many(table,
+ TABLE_FIELD, "Time Zone",
+ TABLE_STRING, tz);
+ if (r < 0)
+ return table_log_add_error(r);
+ }
+ } else if (lease) {
const char *tz;
r = sd_dhcp_lease_get_timezone(lease, &tz);
if (r < 0)
return table_log_add_error(r);
}
+ }
+
+ if (sd_dhcp_client_id_is_set(&info->dhcp_client_id)) {
+ _cleanup_free_ char *id = NULL;
- r = sd_dhcp_lease_get_client_id(lease, &client_id);
+ r = sd_dhcp_client_id_to_string(&info->dhcp_client_id, &id);
if (r >= 0) {
- _cleanup_free_ char *id = NULL;
-
- r = sd_dhcp_client_id_to_string(client_id, &id);
- if (r >= 0) {
- r = table_add_many(table,
- TABLE_FIELD, "DHCPv4 Client ID",
- TABLE_STRING, id);
- if (r < 0)
- return table_log_add_error(r);
- }
+ r = table_add_many(table,
+ TABLE_FIELD, "DHCPv4 Client ID",
+ TABLE_STRING, id);
+ if (r < 0)
+ return table_log_add_error(r);
}
}
if (r < 0)
return table_log_add_error(r);
- r = dump_addresses(rtnl, NULL, table, 0);
+ r = dump_addresses(rtnl, /* message= */ NULL, /* lease= */ NULL, table, /* ifindex= */ 0);
if (r < 0)
return r;