+static int link_status_one(
+ sd_rtnl *rtnl,
+ sd_hwdb *hwdb,
+ const char *name) {
+ _cleanup_strv_free_ char **dns = NULL, **ntp = NULL, **domains = NULL;
+ _cleanup_free_ char *setup_state = NULL, *operational_state = NULL;
+ _cleanup_rtnl_message_unref_ sd_rtnl_message *req = NULL, *reply = NULL;
+ _cleanup_device_unref_ sd_device *d = NULL;
+ char devid[2 + DECIMAL_STR_MAX(int)];
+ _cleanup_free_ char *t = NULL, *network = NULL;
+ const char *driver = NULL, *path = NULL, *vendor = NULL, *model = NULL, *link = NULL;
+ const char *on_color_operational, *off_color_operational,
+ *on_color_setup, *off_color_setup;
+ _cleanup_strv_free_ char **carrier_bound_to = NULL;
+ _cleanup_strv_free_ char **carrier_bound_by = NULL;
+ struct ether_addr e;
+ unsigned iftype;
+ int r, ifindex;
+ bool have_mac;
+ uint32_t mtu;
+
+ assert(rtnl);
+ assert(name);
+
+ if (safe_atoi(name, &ifindex) >= 0 && ifindex > 0)
+ r = sd_rtnl_message_new_link(rtnl, &req, RTM_GETLINK, ifindex);
+ else {
+ r = sd_rtnl_message_new_link(rtnl, &req, RTM_GETLINK, 0);
+ if (r < 0)
+ return rtnl_log_create_error(r);
+
+ r = sd_rtnl_message_append_string(req, IFLA_IFNAME, name);
+ }
+
+ if (r < 0)
+ return rtnl_log_create_error(r);
+
+ r = sd_rtnl_call(rtnl, req, 0, &reply);
+ if (r < 0)
+ return log_error_errno(r, "Failed to query link: %m");
+
+ r = sd_rtnl_message_link_get_ifindex(reply, &ifindex);
+ if (r < 0)
+ return rtnl_log_parse_error(r);
+
+ r = sd_rtnl_message_read_string(reply, IFLA_IFNAME, &name);
+ if (r < 0)
+ return rtnl_log_parse_error(r);
+
+ r = sd_rtnl_message_link_get_type(reply, &iftype);
+ if (r < 0)
+ return rtnl_log_parse_error(r);
+
+ have_mac = sd_rtnl_message_read_ether_addr(reply, IFLA_ADDRESS, &e) >= 0;
+
+ if (have_mac) {
+ const uint8_t *p;
+ bool all_zeroes = true;
+
+ for (p = (uint8_t*) &e; p < (uint8_t*) &e + sizeof(e); p++)
+ if (*p != 0) {
+ all_zeroes = false;
+ break;
+ }
+
+ if (all_zeroes)
+ have_mac = false;
+ }
+
+ sd_rtnl_message_read_u32(reply, IFLA_MTU, &mtu);
+
+ sd_network_link_get_operational_state(ifindex, &operational_state);
+ operational_state_to_color(operational_state, &on_color_operational, &off_color_operational);
+
+ sd_network_link_get_setup_state(ifindex, &setup_state);
+ setup_state_to_color(setup_state, &on_color_setup, &off_color_setup);
+
+ sd_network_link_get_dns(ifindex, &dns);
+ sd_network_link_get_ntp(ifindex, &ntp);
+ sd_network_link_get_domains(ifindex, &domains);
+ r = sd_network_link_get_wildcard_domain(ifindex);
+ if (r > 0) {
+ char *wildcard;
+
+ wildcard = strdup("*");
+ if (!wildcard)
+ return log_oom();
+
+ if (strv_consume(&domains, wildcard) < 0)
+ return log_oom();
+ }
+
+ sprintf(devid, "n%i", ifindex);
+
+ (void)sd_device_new_from_device_id(&d, devid);
+
+ if (d) {
+ (void)sd_device_get_property_value(d, "ID_NET_LINK_FILE", &link);
+ (void)sd_device_get_property_value(d, "ID_NET_DRIVER", &driver);
+ (void)sd_device_get_property_value(d, "ID_PATH", &path);
+
+ r = sd_device_get_property_value(d, "ID_VENDOR_FROM_DATABASE", &vendor);
+ if (r < 0)
+ (void)sd_device_get_property_value(d, "ID_VENDOR", &vendor);
+
+ r = sd_device_get_property_value(d, "ID_MODEL_FROM_DATABASE", &model);
+ if (r < 0)
+ (void)sd_device_get_property_value(d, "ID_MODEL", &model);
+ }
+
+ link_get_type_string(iftype, d, &t);
+
+ sd_network_link_get_network_file(ifindex, &network);
+
+ sd_network_link_get_carrier_bound_to(ifindex, &carrier_bound_to);
+ sd_network_link_get_carrier_bound_by(ifindex, &carrier_bound_by);
+
+ printf("%s%s%s %i: %s\n", on_color_operational, draw_special_char(DRAW_BLACK_CIRCLE), off_color_operational, ifindex, name);
+
+ printf(" Link File: %s\n"
+ " Network File: %s\n"
+ " Type: %s\n"
+ " State: %s%s%s (%s%s%s)\n",
+ strna(link),
+ strna(network),
+ strna(t),
+ on_color_operational, strna(operational_state), off_color_operational,
+ on_color_setup, strna(setup_state), off_color_setup);
+
+ if (path)
+ printf(" Path: %s\n", path);
+ if (driver)
+ printf(" Driver: %s\n", driver);
+ if (vendor)
+ printf(" Vendor: %s\n", vendor);
+ if (model)
+ printf(" Model: %s\n", model);
+
+ if (have_mac) {
+ _cleanup_free_ char *description = NULL;
+ char ea[ETHER_ADDR_TO_STRING_MAX];
+
+ ieee_oui(hwdb, &e, &description);
+
+ if (description)
+ printf(" HW Address: %s (%s)\n", ether_addr_to_string(&e, ea), description);
+ else
+ printf(" HW Address: %s\n", ether_addr_to_string(&e, ea));
+ }
+
+ if (mtu > 0)
+ printf(" MTU: %u\n", mtu);
+
+ dump_addresses(rtnl, " Address: ", ifindex);
+ dump_gateways(rtnl, hwdb, " Gateway: ", ifindex);
+
+ if (!strv_isempty(dns))
+ dump_list(" DNS: ", dns);
+ if (!strv_isempty(domains))
+ dump_list(" Domain: ", domains);
+ if (!strv_isempty(ntp))
+ dump_list(" NTP: ", ntp);
+
+ if (!strv_isempty(carrier_bound_to))
+ dump_list("Carrier Bound To: ", carrier_bound_to);
+
+ if (!strv_isempty(carrier_bound_by))
+ dump_list("Carrier Bound By: ", carrier_bound_by);
+
+ return 0;
+}
+
+static int link_status(int argc, char *argv[], void *userdata) {
+ _cleanup_hwdb_unref_ sd_hwdb *hwdb = NULL;