networkctl.c revision 9085f64a6694f2928c79fcce365edb1dca6937d4
4ba93280223ceb5de1bcedb196c38252f334521aLennart Poettering/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
4ba93280223ceb5de1bcedb196c38252f334521aLennart Poettering This file is part of systemd.
4ba93280223ceb5de1bcedb196c38252f334521aLennart Poettering Copyright 2014 Lennart Poettering
4ba93280223ceb5de1bcedb196c38252f334521aLennart Poettering systemd is free software; you can redistribute it and/or modify it
4ba93280223ceb5de1bcedb196c38252f334521aLennart Poettering under the terms of the GNU Lesser General Public License as published by
4ba93280223ceb5de1bcedb196c38252f334521aLennart Poettering the Free Software Foundation; either version 2.1 of the License, or
4ba93280223ceb5de1bcedb196c38252f334521aLennart Poettering (at your option) any later version.
4ba93280223ceb5de1bcedb196c38252f334521aLennart Poettering systemd is distributed in the hope that it will be useful, but
4ba93280223ceb5de1bcedb196c38252f334521aLennart Poettering WITHOUT ANY WARRANTY; without even the implied warranty of
4ba93280223ceb5de1bcedb196c38252f334521aLennart Poettering MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
4ba93280223ceb5de1bcedb196c38252f334521aLennart Poettering Lesser General Public License for more details.
4ba93280223ceb5de1bcedb196c38252f334521aLennart Poettering You should have received a copy of the GNU Lesser General Public License
4ba93280223ceb5de1bcedb196c38252f334521aLennart Poettering along with systemd; If not, see <http://www.gnu.org/licenses/>.
023fb90b83871a15ef7f57e8cd126e3426f99b9eLennart Poetteringstatic bool arg_no_pager = false;
023fb90b83871a15ef7f57e8cd126e3426f99b9eLennart Poetteringstatic bool arg_legend = true;
023fb90b83871a15ef7f57e8cd126e3426f99b9eLennart Poetteringstatic bool arg_all = false;
023fb90b83871a15ef7f57e8cd126e3426f99b9eLennart Poetteringstatic void pager_open_if_enabled(void) {
023fb90b83871a15ef7f57e8cd126e3426f99b9eLennart Poetteringstatic int link_get_type_string(int iftype, struct udev_device *d, char **ret) {
023fb90b83871a15ef7f57e8cd126e3426f99b9eLennart Poettering const char *t;
023fb90b83871a15ef7f57e8cd126e3426f99b9eLennart Poettering /* WLANs have iftype ARPHRD_ETHER, but we want
023fb90b83871a15ef7f57e8cd126e3426f99b9eLennart Poettering * to show a more useful type string for
04d39279245834494baccfdb9349db8bf80abd13Lennart Poetteringstatic int list_links(char **args, unsigned n) {
04d39279245834494baccfdb9349db8bf80abd13Lennart Poettering _cleanup_rtnl_message_unref_ sd_rtnl_message *req = NULL, *reply = NULL;
04d39279245834494baccfdb9349db8bf80abd13Lennart Poettering _cleanup_udev_unref_ struct udev *udev = NULL;
04d39279245834494baccfdb9349db8bf80abd13Lennart Poettering _cleanup_rtnl_unref_ sd_rtnl *rtnl = NULL;
023fb90b83871a15ef7f57e8cd126e3426f99b9eLennart Poettering unsigned c = 0;
023fb90b83871a15ef7f57e8cd126e3426f99b9eLennart Poettering log_error("Failed to connect to netlink: %s", strerror(-r));
023fb90b83871a15ef7f57e8cd126e3426f99b9eLennart Poettering log_error("Failed to connect to udev: %m");
023fb90b83871a15ef7f57e8cd126e3426f99b9eLennart Poettering r = sd_rtnl_message_new_link(rtnl, &req, RTM_GETLINK, 0);
023fb90b83871a15ef7f57e8cd126e3426f99b9eLennart Poettering r = sd_rtnl_message_request_dump(req, true);
023fb90b83871a15ef7f57e8cd126e3426f99b9eLennart Poettering log_error("Failed to enumerate links: %s", strerror(-r));
023fb90b83871a15ef7f57e8cd126e3426f99b9eLennart Poettering printf("%3s %-16s %-10s %-10s %-10s\n", "IDX", "LINK", "TYPE", "STATE", "OPERATIONAL");
023fb90b83871a15ef7f57e8cd126e3426f99b9eLennart Poettering for (i = reply; i; i = sd_rtnl_message_next(i)) {
023fb90b83871a15ef7f57e8cd126e3426f99b9eLennart Poettering _cleanup_free_ char *state = NULL, *operational_state = NULL;
023fb90b83871a15ef7f57e8cd126e3426f99b9eLennart Poettering _cleanup_udev_device_unref_ struct udev_device *d = NULL;
023fb90b83871a15ef7f57e8cd126e3426f99b9eLennart Poettering r = sd_rtnl_message_link_get_ifindex(i, &ifindex);
023fb90b83871a15ef7f57e8cd126e3426f99b9eLennart Poettering r = sd_rtnl_message_read_string(i, IFLA_IFNAME, &name);
023fb90b83871a15ef7f57e8cd126e3426f99b9eLennart Poettering r = sd_rtnl_message_link_get_type(i, &iftype);
023fb90b83871a15ef7f57e8cd126e3426f99b9eLennart Poettering sd_network_get_link_state(ifindex, &state);
023fb90b83871a15ef7f57e8cd126e3426f99b9eLennart Poettering sd_network_get_link_operational_state(ifindex, &operational_state);
023fb90b83871a15ef7f57e8cd126e3426f99b9eLennart Poettering d = udev_device_new_from_device_id(udev, devid);
4ba93280223ceb5de1bcedb196c38252f334521aLennart Poettering printf("%3i %-16s %-10s %-10s %-10s\n", ifindex, name, strna(t), strna(state), strna(operational_state));
023fb90b83871a15ef7f57e8cd126e3426f99b9eLennart Poetteringstatic int dump_addresses(sd_rtnl *rtnl, const char *prefix, int ifindex) {
023fb90b83871a15ef7f57e8cd126e3426f99b9eLennart Poettering _cleanup_free_ struct local_address *local = NULL;
04d39279245834494baccfdb9349db8bf80abd13Lennart Poettering n = local_addresses(rtnl, ifindex, &local);
023fb90b83871a15ef7f57e8cd126e3426f99b9eLennart Poettering for (i = 0; i < n; i++) {
4ba93280223ceb5de1bcedb196c38252f334521aLennart Poettering r = in_addr_to_string(local[i].family, &local[i].address, &pretty);
023fb90b83871a15ef7f57e8cd126e3426f99b9eLennart Poetteringstatic void dump_list(const char *prefix, char **l) {
023fb90b83871a15ef7f57e8cd126e3426f99b9eLennart Poetteringstatic int link_status_one(sd_rtnl *rtnl, struct udev *udev, const char *name) {
023fb90b83871a15ef7f57e8cd126e3426f99b9eLennart Poettering _cleanup_strv_free_ char **dns = NULL, **ntp = NULL;
023fb90b83871a15ef7f57e8cd126e3426f99b9eLennart Poettering _cleanup_free_ char *state = NULL, *operational_state = NULL;
023fb90b83871a15ef7f57e8cd126e3426f99b9eLennart Poettering _cleanup_rtnl_message_unref_ sd_rtnl_message *req = NULL, *reply = NULL;
4ba93280223ceb5de1bcedb196c38252f334521aLennart Poettering _cleanup_udev_device_unref_ struct udev_device *d = NULL;
023fb90b83871a15ef7f57e8cd126e3426f99b9eLennart Poettering const char *driver = NULL, *path = NULL, *vendor = NULL, *model = NULL;
023fb90b83871a15ef7f57e8cd126e3426f99b9eLennart Poettering if (safe_atoi(name, &ifindex) >= 0 && ifindex > 0)
023fb90b83871a15ef7f57e8cd126e3426f99b9eLennart Poettering r = sd_rtnl_message_new_link(rtnl, &req, RTM_GETLINK, ifindex);
04d39279245834494baccfdb9349db8bf80abd13Lennart Poettering r = sd_rtnl_message_new_link(rtnl, &req, RTM_GETLINK, 0);
023fb90b83871a15ef7f57e8cd126e3426f99b9eLennart Poettering r = sd_rtnl_message_append_string(req, IFLA_IFNAME, name);
04d39279245834494baccfdb9349db8bf80abd13Lennart Poettering log_error("Failed to query link: %s", strerror(-r));
023fb90b83871a15ef7f57e8cd126e3426f99b9eLennart Poettering r = sd_rtnl_message_link_get_ifindex(reply, &ifindex);
023fb90b83871a15ef7f57e8cd126e3426f99b9eLennart Poettering r = sd_rtnl_message_read_string(reply, IFLA_IFNAME, &name);
04d39279245834494baccfdb9349db8bf80abd13Lennart Poettering r = sd_rtnl_message_link_get_type(reply, &iftype);
023fb90b83871a15ef7f57e8cd126e3426f99b9eLennart Poettering have_mac = sd_rtnl_message_read_ether_addr(reply, IFLA_ADDRESS, &e) >= 0;
023fb90b83871a15ef7f57e8cd126e3426f99b9eLennart Poettering for (p = (uint8_t*) &e; p < (uint8_t*) &e + sizeof(e); p++)
023fb90b83871a15ef7f57e8cd126e3426f99b9eLennart Poettering if (*p != 0) {
023fb90b83871a15ef7f57e8cd126e3426f99b9eLennart Poettering sd_rtnl_message_read_u32(reply, IFLA_MTU, &mtu);
023fb90b83871a15ef7f57e8cd126e3426f99b9eLennart Poettering sd_network_get_link_state(ifindex, &state);
023fb90b83871a15ef7f57e8cd126e3426f99b9eLennart Poettering sd_network_get_link_operational_state(ifindex, &operational_state);
4ba93280223ceb5de1bcedb196c38252f334521aLennart Poettering d = udev_device_new_from_device_id(udev, devid);
04d39279245834494baccfdb9349db8bf80abd13Lennart Poettering driver = udev_device_get_property_value(d, "ID_NET_DRIVER");
04d39279245834494baccfdb9349db8bf80abd13Lennart Poettering path = udev_device_get_property_value(d, "ID_PATH");
023fb90b83871a15ef7f57e8cd126e3426f99b9eLennart Poettering vendor = udev_device_get_property_value(d, "ID_VENDOR_FROM_DATABASE");
023fb90b83871a15ef7f57e8cd126e3426f99b9eLennart Poettering vendor = udev_device_get_property_value(d, "ID_VENDOR");
023fb90b83871a15ef7f57e8cd126e3426f99b9eLennart Poettering model = udev_device_get_property_value(d, "ID_MODEL_FROM_DATABASE");
023fb90b83871a15ef7f57e8cd126e3426f99b9eLennart Poettering model = udev_device_get_property_value(d, "ID_MODEL");
023fb90b83871a15ef7f57e8cd126e3426f99b9eLennart Poettering " State: %s (%s)\n",
04d39279245834494baccfdb9349db8bf80abd13Lennart Poettering printf(" HW Address: %s\n", ether_ntoa(&e));
023fb90b83871a15ef7f57e8cd126e3426f99b9eLennart Poettering dump_addresses(rtnl, " Address: ", ifindex);
023fb90b83871a15ef7f57e8cd126e3426f99b9eLennart Poetteringstatic int link_status(char **args, unsigned n) {
023fb90b83871a15ef7f57e8cd126e3426f99b9eLennart Poettering _cleanup_udev_unref_ struct udev *udev = NULL;
023fb90b83871a15ef7f57e8cd126e3426f99b9eLennart Poettering _cleanup_rtnl_unref_ sd_rtnl *rtnl = NULL;
04d39279245834494baccfdb9349db8bf80abd13Lennart Poettering _cleanup_free_ char *operational_state = NULL;
04d39279245834494baccfdb9349db8bf80abd13Lennart Poettering _cleanup_strv_free_ char **dns = NULL, **ntp = NULL;
023fb90b83871a15ef7f57e8cd126e3426f99b9eLennart Poettering sd_network_get_operational_state(&operational_state);
04d39279245834494baccfdb9349db8bf80abd13Lennart Poettering printf(" State: %s\n", operational_state);
023fb90b83871a15ef7f57e8cd126e3426f99b9eLennart Poettering log_error("Failed to connect to netlink: %s", strerror(-r));
023fb90b83871a15ef7f57e8cd126e3426f99b9eLennart Poettering log_error("Failed to connect to udev: %m");
023fb90b83871a15ef7f57e8cd126e3426f99b9eLennart Poettering _cleanup_rtnl_message_unref_ sd_rtnl_message *req = NULL, *reply = NULL;
023fb90b83871a15ef7f57e8cd126e3426f99b9eLennart Poettering r = sd_rtnl_message_new_link(rtnl, &req, RTM_GETLINK, 0);
d60473c7ba32f2325a13f0357b23fd8e25609650Lennart Poettering r = sd_rtnl_message_request_dump(req, true);
const char *nn;
return rtnl_log_parse_error(r);
return rtnl_log_parse_error(r);
if (space)
space = true;
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();