networkctl.c revision 6d0c65ffb4f82e8c6dceb453919b3db54343fc27
522d4a495af3a615526fccdf038d2d68f41a73c8Lennart Poettering/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
522d4a495af3a615526fccdf038d2d68f41a73c8Lennart Poettering This file is part of systemd.
522d4a495af3a615526fccdf038d2d68f41a73c8Lennart Poettering Copyright 2014 Lennart Poettering
522d4a495af3a615526fccdf038d2d68f41a73c8Lennart Poettering systemd is free software; you can redistribute it and/or modify it
522d4a495af3a615526fccdf038d2d68f41a73c8Lennart Poettering under the terms of the GNU Lesser General Public License as published by
522d4a495af3a615526fccdf038d2d68f41a73c8Lennart Poettering the Free Software Foundation; either version 2.1 of the License, or
5430f7f2bc7330f3088b894166bf3524a067e3d8Lennart Poettering (at your option) any later version.
522d4a495af3a615526fccdf038d2d68f41a73c8Lennart Poettering systemd is distributed in the hope that it will be useful, but
522d4a495af3a615526fccdf038d2d68f41a73c8Lennart Poettering WITHOUT ANY WARRANTY; without even the implied warranty of
522d4a495af3a615526fccdf038d2d68f41a73c8Lennart Poettering MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
522d4a495af3a615526fccdf038d2d68f41a73c8Lennart Poettering Lesser General Public License for more details.
5430f7f2bc7330f3088b894166bf3524a067e3d8Lennart Poettering You should have received a copy of the GNU Lesser General Public License
522d4a495af3a615526fccdf038d2d68f41a73c8Lennart Poettering along with systemd; If not, see <http://www.gnu.org/licenses/>.
798d3a524ea57aaf40cb53858aaa45ec702f012dZbigniew Jędrzejewski-Szmekstatic bool arg_no_pager = false;
798d3a524ea57aaf40cb53858aaa45ec702f012dZbigniew Jędrzejewski-Szmekstatic bool arg_legend = true;
798d3a524ea57aaf40cb53858aaa45ec702f012dZbigniew Jędrzejewski-Szmekstatic bool arg_all = false;
798d3a524ea57aaf40cb53858aaa45ec702f012dZbigniew Jędrzejewski-Szmekstatic void pager_open_if_enabled(void) {
798d3a524ea57aaf40cb53858aaa45ec702f012dZbigniew Jędrzejewski-Szmekstatic int link_get_type_string(int iftype, struct udev_device *d, char **ret) {
798d3a524ea57aaf40cb53858aaa45ec702f012dZbigniew Jędrzejewski-Szmek if (iftype == ARPHRD_ETHER && d) {
798d3a524ea57aaf40cb53858aaa45ec702f012dZbigniew Jędrzejewski-Szmek const char *devtype, *id = NULL;
798d3a524ea57aaf40cb53858aaa45ec702f012dZbigniew Jędrzejewski-Szmek /* WLANs have iftype ARPHRD_ETHER, but we want
798d3a524ea57aaf40cb53858aaa45ec702f012dZbigniew Jędrzejewski-Szmek * to show a more useful type string for
798d3a524ea57aaf40cb53858aaa45ec702f012dZbigniew Jędrzejewski-Szmek devtype = udev_device_get_devtype(d);
798d3a524ea57aaf40cb53858aaa45ec702f012dZbigniew Jędrzejewski-Szmek else if (streq_ptr(devtype, "wwan"))
798d3a524ea57aaf40cb53858aaa45ec702f012dZbigniew Jędrzejewski-Szmekstatic int link_info_compare(const void *a, const void *b) {
798d3a524ea57aaf40cb53858aaa45ec702f012dZbigniew Jędrzejewski-Szmek const LinkInfo *x = a, *y = b;
798d3a524ea57aaf40cb53858aaa45ec702f012dZbigniew Jędrzejewski-Szmekstatic int decode_and_sort_links(sd_rtnl_message *m, LinkInfo **ret) {
798d3a524ea57aaf40cb53858aaa45ec702f012dZbigniew Jędrzejewski-Szmek _cleanup_free_ LinkInfo *links = NULL;
798d3a524ea57aaf40cb53858aaa45ec702f012dZbigniew Jędrzejewski-Szmek for (i = m; i; i = sd_rtnl_message_next(i)) {
798d3a524ea57aaf40cb53858aaa45ec702f012dZbigniew Jędrzejewski-Szmek r = sd_rtnl_message_get_type(i, &type);
798d3a524ea57aaf40cb53858aaa45ec702f012dZbigniew Jędrzejewski-Szmek r = sd_rtnl_message_link_get_ifindex(i, &ifindex);
798d3a524ea57aaf40cb53858aaa45ec702f012dZbigniew Jędrzejewski-Szmek r = sd_rtnl_message_read_string(i, IFLA_IFNAME, &name);
798d3a524ea57aaf40cb53858aaa45ec702f012dZbigniew Jędrzejewski-Szmek r = sd_rtnl_message_link_get_type(i, &iftype);
798d3a524ea57aaf40cb53858aaa45ec702f012dZbigniew Jędrzejewski-Szmek if (!GREEDY_REALLOC(links, size, c+1))
798d3a524ea57aaf40cb53858aaa45ec702f012dZbigniew Jędrzejewski-Szmek qsort(links, c, sizeof(LinkInfo), link_info_compare);
798d3a524ea57aaf40cb53858aaa45ec702f012dZbigniew Jędrzejewski-Szmekstatic int list_links(char **args, unsigned n) {
798d3a524ea57aaf40cb53858aaa45ec702f012dZbigniew Jędrzejewski-Szmek _cleanup_rtnl_message_unref_ sd_rtnl_message *req = NULL, *reply = NULL;
798d3a524ea57aaf40cb53858aaa45ec702f012dZbigniew Jędrzejewski-Szmek _cleanup_udev_unref_ struct udev *udev = NULL;
798d3a524ea57aaf40cb53858aaa45ec702f012dZbigniew Jędrzejewski-Szmek _cleanup_rtnl_unref_ sd_rtnl *rtnl = NULL;
798d3a524ea57aaf40cb53858aaa45ec702f012dZbigniew Jędrzejewski-Szmek _cleanup_free_ LinkInfo *links = NULL;
798d3a524ea57aaf40cb53858aaa45ec702f012dZbigniew Jędrzejewski-Szmek log_error("Failed to connect to netlink: %s", strerror(-r));
798d3a524ea57aaf40cb53858aaa45ec702f012dZbigniew Jędrzejewski-Szmek log_error("Failed to connect to udev: %m");
798d3a524ea57aaf40cb53858aaa45ec702f012dZbigniew Jędrzejewski-Szmek r = sd_rtnl_message_new_link(rtnl, &req, RTM_GETLINK, 0);
798d3a524ea57aaf40cb53858aaa45ec702f012dZbigniew Jędrzejewski-Szmek return rtnl_log_create_error(r);
798d3a524ea57aaf40cb53858aaa45ec702f012dZbigniew Jędrzejewski-Szmek r = sd_rtnl_message_request_dump(req, true);
798d3a524ea57aaf40cb53858aaa45ec702f012dZbigniew Jędrzejewski-Szmek return rtnl_log_create_error(r);
798d3a524ea57aaf40cb53858aaa45ec702f012dZbigniew Jędrzejewski-Szmek r = sd_rtnl_call(rtnl, req, 0, &reply);
798d3a524ea57aaf40cb53858aaa45ec702f012dZbigniew Jędrzejewski-Szmek log_error("Failed to enumerate links: %s", strerror(-r));
798d3a524ea57aaf40cb53858aaa45ec702f012dZbigniew Jędrzejewski-Szmek printf("%3s %-16s %-10s %-10s %-10s\n", "IDX", "LINK", "TYPE", "ADMIN", "OPERATIONAL");
798d3a524ea57aaf40cb53858aaa45ec702f012dZbigniew Jędrzejewski-Szmek c = decode_and_sort_links(reply, &links);
798d3a524ea57aaf40cb53858aaa45ec702f012dZbigniew Jędrzejewski-Szmek for (i = 0; i < c; i++) {
798d3a524ea57aaf40cb53858aaa45ec702f012dZbigniew Jędrzejewski-Szmek _cleanup_free_ char *state = NULL, *operational_state = NULL;
798d3a524ea57aaf40cb53858aaa45ec702f012dZbigniew Jędrzejewski-Szmek _cleanup_udev_device_unref_ struct udev_device *d = NULL;
798d3a524ea57aaf40cb53858aaa45ec702f012dZbigniew Jędrzejewski-Szmek const char *on_color = "", *off_color = "";
798d3a524ea57aaf40cb53858aaa45ec702f012dZbigniew Jędrzejewski-Szmek char devid[2 + DECIMAL_STR_MAX(int)];
522d4a495af3a615526fccdf038d2d68f41a73c8Lennart Poettering sd_network_get_link_state(links[i].ifindex, &state);
printf("%3i %-16s %-10s %-10s %s%-10s%s\n", links[i].ifindex, links[i].name, strna(t), strna(state), on_color, strna(operational_state), off_color);
if (arg_legend)
pretty);
STRV_FOREACH(i, l) {
struct ether_addr e;
unsigned iftype;
int r, ifindex;
bool have_mac;
return rtnl_log_create_error(r);
return rtnl_log_create_error(r);
return rtnl_log_parse_error(r);
return rtnl_log_parse_error(r);
return rtnl_log_parse_error(r);
if (have_mac) {
const uint8_t *p;
bool all_zeroes = true;
all_zeroes = false;
if (all_zeroes)
have_mac = false;
if (!vendor)
if (!model)
printf("%s%s%s %i: %s\n", on_color, draw_special_char(DRAW_BLACK_CIRCLE), off_color, ifindex, name);
strna(t),
if (path)
if (driver)
if (vendor)
if (model)
if (have_mac)
if (mtu > 0)
char **name;
if (operational_state)
if (!udev) {
return -errno;
if (arg_all) {
return rtnl_log_create_error(r);
return rtnl_log_create_error(r);
return rtnl_log_parse_error(c);
static void help(void) {
help();
case ARG_VERSION:
case ARG_NO_PAGER:
arg_no_pager = true;
case ARG_NO_LEGEND:
arg_legend = false;
arg_all = true;
return -EINVAL;
const char* verb;
MORE,
LESS,
} argc_cmp;
const int argc;
} verbs[] = {
int left;
if (left <= 0)
help();
return -EINVAL;
case EQUAL:
return -EINVAL;
case MORE:
return -EINVAL;
case LESS:
return -EINVAL;
log_open();
goto finish;
pager_close();