networkctl.c revision ddb7f7fc07a31937989afad53edb87b50e2cad72
ee8c45689526ca973407cbb77bce7b96a062c40bLennart Poettering/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
ee8c45689526ca973407cbb77bce7b96a062c40bLennart Poettering
ee8c45689526ca973407cbb77bce7b96a062c40bLennart Poettering/***
ee8c45689526ca973407cbb77bce7b96a062c40bLennart Poettering This file is part of systemd.
ee8c45689526ca973407cbb77bce7b96a062c40bLennart Poettering
ee8c45689526ca973407cbb77bce7b96a062c40bLennart Poettering Copyright 2014 Lennart Poettering
ee8c45689526ca973407cbb77bce7b96a062c40bLennart 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
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
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 Poettering***/
ee8c45689526ca973407cbb77bce7b96a062c40bLennart Poettering
ee8c45689526ca973407cbb77bce7b96a062c40bLennart Poettering#include <stdbool.h>
1693a943ca581aca2beebb4c812ec6c9f17b8164Lennart Poettering#include <getopt.h>
3f6fd1ba65f962702753c4ad284b588e59689a23Lennart Poettering
ee8c45689526ca973407cbb77bce7b96a062c40bLennart Poettering#include "sd-network.h"
914d6c09f1a449c60c8495c179a8bbe012315ba2Tom Gundersen#include "sd-rtnl.h"
3f6fd1ba65f962702753c4ad284b588e59689a23Lennart Poettering#include "libudev.h"
3f6fd1ba65f962702753c4ad284b588e59689a23Lennart Poettering
3f6fd1ba65f962702753c4ad284b588e59689a23Lennart Poettering#include "build.h"
ee8c45689526ca973407cbb77bce7b96a062c40bLennart Poettering#include "util.h"
b5efdb8af40ea759a1ea584c1bc44ecc81dd00ceLennart Poettering#include "pager.h"
3f6fd1ba65f962702753c4ad284b588e59689a23Lennart Poettering#include "rtnl-util.h"
914d6c09f1a449c60c8495c179a8bbe012315ba2Tom Gundersen#include "udev-util.h"
3f6fd1ba65f962702753c4ad284b588e59689a23Lennart Poettering#include "arphrd-list.h"
81fd1dd3a2cf4cc90a6898d562c9bb0fb238cbd7Tom Gundersen#include "local-addresses.h"
3f6fd1ba65f962702753c4ad284b588e59689a23Lennart Poettering#include "socket-util.h"
ee8c45689526ca973407cbb77bce7b96a062c40bLennart Poettering
8752c5752f3b9023f9ce96a55d70c6e5fc31118fLennart Poetteringstatic bool arg_no_pager = false;
8752c5752f3b9023f9ce96a55d70c6e5fc31118fLennart Poetteringstatic bool arg_legend = true;
3f6fd1ba65f962702753c4ad284b588e59689a23Lennart Poetteringstatic bool arg_all = false;
3f6fd1ba65f962702753c4ad284b588e59689a23Lennart Poettering
6bedfcbb2970e06a4d3280c8fb62083d252ede73Lennart Poetteringstatic void pager_open_if_enabled(void) {
db73295accbec0c6513817f0a64a92018592bb26Lennart Poettering
8b43440b7ef4b81c69c31de7ff820dc07a780254Lennart Poettering if (arg_no_pager)
8752c5752f3b9023f9ce96a55d70c6e5fc31118fLennart Poettering return;
3f6fd1ba65f962702753c4ad284b588e59689a23Lennart Poettering
288a74cce597f81d3ba01d8a5ca7d2ba5b654b7eRonny Chevalier pager_open(false);
3f6fd1ba65f962702753c4ad284b588e59689a23Lennart Poettering}
3f6fd1ba65f962702753c4ad284b588e59689a23Lennart Poettering
ee8c45689526ca973407cbb77bce7b96a062c40bLennart Poetteringstatic int link_get_type_string(int iftype, struct udev_device *d, char **ret) {
ee8c45689526ca973407cbb77bce7b96a062c40bLennart Poettering const char *t;
ee8c45689526ca973407cbb77bce7b96a062c40bLennart Poettering char *p;
9085f64a6694f2928c79fcce365edb1dca6937d4Lennart Poettering
ee8c45689526ca973407cbb77bce7b96a062c40bLennart Poettering if (iftype == ARPHRD_ETHER && d) {
ee8c45689526ca973407cbb77bce7b96a062c40bLennart Poettering const char *devtype, *id = NULL;
ee8c45689526ca973407cbb77bce7b96a062c40bLennart Poettering /* WLANs have iftype ARPHRD_ETHER, but we want
ee8c45689526ca973407cbb77bce7b96a062c40bLennart Poettering * to show a more useful type string for
ee8c45689526ca973407cbb77bce7b96a062c40bLennart Poettering * them */
ee8c45689526ca973407cbb77bce7b96a062c40bLennart Poettering
ee8c45689526ca973407cbb77bce7b96a062c40bLennart Poettering devtype = udev_device_get_devtype(d);
ee8c45689526ca973407cbb77bce7b96a062c40bLennart Poettering if (streq_ptr(devtype, "wlan"))
ee8c45689526ca973407cbb77bce7b96a062c40bLennart Poettering id = "wlan";
914d6c09f1a449c60c8495c179a8bbe012315ba2Tom Gundersen else if (streq_ptr(devtype, "wwan"))
ee8c45689526ca973407cbb77bce7b96a062c40bLennart Poettering id = "wwan";
ee8c45689526ca973407cbb77bce7b96a062c40bLennart Poettering
ee8c45689526ca973407cbb77bce7b96a062c40bLennart Poettering if (id) {
914d6c09f1a449c60c8495c179a8bbe012315ba2Tom Gundersen p = strdup(id);
914d6c09f1a449c60c8495c179a8bbe012315ba2Tom Gundersen if (!p)
ee8c45689526ca973407cbb77bce7b96a062c40bLennart Poettering return -ENOMEM;
732b7f39a2b3b1a2af90102c6262186ae71197acRonny Chevalier
ee8c45689526ca973407cbb77bce7b96a062c40bLennart Poettering *ret = p;
ee8c45689526ca973407cbb77bce7b96a062c40bLennart Poettering return 1;
ee8c45689526ca973407cbb77bce7b96a062c40bLennart Poettering }
ee8c45689526ca973407cbb77bce7b96a062c40bLennart Poettering }
914d6c09f1a449c60c8495c179a8bbe012315ba2Tom Gundersen
914d6c09f1a449c60c8495c179a8bbe012315ba2Tom Gundersen t = arphrd_to_name(iftype);
ee8c45689526ca973407cbb77bce7b96a062c40bLennart Poettering if (!t) {
ee8c45689526ca973407cbb77bce7b96a062c40bLennart Poettering *ret = NULL;
ee8c45689526ca973407cbb77bce7b96a062c40bLennart Poettering return 0;
ee8c45689526ca973407cbb77bce7b96a062c40bLennart Poettering }
ee8c45689526ca973407cbb77bce7b96a062c40bLennart Poettering
ee8c45689526ca973407cbb77bce7b96a062c40bLennart Poettering p = strdup(t);
ee8c45689526ca973407cbb77bce7b96a062c40bLennart Poettering if (!p)
ee8c45689526ca973407cbb77bce7b96a062c40bLennart Poettering return -ENOMEM;
ee8c45689526ca973407cbb77bce7b96a062c40bLennart Poettering
ee8c45689526ca973407cbb77bce7b96a062c40bLennart Poettering ascii_strlower(p);
ee8c45689526ca973407cbb77bce7b96a062c40bLennart Poettering *ret = p;
ee8c45689526ca973407cbb77bce7b96a062c40bLennart Poettering
ee8c45689526ca973407cbb77bce7b96a062c40bLennart Poettering return 0;
ee8c45689526ca973407cbb77bce7b96a062c40bLennart Poettering}
ee8c45689526ca973407cbb77bce7b96a062c40bLennart Poettering
ee8c45689526ca973407cbb77bce7b96a062c40bLennart Poetteringtypedef struct LinkInfo {
ee8c45689526ca973407cbb77bce7b96a062c40bLennart Poettering const char *name;
ee8c45689526ca973407cbb77bce7b96a062c40bLennart Poettering int ifindex;
ee8c45689526ca973407cbb77bce7b96a062c40bLennart Poettering unsigned iftype;
ee8c45689526ca973407cbb77bce7b96a062c40bLennart Poettering} LinkInfo;
ee8c45689526ca973407cbb77bce7b96a062c40bLennart Poettering
ee8c45689526ca973407cbb77bce7b96a062c40bLennart Poetteringstatic int link_info_compare(const void *a, const void *b) {
ee8c45689526ca973407cbb77bce7b96a062c40bLennart Poettering const LinkInfo *x = a, *y = b;
ee8c45689526ca973407cbb77bce7b96a062c40bLennart Poettering
ee8c45689526ca973407cbb77bce7b96a062c40bLennart Poettering return x->ifindex - y->ifindex;
ee8c45689526ca973407cbb77bce7b96a062c40bLennart Poettering}
ee8c45689526ca973407cbb77bce7b96a062c40bLennart Poettering
ee8c45689526ca973407cbb77bce7b96a062c40bLennart Poetteringstatic int decode_and_sort_links(sd_rtnl_message *m, LinkInfo **ret) {
ee8c45689526ca973407cbb77bce7b96a062c40bLennart Poettering _cleanup_free_ LinkInfo *links = NULL;
ee8c45689526ca973407cbb77bce7b96a062c40bLennart Poettering size_t size = 0, c = 0;
ee8c45689526ca973407cbb77bce7b96a062c40bLennart Poettering sd_rtnl_message *i;
6d0c65ffb4f82e8c6dceb453919b3db54343fc27Lennart Poettering int r;
6d0c65ffb4f82e8c6dceb453919b3db54343fc27Lennart Poettering
6d0c65ffb4f82e8c6dceb453919b3db54343fc27Lennart Poettering for (i = m; i; i = sd_rtnl_message_next(i)) {
6d0c65ffb4f82e8c6dceb453919b3db54343fc27Lennart Poettering const char *name;
6d0c65ffb4f82e8c6dceb453919b3db54343fc27Lennart Poettering unsigned iftype;
6d0c65ffb4f82e8c6dceb453919b3db54343fc27Lennart Poettering uint16_t type;
6d0c65ffb4f82e8c6dceb453919b3db54343fc27Lennart Poettering int ifindex;
6d0c65ffb4f82e8c6dceb453919b3db54343fc27Lennart Poettering
6d0c65ffb4f82e8c6dceb453919b3db54343fc27Lennart Poettering r = sd_rtnl_message_get_type(i, &type);
6d0c65ffb4f82e8c6dceb453919b3db54343fc27Lennart Poettering if (r < 0)
6d0c65ffb4f82e8c6dceb453919b3db54343fc27Lennart Poettering return r;
6d0c65ffb4f82e8c6dceb453919b3db54343fc27Lennart Poettering
1c4baffc1895809bae9ac36b670af90a4cb9cd7dTom Gundersen if (type != RTM_NEWLINK)
6d0c65ffb4f82e8c6dceb453919b3db54343fc27Lennart Poettering continue;
6d0c65ffb4f82e8c6dceb453919b3db54343fc27Lennart Poettering
1c4baffc1895809bae9ac36b670af90a4cb9cd7dTom Gundersen r = sd_rtnl_message_link_get_ifindex(i, &ifindex);
6d0c65ffb4f82e8c6dceb453919b3db54343fc27Lennart Poettering if (r < 0)
6d0c65ffb4f82e8c6dceb453919b3db54343fc27Lennart Poettering return r;
1c4baffc1895809bae9ac36b670af90a4cb9cd7dTom Gundersen
6d0c65ffb4f82e8c6dceb453919b3db54343fc27Lennart Poettering r = sd_rtnl_message_read_string(i, IFLA_IFNAME, &name);
6d0c65ffb4f82e8c6dceb453919b3db54343fc27Lennart Poettering if (r < 0)
6d0c65ffb4f82e8c6dceb453919b3db54343fc27Lennart Poettering return r;
6d0c65ffb4f82e8c6dceb453919b3db54343fc27Lennart Poettering
6d0c65ffb4f82e8c6dceb453919b3db54343fc27Lennart Poettering r = sd_rtnl_message_link_get_type(i, &iftype);
1c4baffc1895809bae9ac36b670af90a4cb9cd7dTom Gundersen if (r < 0)
6d0c65ffb4f82e8c6dceb453919b3db54343fc27Lennart Poettering return r;
6d0c65ffb4f82e8c6dceb453919b3db54343fc27Lennart Poettering
6d0c65ffb4f82e8c6dceb453919b3db54343fc27Lennart Poettering if (!GREEDY_REALLOC(links, size, c+1))
6d0c65ffb4f82e8c6dceb453919b3db54343fc27Lennart Poettering return -ENOMEM;
6d0c65ffb4f82e8c6dceb453919b3db54343fc27Lennart Poettering
6d0c65ffb4f82e8c6dceb453919b3db54343fc27Lennart Poettering links[c].name = name;
6d0c65ffb4f82e8c6dceb453919b3db54343fc27Lennart Poettering links[c].ifindex = ifindex;
6d0c65ffb4f82e8c6dceb453919b3db54343fc27Lennart Poettering links[c].iftype = iftype;
6d0c65ffb4f82e8c6dceb453919b3db54343fc27Lennart Poettering c++;
6d0c65ffb4f82e8c6dceb453919b3db54343fc27Lennart Poettering }
1c4baffc1895809bae9ac36b670af90a4cb9cd7dTom Gundersen
6d0c65ffb4f82e8c6dceb453919b3db54343fc27Lennart Poettering qsort_safe(links, c, sizeof(LinkInfo), link_info_compare);
6d0c65ffb4f82e8c6dceb453919b3db54343fc27Lennart Poettering
6d0c65ffb4f82e8c6dceb453919b3db54343fc27Lennart Poettering *ret = links;
6d0c65ffb4f82e8c6dceb453919b3db54343fc27Lennart Poettering links = NULL;
6d0c65ffb4f82e8c6dceb453919b3db54343fc27Lennart Poettering
6d0c65ffb4f82e8c6dceb453919b3db54343fc27Lennart Poettering return (int) c;
6d0c65ffb4f82e8c6dceb453919b3db54343fc27Lennart Poettering}
6d0c65ffb4f82e8c6dceb453919b3db54343fc27Lennart Poettering
6d0c65ffb4f82e8c6dceb453919b3db54343fc27Lennart Poetteringstatic void operational_state_to_color(const char *state, const char **on, const char **off) {
6d0c65ffb4f82e8c6dceb453919b3db54343fc27Lennart Poettering assert(on);
6d0c65ffb4f82e8c6dceb453919b3db54343fc27Lennart Poettering assert(off);
6d0c65ffb4f82e8c6dceb453919b3db54343fc27Lennart Poettering
6d0c65ffb4f82e8c6dceb453919b3db54343fc27Lennart Poettering if (streq_ptr(state, "routable")) {
6d0c65ffb4f82e8c6dceb453919b3db54343fc27Lennart Poettering *on = ansi_highlight_green();
6d0c65ffb4f82e8c6dceb453919b3db54343fc27Lennart Poettering *off = ansi_highlight_off();
6d0c65ffb4f82e8c6dceb453919b3db54343fc27Lennart Poettering } else if (streq_ptr(state, "degraded")) {
a6a4f528899b1dab47408733b4a423c66ea40f7aThomas Hindoe Paaboel Andersen *on = ansi_highlight_yellow();
6d0c65ffb4f82e8c6dceb453919b3db54343fc27Lennart Poettering *off = ansi_highlight_off();
6d0c65ffb4f82e8c6dceb453919b3db54343fc27Lennart Poettering } else
6d0c65ffb4f82e8c6dceb453919b3db54343fc27Lennart Poettering *on = *off = "";
6d0c65ffb4f82e8c6dceb453919b3db54343fc27Lennart Poettering}
6d0c65ffb4f82e8c6dceb453919b3db54343fc27Lennart Poettering
6d0c65ffb4f82e8c6dceb453919b3db54343fc27Lennart Poetteringstatic void setup_state_to_color(const char *state, const char **on, const char **off) {
6d0c65ffb4f82e8c6dceb453919b3db54343fc27Lennart Poettering assert(on);
d57c365bf8f09fbcc649e00f7060ff30809f67c2Lennart Poettering assert(off);
d57c365bf8f09fbcc649e00f7060ff30809f67c2Lennart Poettering
d57c365bf8f09fbcc649e00f7060ff30809f67c2Lennart Poettering if (streq_ptr(state, "configured")) {
d57c365bf8f09fbcc649e00f7060ff30809f67c2Lennart Poettering *on = ansi_highlight_green();
d57c365bf8f09fbcc649e00f7060ff30809f67c2Lennart Poettering *off = ansi_highlight_off();
d57c365bf8f09fbcc649e00f7060ff30809f67c2Lennart Poettering } else if (streq_ptr(state, "configuring")) {
1fc464f6fbecfc5d8ba9f7b98d19e21fb324bfb9Lennart Poettering *on = ansi_highlight_yellow();
d57c365bf8f09fbcc649e00f7060ff30809f67c2Lennart Poettering *off = ansi_highlight_off();
d57c365bf8f09fbcc649e00f7060ff30809f67c2Lennart Poettering } else if (streq_ptr(state, "failed") || streq_ptr(state, "linger")) {
1fc464f6fbecfc5d8ba9f7b98d19e21fb324bfb9Lennart Poettering *on = ansi_highlight_red();
d57c365bf8f09fbcc649e00f7060ff30809f67c2Lennart Poettering *off = ansi_highlight_off();
d57c365bf8f09fbcc649e00f7060ff30809f67c2Lennart Poettering } else
d57c365bf8f09fbcc649e00f7060ff30809f67c2Lennart Poettering *on = *off = "";
d57c365bf8f09fbcc649e00f7060ff30809f67c2Lennart Poettering}
d57c365bf8f09fbcc649e00f7060ff30809f67c2Lennart Poettering
d57c365bf8f09fbcc649e00f7060ff30809f67c2Lennart Poetteringstatic int list_links(char **args, unsigned n) {
d57c365bf8f09fbcc649e00f7060ff30809f67c2Lennart Poettering _cleanup_rtnl_message_unref_ sd_rtnl_message *req = NULL, *reply = NULL;
d57c365bf8f09fbcc649e00f7060ff30809f67c2Lennart Poettering _cleanup_udev_unref_ struct udev *udev = NULL;
d57c365bf8f09fbcc649e00f7060ff30809f67c2Lennart Poettering _cleanup_rtnl_unref_ sd_rtnl *rtnl = NULL;
d57c365bf8f09fbcc649e00f7060ff30809f67c2Lennart Poettering _cleanup_free_ LinkInfo *links = NULL;
1fc464f6fbecfc5d8ba9f7b98d19e21fb324bfb9Lennart Poettering int r, c, i;
d57c365bf8f09fbcc649e00f7060ff30809f67c2Lennart Poettering
d57c365bf8f09fbcc649e00f7060ff30809f67c2Lennart Poettering pager_open_if_enabled();
1fc464f6fbecfc5d8ba9f7b98d19e21fb324bfb9Lennart Poettering
d57c365bf8f09fbcc649e00f7060ff30809f67c2Lennart Poettering r = sd_rtnl_open(&rtnl, 0);
d57c365bf8f09fbcc649e00f7060ff30809f67c2Lennart Poettering if (r < 0) {
1fc464f6fbecfc5d8ba9f7b98d19e21fb324bfb9Lennart Poettering log_error("Failed to connect to netlink: %s", strerror(-r));
d57c365bf8f09fbcc649e00f7060ff30809f67c2Lennart Poettering return r;
d57c365bf8f09fbcc649e00f7060ff30809f67c2Lennart Poettering }
d57c365bf8f09fbcc649e00f7060ff30809f67c2Lennart Poettering
d57c365bf8f09fbcc649e00f7060ff30809f67c2Lennart Poettering udev = udev_new();
266b538958932e6fc27dfce4917336e70e17e29eTom Gundersen if (!udev) {
1c4baffc1895809bae9ac36b670af90a4cb9cd7dTom Gundersen log_error("Failed to connect to udev: %m");
1c4baffc1895809bae9ac36b670af90a4cb9cd7dTom Gundersen return -errno;
6d0c65ffb4f82e8c6dceb453919b3db54343fc27Lennart Poettering }
6d0c65ffb4f82e8c6dceb453919b3db54343fc27Lennart Poettering
ee8c45689526ca973407cbb77bce7b96a062c40bLennart Poettering r = sd_rtnl_message_new_link(rtnl, &req, RTM_GETLINK, 0);
ee8c45689526ca973407cbb77bce7b96a062c40bLennart Poettering if (r < 0)
ee8c45689526ca973407cbb77bce7b96a062c40bLennart Poettering return rtnl_log_create_error(r);
1c4baffc1895809bae9ac36b670af90a4cb9cd7dTom Gundersen
f647962d64e844689f3e2acfce6102fc47e76df2Michal Schmidt r = sd_rtnl_message_request_dump(req, true);
f647962d64e844689f3e2acfce6102fc47e76df2Michal Schmidt if (r < 0)
ee8c45689526ca973407cbb77bce7b96a062c40bLennart Poettering return rtnl_log_create_error(r);
ee8c45689526ca973407cbb77bce7b96a062c40bLennart Poettering
ee8c45689526ca973407cbb77bce7b96a062c40bLennart Poettering r = sd_rtnl_call(rtnl, req, 0, &reply);
ee8c45689526ca973407cbb77bce7b96a062c40bLennart Poettering if (r < 0) {
ee8c45689526ca973407cbb77bce7b96a062c40bLennart Poettering log_error("Failed to enumerate links: %s", strerror(-r));
1c4baffc1895809bae9ac36b670af90a4cb9cd7dTom Gundersen return r;
ee8c45689526ca973407cbb77bce7b96a062c40bLennart Poettering }
ee8c45689526ca973407cbb77bce7b96a062c40bLennart Poettering
ee8c45689526ca973407cbb77bce7b96a062c40bLennart Poettering if (arg_legend)
1c4baffc1895809bae9ac36b670af90a4cb9cd7dTom Gundersen printf("%3s %-16s %-18s %-11s %-10s\n", "IDX", "LINK", "TYPE", "OPERATIONAL", "SETUP");
f647962d64e844689f3e2acfce6102fc47e76df2Michal Schmidt
f647962d64e844689f3e2acfce6102fc47e76df2Michal Schmidt c = decode_and_sort_links(reply, &links);
ee8c45689526ca973407cbb77bce7b96a062c40bLennart Poettering if (c < 0)
ee8c45689526ca973407cbb77bce7b96a062c40bLennart Poettering return rtnl_log_parse_error(c);
3e3db0ee860025ad663b13b0ace4e6d627611332Lennart Poettering
ee8c45689526ca973407cbb77bce7b96a062c40bLennart Poettering for (i = 0; i < c; i++) {
6d0c65ffb4f82e8c6dceb453919b3db54343fc27Lennart Poettering _cleanup_free_ char *setup_state = NULL, *operational_state = NULL;
6d0c65ffb4f82e8c6dceb453919b3db54343fc27Lennart Poettering _cleanup_udev_device_unref_ struct udev_device *d = NULL;
6d0c65ffb4f82e8c6dceb453919b3db54343fc27Lennart Poettering const char *on_color_operational, *off_color_operational,
6d0c65ffb4f82e8c6dceb453919b3db54343fc27Lennart Poettering *on_color_setup, *off_color_setup;
6d0c65ffb4f82e8c6dceb453919b3db54343fc27Lennart Poettering char devid[2 + DECIMAL_STR_MAX(int)];
ab1525bc2d92780b4dc64bc5b9cdb52594e2df7dLennart Poettering _cleanup_free_ char *t = NULL;
914d6c09f1a449c60c8495c179a8bbe012315ba2Tom Gundersen
d57c365bf8f09fbcc649e00f7060ff30809f67c2Lennart Poettering 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);
7d6884b65e6ea7317346d29bc2f6c9ba051a0cacThomas Hindoe Paaboel Andersen
ee8c45689526ca973407cbb77bce7b96a062c40bLennart Poettering sd_network_link_get_setup_state(links[i].ifindex, &setup_state);
ee8c45689526ca973407cbb77bce7b96a062c40bLennart Poettering setup_state_to_color(setup_state, &on_color_setup, &off_color_setup);
d6731e4c7964ee2860d4f5abdb0b52acd7a66960Tom Gundersen
d57c365bf8f09fbcc649e00f7060ff30809f67c2Lennart Poettering sprintf(devid, "n%i", links[i].ifindex);
d57c365bf8f09fbcc649e00f7060ff30809f67c2Lennart Poettering d = udev_device_new_from_device_id(udev, devid);
d57c365bf8f09fbcc649e00f7060ff30809f67c2Lennart Poettering
d57c365bf8f09fbcc649e00f7060ff30809f67c2Lennart Poettering link_get_type_string(links[i].iftype, d, &t);
ee8c45689526ca973407cbb77bce7b96a062c40bLennart Poettering
6d0c65ffb4f82e8c6dceb453919b3db54343fc27Lennart Poettering printf("%3i %-16s %-18s %s%-11s%s %s%-10s%s\n",
914d6c09f1a449c60c8495c179a8bbe012315ba2Tom Gundersen links[i].ifindex, links[i].name, strna(t),
ee8c45689526ca973407cbb77bce7b96a062c40bLennart Poettering on_color_operational, strna(operational_state), off_color_operational,
6d0c65ffb4f82e8c6dceb453919b3db54343fc27Lennart Poettering on_color_setup, strna(setup_state), off_color_setup);
ee8c45689526ca973407cbb77bce7b96a062c40bLennart Poettering }
3e3db0ee860025ad663b13b0ace4e6d627611332Lennart Poettering
d57c365bf8f09fbcc649e00f7060ff30809f67c2Lennart Poettering if (arg_legend)
d57c365bf8f09fbcc649e00f7060ff30809f67c2Lennart Poettering printf("\n%i links listed.\n", c);
d57c365bf8f09fbcc649e00f7060ff30809f67c2Lennart Poettering
ee8c45689526ca973407cbb77bce7b96a062c40bLennart Poettering return 0;
ee8c45689526ca973407cbb77bce7b96a062c40bLennart Poettering}
ee8c45689526ca973407cbb77bce7b96a062c40bLennart Poettering
6d0c65ffb4f82e8c6dceb453919b3db54343fc27Lennart Poetteringstatic int dump_addresses(sd_rtnl *rtnl, const char *prefix, int ifindex) {
ee8c45689526ca973407cbb77bce7b96a062c40bLennart Poettering _cleanup_free_ struct local_address *local = NULL;
ee8c45689526ca973407cbb77bce7b96a062c40bLennart Poettering int r, n, i;
ee8c45689526ca973407cbb77bce7b96a062c40bLennart Poettering
ee8c45689526ca973407cbb77bce7b96a062c40bLennart Poettering n = local_addresses(rtnl, ifindex, &local);
c09da72900b03fcddade06643f24c6357f3e0482Tom Gundersen if (n < 0)
81fd1dd3a2cf4cc90a6898d562c9bb0fb238cbd7Tom Gundersen return n;
81fd1dd3a2cf4cc90a6898d562c9bb0fb238cbd7Tom Gundersen
81fd1dd3a2cf4cc90a6898d562c9bb0fb238cbd7Tom Gundersen for (i = 0; i < n; i++) {
81fd1dd3a2cf4cc90a6898d562c9bb0fb238cbd7Tom Gundersen _cleanup_free_ char *pretty = NULL;
81fd1dd3a2cf4cc90a6898d562c9bb0fb238cbd7Tom Gundersen
81fd1dd3a2cf4cc90a6898d562c9bb0fb238cbd7Tom Gundersen r = in_addr_to_string(local[i].family, &local[i].address, &pretty);
c09da72900b03fcddade06643f24c6357f3e0482Tom Gundersen if (r < 0)
888943fc6246b2917168fff59380b58b678ba157Lennart Poettering return r;
888943fc6246b2917168fff59380b58b678ba157Lennart Poettering
888943fc6246b2917168fff59380b58b678ba157Lennart Poettering printf("%*s%s\n",
81fd1dd3a2cf4cc90a6898d562c9bb0fb238cbd7Tom Gundersen (int) strlen(prefix),
81fd1dd3a2cf4cc90a6898d562c9bb0fb238cbd7Tom Gundersen i == 0 ? prefix : "",
81fd1dd3a2cf4cc90a6898d562c9bb0fb238cbd7Tom Gundersen pretty);
c09da72900b03fcddade06643f24c6357f3e0482Tom Gundersen }
c09da72900b03fcddade06643f24c6357f3e0482Tom Gundersen
c09da72900b03fcddade06643f24c6357f3e0482Tom Gundersen return 0;
c09da72900b03fcddade06643f24c6357f3e0482Tom Gundersen}
81fd1dd3a2cf4cc90a6898d562c9bb0fb238cbd7Tom Gundersen
c09da72900b03fcddade06643f24c6357f3e0482Tom Gundersenstatic void dump_list(const char *prefix, char **l) {
81fd1dd3a2cf4cc90a6898d562c9bb0fb238cbd7Tom Gundersen char **i;
81fd1dd3a2cf4cc90a6898d562c9bb0fb238cbd7Tom Gundersen
81fd1dd3a2cf4cc90a6898d562c9bb0fb238cbd7Tom Gundersen STRV_FOREACH(i, l) {
c09da72900b03fcddade06643f24c6357f3e0482Tom Gundersen printf("%*s%s\n",
81fd1dd3a2cf4cc90a6898d562c9bb0fb238cbd7Tom Gundersen (int) strlen(prefix),
81fd1dd3a2cf4cc90a6898d562c9bb0fb238cbd7Tom Gundersen i == l ? prefix : "",
81fd1dd3a2cf4cc90a6898d562c9bb0fb238cbd7Tom Gundersen *i);
c09da72900b03fcddade06643f24c6357f3e0482Tom Gundersen }
81fd1dd3a2cf4cc90a6898d562c9bb0fb238cbd7Tom Gundersen}
81fd1dd3a2cf4cc90a6898d562c9bb0fb238cbd7Tom Gundersen
81fd1dd3a2cf4cc90a6898d562c9bb0fb238cbd7Tom Gundersenstatic int link_status_one(sd_rtnl *rtnl, struct udev *udev, const char *name) {
c09da72900b03fcddade06643f24c6357f3e0482Tom Gundersen _cleanup_strv_free_ char **dns = NULL, **ntp = NULL, **domains = NULL;
c09da72900b03fcddade06643f24c6357f3e0482Tom Gundersen _cleanup_free_ char *setup_state = NULL, *operational_state = NULL;
69fb1176c403e437c4fba763ba242b540c73898fLennart Poettering _cleanup_rtnl_message_unref_ sd_rtnl_message *req = NULL, *reply = NULL;
1c4baffc1895809bae9ac36b670af90a4cb9cd7dTom Gundersen _cleanup_udev_device_unref_ struct udev_device *d = NULL;
81fd1dd3a2cf4cc90a6898d562c9bb0fb238cbd7Tom Gundersen char devid[2 + DECIMAL_STR_MAX(int)];
69fb1176c403e437c4fba763ba242b540c73898fLennart Poettering _cleanup_free_ char *t = NULL;
69fb1176c403e437c4fba763ba242b540c73898fLennart Poettering const char *driver = NULL, *path = NULL, *vendor = NULL, *model = NULL;
69fb1176c403e437c4fba763ba242b540c73898fLennart Poettering const char *on_color_operational, *off_color_operational,
69fb1176c403e437c4fba763ba242b540c73898fLennart Poettering *on_color_setup, *off_color_setup;
1c4baffc1895809bae9ac36b670af90a4cb9cd7dTom Gundersen struct ether_addr e;
1c4baffc1895809bae9ac36b670af90a4cb9cd7dTom Gundersen unsigned iftype;
c09da72900b03fcddade06643f24c6357f3e0482Tom Gundersen int r, ifindex;
c09da72900b03fcddade06643f24c6357f3e0482Tom Gundersen bool have_mac;
c09da72900b03fcddade06643f24c6357f3e0482Tom Gundersen uint32_t mtu;
c09da72900b03fcddade06643f24c6357f3e0482Tom Gundersen
c09da72900b03fcddade06643f24c6357f3e0482Tom Gundersen assert(rtnl);
c09da72900b03fcddade06643f24c6357f3e0482Tom Gundersen assert(udev);
c09da72900b03fcddade06643f24c6357f3e0482Tom Gundersen assert(name);
c09da72900b03fcddade06643f24c6357f3e0482Tom Gundersen
c09da72900b03fcddade06643f24c6357f3e0482Tom Gundersen if (safe_atoi(name, &ifindex) >= 0 && ifindex > 0)
c09da72900b03fcddade06643f24c6357f3e0482Tom Gundersen r = sd_rtnl_message_new_link(rtnl, &req, RTM_GETLINK, ifindex);
c09da72900b03fcddade06643f24c6357f3e0482Tom Gundersen else {
c09da72900b03fcddade06643f24c6357f3e0482Tom Gundersen r = sd_rtnl_message_new_link(rtnl, &req, RTM_GETLINK, 0);
1c4baffc1895809bae9ac36b670af90a4cb9cd7dTom Gundersen if (r < 0)
c09da72900b03fcddade06643f24c6357f3e0482Tom Gundersen return rtnl_log_create_error(r);
c09da72900b03fcddade06643f24c6357f3e0482Tom Gundersen
c09da72900b03fcddade06643f24c6357f3e0482Tom Gundersen r = sd_rtnl_message_append_string(req, IFLA_IFNAME, name);
1c4baffc1895809bae9ac36b670af90a4cb9cd7dTom Gundersen }
c09da72900b03fcddade06643f24c6357f3e0482Tom Gundersen
c09da72900b03fcddade06643f24c6357f3e0482Tom Gundersen if (r < 0)
c09da72900b03fcddade06643f24c6357f3e0482Tom Gundersen return rtnl_log_create_error(r);
1c4baffc1895809bae9ac36b670af90a4cb9cd7dTom Gundersen
c09da72900b03fcddade06643f24c6357f3e0482Tom Gundersen r = sd_rtnl_call(rtnl, req, 0, &reply);
c09da72900b03fcddade06643f24c6357f3e0482Tom Gundersen if (r < 0) {
c09da72900b03fcddade06643f24c6357f3e0482Tom Gundersen log_error("Failed to query link: %s", strerror(-r));
c09da72900b03fcddade06643f24c6357f3e0482Tom Gundersen return r;
c09da72900b03fcddade06643f24c6357f3e0482Tom Gundersen }
1c4baffc1895809bae9ac36b670af90a4cb9cd7dTom Gundersen
c09da72900b03fcddade06643f24c6357f3e0482Tom Gundersen r = sd_rtnl_message_link_get_ifindex(reply, &ifindex);
c09da72900b03fcddade06643f24c6357f3e0482Tom Gundersen if (r < 0)
c09da72900b03fcddade06643f24c6357f3e0482Tom Gundersen return rtnl_log_parse_error(r);
c09da72900b03fcddade06643f24c6357f3e0482Tom Gundersen
c09da72900b03fcddade06643f24c6357f3e0482Tom Gundersen r = sd_rtnl_message_read_string(reply, IFLA_IFNAME, &name);
1c4baffc1895809bae9ac36b670af90a4cb9cd7dTom Gundersen if (r < 0)
c09da72900b03fcddade06643f24c6357f3e0482Tom Gundersen return rtnl_log_parse_error(r);
c09da72900b03fcddade06643f24c6357f3e0482Tom Gundersen
c09da72900b03fcddade06643f24c6357f3e0482Tom Gundersen r = sd_rtnl_message_link_get_type(reply, &iftype);
c09da72900b03fcddade06643f24c6357f3e0482Tom Gundersen if (r < 0)
c09da72900b03fcddade06643f24c6357f3e0482Tom Gundersen return rtnl_log_parse_error(r);
c09da72900b03fcddade06643f24c6357f3e0482Tom Gundersen
c09da72900b03fcddade06643f24c6357f3e0482Tom Gundersen have_mac = sd_rtnl_message_read_ether_addr(reply, IFLA_ADDRESS, &e) >= 0;
c09da72900b03fcddade06643f24c6357f3e0482Tom Gundersen
c09da72900b03fcddade06643f24c6357f3e0482Tom Gundersen if (have_mac) {
c09da72900b03fcddade06643f24c6357f3e0482Tom Gundersen const uint8_t *p;
c09da72900b03fcddade06643f24c6357f3e0482Tom Gundersen bool all_zeroes = true;
c09da72900b03fcddade06643f24c6357f3e0482Tom Gundersen
c09da72900b03fcddade06643f24c6357f3e0482Tom Gundersen for (p = (uint8_t*) &e; p < (uint8_t*) &e + sizeof(e); p++)
c09da72900b03fcddade06643f24c6357f3e0482Tom Gundersen if (*p != 0) {
c09da72900b03fcddade06643f24c6357f3e0482Tom Gundersen all_zeroes = false;
c09da72900b03fcddade06643f24c6357f3e0482Tom Gundersen break;
c09da72900b03fcddade06643f24c6357f3e0482Tom Gundersen }
c09da72900b03fcddade06643f24c6357f3e0482Tom Gundersen
c09da72900b03fcddade06643f24c6357f3e0482Tom Gundersen if (all_zeroes)
c09da72900b03fcddade06643f24c6357f3e0482Tom Gundersen have_mac = false;
c09da72900b03fcddade06643f24c6357f3e0482Tom Gundersen }
c09da72900b03fcddade06643f24c6357f3e0482Tom Gundersen
c09da72900b03fcddade06643f24c6357f3e0482Tom Gundersen sd_rtnl_message_read_u32(reply, IFLA_MTU, &mtu);
144232a8e0ea77eed8c5a456832758681b5b3511Torstein Husebø
c09da72900b03fcddade06643f24c6357f3e0482Tom Gundersen sd_network_link_get_operational_state(ifindex, &operational_state);
c09da72900b03fcddade06643f24c6357f3e0482Tom Gundersen operational_state_to_color(operational_state, &on_color_operational, &off_color_operational);
c09da72900b03fcddade06643f24c6357f3e0482Tom Gundersen
c09da72900b03fcddade06643f24c6357f3e0482Tom Gundersen sd_network_link_get_setup_state(ifindex, &setup_state);
c09da72900b03fcddade06643f24c6357f3e0482Tom Gundersen setup_state_to_color(setup_state, &on_color_setup, &off_color_setup);
c09da72900b03fcddade06643f24c6357f3e0482Tom Gundersen
c09da72900b03fcddade06643f24c6357f3e0482Tom Gundersen sd_network_link_get_dns(ifindex, &dns);
c09da72900b03fcddade06643f24c6357f3e0482Tom Gundersen sd_network_link_get_ntp(ifindex, &ntp);
1c4baffc1895809bae9ac36b670af90a4cb9cd7dTom Gundersen sd_network_link_get_domains(ifindex, &domains);
c09da72900b03fcddade06643f24c6357f3e0482Tom Gundersen r = sd_network_link_get_wildcard_domain(ifindex);
c09da72900b03fcddade06643f24c6357f3e0482Tom Gundersen if (r > 0) {
c09da72900b03fcddade06643f24c6357f3e0482Tom Gundersen char *wildcard;
c09da72900b03fcddade06643f24c6357f3e0482Tom Gundersen
c09da72900b03fcddade06643f24c6357f3e0482Tom Gundersen wildcard = strdup("*");
1c4baffc1895809bae9ac36b670af90a4cb9cd7dTom Gundersen if (!wildcard)
c09da72900b03fcddade06643f24c6357f3e0482Tom Gundersen return log_oom();
c09da72900b03fcddade06643f24c6357f3e0482Tom Gundersen
c09da72900b03fcddade06643f24c6357f3e0482Tom Gundersen if (strv_consume(&domains, wildcard) < 0)
c09da72900b03fcddade06643f24c6357f3e0482Tom Gundersen return log_oom();
c09da72900b03fcddade06643f24c6357f3e0482Tom Gundersen }
c09da72900b03fcddade06643f24c6357f3e0482Tom Gundersen
c09da72900b03fcddade06643f24c6357f3e0482Tom Gundersen sprintf(devid, "n%i", ifindex);
c09da72900b03fcddade06643f24c6357f3e0482Tom Gundersen d = udev_device_new_from_device_id(udev, devid);
c09da72900b03fcddade06643f24c6357f3e0482Tom Gundersen
c09da72900b03fcddade06643f24c6357f3e0482Tom Gundersen link_get_type_string(iftype, d, &t);
c09da72900b03fcddade06643f24c6357f3e0482Tom Gundersen
1c4baffc1895809bae9ac36b670af90a4cb9cd7dTom Gundersen if (d) {
c09da72900b03fcddade06643f24c6357f3e0482Tom Gundersen driver = udev_device_get_property_value(d, "ID_NET_DRIVER");
c09da72900b03fcddade06643f24c6357f3e0482Tom Gundersen path = udev_device_get_property_value(d, "ID_PATH");
c09da72900b03fcddade06643f24c6357f3e0482Tom Gundersen
c09da72900b03fcddade06643f24c6357f3e0482Tom Gundersen vendor = udev_device_get_property_value(d, "ID_VENDOR_FROM_DATABASE");
c09da72900b03fcddade06643f24c6357f3e0482Tom Gundersen if (!vendor)
c09da72900b03fcddade06643f24c6357f3e0482Tom Gundersen vendor = udev_device_get_property_value(d, "ID_VENDOR");
c09da72900b03fcddade06643f24c6357f3e0482Tom Gundersen
c09da72900b03fcddade06643f24c6357f3e0482Tom Gundersen model = udev_device_get_property_value(d, "ID_MODEL_FROM_DATABASE");
c09da72900b03fcddade06643f24c6357f3e0482Tom Gundersen if (!model)
c09da72900b03fcddade06643f24c6357f3e0482Tom Gundersen model = udev_device_get_property_value(d, "ID_MODEL");
c09da72900b03fcddade06643f24c6357f3e0482Tom Gundersen }
c09da72900b03fcddade06643f24c6357f3e0482Tom Gundersen
c09da72900b03fcddade06643f24c6357f3e0482Tom Gundersen
69fb1176c403e437c4fba763ba242b540c73898fLennart Poettering printf("%s%s%s %i: %s\n", on_color_operational, draw_special_char(DRAW_BLACK_CIRCLE), off_color_operational, ifindex, name);
1c4baffc1895809bae9ac36b670af90a4cb9cd7dTom Gundersen
81fd1dd3a2cf4cc90a6898d562c9bb0fb238cbd7Tom Gundersen printf(" Type: %s\n"
69fb1176c403e437c4fba763ba242b540c73898fLennart Poettering " State: %s%s%s (%s%s%s)\n",
69fb1176c403e437c4fba763ba242b540c73898fLennart Poettering strna(t),
b6a3ca6d876ab59b4f29ed67f54ef87005177906Tom Gundersen on_color_operational, strna(operational_state), off_color_operational,
b6a3ca6d876ab59b4f29ed67f54ef87005177906Tom Gundersen on_color_setup, strna(setup_state), off_color_setup);
c09da72900b03fcddade06643f24c6357f3e0482Tom Gundersen
b6a3ca6d876ab59b4f29ed67f54ef87005177906Tom Gundersen if (path)
b6a3ca6d876ab59b4f29ed67f54ef87005177906Tom Gundersen printf(" Path: %s\n", path);
b6a3ca6d876ab59b4f29ed67f54ef87005177906Tom Gundersen if (driver)
c09da72900b03fcddade06643f24c6357f3e0482Tom Gundersen printf(" Driver: %s\n", driver);
b6a3ca6d876ab59b4f29ed67f54ef87005177906Tom Gundersen if (vendor)
b6a3ca6d876ab59b4f29ed67f54ef87005177906Tom Gundersen printf(" Vendor: %s\n", vendor);
c09da72900b03fcddade06643f24c6357f3e0482Tom Gundersen if (model)
b6a3ca6d876ab59b4f29ed67f54ef87005177906Tom Gundersen printf(" Model: %s\n", model);
c09da72900b03fcddade06643f24c6357f3e0482Tom Gundersen
b6a3ca6d876ab59b4f29ed67f54ef87005177906Tom Gundersen if (have_mac) {
c09da72900b03fcddade06643f24c6357f3e0482Tom Gundersen char ea[ETHER_ADDR_TO_STRING_MAX];
69fb1176c403e437c4fba763ba242b540c73898fLennart Poettering printf(" HW Address: %s\n", ether_addr_to_string(&e, ea));
c09da72900b03fcddade06643f24c6357f3e0482Tom Gundersen }
b6a3ca6d876ab59b4f29ed67f54ef87005177906Tom Gundersen
c09da72900b03fcddade06643f24c6357f3e0482Tom Gundersen if (mtu > 0)
1693a943ca581aca2beebb4c812ec6c9f17b8164Lennart Poettering printf(" MTU: %u\n", mtu);
1693a943ca581aca2beebb4c812ec6c9f17b8164Lennart Poettering
1693a943ca581aca2beebb4c812ec6c9f17b8164Lennart Poettering dump_addresses(rtnl, " Address: ", ifindex);
1693a943ca581aca2beebb4c812ec6c9f17b8164Lennart Poettering
1693a943ca581aca2beebb4c812ec6c9f17b8164Lennart Poettering if (!strv_isempty(dns))
b6a3ca6d876ab59b4f29ed67f54ef87005177906Tom Gundersen dump_list(" DNS: ", dns);
1693a943ca581aca2beebb4c812ec6c9f17b8164Lennart Poettering if (!strv_isempty(domains))
1693a943ca581aca2beebb4c812ec6c9f17b8164Lennart Poettering dump_list(" Domain: ", domains);
1693a943ca581aca2beebb4c812ec6c9f17b8164Lennart Poettering if (!strv_isempty(ntp))
1693a943ca581aca2beebb4c812ec6c9f17b8164Lennart Poettering dump_list(" NTP: ", ntp);
1693a943ca581aca2beebb4c812ec6c9f17b8164Lennart Poettering
1693a943ca581aca2beebb4c812ec6c9f17b8164Lennart Poettering return 0;
1693a943ca581aca2beebb4c812ec6c9f17b8164Lennart Poettering}
1693a943ca581aca2beebb4c812ec6c9f17b8164Lennart Poettering
1693a943ca581aca2beebb4c812ec6c9f17b8164Lennart Poetteringstatic int link_status(char **args, unsigned n) {
1693a943ca581aca2beebb4c812ec6c9f17b8164Lennart Poettering _cleanup_udev_unref_ struct udev *udev = NULL;
1693a943ca581aca2beebb4c812ec6c9f17b8164Lennart Poettering _cleanup_rtnl_unref_ sd_rtnl *rtnl = NULL;
1693a943ca581aca2beebb4c812ec6c9f17b8164Lennart Poettering char **name;
1693a943ca581aca2beebb4c812ec6c9f17b8164Lennart Poettering int r;
1693a943ca581aca2beebb4c812ec6c9f17b8164Lennart Poettering
1693a943ca581aca2beebb4c812ec6c9f17b8164Lennart Poettering r = sd_rtnl_open(&rtnl, 0);
c09da72900b03fcddade06643f24c6357f3e0482Tom Gundersen if (r < 0) {
c09da72900b03fcddade06643f24c6357f3e0482Tom Gundersen log_error("Failed to connect to netlink: %s", strerror(-r));
c09da72900b03fcddade06643f24c6357f3e0482Tom Gundersen return r;
c09da72900b03fcddade06643f24c6357f3e0482Tom Gundersen }
c09da72900b03fcddade06643f24c6357f3e0482Tom Gundersen
69fb1176c403e437c4fba763ba242b540c73898fLennart Poettering udev = udev_new();
1c4baffc1895809bae9ac36b670af90a4cb9cd7dTom Gundersen if (!udev) {
69fb1176c403e437c4fba763ba242b540c73898fLennart Poettering log_error("Failed to connect to udev: %m");
69fb1176c403e437c4fba763ba242b540c73898fLennart Poettering return -errno;
69fb1176c403e437c4fba763ba242b540c73898fLennart Poettering }
ee8c45689526ca973407cbb77bce7b96a062c40bLennart Poettering
ee8c45689526ca973407cbb77bce7b96a062c40bLennart Poettering if (n <= 1 && !arg_all) {
ee8c45689526ca973407cbb77bce7b96a062c40bLennart Poettering _cleanup_free_ char *operational_state = NULL;
1d050e1e0a7082e23ee9b31fa0b819cb332b3444Lennart Poettering _cleanup_strv_free_ char **dns = NULL, **ntp = NULL, **domains = NULL;
ee8c45689526ca973407cbb77bce7b96a062c40bLennart Poettering _cleanup_free_ struct local_address *addresses = NULL;
ee8c45689526ca973407cbb77bce7b96a062c40bLennart Poettering const char *on_color_operational, *off_color_operational;
ee8c45689526ca973407cbb77bce7b96a062c40bLennart Poettering int i, c;
ee8c45689526ca973407cbb77bce7b96a062c40bLennart Poettering
ee8c45689526ca973407cbb77bce7b96a062c40bLennart Poettering sd_network_get_operational_state(&operational_state);
ee8c45689526ca973407cbb77bce7b96a062c40bLennart Poettering operational_state_to_color(operational_state, &on_color_operational, &off_color_operational);
ee8c45689526ca973407cbb77bce7b96a062c40bLennart Poettering
ee8c45689526ca973407cbb77bce7b96a062c40bLennart Poettering printf(" State: %s%s%s\n", on_color_operational, strna(operational_state), off_color_operational);
ee8c45689526ca973407cbb77bce7b96a062c40bLennart Poettering
ee8c45689526ca973407cbb77bce7b96a062c40bLennart Poettering c = local_addresses(rtnl, 0, &addresses);
1693a943ca581aca2beebb4c812ec6c9f17b8164Lennart Poettering for (i = 0; i < c; i++) {
ee8c45689526ca973407cbb77bce7b96a062c40bLennart Poettering _cleanup_free_ char *pretty = NULL;
ee8c45689526ca973407cbb77bce7b96a062c40bLennart Poettering
ee8c45689526ca973407cbb77bce7b96a062c40bLennart Poettering r = in_addr_to_string(addresses[i].family, &addresses[i].address, &pretty);
1693a943ca581aca2beebb4c812ec6c9f17b8164Lennart Poettering if (r < 0)
1693a943ca581aca2beebb4c812ec6c9f17b8164Lennart Poettering return log_oom();
1693a943ca581aca2beebb4c812ec6c9f17b8164Lennart Poettering
1693a943ca581aca2beebb4c812ec6c9f17b8164Lennart Poettering printf("%13s %s\n",
1693a943ca581aca2beebb4c812ec6c9f17b8164Lennart Poettering i > 0 ? "" : "Address:", pretty);
1693a943ca581aca2beebb4c812ec6c9f17b8164Lennart Poettering }
1693a943ca581aca2beebb4c812ec6c9f17b8164Lennart Poettering
1693a943ca581aca2beebb4c812ec6c9f17b8164Lennart Poettering sd_network_get_dns(&dns);
1693a943ca581aca2beebb4c812ec6c9f17b8164Lennart Poettering if (!strv_isempty(dns))
1693a943ca581aca2beebb4c812ec6c9f17b8164Lennart Poettering dump_list(" DNS: ", dns);
1693a943ca581aca2beebb4c812ec6c9f17b8164Lennart Poettering
1693a943ca581aca2beebb4c812ec6c9f17b8164Lennart Poettering sd_network_get_domains(&domains);
ee8c45689526ca973407cbb77bce7b96a062c40bLennart Poettering if (!strv_isempty(domains))
ee8c45689526ca973407cbb77bce7b96a062c40bLennart Poettering dump_list(" Domain: ", domains);
ee8c45689526ca973407cbb77bce7b96a062c40bLennart Poettering
ee8c45689526ca973407cbb77bce7b96a062c40bLennart Poettering sd_network_get_ntp(&ntp);
ee8c45689526ca973407cbb77bce7b96a062c40bLennart Poettering if (!strv_isempty(ntp))
ee8c45689526ca973407cbb77bce7b96a062c40bLennart Poettering dump_list(" NTP: ", ntp);
ee8c45689526ca973407cbb77bce7b96a062c40bLennart Poettering
ee8c45689526ca973407cbb77bce7b96a062c40bLennart Poettering return 0;
ee8c45689526ca973407cbb77bce7b96a062c40bLennart Poettering }
ee8c45689526ca973407cbb77bce7b96a062c40bLennart Poettering
ee8c45689526ca973407cbb77bce7b96a062c40bLennart Poettering pager_open_if_enabled();
ee8c45689526ca973407cbb77bce7b96a062c40bLennart Poettering
ee8c45689526ca973407cbb77bce7b96a062c40bLennart Poettering if (arg_all) {
ee8c45689526ca973407cbb77bce7b96a062c40bLennart Poettering _cleanup_rtnl_message_unref_ sd_rtnl_message *req = NULL, *reply = NULL;
ee8c45689526ca973407cbb77bce7b96a062c40bLennart Poettering _cleanup_free_ LinkInfo *links = NULL;
ee8c45689526ca973407cbb77bce7b96a062c40bLennart Poettering int c, i;
69fb1176c403e437c4fba763ba242b540c73898fLennart Poettering
1c4baffc1895809bae9ac36b670af90a4cb9cd7dTom Gundersen r = sd_rtnl_message_new_link(rtnl, &req, RTM_GETLINK, 0);
81fd1dd3a2cf4cc90a6898d562c9bb0fb238cbd7Tom Gundersen if (r < 0)
69fb1176c403e437c4fba763ba242b540c73898fLennart Poettering return rtnl_log_create_error(r);
2301cb9fdb774d0a1b3d8f5e95c5d358721ccacbLennart Poettering
64d6c22905e94b02e760747c6c143dc9893083d9Thomas Hindoe Paaboel Andersen r = sd_rtnl_message_request_dump(req, true);
1c4baffc1895809bae9ac36b670af90a4cb9cd7dTom Gundersen if (r < 0)
914d6c09f1a449c60c8495c179a8bbe012315ba2Tom Gundersen return rtnl_log_create_error(r);
9085f64a6694f2928c79fcce365edb1dca6937d4Lennart Poettering
373d9f173f910d547159917401c4b1f84af85736Tom Gundersen r = sd_rtnl_call(rtnl, req, 0, &reply);
af5effc4220dab6c4c87a130bae7be441f6967caTom Gundersen if (r < 0) {
d57c365bf8f09fbcc649e00f7060ff30809f67c2Lennart Poettering log_error("Failed to enumerate links: %s", strerror(-r));
d57c365bf8f09fbcc649e00f7060ff30809f67c2Lennart Poettering return r;
0d4ad91dd4fc831c31a9775b0eadf97fea6cd7f6Alin Rauta }
0d4ad91dd4fc831c31a9775b0eadf97fea6cd7f6Alin Rauta
9085f64a6694f2928c79fcce365edb1dca6937d4Lennart Poettering c = decode_and_sort_links(reply, &links);
9085f64a6694f2928c79fcce365edb1dca6937d4Lennart Poettering if (c < 0)
9085f64a6694f2928c79fcce365edb1dca6937d4Lennart Poettering return rtnl_log_parse_error(c);
9085f64a6694f2928c79fcce365edb1dca6937d4Lennart Poettering
9085f64a6694f2928c79fcce365edb1dca6937d4Lennart Poettering for (i = 0; i < c; i++) {
9085f64a6694f2928c79fcce365edb1dca6937d4Lennart Poettering if (i > 0)
9085f64a6694f2928c79fcce365edb1dca6937d4Lennart Poettering fputc('\n', stdout);
9085f64a6694f2928c79fcce365edb1dca6937d4Lennart Poettering
9085f64a6694f2928c79fcce365edb1dca6937d4Lennart Poettering link_status_one(rtnl, udev, links[i].name);
6ad623a3f77e087e308f334525fd4046811f2a9aLennart Poettering }
9085f64a6694f2928c79fcce365edb1dca6937d4Lennart Poettering }
9085f64a6694f2928c79fcce365edb1dca6937d4Lennart Poettering
9085f64a6694f2928c79fcce365edb1dca6937d4Lennart Poettering STRV_FOREACH(name, args + 1) {
9085f64a6694f2928c79fcce365edb1dca6937d4Lennart Poettering if (name != args+1)
9085f64a6694f2928c79fcce365edb1dca6937d4Lennart Poettering fputc('\n', stdout);
9085f64a6694f2928c79fcce365edb1dca6937d4Lennart Poettering
1c4baffc1895809bae9ac36b670af90a4cb9cd7dTom Gundersen link_status_one(rtnl, udev, *name);
9085f64a6694f2928c79fcce365edb1dca6937d4Lennart Poettering }
9085f64a6694f2928c79fcce365edb1dca6937d4Lennart Poettering
9085f64a6694f2928c79fcce365edb1dca6937d4Lennart Poettering return 0;
9085f64a6694f2928c79fcce365edb1dca6937d4Lennart Poettering}
9085f64a6694f2928c79fcce365edb1dca6937d4Lennart Poettering
1c4baffc1895809bae9ac36b670af90a4cb9cd7dTom Gundersenstatic void help(void) {
f647962d64e844689f3e2acfce6102fc47e76df2Michal Schmidt printf("%s [OPTIONS...]\n\n"
f647962d64e844689f3e2acfce6102fc47e76df2Michal Schmidt "Query and control the networking subsystem.\n\n"
9085f64a6694f2928c79fcce365edb1dca6937d4Lennart 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"
1c4baffc1895809bae9ac36b670af90a4cb9cd7dTom Gundersen "Commands:\n"
9085f64a6694f2928c79fcce365edb1dca6937d4Lennart Poettering " list List links\n"
9085f64a6694f2928c79fcce365edb1dca6937d4Lennart Poettering " status LINK Show link status\n"
9085f64a6694f2928c79fcce365edb1dca6937d4Lennart Poettering , program_invocation_short_name);
9085f64a6694f2928c79fcce365edb1dca6937d4Lennart Poettering}
9085f64a6694f2928c79fcce365edb1dca6937d4Lennart Poettering
9085f64a6694f2928c79fcce365edb1dca6937d4Lennart Poetteringstatic int parse_argv(int argc, char *argv[]) {
9085f64a6694f2928c79fcce365edb1dca6937d4Lennart Poettering
1c4baffc1895809bae9ac36b670af90a4cb9cd7dTom Gundersen enum {
9085f64a6694f2928c79fcce365edb1dca6937d4Lennart Poettering ARG_VERSION = 0x100,
9085f64a6694f2928c79fcce365edb1dca6937d4Lennart Poettering ARG_NO_PAGER,
9085f64a6694f2928c79fcce365edb1dca6937d4Lennart Poettering ARG_NO_LEGEND,
9085f64a6694f2928c79fcce365edb1dca6937d4Lennart Poettering };
9085f64a6694f2928c79fcce365edb1dca6937d4Lennart Poettering
9085f64a6694f2928c79fcce365edb1dca6937d4Lennart Poettering static const struct option options[] = {
9085f64a6694f2928c79fcce365edb1dca6937d4Lennart Poettering { "help", no_argument, NULL, 'h' },
9085f64a6694f2928c79fcce365edb1dca6937d4Lennart Poettering { "version", no_argument, NULL, ARG_VERSION },
9085f64a6694f2928c79fcce365edb1dca6937d4Lennart Poettering { "no-pager", no_argument, NULL, ARG_NO_PAGER },
9085f64a6694f2928c79fcce365edb1dca6937d4Lennart Poettering { "no-legend", no_argument, NULL, ARG_NO_LEGEND },
9085f64a6694f2928c79fcce365edb1dca6937d4Lennart Poettering { "all", no_argument, NULL, 'a' },
9085f64a6694f2928c79fcce365edb1dca6937d4Lennart Poettering {}
9085f64a6694f2928c79fcce365edb1dca6937d4Lennart Poettering };
9085f64a6694f2928c79fcce365edb1dca6937d4Lennart Poettering
9085f64a6694f2928c79fcce365edb1dca6937d4Lennart Poettering int c;
1c4baffc1895809bae9ac36b670af90a4cb9cd7dTom Gundersen
9085f64a6694f2928c79fcce365edb1dca6937d4Lennart Poettering assert(argc >= 0);
d6731e4c7964ee2860d4f5abdb0b52acd7a66960Tom Gundersen assert(argv);
d57c365bf8f09fbcc649e00f7060ff30809f67c2Lennart Poettering
d57c365bf8f09fbcc649e00f7060ff30809f67c2Lennart Poettering while ((c = getopt_long(argc, argv, "ha", options, NULL)) >= 0) {
d57c365bf8f09fbcc649e00f7060ff30809f67c2Lennart Poettering
d57c365bf8f09fbcc649e00f7060ff30809f67c2Lennart Poettering switch (c) {
9085f64a6694f2928c79fcce365edb1dca6937d4Lennart Poettering
d6731e4c7964ee2860d4f5abdb0b52acd7a66960Tom Gundersen case 'h':
2301cb9fdb774d0a1b3d8f5e95c5d358721ccacbLennart Poettering help();
67272d157a35e5cda4e5c904eafdcc23d20541d1Tom Gundersen return 0;
67272d157a35e5cda4e5c904eafdcc23d20541d1Tom Gundersen
67272d157a35e5cda4e5c904eafdcc23d20541d1Tom Gundersen case ARG_VERSION:
67272d157a35e5cda4e5c904eafdcc23d20541d1Tom Gundersen puts(PACKAGE_STRING);
67272d157a35e5cda4e5c904eafdcc23d20541d1Tom Gundersen puts(SYSTEMD_FEATURES);
1405434b6986d3c3d6ccaaa2e472bad843cbbfa1Lennart Poettering return 0;
1405434b6986d3c3d6ccaaa2e472bad843cbbfa1Lennart Poettering
1405434b6986d3c3d6ccaaa2e472bad843cbbfa1Lennart Poettering case ARG_NO_PAGER:
1405434b6986d3c3d6ccaaa2e472bad843cbbfa1Lennart Poettering arg_no_pager = true;
1405434b6986d3c3d6ccaaa2e472bad843cbbfa1Lennart Poettering break;
67272d157a35e5cda4e5c904eafdcc23d20541d1Tom Gundersen
9085f64a6694f2928c79fcce365edb1dca6937d4Lennart Poettering case ARG_NO_LEGEND:
9085f64a6694f2928c79fcce365edb1dca6937d4Lennart Poettering arg_legend = false;
914d6c09f1a449c60c8495c179a8bbe012315ba2Tom Gundersen break;
914d6c09f1a449c60c8495c179a8bbe012315ba2Tom Gundersen
914d6c09f1a449c60c8495c179a8bbe012315ba2Tom Gundersen case 'a':
9085f64a6694f2928c79fcce365edb1dca6937d4Lennart Poettering arg_all = true;
914d6c09f1a449c60c8495c179a8bbe012315ba2Tom Gundersen break;
914d6c09f1a449c60c8495c179a8bbe012315ba2Tom Gundersen
914d6c09f1a449c60c8495c179a8bbe012315ba2Tom Gundersen case '?':
9085f64a6694f2928c79fcce365edb1dca6937d4Lennart Poettering return -EINVAL;
914d6c09f1a449c60c8495c179a8bbe012315ba2Tom Gundersen
914d6c09f1a449c60c8495c179a8bbe012315ba2Tom Gundersen default:
914d6c09f1a449c60c8495c179a8bbe012315ba2Tom Gundersen assert_not_reached("Unhandled option");
9085f64a6694f2928c79fcce365edb1dca6937d4Lennart Poettering }
914d6c09f1a449c60c8495c179a8bbe012315ba2Tom Gundersen }
914d6c09f1a449c60c8495c179a8bbe012315ba2Tom Gundersen
914d6c09f1a449c60c8495c179a8bbe012315ba2Tom Gundersen return 1;
9085f64a6694f2928c79fcce365edb1dca6937d4Lennart Poettering}
9085f64a6694f2928c79fcce365edb1dca6937d4Lennart Poettering
b1acce80cd60fe95f16df2f1ad23ff2ad82d08e5Lennart Poetteringstatic int networkctl_main(int argc, char *argv[]) {
b1acce80cd60fe95f16df2f1ad23ff2ad82d08e5Lennart Poettering
373d9f173f910d547159917401c4b1f84af85736Tom Gundersen static const struct {
df3fb561b2df486a495a5f0bcc83168bd1860533Lennart Poettering const char* verb;
0d4ad91dd4fc831c31a9775b0eadf97fea6cd7f6Alin Rauta const enum {
0d4ad91dd4fc831c31a9775b0eadf97fea6cd7f6Alin Rauta MORE,
0d4ad91dd4fc831c31a9775b0eadf97fea6cd7f6Alin Rauta LESS,
d57c365bf8f09fbcc649e00f7060ff30809f67c2Lennart Poettering EQUAL
9085f64a6694f2928c79fcce365edb1dca6937d4Lennart Poettering } argc_cmp;
0d4ad91dd4fc831c31a9775b0eadf97fea6cd7f6Alin Rauta const int argc;
0d4ad91dd4fc831c31a9775b0eadf97fea6cd7f6Alin Rauta int (* const dispatch)(char **args, unsigned n);
0d4ad91dd4fc831c31a9775b0eadf97fea6cd7f6Alin Rauta } verbs[] = {
0d4ad91dd4fc831c31a9775b0eadf97fea6cd7f6Alin Rauta { "list", LESS, 1, list_links },
af5effc4220dab6c4c87a130bae7be441f6967caTom Gundersen { "status", MORE, 1, link_status },
373d9f173f910d547159917401c4b1f84af85736Tom Gundersen };
9085f64a6694f2928c79fcce365edb1dca6937d4Lennart Poettering
d57c365bf8f09fbcc649e00f7060ff30809f67c2Lennart Poettering int left;
d57c365bf8f09fbcc649e00f7060ff30809f67c2Lennart Poettering unsigned i;
9085f64a6694f2928c79fcce365edb1dca6937d4Lennart Poettering
9085f64a6694f2928c79fcce365edb1dca6937d4Lennart Poettering assert(argc >= 0);
0d4ad91dd4fc831c31a9775b0eadf97fea6cd7f6Alin Rauta assert(argv);
9085f64a6694f2928c79fcce365edb1dca6937d4Lennart Poettering
0d4ad91dd4fc831c31a9775b0eadf97fea6cd7f6Alin Rauta left = argc - optind;
9085f64a6694f2928c79fcce365edb1dca6937d4Lennart Poettering
0d4ad91dd4fc831c31a9775b0eadf97fea6cd7f6Alin Rauta if (left <= 0)
9085f64a6694f2928c79fcce365edb1dca6937d4Lennart Poettering /* Special rule: no arguments means "list" */
0d4ad91dd4fc831c31a9775b0eadf97fea6cd7f6Alin Rauta i = 0;
9085f64a6694f2928c79fcce365edb1dca6937d4Lennart Poettering else {
db73295accbec0c6513817f0a64a92018592bb26Lennart Poettering if (streq(argv[optind], "help")) {
888943fc6246b2917168fff59380b58b678ba157Lennart Poettering help();
db73295accbec0c6513817f0a64a92018592bb26Lennart Poettering return 0;
888943fc6246b2917168fff59380b58b678ba157Lennart Poettering }
888943fc6246b2917168fff59380b58b678ba157Lennart Poettering
888943fc6246b2917168fff59380b58b678ba157Lennart Poettering for (i = 0; i < ELEMENTSOF(verbs); i++)
888943fc6246b2917168fff59380b58b678ba157Lennart Poettering if (streq(argv[optind], verbs[i].verb))
0d4ad91dd4fc831c31a9775b0eadf97fea6cd7f6Alin Rauta break;
888943fc6246b2917168fff59380b58b678ba157Lennart Poettering
0d4ad91dd4fc831c31a9775b0eadf97fea6cd7f6Alin Rauta if (i >= ELEMENTSOF(verbs)) {
db73295accbec0c6513817f0a64a92018592bb26Lennart Poettering log_error("Unknown operation %s", argv[optind]);
9085f64a6694f2928c79fcce365edb1dca6937d4Lennart Poettering return -EINVAL;
9085f64a6694f2928c79fcce365edb1dca6937d4Lennart Poettering }
0d4ad91dd4fc831c31a9775b0eadf97fea6cd7f6Alin Rauta }
9085f64a6694f2928c79fcce365edb1dca6937d4Lennart Poettering
0d4ad91dd4fc831c31a9775b0eadf97fea6cd7f6Alin Rauta switch (verbs[i].argc_cmp) {
0d4ad91dd4fc831c31a9775b0eadf97fea6cd7f6Alin Rauta
9085f64a6694f2928c79fcce365edb1dca6937d4Lennart Poettering case EQUAL:
9085f64a6694f2928c79fcce365edb1dca6937d4Lennart Poettering if (left != verbs[i].argc) {
0d4ad91dd4fc831c31a9775b0eadf97fea6cd7f6Alin Rauta log_error("Invalid number of arguments.");
2301cb9fdb774d0a1b3d8f5e95c5d358721ccacbLennart Poettering return -EINVAL;
0d4ad91dd4fc831c31a9775b0eadf97fea6cd7f6Alin Rauta }
8eb9058dc1f99a5eb9b8726a978fcc0720837a10Lennart Poettering
8eb9058dc1f99a5eb9b8726a978fcc0720837a10Lennart Poettering break;
9085f64a6694f2928c79fcce365edb1dca6937d4Lennart Poettering
0d4ad91dd4fc831c31a9775b0eadf97fea6cd7f6Alin Rauta case MORE:
0d4ad91dd4fc831c31a9775b0eadf97fea6cd7f6Alin Rauta if (left < verbs[i].argc) {
0d4ad91dd4fc831c31a9775b0eadf97fea6cd7f6Alin Rauta log_error("Too few arguments.");
0d4ad91dd4fc831c31a9775b0eadf97fea6cd7f6Alin Rauta return -EINVAL;
0d4ad91dd4fc831c31a9775b0eadf97fea6cd7f6Alin Rauta }
0d4ad91dd4fc831c31a9775b0eadf97fea6cd7f6Alin Rauta
0d4ad91dd4fc831c31a9775b0eadf97fea6cd7f6Alin Rauta break;
9085f64a6694f2928c79fcce365edb1dca6937d4Lennart Poettering
64d6c22905e94b02e760747c6c143dc9893083d9Thomas Hindoe Paaboel Andersen case LESS:
64d6c22905e94b02e760747c6c143dc9893083d9Thomas Hindoe Paaboel Andersen if (left > verbs[i].argc) {
64d6c22905e94b02e760747c6c143dc9893083d9Thomas Hindoe Paaboel Andersen log_error("Too many arguments.");
8eb9058dc1f99a5eb9b8726a978fcc0720837a10Lennart Poettering return -EINVAL;
9085f64a6694f2928c79fcce365edb1dca6937d4Lennart Poettering }
9085f64a6694f2928c79fcce365edb1dca6937d4Lennart Poettering
9085f64a6694f2928c79fcce365edb1dca6937d4Lennart Poettering break;
266b538958932e6fc27dfce4917336e70e17e29eTom Gundersen
81fd1dd3a2cf4cc90a6898d562c9bb0fb238cbd7Tom Gundersen default:
1c4baffc1895809bae9ac36b670af90a4cb9cd7dTom Gundersen assert_not_reached("Unknown comparison operator.");
ee8c45689526ca973407cbb77bce7b96a062c40bLennart Poettering }
ee8c45689526ca973407cbb77bce7b96a062c40bLennart Poettering
ee8c45689526ca973407cbb77bce7b96a062c40bLennart Poettering return verbs[i].dispatch(argv + optind, left);
1c4baffc1895809bae9ac36b670af90a4cb9cd7dTom Gundersen}
f647962d64e844689f3e2acfce6102fc47e76df2Michal Schmidt
f647962d64e844689f3e2acfce6102fc47e76df2Michal Schmidtint main(int argc, char* argv[]) {
f7d68aa8c9430dfddee5f913f93b405a5d75723aLennart Poettering int r;
81fd1dd3a2cf4cc90a6898d562c9bb0fb238cbd7Tom Gundersen
81fd1dd3a2cf4cc90a6898d562c9bb0fb238cbd7Tom Gundersen log_parse_environment();
81fd1dd3a2cf4cc90a6898d562c9bb0fb238cbd7Tom Gundersen log_open();
69fb1176c403e437c4fba763ba242b540c73898fLennart Poettering
266b538958932e6fc27dfce4917336e70e17e29eTom Gundersen r = parse_argv(argc, argv);
ee8c45689526ca973407cbb77bce7b96a062c40bLennart Poettering if (r <= 0)
c627729fc49d59ffcecc09555a34d9dd139927ceLennart Poettering goto finish;
e92da1e5d0a3b38804e173af136ec7a076c7757eLennart Poettering
ee8c45689526ca973407cbb77bce7b96a062c40bLennart Poettering r = networkctl_main(argc, argv);
03cc0fd1431b82e59c11ae12a274c1f2df23169dLennart Poettering
e92da1e5d0a3b38804e173af136ec7a076c7757eLennart Poetteringfinish:
5323ead145304785121b72dcbc1c244303de7575Daniel Buch pager_close();
b1acce80cd60fe95f16df2f1ad23ff2ad82d08e5Lennart Poettering
b1acce80cd60fe95f16df2f1ad23ff2ad82d08e5Lennart Poettering return r < 0 ? EXIT_FAILURE : EXIT_SUCCESS;
b1acce80cd60fe95f16df2f1ad23ff2ad82d08e5Lennart Poettering}
03cc0fd1431b82e59c11ae12a274c1f2df23169dLennart Poettering