diff --git a/src/basic/format-util.c b/src/basic/format-util.c index e2c7b134d01..94501853a15 100644 --- a/src/basic/format-util.c +++ b/src/basic/format-util.c @@ -3,23 +3,43 @@ #include "format-util.h" #include "memory-util.h" #include "stdio-util.h" +#include "strxcpyx.h" + +assert_cc(STRLEN("%") + DECIMAL_STR_MAX(int) <= IF_NAMESIZE); +int format_ifname_full(int ifindex, FormatIfnameFlag flag, char buf[static IF_NAMESIZE]) { + if (ifindex <= 0) + return -EINVAL; -assert_cc(DECIMAL_STR_MAX(int) + 1 <= IF_NAMESIZE + 1); -char *format_ifname_full(int ifindex, char buf[static IF_NAMESIZE + 1], FormatIfnameFlag flag) { - /* Buffer is always cleared */ - memzero(buf, IF_NAMESIZE + 1); if (if_indextoname(ifindex, buf)) - return buf; + return 0; if (!FLAGS_SET(flag, FORMAT_IFNAME_IFINDEX)) - return NULL; + return -errno; if (FLAGS_SET(flag, FORMAT_IFNAME_IFINDEX_WITH_PERCENT)) - assert(snprintf_ok(buf, IF_NAMESIZE + 1, "%%%d", ifindex)); + assert(snprintf_ok(buf, IF_NAMESIZE, "%%%d", ifindex)); else - assert(snprintf_ok(buf, IF_NAMESIZE + 1, "%d", ifindex)); + assert(snprintf_ok(buf, IF_NAMESIZE, "%d", ifindex)); - return buf; + return 0; +} + +int format_ifname_full_alloc(int ifindex, FormatIfnameFlag flag, char **ret) { + char buf[IF_NAMESIZE], *copy; + int r; + + assert(ret); + + r = format_ifname_full(ifindex, flag, buf); + if (r < 0) + return r; + + copy = strdup(buf); + if (!copy) + return -ENOMEM; + + *ret = copy; + return 0; } char *format_bytes_full(char *buf, size_t l, uint64_t t, FormatBytesFlag flag) { diff --git a/src/basic/format-util.h b/src/basic/format-util.h index 579f2318975..7dd422b9874 100644 --- a/src/basic/format-util.h +++ b/src/basic/format-util.h @@ -61,10 +61,23 @@ typedef enum { FORMAT_IFNAME_IFINDEX_WITH_PERCENT = (1 << 1) | FORMAT_IFNAME_IFINDEX, } FormatIfnameFlag; -char *format_ifname_full(int ifindex, char buf[static IF_NAMESIZE + 1], FormatIfnameFlag flag); -static inline char *format_ifname(int ifindex, char buf[static IF_NAMESIZE + 1]) { - return format_ifname_full(ifindex, buf, 0); +int format_ifname_full(int ifindex, FormatIfnameFlag flag, char buf[static IF_NAMESIZE]); +int format_ifname_full_alloc(int ifindex, FormatIfnameFlag flag, char **ret); + +static inline int format_ifname(int ifindex, char buf[static IF_NAMESIZE]) { + return format_ifname_full(ifindex, 0, buf); } +static inline int format_ifname_alloc(int ifindex, char **ret) { + return format_ifname_full_alloc(ifindex, 0, ret); +} + +static inline char *_format_ifname_full(int ifindex, FormatIfnameFlag flag, char buf[static IF_NAMESIZE]) { + (void) format_ifname_full(ifindex, flag, buf); + return buf; +} + +#define FORMAT_IFNAME_FULL(index, flag) _format_ifname_full(index, flag, (char[IF_NAMESIZE]){}) +#define FORMAT_IFNAME(index) _format_ifname_full(index, 0, (char[IF_NAMESIZE]){}) typedef enum { FORMAT_BYTES_USE_IEC = 1 << 0, diff --git a/src/basic/socket-util.c b/src/basic/socket-util.c index b5defd10f64..1e66f8700bc 100644 --- a/src/basic/socket-util.c +++ b/src/basic/socket-util.c @@ -455,23 +455,23 @@ int sockaddr_pretty( if (r < 0) return -ENOMEM; } else { - char a[INET6_ADDRSTRLEN], ifname[IF_NAMESIZE + 1]; + char a[INET6_ADDRSTRLEN]; inet_ntop(AF_INET6, &sa->in6.sin6_addr, a, sizeof(a)); - if (sa->in6.sin6_scope_id != 0) - format_ifname_full(sa->in6.sin6_scope_id, ifname, FORMAT_IFNAME_IFINDEX); if (include_port) { - r = asprintf(&p, + if (asprintf(&p, "[%s]:%u%s%s", a, be16toh(sa->in6.sin6_port), sa->in6.sin6_scope_id != 0 ? "%" : "", - sa->in6.sin6_scope_id != 0 ? ifname : ""); - if (r < 0) + FORMAT_IFNAME_FULL(sa->in6.sin6_scope_id, FORMAT_IFNAME_IFINDEX)) < 0) return -ENOMEM; } else { - p = sa->in6.sin6_scope_id != 0 ? strjoin(a, "%", ifname) : strdup(a); + if (sa->in6.sin6_scope_id != 0) + p = strjoin(a, "%", FORMAT_IFNAME_FULL(sa->in6.sin6_scope_id, FORMAT_IFNAME_IFINDEX)); + else + p = strdup(a); if (!p) return -ENOMEM; } @@ -1233,7 +1233,7 @@ int socket_bind_to_ifname(int fd, const char *ifname) { } int socket_bind_to_ifindex(int fd, int ifindex) { - char ifname[IF_NAMESIZE + 1]; + char ifname[IF_NAMESIZE]; int r; assert(fd >= 0); @@ -1251,8 +1251,9 @@ int socket_bind_to_ifindex(int fd, int ifindex) { return r; /* Fall back to SO_BINDTODEVICE on kernels < 5.0 which didn't have SO_BINDTOIFINDEX */ - if (!format_ifname(ifindex, ifname)) - return -errno; + r = format_ifname(ifindex, ifname); + if (r < 0) + return r; return socket_bind_to_ifname(fd, ifname); } diff --git a/src/libsystemd-network/network-common.c b/src/libsystemd-network/network-common.c index 9bc0da96cda..c8f3305b190 100644 --- a/src/libsystemd-network/network-common.c +++ b/src/libsystemd-network/network-common.c @@ -2,11 +2,8 @@ #include "format-util.h" #include "network-common.h" -#include "string-util.h" const char *get_ifname(int ifindex, char **ifname) { - char buf[IF_NAMESIZE + 1]; - assert(ifname); /* This sets ifname only when it is not set yet. */ @@ -14,11 +11,8 @@ const char *get_ifname(int ifindex, char **ifname) { if (*ifname) return *ifname; - if (ifindex <= 0) + if (format_ifname_alloc(ifindex, ifname) < 0) return NULL; - if (!format_ifname(ifindex, buf)) - return NULL; - - return *ifname = strdup(buf); + return *ifname; } diff --git a/src/libsystemd/sd-device/sd-device.c b/src/libsystemd/sd-device/sd-device.c index b9268dfcd19..7e11ea2d39e 100644 --- a/src/libsystemd/sd-device/sd-device.c +++ b/src/libsystemd/sd-device/sd-device.c @@ -284,12 +284,12 @@ _public_ int sd_device_new_from_ifname(sd_device **ret, const char *ifname) { } _public_ int sd_device_new_from_ifindex(sd_device **ret, int ifindex) { - char ifname[IF_NAMESIZE + 1]; + char ifname[IF_NAMESIZE]; assert_return(ret, -EINVAL); assert_return(ifindex > 0, -EINVAL); - if (!format_ifname(ifindex, ifname)) + if (format_ifname(ifindex, ifname) < 0) return -ENODEV; return device_new_from_main_ifname(ret, ifname); diff --git a/src/libsystemd/sd-netlink/netlink-util.c b/src/libsystemd/sd-netlink/netlink-util.c index 886bb48210a..49249ca6722 100644 --- a/src/libsystemd/sd-netlink/netlink-util.c +++ b/src/libsystemd/sd-netlink/netlink-util.c @@ -12,7 +12,7 @@ int rtnl_set_link_name(sd_netlink **rtnl, int ifindex, const char *name) { _cleanup_(sd_netlink_message_unrefp) sd_netlink_message *message = NULL; _cleanup_strv_free_ char **alternative_names = NULL; - char old_name[IF_NAMESIZE + 1] = {}; + char old_name[IF_NAMESIZE] = {}; int r; assert(rtnl); @@ -33,7 +33,9 @@ int rtnl_set_link_name(sd_netlink **rtnl, int ifindex, const char *name) { return log_debug_errno(r, "Failed to remove '%s' from alternative names on network interface %i: %m", name, ifindex); - format_ifname(ifindex, old_name); + r = format_ifname(ifindex, old_name); + if (r < 0) + return log_debug_errno(r, "Failed to get current name of network interface %i: %m", ifindex); } r = sd_rtnl_message_new_link(*rtnl, &message, RTM_SETLINK, ifindex); diff --git a/src/machine/machinectl.c b/src/machine/machinectl.c index c3a2384f150..d18374dda02 100644 --- a/src/machine/machinectl.c +++ b/src/machine/machinectl.c @@ -557,9 +557,9 @@ static void print_machine_status_info(sd_bus *bus, MachineStatusInfo *i) { fputs("\t Iface:", stdout); for (size_t c = 0; c < i->n_netif; c++) { - char name[IF_NAMESIZE+1]; + char name[IF_NAMESIZE]; - if (format_ifname(i->netif[c], name)) { + if (format_ifname(i->netif[c], name) >= 0) { fputc(' ', stdout); fputs(name, stdout); diff --git a/src/network/networkctl.c b/src/network/networkctl.c index d4a7da9f71f..32332ac0ba7 100644 --- a/src/network/networkctl.c +++ b/src/network/networkctl.c @@ -1044,7 +1044,6 @@ static int dump_gateways( for (int i = 0; i < n; i++) { _cleanup_free_ char *gateway = NULL, *description = NULL; - char name[IF_NAMESIZE+1]; r = in_addr_to_string(local[i].family, &local[i].address, &gateway); if (r < 0) @@ -1063,7 +1062,7 @@ static int dump_gateways( r = strv_extendf(&buf, "%s%s%s", gateway, ifindex <= 0 ? " on " : "", - ifindex <= 0 ? format_ifname_full(local[i].ifindex, name, FORMAT_IFNAME_IFINDEX_WITH_PERCENT) : ""); + ifindex <= 0 ? FORMAT_IFNAME_FULL(local[i].ifindex, FORMAT_IFNAME_IFINDEX_WITH_PERCENT) : ""); if (r < 0) return log_oom(); } @@ -1094,7 +1093,6 @@ static int dump_addresses( for (int i = 0; i < n; i++) { _cleanup_free_ char *pretty = NULL; - char name[IF_NAMESIZE+1]; r = in_addr_to_string(local[i].family, &local[i].address, &pretty); if (r < 0) @@ -1118,7 +1116,7 @@ static int dump_addresses( r = strv_extendf(&buf, "%s%s%s", pretty, ifindex <= 0 ? " on " : "", - ifindex <= 0 ? format_ifname_full(local[i].ifindex, name, FORMAT_IFNAME_IFINDEX_WITH_PERCENT) : ""); + ifindex <= 0 ? FORMAT_IFNAME_FULL(local[i].ifindex, FORMAT_IFNAME_IFINDEX_WITH_PERCENT) : ""); if (r < 0) return log_oom(); } @@ -2682,12 +2680,9 @@ static int link_up_down(int argc, char *argv[], void *userdata) { SET_FOREACH(p, indexes) { index = PTR_TO_INT(p); r = link_up_down_send_message(rtnl, argv[0], index); - if (r < 0) { - char ifname[IF_NAMESIZE + 1]; - + if (r < 0) return log_error_errno(r, "Failed to bring %s interface %s: %m", - argv[0], format_ifname_full(index, ifname, FORMAT_IFNAME_IFINDEX)); - } + argv[0], FORMAT_IFNAME_FULL(index, FORMAT_IFNAME_IFINDEX)); } return r; @@ -2720,12 +2715,9 @@ static int link_delete(int argc, char *argv[], void *userdata) { SET_FOREACH(p, indexes) { index = PTR_TO_INT(p); r = link_delete_send_message(rtnl, index); - if (r < 0) { - char ifname[IF_NAMESIZE + 1]; - + if (r < 0) return log_error_errno(r, "Failed to delete interface %s: %m", - format_ifname_full(index, ifname, FORMAT_IFNAME_IFINDEX)); - } + FORMAT_IFNAME_FULL(index, FORMAT_IFNAME_IFINDEX)); } return r; @@ -2844,12 +2836,9 @@ static int verb_reconfigure(int argc, char *argv[], void *userdata) { SET_FOREACH(p, indexes) { index = PTR_TO_INT(p); r = bus_call_method(bus, bus_network_mgr, "ReconfigureLink", &error, NULL, "i", index); - if (r < 0) { - char ifname[IF_NAMESIZE + 1]; - + if (r < 0) return log_error_errno(r, "Failed to reconfigure network interface %s: %m", - format_ifname_full(index, ifname, FORMAT_IFNAME_IFINDEX)); - } + FORMAT_IFNAME_FULL(index, FORMAT_IFNAME_IFINDEX)); } return 0; diff --git a/src/network/networkd-link.c b/src/network/networkd-link.c index 467f58873cd..327815def51 100644 --- a/src/network/networkd-link.c +++ b/src/network/networkd-link.c @@ -2212,7 +2212,7 @@ static int link_update_alternative_names(Link *link, sd_netlink_message *message } static int link_update_name(Link *link, sd_netlink_message *message) { - char ifname_from_index[IF_NAMESIZE + 1]; + char ifname_from_index[IF_NAMESIZE]; const char *ifname; int r; @@ -2229,8 +2229,9 @@ static int link_update_name(Link *link, sd_netlink_message *message) { if (streq(ifname, link->ifname)) return 0; - if (!format_ifname(link->ifindex, ifname_from_index)) - return log_link_debug_errno(link, SYNTHETIC_ERRNO(ENXIO), "Could not get interface name for index %i.", link->ifindex); + r = format_ifname(link->ifindex, ifname_from_index); + if (r < 0) + return log_link_debug_errno(link, r, "Could not get interface name for index %i.", link->ifindex); if (!streq(ifname, ifname_from_index)) { log_link_debug(link, "New interface name '%s' received from the kernel does not correspond " diff --git a/src/resolve/resolvectl.c b/src/resolve/resolvectl.c index 076dbe8cd96..c4d9bf58555 100644 --- a/src/resolve/resolvectl.c +++ b/src/resolve/resolvectl.c @@ -187,17 +187,19 @@ static void print_source(uint64_t flags, usec_t rtt) { } static void print_ifindex_comment(int printed_so_far, int ifindex) { - char ifname[IF_NAMESIZE + 1]; + char ifname[IF_NAMESIZE]; + int r; if (ifindex <= 0) return; - if (!format_ifname(ifindex, ifname)) - log_warning_errno(errno, "Failed to resolve interface name for index %i, ignoring: %m", ifindex); - else - printf("%*s%s-- link: %s%s", - 60 > printed_so_far ? 60 - printed_so_far : 0, " ", /* Align comment to the 60th column */ - ansi_grey(), ifname, ansi_normal()); + r = format_ifname(ifindex, ifname); + if (r < 0) + return (void) log_warning_errno(r, "Failed to resolve interface name for index %i, ignoring: %m", ifindex); + + printf("%*s%s-- link: %s%s", + 60 > printed_so_far ? 60 - printed_so_far : 0, " ", /* Align comment to the 60th column */ + ansi_grey(), ifname, ansi_normal()); } static int resolve_host(sd_bus *bus, const char *name) { @@ -1555,15 +1557,16 @@ static int status_ifindex(sd_bus *bus, int ifindex, const char *name, StatusMode _cleanup_(link_info_clear) LinkInfo link_info = {}; _cleanup_(table_unrefp) Table *table = NULL; _cleanup_free_ char *p = NULL; - char ifi[DECIMAL_STR_MAX(int)], ifname[IF_NAMESIZE + 1] = ""; + char ifi[DECIMAL_STR_MAX(int)], ifname[IF_NAMESIZE]; int r; assert(bus); assert(ifindex > 0); if (!name) { - if (!format_ifname(ifindex, ifname)) - return log_error_errno(errno, "Failed to resolve interface name for %i: %m", ifindex); + r = format_ifname(ifindex, ifname); + if (r < 0) + return log_error_errno(r, "Failed to resolve interface name for %i: %m", ifindex); name = ifname; } diff --git a/src/resolve/resolved-dns-cache.c b/src/resolve/resolved-dns-cache.c index c2fca1fabea..57e0ac3acc6 100644 --- a/src/resolve/resolved-dns-cache.c +++ b/src/resolve/resolved-dns-cache.c @@ -504,7 +504,6 @@ static int dns_cache_put_positive( if (DEBUG_LOGGING) { _cleanup_free_ char *t = NULL; - char ifname[IF_NAMESIZE + 1]; (void) in_addr_to_string(i->owner_family, &i->owner_address, &t); @@ -514,7 +513,7 @@ static int dns_cache_put_positive( i->shared_owner ? " shared" : "", dns_resource_key_to_string(i->key, key_str, sizeof key_str), (i->until - timestamp) / USEC_PER_SEC, - i->ifindex == 0 ? "*" : strna(format_ifname(i->ifindex, ifname)), + i->ifindex == 0 ? "*" : FORMAT_IFNAME(i->ifindex), af_to_name_short(i->owner_family), strna(t)); } diff --git a/src/shared/format-table.c b/src/shared/format-table.c index 806c24ad730..e524aa095e5 100644 --- a/src/shared/format-table.c +++ b/src/shared/format-table.c @@ -1665,16 +1665,9 @@ static const char *table_data_format(Table *t, TableData *d, bool avoid_uppercas case TABLE_IFINDEX: { _cleanup_free_ char *p = NULL; - char name[IF_NAMESIZE + 1]; - if (format_ifname(d->ifindex, name)) { - p = strdup(name); - if (!p) - return NULL; - } else { - if (asprintf(&p, "%i" , d->ifindex) < 0) - return NULL; - } + if (format_ifname_full_alloc(d->ifindex, FORMAT_IFNAME_IFINDEX, &p) < 0) + return NULL; d->formatted = TAKE_PTR(p); break; diff --git a/src/test/test-nss-hosts.c b/src/test/test-nss-hosts.c index f9c0bd6ff9e..01cbff9b834 100644 --- a/src/test/test-nss-hosts.c +++ b/src/test/test-nss-hosts.c @@ -41,14 +41,12 @@ static const char* af_to_string(int family, char *buf, size_t buf_len) { } static int print_gaih_addrtuples(const struct gaih_addrtuple *tuples) { - int n = 0; + int r, n = 0; for (const struct gaih_addrtuple *it = tuples; it; it = it->next) { _cleanup_free_ char *a = NULL; union in_addr_union u; - int r; char family_name[DECIMAL_STR_MAX(int)]; - char ifname[IF_NAMESIZE + 1]; memcpy(&u, it->addr, 16); r = in_addr_to_string(it->family, &u, &a); @@ -56,21 +54,13 @@ static int print_gaih_addrtuples(const struct gaih_addrtuple *tuples) { if (r == -EAFNOSUPPORT) assert_se(a = hexmem(it->addr, 16)); - if (it->scopeid == 0) - goto numerical_index; - - if (!format_ifname(it->scopeid, ifname)) { - log_warning_errno(errno, "if_indextoname(%d) failed: %m", it->scopeid); - numerical_index: - xsprintf(ifname, "%i", it->scopeid); - }; - - log_info(" \"%s\" %s %s %%%s", + log_info(" \"%s\" %s %s %s", it->name, af_to_string(it->family, family_name, sizeof family_name), a, - ifname); - n ++; + FORMAT_IFNAME_FULL(it->scopeid, FORMAT_IFNAME_IFINDEX_WITH_PERCENT)); + + n++; } return n; }