networkctl.c revision 49699bac94d24b444274f91f85c82e6fad04d029
ee8c45689526ca973407cbb77bce7b96a062c40bLennart Poettering/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
ee8c45689526ca973407cbb77bce7b96a062c40bLennart Poettering This file is part of systemd.
ee8c45689526ca973407cbb77bce7b96a062c40bLennart Poettering Copyright 2014 Lennart Poettering
ee8c45689526ca973407cbb77bce7b96a062c40bLennart Poettering systemd is free software; you can redistribute it and/or modify it
ee8c45689526ca973407cbb77bce7b96a062c40bLennart Poettering under the terms of the GNU Lesser General Public License as published by
ee8c45689526ca973407cbb77bce7b96a062c40bLennart Poettering the Free Software Foundation; either version 2.1 of the License, or
ee8c45689526ca973407cbb77bce7b96a062c40bLennart Poettering (at your option) any later version.
ee8c45689526ca973407cbb77bce7b96a062c40bLennart Poettering systemd is distributed in the hope that it will be useful, but
ee8c45689526ca973407cbb77bce7b96a062c40bLennart Poettering WITHOUT ANY WARRANTY; without even the implied warranty of
ee8c45689526ca973407cbb77bce7b96a062c40bLennart Poettering MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
ee8c45689526ca973407cbb77bce7b96a062c40bLennart Poettering Lesser General Public License for more details.
ee8c45689526ca973407cbb77bce7b96a062c40bLennart Poettering You should have received a copy of the GNU Lesser General Public License
ee8c45689526ca973407cbb77bce7b96a062c40bLennart Poettering along with systemd; If not, see <http://www.gnu.org/licenses/>.
ee8c45689526ca973407cbb77bce7b96a062c40bLennart Poetteringstatic bool arg_no_pager = false;
ee8c45689526ca973407cbb77bce7b96a062c40bLennart Poetteringstatic bool arg_legend = true;
9085f64a6694f2928c79fcce365edb1dca6937d4Lennart Poetteringstatic bool arg_all = false;
ee8c45689526ca973407cbb77bce7b96a062c40bLennart Poetteringstatic void pager_open_if_enabled(void) {
ee8c45689526ca973407cbb77bce7b96a062c40bLennart Poetteringstatic int link_get_type_string(int iftype, struct udev_device *d, char **ret) {
ee8c45689526ca973407cbb77bce7b96a062c40bLennart Poettering const char *t;
ee8c45689526ca973407cbb77bce7b96a062c40bLennart Poettering /* WLANs have iftype ARPHRD_ETHER, but we want
ee8c45689526ca973407cbb77bce7b96a062c40bLennart Poettering * to show a more useful type string for
6d0c65ffb4f82e8c6dceb453919b3db54343fc27Lennart Poetteringtypedef struct LinkInfo {
6d0c65ffb4f82e8c6dceb453919b3db54343fc27Lennart Poetteringstatic int link_info_compare(const void *a, const void *b) {
6d0c65ffb4f82e8c6dceb453919b3db54343fc27Lennart Poettering const LinkInfo *x = a, *y = b;
6d0c65ffb4f82e8c6dceb453919b3db54343fc27Lennart Poetteringstatic int decode_and_sort_links(sd_rtnl_message *m, LinkInfo **ret) {
6d0c65ffb4f82e8c6dceb453919b3db54343fc27Lennart Poettering for (i = m; i; i = sd_rtnl_message_next(i)) {
6d0c65ffb4f82e8c6dceb453919b3db54343fc27Lennart Poettering r = sd_rtnl_message_link_get_ifindex(i, &ifindex);
6d0c65ffb4f82e8c6dceb453919b3db54343fc27Lennart Poettering r = sd_rtnl_message_read_string(i, IFLA_IFNAME, &name);
6d0c65ffb4f82e8c6dceb453919b3db54343fc27Lennart Poettering r = sd_rtnl_message_link_get_type(i, &iftype);
a6a4f528899b1dab47408733b4a423c66ea40f7aThomas Hindoe Paaboel Andersen qsort_safe(links, c, sizeof(LinkInfo), link_info_compare);
6d0c65ffb4f82e8c6dceb453919b3db54343fc27Lennart Poettering return (int) c;
d57c365bf8f09fbcc649e00f7060ff30809f67c2Lennart Poetteringstatic void operational_state_to_color(const char *state, const char **on, const char **off) {
d57c365bf8f09fbcc649e00f7060ff30809f67c2Lennart Poettering } else if (streq_ptr(state, "degraded")) {
d57c365bf8f09fbcc649e00f7060ff30809f67c2Lennart Poetteringstatic void setup_state_to_color(const char *state, const char **on, const char **off) {
d57c365bf8f09fbcc649e00f7060ff30809f67c2Lennart Poettering } else if (streq_ptr(state, "configuring")) {
d57c365bf8f09fbcc649e00f7060ff30809f67c2Lennart Poettering } else if (streq_ptr(state, "failed") || streq_ptr(state, "linger")) {
266b538958932e6fc27dfce4917336e70e17e29eTom Gundersenstatic int list_links(int argc, char *argv[], void *userdata) {
ee8c45689526ca973407cbb77bce7b96a062c40bLennart Poettering _cleanup_rtnl_message_unref_ sd_rtnl_message *req = NULL, *reply = NULL;
ee8c45689526ca973407cbb77bce7b96a062c40bLennart Poettering _cleanup_udev_unref_ struct udev *udev = NULL;
ee8c45689526ca973407cbb77bce7b96a062c40bLennart Poettering _cleanup_rtnl_unref_ sd_rtnl *rtnl = NULL;
f647962d64e844689f3e2acfce6102fc47e76df2Michal Schmidt return log_error_errno(r, "Failed to connect to netlink: %m");
4a62c710b62a5a3c7a8a278b810b9d5b5a0c8f4fMichal Schmidt return log_error_errno(errno, "Failed to connect to udev: %m");
ee8c45689526ca973407cbb77bce7b96a062c40bLennart Poettering r = sd_rtnl_message_new_link(rtnl, &req, RTM_GETLINK, 0);
ee8c45689526ca973407cbb77bce7b96a062c40bLennart Poettering r = sd_rtnl_message_request_dump(req, true);
f647962d64e844689f3e2acfce6102fc47e76df2Michal Schmidt return log_error_errno(r, "Failed to enumerate links: %m");
3e3db0ee860025ad663b13b0ace4e6d627611332Lennart Poettering printf("%3s %-16s %-18s %-11s %-10s\n", "IDX", "LINK", "TYPE", "OPERATIONAL", "SETUP");
6d0c65ffb4f82e8c6dceb453919b3db54343fc27Lennart Poettering c = decode_and_sort_links(reply, &links);
6d0c65ffb4f82e8c6dceb453919b3db54343fc27Lennart Poettering for (i = 0; i < c; i++) {
ab1525bc2d92780b4dc64bc5b9cdb52594e2df7dLennart Poettering _cleanup_free_ char *setup_state = NULL, *operational_state = NULL;
ee8c45689526ca973407cbb77bce7b96a062c40bLennart Poettering _cleanup_udev_device_unref_ struct udev_device *d = NULL;
d57c365bf8f09fbcc649e00f7060ff30809f67c2Lennart Poettering const char *on_color_operational, *off_color_operational,
d6731e4c7964ee2860d4f5abdb0b52acd7a66960Tom Gundersen sd_network_link_get_operational_state(links[i].ifindex, &operational_state);
d57c365bf8f09fbcc649e00f7060ff30809f67c2Lennart Poettering operational_state_to_color(operational_state, &on_color_operational, &off_color_operational);
d57c365bf8f09fbcc649e00f7060ff30809f67c2Lennart Poettering sd_network_link_get_setup_state(links[i].ifindex, &setup_state);
d57c365bf8f09fbcc649e00f7060ff30809f67c2Lennart Poettering setup_state_to_color(setup_state, &on_color_setup, &off_color_setup);
ee8c45689526ca973407cbb77bce7b96a062c40bLennart Poettering d = udev_device_new_from_device_id(udev, devid);
6d0c65ffb4f82e8c6dceb453919b3db54343fc27Lennart Poettering link_get_type_string(links[i].iftype, d, &t);
3e3db0ee860025ad663b13b0ace4e6d627611332Lennart Poettering printf("%3i %-16s %-18s %s%-11s%s %s%-10s%s\n",
d57c365bf8f09fbcc649e00f7060ff30809f67c2Lennart Poettering links[i].ifindex, links[i].name, strna(t),
d57c365bf8f09fbcc649e00f7060ff30809f67c2Lennart Poettering on_color_operational, strna(operational_state), off_color_operational,
d57c365bf8f09fbcc649e00f7060ff30809f67c2Lennart Poettering on_color_setup, strna(setup_state), off_color_setup);
c09da72900b03fcddade06643f24c6357f3e0482Tom Gundersen/* IEEE Organizationally Unique Identifier vendor string */
81fd1dd3a2cf4cc90a6898d562c9bb0fb238cbd7Tom Gundersenstatic int ieee_oui(sd_hwdb *hwdb, struct ether_addr *mac, char **ret) {
81fd1dd3a2cf4cc90a6898d562c9bb0fb238cbd7Tom Gundersen char modalias[strlen("OUI:XXYYXXYYXXYY") + 1], *desc;
c09da72900b03fcddade06643f24c6357f3e0482Tom Gundersen /* skip commonly misused 00:00:00 (Xerox) prefix */
81fd1dd3a2cf4cc90a6898d562c9bb0fb238cbd7Tom Gundersen snprintf(modalias, sizeof(modalias), "OUI:" ETHER_ADDR_FORMAT_STR, ETHER_ADDR_FORMAT_VAL(*mac));
81fd1dd3a2cf4cc90a6898d562c9bb0fb238cbd7Tom Gundersen r = sd_hwdb_get(hwdb, modalias, "ID_OUI_FROM_DATABASE", &description);
c09da72900b03fcddade06643f24c6357f3e0482Tom Gundersen _cleanup_rtnl_message_unref_ sd_rtnl_message *req = NULL, *reply = NULL;
c09da72900b03fcddade06643f24c6357f3e0482Tom Gundersen assert(family == AF_INET || family == AF_INET6);
c09da72900b03fcddade06643f24c6357f3e0482Tom Gundersen r = sd_rtnl_message_new_neigh(rtnl, &req, RTM_GETNEIGH, ifindex, family);
c09da72900b03fcddade06643f24c6357f3e0482Tom Gundersen for (m = reply; m; m = sd_rtnl_message_next(m)) {
c09da72900b03fcddade06643f24c6357f3e0482Tom Gundersen r = sd_rtnl_message_neigh_get_family(m, &fam);
c09da72900b03fcddade06643f24c6357f3e0482Tom Gundersen log_error_errno(r, "could not get family: %m");
c09da72900b03fcddade06643f24c6357f3e0482Tom Gundersen r = sd_rtnl_message_neigh_get_ifindex(m, &ifi);
144232a8e0ea77eed8c5a456832758681b5b3511Torstein Husebø log_error_errno(r, "could not get ifindex: %m");
c09da72900b03fcddade06643f24c6357f3e0482Tom Gundersen r = sd_rtnl_message_read_in_addr(m, NDA_DST, &gw.in);
c09da72900b03fcddade06643f24c6357f3e0482Tom Gundersen r = sd_rtnl_message_read_in6_addr(m, NDA_DST, &gw.in6);
c09da72900b03fcddade06643f24c6357f3e0482Tom Gundersen r = sd_rtnl_message_read_ether_addr(m, NDA_LLADDR, &mac);
c09da72900b03fcddade06643f24c6357f3e0482Tom Gundersen r = ieee_oui(hwdb, &mac, gateway_description);
b6a3ca6d876ab59b4f29ed67f54ef87005177906Tom Gundersen _cleanup_free_ struct local_address *local = NULL;
b6a3ca6d876ab59b4f29ed67f54ef87005177906Tom Gundersen n = local_gateways(rtnl, ifindex, AF_UNSPEC, &local);
b6a3ca6d876ab59b4f29ed67f54ef87005177906Tom Gundersen for (i = 0; i < n; i++) {
b6a3ca6d876ab59b4f29ed67f54ef87005177906Tom Gundersen _cleanup_free_ char *gateway = NULL, *description = NULL;
b6a3ca6d876ab59b4f29ed67f54ef87005177906Tom Gundersen r = in_addr_to_string(local[i].family, &local[i].address, &gateway);
69fb1176c403e437c4fba763ba242b540c73898fLennart Poettering r = get_gateway_description(rtnl, hwdb, local[i].ifindex, local[i].family, &local[i].address, &description);
b6a3ca6d876ab59b4f29ed67f54ef87005177906Tom Gundersen log_debug_errno(r, "Could not get description of gateway: %m");
1693a943ca581aca2beebb4c812ec6c9f17b8164Lennart Poettering /* Show interface name for the entry if we show
1693a943ca581aca2beebb4c812ec6c9f17b8164Lennart Poettering * entries for all interfaces */
1693a943ca581aca2beebb4c812ec6c9f17b8164Lennart Poettering if (if_indextoname(local[i].ifindex, name)) {
ee8c45689526ca973407cbb77bce7b96a062c40bLennart Poettering _cleanup_free_ struct local_address *local = NULL;
1d050e1e0a7082e23ee9b31fa0b819cb332b3444Lennart Poettering n = local_addresses(rtnl, ifindex, AF_UNSPEC, &local);
ee8c45689526ca973407cbb77bce7b96a062c40bLennart Poettering for (i = 0; i < n; i++) {
ee8c45689526ca973407cbb77bce7b96a062c40bLennart Poettering r = in_addr_to_string(local[i].family, &local[i].address, &pretty);
1693a943ca581aca2beebb4c812ec6c9f17b8164Lennart Poettering if (if_indextoname(local[i].ifindex, name)) {
ee8c45689526ca973407cbb77bce7b96a062c40bLennart Poetteringstatic void dump_list(const char *prefix, char **l) {
69fb1176c403e437c4fba763ba242b540c73898fLennart Poettering const char *name) {
2301cb9fdb774d0a1b3d8f5e95c5d358721ccacbLennart Poettering _cleanup_strv_free_ char **dns = NULL, **ntp = NULL, **domains = NULL;
6c03d27d9f7e831194dbd8bd6bcdeef9273edb6eThomas Hindoe Paaboel Andersen _cleanup_free_ char *setup_state = NULL, *operational_state = NULL;
9085f64a6694f2928c79fcce365edb1dca6937d4Lennart Poettering _cleanup_rtnl_message_unref_ sd_rtnl_message *req = NULL, *reply = NULL;
9085f64a6694f2928c79fcce365edb1dca6937d4Lennart Poettering _cleanup_udev_device_unref_ struct udev_device *d = NULL;
373d9f173f910d547159917401c4b1f84af85736Tom Gundersen _cleanup_free_ char *t = NULL, *network = NULL;
af5effc4220dab6c4c87a130bae7be441f6967caTom Gundersen const char *driver = NULL, *path = NULL, *vendor = NULL, *model = NULL, *link = NULL;
d57c365bf8f09fbcc649e00f7060ff30809f67c2Lennart Poettering const char *on_color_operational, *off_color_operational,
9085f64a6694f2928c79fcce365edb1dca6937d4Lennart Poettering if (safe_atoi(name, &ifindex) >= 0 && ifindex > 0)
9085f64a6694f2928c79fcce365edb1dca6937d4Lennart Poettering r = sd_rtnl_message_new_link(rtnl, &req, RTM_GETLINK, ifindex);
9085f64a6694f2928c79fcce365edb1dca6937d4Lennart Poettering r = sd_rtnl_message_new_link(rtnl, &req, RTM_GETLINK, 0);
9085f64a6694f2928c79fcce365edb1dca6937d4Lennart Poettering r = sd_rtnl_message_append_string(req, IFLA_IFNAME, name);
f647962d64e844689f3e2acfce6102fc47e76df2Michal Schmidt return log_error_errno(r, "Failed to query link: %m");
9085f64a6694f2928c79fcce365edb1dca6937d4Lennart Poettering r = sd_rtnl_message_link_get_ifindex(reply, &ifindex);
9085f64a6694f2928c79fcce365edb1dca6937d4Lennart Poettering r = sd_rtnl_message_read_string(reply, IFLA_IFNAME, &name);
9085f64a6694f2928c79fcce365edb1dca6937d4Lennart Poettering r = sd_rtnl_message_link_get_type(reply, &iftype);
9085f64a6694f2928c79fcce365edb1dca6937d4Lennart Poettering have_mac = sd_rtnl_message_read_ether_addr(reply, IFLA_ADDRESS, &e) >= 0;
9085f64a6694f2928c79fcce365edb1dca6937d4Lennart Poettering for (p = (uint8_t*) &e; p < (uint8_t*) &e + sizeof(e); p++)
9085f64a6694f2928c79fcce365edb1dca6937d4Lennart Poettering if (*p != 0) {
9085f64a6694f2928c79fcce365edb1dca6937d4Lennart Poettering sd_rtnl_message_read_u32(reply, IFLA_MTU, &mtu);
d6731e4c7964ee2860d4f5abdb0b52acd7a66960Tom Gundersen sd_network_link_get_operational_state(ifindex, &operational_state);
d57c365bf8f09fbcc649e00f7060ff30809f67c2Lennart Poettering operational_state_to_color(operational_state, &on_color_operational, &off_color_operational);
d57c365bf8f09fbcc649e00f7060ff30809f67c2Lennart Poettering sd_network_link_get_setup_state(ifindex, &setup_state);
d57c365bf8f09fbcc649e00f7060ff30809f67c2Lennart Poettering setup_state_to_color(setup_state, &on_color_setup, &off_color_setup);
2301cb9fdb774d0a1b3d8f5e95c5d358721ccacbLennart Poettering sd_network_link_get_domains(ifindex, &domains);
67272d157a35e5cda4e5c904eafdcc23d20541d1Tom Gundersen r = sd_network_link_get_wildcard_domain(ifindex);
1405434b6986d3c3d6ccaaa2e472bad843cbbfa1Lennart Poettering if (strv_consume(&domains, wildcard) < 0)
9085f64a6694f2928c79fcce365edb1dca6937d4Lennart Poettering d = udev_device_new_from_device_id(udev, devid);
af5effc4220dab6c4c87a130bae7be441f6967caTom Gundersen link = udev_device_get_property_value(d, "ID_NET_LINK_FILE");
9085f64a6694f2928c79fcce365edb1dca6937d4Lennart Poettering driver = udev_device_get_property_value(d, "ID_NET_DRIVER");
9085f64a6694f2928c79fcce365edb1dca6937d4Lennart Poettering path = udev_device_get_property_value(d, "ID_PATH");
9085f64a6694f2928c79fcce365edb1dca6937d4Lennart Poettering vendor = udev_device_get_property_value(d, "ID_VENDOR_FROM_DATABASE");
9085f64a6694f2928c79fcce365edb1dca6937d4Lennart Poettering vendor = udev_device_get_property_value(d, "ID_VENDOR");
9085f64a6694f2928c79fcce365edb1dca6937d4Lennart Poettering model = udev_device_get_property_value(d, "ID_MODEL_FROM_DATABASE");
9085f64a6694f2928c79fcce365edb1dca6937d4Lennart Poettering model = udev_device_get_property_value(d, "ID_MODEL");
373d9f173f910d547159917401c4b1f84af85736Tom Gundersen sd_network_link_get_network_file(ifindex, &network);
d57c365bf8f09fbcc649e00f7060ff30809f67c2Lennart Poettering printf("%s%s%s %i: %s\n", on_color_operational, draw_special_char(DRAW_BLACK_CIRCLE), off_color_operational, ifindex, name);
af5effc4220dab6c4c87a130bae7be441f6967caTom Gundersen "Network File: %s\n"
373d9f173f910d547159917401c4b1f84af85736Tom Gundersen " Type: %s\n"
d57c365bf8f09fbcc649e00f7060ff30809f67c2Lennart Poettering " State: %s%s%s (%s%s%s)\n",
d57c365bf8f09fbcc649e00f7060ff30809f67c2Lennart Poettering on_color_operational, strna(operational_state), off_color_operational,
d57c365bf8f09fbcc649e00f7060ff30809f67c2Lennart Poettering on_color_setup, strna(setup_state), off_color_setup);
888943fc6246b2917168fff59380b58b678ba157Lennart Poettering printf(" HW Address: %s (%s)\n", ether_addr_to_string(&e, ea), description);
888943fc6246b2917168fff59380b58b678ba157Lennart Poettering printf(" HW Address: %s\n", ether_addr_to_string(&e, ea));
9085f64a6694f2928c79fcce365edb1dca6937d4Lennart Poettering dump_addresses(rtnl, " Address: ", ifindex);
888943fc6246b2917168fff59380b58b678ba157Lennart Poettering dump_gateways(rtnl, hwdb, " Gateway: ", ifindex);
266b538958932e6fc27dfce4917336e70e17e29eTom Gundersenstatic int link_status(int argc, char *argv[], void *userdata) {
ee8c45689526ca973407cbb77bce7b96a062c40bLennart Poettering _cleanup_udev_unref_ struct udev *udev = NULL;
ee8c45689526ca973407cbb77bce7b96a062c40bLennart Poettering _cleanup_rtnl_unref_ sd_rtnl *rtnl = NULL;
f647962d64e844689f3e2acfce6102fc47e76df2Michal Schmidt return log_error_errno(r, "Failed to connect to netlink: %m");
4a62c710b62a5a3c7a8a278b810b9d5b5a0c8f4fMichal Schmidt return log_error_errno(errno, "Failed to connect to udev: %m");
81fd1dd3a2cf4cc90a6898d562c9bb0fb238cbd7Tom Gundersen log_debug_errno(r, "Failed to open hardware database: %m");
ee8c45689526ca973407cbb77bce7b96a062c40bLennart Poettering _cleanup_free_ char *operational_state = NULL;
c627729fc49d59ffcecc09555a34d9dd139927ceLennart Poettering _cleanup_strv_free_ char **dns = NULL, **ntp = NULL, **domains = NULL;
e92da1e5d0a3b38804e173af136ec7a076c7757eLennart Poettering const char *on_color_operational, *off_color_operational;
03cc0fd1431b82e59c11ae12a274c1f2df23169dLennart Poettering sd_network_get_operational_state(&operational_state);
e92da1e5d0a3b38804e173af136ec7a076c7757eLennart Poettering operational_state_to_color(operational_state, &on_color_operational, &off_color_operational);
b1acce80cd60fe95f16df2f1ad23ff2ad82d08e5Lennart Poettering on_color_operational, draw_special_char(DRAW_BLACK_CIRCLE), off_color_operational,
b1acce80cd60fe95f16df2f1ad23ff2ad82d08e5Lennart Poettering on_color_operational, strna(operational_state), off_color_operational);
69fb1176c403e437c4fba763ba242b540c73898fLennart Poettering dump_gateways(rtnl, hwdb, " Gateway: ", 0);
ee8c45689526ca973407cbb77bce7b96a062c40bLennart Poettering _cleanup_rtnl_message_unref_ sd_rtnl_message *req = NULL, *reply = NULL;
9085f64a6694f2928c79fcce365edb1dca6937d4Lennart Poettering r = sd_rtnl_message_new_link(rtnl, &req, RTM_GETLINK, 0);
9085f64a6694f2928c79fcce365edb1dca6937d4Lennart Poettering r = sd_rtnl_message_request_dump(req, true);
f647962d64e844689f3e2acfce6102fc47e76df2Michal Schmidt return log_error_errno(r, "Failed to enumerate links: %m");
6d0c65ffb4f82e8c6dceb453919b3db54343fc27Lennart Poettering c = decode_and_sort_links(reply, &links);
6d0c65ffb4f82e8c6dceb453919b3db54343fc27Lennart Poettering for (i = 0; i < c; i++) {
69fb1176c403e437c4fba763ba242b540c73898fLennart Poettering link_status_one(rtnl, udev, hwdb, links[i].name);
69fb1176c403e437c4fba763ba242b540c73898fLennart Poettering link_status_one(rtnl, udev, hwdb, *name);
49699bac94d24b444274f91f85c82e6fad04d029Susant Sahaniconst char *lldp_system_capability_to_string(LLDPSystemCapabilities d) _const_;
49699bac94d24b444274f91f85c82e6fad04d029Susant SahaniLLDPSystemCapabilities lldp_system_capability_from_string(const char *d) _pure_;
49699bac94d24b444274f91f85c82e6fad04d029Susant Sahanistatic const char* const lldp_system_capability_table[_LLDP_SYSTEM_CAPABILITIES_MAX + 1] = {
49699bac94d24b444274f91f85c82e6fad04d029Susant SahaniDEFINE_STRING_TABLE_LOOKUP(lldp_system_capability, LLDPSystemCapabilities);
49699bac94d24b444274f91f85c82e6fad04d029Susant Sahani s = strjoin(t, lldp_system_capability_to_string(LLDP_SYSTEM_CAPABILITIES_OTHER), " ", NULL);
49699bac94d24b444274f91f85c82e6fad04d029Susant Sahani if (cap & LLDP_SYSTEM_CAPABILITIES_REPEATER) {
49699bac94d24b444274f91f85c82e6fad04d029Susant Sahani s = strjoin(t, lldp_system_capability_to_string(LLDP_SYSTEM_CAPABILITIES_REPEATER), " ", NULL);
49699bac94d24b444274f91f85c82e6fad04d029Susant Sahani s = strjoin(t, lldp_system_capability_to_string(LLDP_SYSTEM_CAPABILITIES_BRIDGE), " ", NULL);
49699bac94d24b444274f91f85c82e6fad04d029Susant Sahani s = strjoin(t, lldp_system_capability_to_string(LLDP_SYSTEM_CAPABILITIES_WLAN_AP), " ", NULL);
49699bac94d24b444274f91f85c82e6fad04d029Susant Sahani s = strjoin(t, lldp_system_capability_to_string(LLDP_SYSTEM_CAPABILITIES_ROUTER), " ", NULL);
49699bac94d24b444274f91f85c82e6fad04d029Susant Sahani s = strjoin(t, lldp_system_capability_to_string(LLDP_SYSTEM_CAPABILITIES_PHONE), " ", NULL);
49699bac94d24b444274f91f85c82e6fad04d029Susant Sahani s = strjoin(t, lldp_system_capability_to_string(LLDP_SYSTEM_CAPABILITIES_DOCSIS), " ", NULL);
49699bac94d24b444274f91f85c82e6fad04d029Susant Sahani s = strjoin(t, lldp_system_capability_to_string(LLDP_SYSTEM_CAPABILITIES_STATION), " ", NULL);
49699bac94d24b444274f91f85c82e6fad04d029Susant Sahani s = strjoin(t, lldp_system_capability_to_string(LLDP_SYSTEM_CAPABILITIES_CVLAN), " ", NULL);
49699bac94d24b444274f91f85c82e6fad04d029Susant Sahani s = strjoin(t, lldp_system_capability_to_string(LLDP_SYSTEM_CAPABILITIES_SVLAN), " ", NULL);
49699bac94d24b444274f91f85c82e6fad04d029Susant Sahani s = strappend(t, lldp_system_capability_to_string(LLDP_SYSTEM_CAPABILITIES_TPMR));
49699bac94d24b444274f91f85c82e6fad04d029Susant Sahani s = strappend(t, lldp_system_capability_to_string(_LLDP_SYSTEM_CAPABILITIES_MAX));
49699bac94d24b444274f91f85c82e6fad04d029Susant Sahanistatic int link_lldp_status(int argc, char *argv[], void *userdata) {
49699bac94d24b444274f91f85c82e6fad04d029Susant Sahani _cleanup_rtnl_message_unref_ sd_rtnl_message *req = NULL, *reply = NULL;
49699bac94d24b444274f91f85c82e6fad04d029Susant Sahani int i, r, c, j;
49699bac94d24b444274f91f85c82e6fad04d029Susant Sahani return log_error_errno(r, "Failed to connect to netlink: %m");
49699bac94d24b444274f91f85c82e6fad04d029Susant Sahani r = sd_rtnl_message_new_link(rtnl, &req, RTM_GETLINK, 0);
49699bac94d24b444274f91f85c82e6fad04d029Susant Sahani return log_error_errno(r, "Failed to enumerate links: %m");
49699bac94d24b444274f91f85c82e6fad04d029Susant Sahani printf("Capability Codes: (O) - Other, (P) - Repeater, (B) - Bridge , (W) - WLAN Access Point, (R) = Router, (T) - Telephone,\n"
49699bac94d24b444274f91f85c82e6fad04d029Susant Sahani "(D) - Data Over Cable Service Interface Specifications, (A) - Station, (C) - Customer VLAN, (S) - Service VLAN,\n"
49699bac94d24b444274f91f85c82e6fad04d029Susant Sahani "(M) - Two-port MAC Relay (TPMR)\n\n");
49699bac94d24b444274f91f85c82e6fad04d029Susant Sahani printf("%s %16s %24s %16s %16s\n", "Local Intf", "Device ID", "Port ID", "TTL", "Capability");
49699bac94d24b444274f91f85c82e6fad04d029Susant Sahani for (i = j = 0; i < c; i++) {
49699bac94d24b444274f91f85c82e6fad04d029Susant Sahani _cleanup_free_ char *chassis = NULL, *port = NULL, *cap = NULL, *lldp = NULL;
49699bac94d24b444274f91f85c82e6fad04d029Susant Sahani r = sd_network_link_get_lldp(links[i].ifindex, &lldp);
49699bac94d24b444274f91f85c82e6fad04d029Susant Sahani _cleanup_free_ char *t = NULL, *a = NULL, *b = NULL;
49699bac94d24b444274f91f85c82e6fad04d029Susant Sahani printf("%10s %24s %16s %16lu %16s\n", links[i].name, chassis, port, ttl, cap);
ee8c45689526ca973407cbb77bce7b96a062c40bLennart Poetteringstatic void help(void) {
ee8c45689526ca973407cbb77bce7b96a062c40bLennart Poettering "Query and control the networking subsystem.\n\n"
ee8c45689526ca973407cbb77bce7b96a062c40bLennart Poettering " -h --help Show this help\n"
9085f64a6694f2928c79fcce365edb1dca6937d4Lennart Poettering " --version Show package version\n"
9085f64a6694f2928c79fcce365edb1dca6937d4Lennart Poettering " --no-pager Do not pipe output into a pager\n"
9085f64a6694f2928c79fcce365edb1dca6937d4Lennart Poettering " --no-legend Do not show the headers and footers\n"
9085f64a6694f2928c79fcce365edb1dca6937d4Lennart Poettering " -a --all Show status for all links\n\n"
ee8c45689526ca973407cbb77bce7b96a062c40bLennart Poettering " list List links\n"
ee8c45689526ca973407cbb77bce7b96a062c40bLennart Poettering " status LINK Show link status\n"
49699bac94d24b444274f91f85c82e6fad04d029Susant Sahani " lldp Show lldp information\n"
ee8c45689526ca973407cbb77bce7b96a062c40bLennart Poetteringstatic int parse_argv(int argc, char *argv[]) {
ee8c45689526ca973407cbb77bce7b96a062c40bLennart Poettering { "version", no_argument, NULL, ARG_VERSION },
ee8c45689526ca973407cbb77bce7b96a062c40bLennart Poettering { "no-pager", no_argument, NULL, ARG_NO_PAGER },
ee8c45689526ca973407cbb77bce7b96a062c40bLennart Poettering { "no-legend", no_argument, NULL, ARG_NO_LEGEND },
9085f64a6694f2928c79fcce365edb1dca6937d4Lennart Poettering while ((c = getopt_long(argc, argv, "ha", options, NULL)) >= 0) {
ee8c45689526ca973407cbb77bce7b96a062c40bLennart Poetteringstatic int networkctl_main(int argc, char *argv[]) {
266b538958932e6fc27dfce4917336e70e17e29eTom Gundersen { "list", VERB_ANY, 1, VERB_DEFAULT, list_links },
49699bac94d24b444274f91f85c82e6fad04d029Susant Sahani { "lldp", VERB_ANY, 1, VERB_DEFAULT, link_lldp_status },
266b538958932e6fc27dfce4917336e70e17e29eTom Gundersen return dispatch_verb(argc, argv, verbs, NULL);