From: Zbigniew Jędrzejewski-Szmek Date: Fri, 10 Jan 2020 16:22:37 +0000 (+0100) Subject: util-lib: move things that parse ifnames to shared/ X-Git-Tag: v245-rc1~138^2~5 X-Git-Url: http://git.ipfire.org/gitweb.cgi?a=commitdiff_plain;h=5c3fa98db68fbcf1f559b16238a5aba429a56448;p=thirdparty%2Fsystemd.git util-lib: move things that parse ifnames to shared/ In subsequent commits, calls to if_nametoindex() will be replaced by a wrapper that falls back to alternative name resolution over netlink. netlink support requires libsystemd (for sd-netlink), and we don't want to add any functions that require netlink in basic/. So stuff that calls if_nametoindex() for user supplied interface names, and everything that depends on that, needs to be moved. --- diff --git a/src/activate/activate.c b/src/activate/activate.c index 77b9a055ca2..5d796ab38df 100644 --- a/src/activate/activate.c +++ b/src/activate/activate.c @@ -17,6 +17,7 @@ #include "pretty-print.h" #include "process-util.h" #include "signal-util.h" +#include "socket-netlink.h" #include "socket-util.h" #include "string-util.h" #include "strv.h" diff --git a/src/basic/in-addr-util.c b/src/basic/in-addr-util.c index b6ca27e3e82..bfe855fb4b9 100644 --- a/src/basic/in-addr-util.c +++ b/src/basic/in-addr-util.c @@ -439,42 +439,6 @@ int in_addr_from_string_auto(const char *s, int *ret_family, union in_addr_union return -EINVAL; } -int in_addr_ifindex_from_string_auto(const char *s, int *family, union in_addr_union *ret_addr, int *ret_ifindex) { - _cleanup_free_ char *buf = NULL; - const char *suffix; - int r, ifindex = 0; - - assert(s); - assert(family); - assert(ret_addr); - - /* Similar to in_addr_from_string_auto() but also parses an optionally appended IPv6 zone suffix ("scope id") - * if one is found. */ - - suffix = strchr(s, '%'); - if (suffix) { - if (ret_ifindex) { - /* If we shall return the interface index, try to parse it */ - ifindex = parse_ifindex_or_ifname(suffix + 1); - if (ifindex < 0) - return ifindex; - } - - s = buf = strndup(s, suffix - s); - if (!buf) - return -ENOMEM; - } - - r = in_addr_from_string_auto(s, family, ret_addr); - if (r < 0) - return r; - - if (ret_ifindex) - *ret_ifindex = ifindex; - - return r; -} - unsigned char in4_addr_netmask_to_prefixlen(const struct in_addr *addr) { assert(addr); diff --git a/src/basic/in-addr-util.h b/src/basic/in-addr-util.h index 28afc7d86cf..ae2dad0bb1e 100644 --- a/src/basic/in-addr-util.h +++ b/src/basic/in-addr-util.h @@ -42,7 +42,7 @@ int in_addr_prefix_to_string(int family, const union in_addr_union *u, unsigned int in_addr_ifindex_to_string(int family, const union in_addr_union *u, int ifindex, char **ret); int in_addr_from_string(int family, const char *s, union in_addr_union *ret); int in_addr_from_string_auto(const char *s, int *ret_family, union in_addr_union *ret); -int in_addr_ifindex_from_string_auto(const char *s, int *family, union in_addr_union *ret, int *ifindex); + unsigned char in4_addr_netmask_to_prefixlen(const struct in_addr *addr); struct in_addr* in4_addr_prefixlen_to_netmask(struct in_addr *addr, unsigned char prefixlen); int in4_addr_default_prefixlen(const struct in_addr *addr, unsigned char *prefixlen); diff --git a/src/basic/socket-label.c b/src/basic/socket-label.c index 8c087268e4b..ec52d816536 100644 --- a/src/basic/socket-label.c +++ b/src/basic/socket-label.c @@ -134,31 +134,3 @@ int socket_address_listen( return r; } - -int make_socket_fd(int log_level, const char* address, int type, int flags) { - SocketAddress a; - int fd, r; - - r = socket_address_parse(&a, address); - if (r < 0) - return log_error_errno(r, "Failed to parse socket address \"%s\": %m", address); - - a.type = type; - - fd = socket_address_listen(&a, type | flags, SOMAXCONN, SOCKET_ADDRESS_DEFAULT, - NULL, false, false, false, 0755, 0644, NULL); - if (fd < 0 || log_get_max_level() >= log_level) { - _cleanup_free_ char *p = NULL; - - r = socket_address_print(&a, &p); - if (r < 0) - return log_error_errno(r, "socket_address_print(): %m"); - - if (fd < 0) - log_error_errno(fd, "Failed to listen on %s: %m", p); - else - log_full(log_level, "Listening on %s", p); - } - - return fd; -} diff --git a/src/basic/socket-util.c b/src/basic/socket-util.c index b482ca988ce..ad467ab8511 100644 --- a/src/basic/socket-util.c +++ b/src/basic/socket-util.c @@ -52,227 +52,6 @@ static const char* const socket_address_type_table[] = { DEFINE_STRING_TABLE_LOOKUP(socket_address_type, int); -int socket_address_parse(SocketAddress *a, const char *s) { - _cleanup_free_ char *n = NULL; - char *e; - int r; - - assert(a); - assert(s); - - *a = (SocketAddress) { - .type = SOCK_STREAM, - }; - - if (*s == '[') { - uint16_t port; - - /* IPv6 in [x:.....:z]:p notation */ - - e = strchr(s+1, ']'); - if (!e) - return -EINVAL; - - n = strndup(s+1, e-s-1); - if (!n) - return -ENOMEM; - - errno = 0; - if (inet_pton(AF_INET6, n, &a->sockaddr.in6.sin6_addr) <= 0) - return errno_or_else(EINVAL); - - e++; - if (*e != ':') - return -EINVAL; - - e++; - r = parse_ip_port(e, &port); - if (r < 0) - return r; - - a->sockaddr.in6.sin6_family = AF_INET6; - a->sockaddr.in6.sin6_port = htobe16(port); - a->size = sizeof(struct sockaddr_in6); - - } else if (*s == '/') { - /* AF_UNIX socket */ - - size_t l; - - l = strlen(s); - if (l >= sizeof(a->sockaddr.un.sun_path)) /* Note that we refuse non-NUL-terminated sockets when - * parsing (the kernel itself is less strict here in what it - * accepts) */ - return -EINVAL; - - a->sockaddr.un.sun_family = AF_UNIX; - memcpy(a->sockaddr.un.sun_path, s, l); - a->size = offsetof(struct sockaddr_un, sun_path) + l + 1; - - } else if (*s == '@') { - /* Abstract AF_UNIX socket */ - size_t l; - - l = strlen(s+1); - if (l >= sizeof(a->sockaddr.un.sun_path) - 1) /* Note that we refuse non-NUL-terminated sockets here - * when parsing, even though abstract namespace sockets - * explicitly allow embedded NUL bytes and don't consider - * them special. But it's simply annoying to debug such - * sockets. */ - return -EINVAL; - - a->sockaddr.un.sun_family = AF_UNIX; - memcpy(a->sockaddr.un.sun_path+1, s+1, l); - a->size = offsetof(struct sockaddr_un, sun_path) + 1 + l; - - } else if (startswith(s, "vsock:")) { - /* AF_VSOCK socket in vsock:cid:port notation */ - const char *cid_start = s + STRLEN("vsock:"); - unsigned port; - - e = strchr(cid_start, ':'); - if (!e) - return -EINVAL; - - r = safe_atou(e+1, &port); - if (r < 0) - return r; - - n = strndup(cid_start, e - cid_start); - if (!n) - return -ENOMEM; - - if (!isempty(n)) { - r = safe_atou(n, &a->sockaddr.vm.svm_cid); - if (r < 0) - return r; - } else - a->sockaddr.vm.svm_cid = VMADDR_CID_ANY; - - a->sockaddr.vm.svm_family = AF_VSOCK; - a->sockaddr.vm.svm_port = port; - a->size = sizeof(struct sockaddr_vm); - - } else { - uint16_t port; - - e = strchr(s, ':'); - if (e) { - r = parse_ip_port(e + 1, &port); - if (r < 0) - return r; - - n = strndup(s, e-s); - if (!n) - return -ENOMEM; - - /* IPv4 in w.x.y.z:p notation? */ - r = inet_pton(AF_INET, n, &a->sockaddr.in.sin_addr); - if (r < 0) - return -errno; - - if (r > 0) { - /* Gotcha, it's a traditional IPv4 address */ - a->sockaddr.in.sin_family = AF_INET; - a->sockaddr.in.sin_port = htobe16(port); - a->size = sizeof(struct sockaddr_in); - } else { - unsigned idx; - - if (strlen(n) > IF_NAMESIZE-1) - return -EINVAL; - - /* Uh, our last resort, an interface name */ - idx = if_nametoindex(n); - if (idx == 0) - return -EINVAL; - - a->sockaddr.in6.sin6_family = AF_INET6; - a->sockaddr.in6.sin6_port = htobe16(port); - a->sockaddr.in6.sin6_scope_id = idx; - a->sockaddr.in6.sin6_addr = in6addr_any; - a->size = sizeof(struct sockaddr_in6); - } - } else { - - /* Just a port */ - r = parse_ip_port(s, &port); - if (r < 0) - return r; - - if (socket_ipv6_is_supported()) { - a->sockaddr.in6.sin6_family = AF_INET6; - a->sockaddr.in6.sin6_port = htobe16(port); - a->sockaddr.in6.sin6_addr = in6addr_any; - a->size = sizeof(struct sockaddr_in6); - } else { - a->sockaddr.in.sin_family = AF_INET; - a->sockaddr.in.sin_port = htobe16(port); - a->sockaddr.in.sin_addr.s_addr = INADDR_ANY; - a->size = sizeof(struct sockaddr_in); - } - } - } - - return 0; -} - -int socket_address_parse_and_warn(SocketAddress *a, const char *s) { - SocketAddress b; - int r; - - /* Similar to socket_address_parse() but warns for IPv6 sockets when we don't support them. */ - - r = socket_address_parse(&b, s); - if (r < 0) - return r; - - if (!socket_ipv6_is_supported() && b.sockaddr.sa.sa_family == AF_INET6) { - log_warning("Binding to IPv6 address not available since kernel does not support IPv6."); - return -EAFNOSUPPORT; - } - - *a = b; - return 0; -} - -int socket_address_parse_netlink(SocketAddress *a, const char *s) { - _cleanup_free_ char *word = NULL; - unsigned group = 0; - int family, r; - - assert(a); - assert(s); - - zero(*a); - a->type = SOCK_RAW; - - r = extract_first_word(&s, &word, NULL, 0); - if (r < 0) - return r; - if (r == 0) - return -EINVAL; - - family = netlink_family_from_string(word); - if (family < 0) - return -EINVAL; - - if (!isempty(s)) { - r = safe_atou(s, &group); - if (r < 0) - return r; - } - - a->sockaddr.nl.nl_family = AF_NETLINK; - a->sockaddr.nl.nl_groups = group; - - a->type = SOCK_RAW; - a->size = sizeof(struct sockaddr_nl); - a->protocol = family; - - return 0; -} - int socket_address_verify(const SocketAddress *a, bool strict) { assert(a); @@ -482,32 +261,6 @@ bool socket_address_equal(const SocketAddress *a, const SocketAddress *b) { return true; } -bool socket_address_is(const SocketAddress *a, const char *s, int type) { - struct SocketAddress b; - - assert(a); - assert(s); - - if (socket_address_parse(&b, s) < 0) - return false; - - b.type = type; - - return socket_address_equal(a, &b); -} - -bool socket_address_is_netlink(const SocketAddress *a, const char *s) { - struct SocketAddress b; - - assert(a); - assert(s); - - if (socket_address_parse_netlink(&b, s) < 0) - return false; - - return socket_address_equal(a, &b); -} - const char* socket_address_get_path(const SocketAddress *a) { assert(a); diff --git a/src/basic/socket-util.h b/src/basic/socket-util.h index 17c20abc32f..24e12139516 100644 --- a/src/basic/socket-util.h +++ b/src/basic/socket-util.h @@ -41,6 +41,8 @@ union sockaddr_union { uint8_t un_buffer[sizeof(struct sockaddr_un) + 1]; }; +#define SUN_PATH_LEN (sizeof(((struct sockaddr_un){}).sun_path)) + typedef struct SocketAddress { union sockaddr_union sockaddr; @@ -68,12 +70,6 @@ typedef enum SocketAddressBindIPv6Only { const char* socket_address_type_to_string(int t) _const_; int socket_address_type_from_string(const char *s) _pure_; -int socket_address_parse(SocketAddress *a, const char *s); -int socket_address_parse_and_warn(SocketAddress *a, const char *s); -int socket_address_parse_netlink(SocketAddress *a, const char *s); -int socket_address_print(const SocketAddress *a, char **p); -int socket_address_verify(const SocketAddress *a, bool strict) _pure_; - int sockaddr_un_unlink(const struct sockaddr_un *sa); static inline int socket_address_unlink(const SocketAddress *a) { @@ -94,11 +90,9 @@ int socket_address_listen( mode_t directory_mode, mode_t socket_mode, const char *label); -int make_socket_fd(int log_level, const char* address, int type, int flags); - -bool socket_address_is(const SocketAddress *a, const char *s, int type); -bool socket_address_is_netlink(const SocketAddress *a, const char *s); +int socket_address_verify(const SocketAddress *a, bool strict) _pure_; +int socket_address_print(const SocketAddress *a, char **p); bool socket_address_matches_fd(const SocketAddress *a, int fd); bool socket_address_equal(const SocketAddress *a, const SocketAddress *b) _pure_; diff --git a/src/core/dbus-socket.c b/src/core/dbus-socket.c index 25d3d71391b..c8253c7940d 100644 --- a/src/core/dbus-socket.c +++ b/src/core/dbus-socket.c @@ -12,6 +12,7 @@ #include "parse-util.h" #include "path-util.h" #include "socket.h" +#include "socket-netlink.h" #include "socket-util.h" #include "string-util.h" #include "unit.h" diff --git a/src/core/load-fragment.c b/src/core/load-fragment.c index 1679e047dd7..3da78b30a4a 100644 --- a/src/core/load-fragment.c +++ b/src/core/load-fragment.c @@ -48,6 +48,7 @@ #endif #include "securebits-util.h" #include "signal-util.h" +#include "socket-netlink.h" #include "stat-util.h" #include "string-util.h" #include "strv.h" diff --git a/src/core/socket.c b/src/core/socket.c index c587eaebed5..633be683370 100644 --- a/src/core/socket.c +++ b/src/core/socket.c @@ -36,6 +36,7 @@ #include "signal-util.h" #include "smack-util.h" #include "socket.h" +#include "socket-netlink.h" #include "special.h" #include "string-table.h" #include "string-util.h" diff --git a/src/journal-remote/journal-remote-main.c b/src/journal-remote/journal-remote-main.c index ac2bf648d2a..88e42d3a984 100644 --- a/src/journal-remote/journal-remote-main.c +++ b/src/journal-remote/journal-remote-main.c @@ -17,6 +17,7 @@ #include "process-util.h" #include "rlimit-util.h" #include "signal-util.h" +#include "socket-netlink.h" #include "socket-util.h" #include "stat-util.h" #include "string-table.h" diff --git a/src/resolve/resolvectl.c b/src/resolve/resolvectl.c index 87ecd519d58..cabb3f6c699 100644 --- a/src/resolve/resolvectl.c +++ b/src/resolve/resolvectl.c @@ -16,7 +16,6 @@ #include "escape.h" #include "format-util.h" #include "gcrypt-util.h" -#include "in-addr-util.h" #include "main-func.h" #include "missing_network.h" #include "netlink-util.h" @@ -27,6 +26,7 @@ #include "resolvectl.h" #include "resolved-def.h" #include "resolved-dns-packet.h" +#include "socket-netlink.h" #include "string-table.h" #include "strv.h" #include "terminal-util.h" diff --git a/src/resolve/resolved-bus.c b/src/resolve/resolved-bus.c index 2c1aba911ac..ff6acb2eac1 100644 --- a/src/resolve/resolved-bus.c +++ b/src/resolve/resolved-bus.c @@ -12,6 +12,7 @@ #include "resolved-dnssd-bus.h" #include "resolved-dnssd.h" #include "resolved-link-bus.h" +#include "socket-netlink.h" #include "stdio-util.h" #include "strv.h" #include "user-util.h" diff --git a/src/resolve/resolved-etc-hosts.c b/src/resolve/resolved-etc-hosts.c index 6a23d2bb8e8..e6bf20db54f 100644 --- a/src/resolve/resolved-etc-hosts.c +++ b/src/resolve/resolved-etc-hosts.c @@ -9,6 +9,7 @@ #include "hostname-util.h" #include "resolved-dns-synthesize.h" #include "resolved-etc-hosts.h" +#include "socket-netlink.h" #include "string-util.h" #include "strv.h" #include "time-util.h" diff --git a/src/resolve/resolved-util.c b/src/resolve/resolved-util.c index 2f18f8c19d6..ac8df635135 100644 --- a/src/resolve/resolved-util.c +++ b/src/resolve/resolved-util.c @@ -1,9 +1,9 @@ /* SPDX-License-Identifier: LGPL-2.1+ */ #include "alloc-util.h" -#include "in-addr-util.h" #include "macro.h" #include "resolved-util.h" +#include "socket-netlink.h" int in_addr_ifindex_name_from_string_auto(const char *s, int *family, union in_addr_union *ret, int *ifindex, char **server_name) { _cleanup_free_ char *buf = NULL, *name = NULL; diff --git a/src/shared/meson.build b/src/shared/meson.build index 3b53ce1a757..08aa480b6c8 100644 --- a/src/shared/meson.build +++ b/src/shared/meson.build @@ -165,6 +165,8 @@ shared_sources = files(''' serialize.h sleep-config.c sleep-config.h + socket-netlink.c + socket-netlink.h spawn-ask-password-agent.c spawn-ask-password-agent.h spawn-polkit-agent.c diff --git a/src/shared/socket-netlink.c b/src/shared/socket-netlink.c new file mode 100644 index 00000000000..9f992d3e2f2 --- /dev/null +++ b/src/shared/socket-netlink.c @@ -0,0 +1,327 @@ +/* SPDX-License-Identifier: LGPL-2.1+ */ + +#include +#include +#include +#include + +#include "alloc-util.h" +#include "errno-util.h" +#include "extract-word.h" +#include "log.h" +#include "memory-util.h" +#include "parse-util.h" +#include "socket-netlink.h" +#include "socket-util.h" +#include "string-util.h" + +int socket_address_parse(SocketAddress *a, const char *s) { + _cleanup_free_ char *n = NULL; + char *e; + int r; + + assert(a); + assert(s); + + *a = (SocketAddress) { + .type = SOCK_STREAM, + }; + + if (*s == '[') { + uint16_t port; + + /* IPv6 in [x:.....:z]:p notation */ + + e = strchr(s+1, ']'); + if (!e) + return -EINVAL; + + n = strndup(s+1, e-s-1); + if (!n) + return -ENOMEM; + + errno = 0; + if (inet_pton(AF_INET6, n, &a->sockaddr.in6.sin6_addr) <= 0) + return errno_or_else(EINVAL); + + e++; + if (*e != ':') + return -EINVAL; + + e++; + r = parse_ip_port(e, &port); + if (r < 0) + return r; + + a->sockaddr.in6.sin6_family = AF_INET6; + a->sockaddr.in6.sin6_port = htobe16(port); + a->size = sizeof(struct sockaddr_in6); + + } else if (*s == '/') { + /* AF_UNIX socket */ + + size_t l; + + l = strlen(s); + if (l >= sizeof(a->sockaddr.un.sun_path)) /* Note that we refuse non-NUL-terminated sockets when + * parsing (the kernel itself is less strict here in what it + * accepts) */ + return -EINVAL; + + a->sockaddr.un.sun_family = AF_UNIX; + memcpy(a->sockaddr.un.sun_path, s, l); + a->size = offsetof(struct sockaddr_un, sun_path) + l + 1; + + } else if (*s == '@') { + /* Abstract AF_UNIX socket */ + size_t l; + + l = strlen(s+1); + if (l >= sizeof(a->sockaddr.un.sun_path) - 1) /* Note that we refuse non-NUL-terminated sockets here + * when parsing, even though abstract namespace sockets + * explicitly allow embedded NUL bytes and don't consider + * them special. But it's simply annoying to debug such + * sockets. */ + return -EINVAL; + + a->sockaddr.un.sun_family = AF_UNIX; + memcpy(a->sockaddr.un.sun_path+1, s+1, l); + a->size = offsetof(struct sockaddr_un, sun_path) + 1 + l; + + } else if (startswith(s, "vsock:")) { + /* AF_VSOCK socket in vsock:cid:port notation */ + const char *cid_start = s + STRLEN("vsock:"); + unsigned port; + + e = strchr(cid_start, ':'); + if (!e) + return -EINVAL; + + r = safe_atou(e+1, &port); + if (r < 0) + return r; + + n = strndup(cid_start, e - cid_start); + if (!n) + return -ENOMEM; + + if (!isempty(n)) { + r = safe_atou(n, &a->sockaddr.vm.svm_cid); + if (r < 0) + return r; + } else + a->sockaddr.vm.svm_cid = VMADDR_CID_ANY; + + a->sockaddr.vm.svm_family = AF_VSOCK; + a->sockaddr.vm.svm_port = port; + a->size = sizeof(struct sockaddr_vm); + + } else { + uint16_t port; + + e = strchr(s, ':'); + if (e) { + r = parse_ip_port(e + 1, &port); + if (r < 0) + return r; + + n = strndup(s, e-s); + if (!n) + return -ENOMEM; + + /* IPv4 in w.x.y.z:p notation? */ + r = inet_pton(AF_INET, n, &a->sockaddr.in.sin_addr); + if (r < 0) + return -errno; + + if (r > 0) { + /* Gotcha, it's a traditional IPv4 address */ + a->sockaddr.in.sin_family = AF_INET; + a->sockaddr.in.sin_port = htobe16(port); + a->size = sizeof(struct sockaddr_in); + } else { + unsigned idx; + + if (strlen(n) > IF_NAMESIZE-1) + return -EINVAL; + + /* Uh, our last resort, an interface name */ + idx = if_nametoindex(n); + if (idx == 0) + return -EINVAL; + + a->sockaddr.in6.sin6_family = AF_INET6; + a->sockaddr.in6.sin6_port = htobe16(port); + a->sockaddr.in6.sin6_scope_id = idx; + a->sockaddr.in6.sin6_addr = in6addr_any; + a->size = sizeof(struct sockaddr_in6); + } + } else { + + /* Just a port */ + r = parse_ip_port(s, &port); + if (r < 0) + return r; + + if (socket_ipv6_is_supported()) { + a->sockaddr.in6.sin6_family = AF_INET6; + a->sockaddr.in6.sin6_port = htobe16(port); + a->sockaddr.in6.sin6_addr = in6addr_any; + a->size = sizeof(struct sockaddr_in6); + } else { + a->sockaddr.in.sin_family = AF_INET; + a->sockaddr.in.sin_port = htobe16(port); + a->sockaddr.in.sin_addr.s_addr = INADDR_ANY; + a->size = sizeof(struct sockaddr_in); + } + } + } + + return 0; +} + +int socket_address_parse_and_warn(SocketAddress *a, const char *s) { + SocketAddress b; + int r; + + /* Similar to socket_address_parse() but warns for IPv6 sockets when we don't support them. */ + + r = socket_address_parse(&b, s); + if (r < 0) + return r; + + if (!socket_ipv6_is_supported() && b.sockaddr.sa.sa_family == AF_INET6) { + log_warning("Binding to IPv6 address not available since kernel does not support IPv6."); + return -EAFNOSUPPORT; + } + + *a = b; + return 0; +} + +int socket_address_parse_netlink(SocketAddress *a, const char *s) { + _cleanup_free_ char *word = NULL; + unsigned group = 0; + int family, r; + + assert(a); + assert(s); + + zero(*a); + a->type = SOCK_RAW; + + r = extract_first_word(&s, &word, NULL, 0); + if (r < 0) + return r; + if (r == 0) + return -EINVAL; + + family = netlink_family_from_string(word); + if (family < 0) + return -EINVAL; + + if (!isempty(s)) { + r = safe_atou(s, &group); + if (r < 0) + return r; + } + + a->sockaddr.nl.nl_family = AF_NETLINK; + a->sockaddr.nl.nl_groups = group; + + a->type = SOCK_RAW; + a->size = sizeof(struct sockaddr_nl); + a->protocol = family; + + return 0; +} + +bool socket_address_is(const SocketAddress *a, const char *s, int type) { + struct SocketAddress b; + + assert(a); + assert(s); + + if (socket_address_parse(&b, s) < 0) + return false; + + b.type = type; + + return socket_address_equal(a, &b); +} + +bool socket_address_is_netlink(const SocketAddress *a, const char *s) { + struct SocketAddress b; + + assert(a); + assert(s); + + if (socket_address_parse_netlink(&b, s) < 0) + return false; + + return socket_address_equal(a, &b); +} + +int make_socket_fd(int log_level, const char* address, int type, int flags) { + SocketAddress a; + int fd, r; + + r = socket_address_parse(&a, address); + if (r < 0) + return log_error_errno(r, "Failed to parse socket address \"%s\": %m", address); + + a.type = type; + + fd = socket_address_listen(&a, type | flags, SOMAXCONN, SOCKET_ADDRESS_DEFAULT, + NULL, false, false, false, 0755, 0644, NULL); + if (fd < 0 || log_get_max_level() >= log_level) { + _cleanup_free_ char *p = NULL; + + r = socket_address_print(&a, &p); + if (r < 0) + return log_error_errno(r, "socket_address_print(): %m"); + + if (fd < 0) + log_error_errno(fd, "Failed to listen on %s: %m", p); + else + log_full(log_level, "Listening on %s", p); + } + + return fd; +} + +int in_addr_ifindex_from_string_auto(const char *s, int *family, union in_addr_union *ret_addr, int *ret_ifindex) { + _cleanup_free_ char *buf = NULL; + const char *suffix; + int r, ifindex = 0; + + assert(s); + assert(family); + assert(ret_addr); + + /* Similar to in_addr_from_string_auto() but also parses an optionally appended IPv6 zone suffix ("scope id") + * if one is found. */ + + suffix = strchr(s, '%'); + if (suffix) { + if (ret_ifindex) { + /* If we shall return the interface index, try to parse it */ + ifindex = parse_ifindex_or_ifname(suffix + 1); + if (ifindex < 0) + return ifindex; + } + + s = buf = strndup(s, suffix - s); + if (!buf) + return -ENOMEM; + } + + r = in_addr_from_string_auto(s, family, ret_addr); + if (r < 0) + return r; + + if (ret_ifindex) + *ret_ifindex = ifindex; + + return r; +} diff --git a/src/shared/socket-netlink.h b/src/shared/socket-netlink.h new file mode 100644 index 00000000000..8808c589b77 --- /dev/null +++ b/src/shared/socket-netlink.h @@ -0,0 +1,17 @@ +/* SPDX-License-Identifier: LGPL-2.1+ */ +#pragma once + +#include "in-addr-util.h" +#include "macro.h" +#include "socket-util.h" + +int make_socket_fd(int log_level, const char* address, int type, int flags); + +int socket_address_parse(SocketAddress *a, const char *s); +int socket_address_parse_and_warn(SocketAddress *a, const char *s); +int socket_address_parse_netlink(SocketAddress *a, const char *s); + +bool socket_address_is(const SocketAddress *a, const char *s, int type); +bool socket_address_is_netlink(const SocketAddress *a, const char *s); + +int in_addr_ifindex_from_string_auto(const char *s, int *family, union in_addr_union *ret, int *ifindex); diff --git a/src/test/meson.build b/src/test/meson.build index 7e5a61a11e2..5df1366561d 100644 --- a/src/test/meson.build +++ b/src/test/meson.build @@ -362,6 +362,10 @@ tests += [ [], []], + [['src/test/test-socket-netlink.c'], + [], + []], + [['src/test/test-in-addr-util.c'], [], []], diff --git a/src/test/test-socket-netlink.c b/src/test/test-socket-netlink.c new file mode 100644 index 00000000000..0a2007f0b7e --- /dev/null +++ b/src/test/test-socket-netlink.c @@ -0,0 +1,227 @@ +/* SPDX-License-Identifier: LGPL-2.1+ */ + +#include "alloc-util.h" +#include "tests.h" +#include "socket-netlink.h" +#include "string-util.h" + +static void test_socket_address_parse_one(const char *in, int ret, int family, const char *expected) { + SocketAddress a; + _cleanup_free_ char *out = NULL; + int r; + + r = socket_address_parse(&a, in); + if (r >= 0) + assert_se(socket_address_print(&a, &out) >= 0); + + log_info("\"%s\" → %s → \"%s\" (expect \"%s\")", in, + r >= 0 ? "✓" : "✗", empty_to_dash(out), r >= 0 ? expected ?: in : "-"); + assert_se(r == ret); + if (r >= 0) { + assert_se(a.sockaddr.sa.sa_family == family); + assert_se(streq(out, expected ?: in)); + } +} + +static void test_socket_address_parse(void) { + log_info("/* %s */", __func__); + + test_socket_address_parse_one("junk", -EINVAL, 0, NULL); + test_socket_address_parse_one("192.168.1.1", -EINVAL, 0, NULL); + test_socket_address_parse_one(".168.1.1", -EINVAL, 0, NULL); + test_socket_address_parse_one("989.168.1.1", -EINVAL, 0, NULL); + test_socket_address_parse_one("192.168.1.1:65536", -ERANGE, 0, NULL); + test_socket_address_parse_one("192.168.1.1:0", -EINVAL, 0, NULL); + test_socket_address_parse_one("0", -EINVAL, 0, NULL); + test_socket_address_parse_one("65536", -ERANGE, 0, NULL); + + const int default_family = socket_ipv6_is_supported() ? AF_INET6 : AF_INET; + + test_socket_address_parse_one("65535", 0, default_family, "[::]:65535"); + + /* The checks below will pass even if ipv6 is disabled in + * kernel. The underlying glibc's inet_pton() is just a string + * parser and doesn't make any syscalls. */ + + test_socket_address_parse_one("[::1]", -EINVAL, 0, NULL); + test_socket_address_parse_one("[::1]8888", -EINVAL, 0, NULL); + test_socket_address_parse_one("::1", -EINVAL, 0, NULL); + test_socket_address_parse_one("[::1]:0", -EINVAL, 0, NULL); + test_socket_address_parse_one("[::1]:65536", -ERANGE, 0, NULL); + test_socket_address_parse_one("[a:b:1]:8888", -EINVAL, 0, NULL); + + test_socket_address_parse_one("8888", 0, default_family, "[::]:8888"); + test_socket_address_parse_one("[2001:0db8:0000:85a3:0000:0000:ac1f:8001]:8888", 0, AF_INET6, + "[2001:db8:0:85a3::ac1f:8001]:8888"); + test_socket_address_parse_one("[::1]:8888", 0, AF_INET6, NULL); + test_socket_address_parse_one("192.168.1.254:8888", 0, AF_INET, NULL); + test_socket_address_parse_one("/foo/bar", 0, AF_UNIX, NULL); + test_socket_address_parse_one("/", 0, AF_UNIX, NULL); + test_socket_address_parse_one("@abstract", 0, AF_UNIX, NULL); + + { + char aaa[SUN_PATH_LEN + 1] = "@"; + + memset(aaa + 1, 'a', SUN_PATH_LEN - 1); + char_array_0(aaa); + + test_socket_address_parse_one(aaa, -EINVAL, 0, NULL); + + aaa[SUN_PATH_LEN - 1] = '\0'; + test_socket_address_parse_one(aaa, 0, AF_UNIX, NULL); + } + + test_socket_address_parse_one("vsock:2:1234", 0, AF_VSOCK, NULL); + test_socket_address_parse_one("vsock::1234", 0, AF_VSOCK, NULL); + test_socket_address_parse_one("vsock:2:1234x", -EINVAL, 0, NULL); + test_socket_address_parse_one("vsock:2x:1234", -EINVAL, 0, NULL); + test_socket_address_parse_one("vsock:2", -EINVAL, 0, NULL); +} + +static void test_socket_address_parse_netlink(void) { + SocketAddress a; + + log_info("/* %s */", __func__); + + assert_se(socket_address_parse_netlink(&a, "junk") < 0); + assert_se(socket_address_parse_netlink(&a, "") < 0); + + assert_se(socket_address_parse_netlink(&a, "route") >= 0); + assert_se(a.sockaddr.nl.nl_family == AF_NETLINK); + assert_se(a.sockaddr.nl.nl_groups == 0); + assert_se(a.protocol == NETLINK_ROUTE); + assert_se(socket_address_parse_netlink(&a, "route") >= 0); + assert_se(socket_address_parse_netlink(&a, "route 10") >= 0); + assert_se(a.sockaddr.nl.nl_family == AF_NETLINK); + assert_se(a.sockaddr.nl.nl_groups == 10); + assert_se(a.protocol == NETLINK_ROUTE); + + /* With spaces and tabs */ + assert_se(socket_address_parse_netlink(&a, " kobject-uevent ") >= 0); + assert_se(a.sockaddr.nl.nl_family == AF_NETLINK); + assert_se(a.sockaddr.nl.nl_groups == 0); + assert_se(a.protocol == NETLINK_KOBJECT_UEVENT); + assert_se(socket_address_parse_netlink(&a, " \t kobject-uevent \t 10") >= 0); + assert_se(a.sockaddr.nl.nl_family == AF_NETLINK); + assert_se(a.sockaddr.nl.nl_groups == 10); + assert_se(a.protocol == NETLINK_KOBJECT_UEVENT); + assert_se(socket_address_parse_netlink(&a, "kobject-uevent\t10") >= 0); + assert_se(a.sockaddr.nl.nl_family == AF_NETLINK); + assert_se(a.sockaddr.nl.nl_groups == 10); + assert_se(a.protocol == NETLINK_KOBJECT_UEVENT); + + /* trailing space is not supported */ + assert_se(socket_address_parse_netlink(&a, "kobject-uevent\t10 ") < 0); + + /* Group must be unsigned */ + assert_se(socket_address_parse_netlink(&a, "kobject-uevent -1") < 0); + + /* oss-fuzz #6884 */ + assert_se(socket_address_parse_netlink(&a, "\xff") < 0); +} + +static void test_socket_address_equal(void) { + SocketAddress a, b; + + log_info("/* %s */", __func__); + + assert_se(socket_address_parse(&a, "192.168.1.1:8888") >= 0); + assert_se(socket_address_parse(&b, "192.168.1.1:888") >= 0); + assert_se(!socket_address_equal(&a, &b)); + + assert_se(socket_address_parse(&a, "192.168.1.1:8888") >= 0); + assert_se(socket_address_parse(&b, "192.16.1.1:8888") >= 0); + assert_se(!socket_address_equal(&a, &b)); + + assert_se(socket_address_parse(&a, "192.168.1.1:8888") >= 0); + assert_se(socket_address_parse(&b, "8888") >= 0); + assert_se(!socket_address_equal(&a, &b)); + + assert_se(socket_address_parse(&a, "192.168.1.1:8888") >= 0); + assert_se(socket_address_parse(&b, "/foo/bar/") >= 0); + assert_se(!socket_address_equal(&a, &b)); + + assert_se(socket_address_parse(&a, "192.168.1.1:8888") >= 0); + assert_se(socket_address_parse(&b, "192.168.1.1:8888") >= 0); + assert_se(socket_address_equal(&a, &b)); + + assert_se(socket_address_parse(&a, "/foo/bar") >= 0); + assert_se(socket_address_parse(&b, "/foo/bar") >= 0); + assert_se(socket_address_equal(&a, &b)); + + assert_se(socket_address_parse(&a, "[::1]:8888") >= 0); + assert_se(socket_address_parse(&b, "[::1]:8888") >= 0); + assert_se(socket_address_equal(&a, &b)); + + assert_se(socket_address_parse(&a, "@abstract") >= 0); + assert_se(socket_address_parse(&b, "@abstract") >= 0); + assert_se(socket_address_equal(&a, &b)); + + assert_se(socket_address_parse_netlink(&a, "firewall") >= 0); + assert_se(socket_address_parse_netlink(&b, "firewall") >= 0); + assert_se(socket_address_equal(&a, &b)); + + assert_se(socket_address_parse(&a, "vsock:2:1234") >= 0); + assert_se(socket_address_parse(&b, "vsock:2:1234") >= 0); + assert_se(socket_address_equal(&a, &b)); + assert_se(socket_address_parse(&b, "vsock:2:1235") >= 0); + assert_se(!socket_address_equal(&a, &b)); + assert_se(socket_address_parse(&b, "vsock:3:1234") >= 0); + assert_se(!socket_address_equal(&a, &b)); +} + +static void test_socket_address_get_path(void) { + SocketAddress a; + + log_info("/* %s */", __func__); + + assert_se(socket_address_parse(&a, "192.168.1.1:8888") >= 0); + assert_se(!socket_address_get_path(&a)); + + assert_se(socket_address_parse(&a, "@abstract") >= 0); + assert_se(!socket_address_get_path(&a)); + + assert_se(socket_address_parse(&a, "[::1]:8888") >= 0); + assert_se(!socket_address_get_path(&a)); + + assert_se(socket_address_parse(&a, "/foo/bar") >= 0); + assert_se(streq(socket_address_get_path(&a), "/foo/bar")); + + assert_se(socket_address_parse(&a, "vsock:2:1234") >= 0); + assert_se(!socket_address_get_path(&a)); +} + +static void test_socket_address_is(void) { + SocketAddress a; + + log_info("/* %s */", __func__); + + assert_se(socket_address_parse(&a, "192.168.1.1:8888") >= 0); + assert_se(socket_address_is(&a, "192.168.1.1:8888", SOCK_STREAM)); + assert_se(!socket_address_is(&a, "route", SOCK_STREAM)); + assert_se(!socket_address_is(&a, "192.168.1.1:8888", SOCK_RAW)); +} + +static void test_socket_address_is_netlink(void) { + SocketAddress a; + + log_info("/* %s */", __func__); + + assert_se(socket_address_parse_netlink(&a, "route 10") >= 0); + assert_se(socket_address_is_netlink(&a, "route 10")); + assert_se(!socket_address_is_netlink(&a, "192.168.1.1:8888")); + assert_se(!socket_address_is_netlink(&a, "route 1")); +} + +int main(int argc, char *argv[]) { + test_setup_logging(LOG_DEBUG); + + test_socket_address_parse(); + test_socket_address_parse_netlink(); + test_socket_address_equal(); + test_socket_address_get_path(); + test_socket_address_is(); + test_socket_address_is_netlink(); + + return 0; +} diff --git a/src/test/test-socket-util.c b/src/test/test-socket-util.c index 2489d00e263..d36caaa71e7 100644 --- a/src/test/test-socket-util.c +++ b/src/test/test-socket-util.c @@ -17,11 +17,14 @@ #include "macro.h" #include "missing_network.h" #include "process-util.h" +#include "socket-netlink.h" #include "socket-util.h" #include "string-util.h" #include "tests.h" #include "tmpfile-util.h" +assert_cc(SUN_PATH_LEN == 108); + static void test_ifname_valid(void) { log_info("/* %s */", __func__); @@ -48,82 +51,6 @@ static void test_ifname_valid(void) { assert(ifname_valid_full("xxxxxxxxxxxxxxxx", true)); } -static void test_socket_address_parse_one(const char *in, int ret, int family, const char *expected) { - SocketAddress a; - _cleanup_free_ char *out = NULL; - int r; - - r = socket_address_parse(&a, in); - if (r >= 0) - assert_se(socket_address_print(&a, &out) >= 0); - - log_info("\"%s\" → %s → \"%s\" (expect \"%s\")", in, - r >= 0 ? "✓" : "✗", empty_to_dash(out), r >= 0 ? expected ?: in : "-"); - assert_se(r == ret); - if (r >= 0) { - assert_se(a.sockaddr.sa.sa_family == family); - assert_se(streq(out, expected ?: in)); - } -} - -#define SUN_PATH_LEN (sizeof(((struct sockaddr_un){}).sun_path)) -assert_cc(SUN_PATH_LEN == 108); - -static void test_socket_address_parse(void) { - log_info("/* %s */", __func__); - - test_socket_address_parse_one("junk", -EINVAL, 0, NULL); - test_socket_address_parse_one("192.168.1.1", -EINVAL, 0, NULL); - test_socket_address_parse_one(".168.1.1", -EINVAL, 0, NULL); - test_socket_address_parse_one("989.168.1.1", -EINVAL, 0, NULL); - test_socket_address_parse_one("192.168.1.1:65536", -ERANGE, 0, NULL); - test_socket_address_parse_one("192.168.1.1:0", -EINVAL, 0, NULL); - test_socket_address_parse_one("0", -EINVAL, 0, NULL); - test_socket_address_parse_one("65536", -ERANGE, 0, NULL); - - const int default_family = socket_ipv6_is_supported() ? AF_INET6 : AF_INET; - - test_socket_address_parse_one("65535", 0, default_family, "[::]:65535"); - - /* The checks below will pass even if ipv6 is disabled in - * kernel. The underlying glibc's inet_pton() is just a string - * parser and doesn't make any syscalls. */ - - test_socket_address_parse_one("[::1]", -EINVAL, 0, NULL); - test_socket_address_parse_one("[::1]8888", -EINVAL, 0, NULL); - test_socket_address_parse_one("::1", -EINVAL, 0, NULL); - test_socket_address_parse_one("[::1]:0", -EINVAL, 0, NULL); - test_socket_address_parse_one("[::1]:65536", -ERANGE, 0, NULL); - test_socket_address_parse_one("[a:b:1]:8888", -EINVAL, 0, NULL); - - test_socket_address_parse_one("8888", 0, default_family, "[::]:8888"); - test_socket_address_parse_one("[2001:0db8:0000:85a3:0000:0000:ac1f:8001]:8888", 0, AF_INET6, - "[2001:db8:0:85a3::ac1f:8001]:8888"); - test_socket_address_parse_one("[::1]:8888", 0, AF_INET6, NULL); - test_socket_address_parse_one("192.168.1.254:8888", 0, AF_INET, NULL); - test_socket_address_parse_one("/foo/bar", 0, AF_UNIX, NULL); - test_socket_address_parse_one("/", 0, AF_UNIX, NULL); - test_socket_address_parse_one("@abstract", 0, AF_UNIX, NULL); - - { - char aaa[SUN_PATH_LEN + 1] = "@"; - - memset(aaa + 1, 'a', SUN_PATH_LEN - 1); - char_array_0(aaa); - - test_socket_address_parse_one(aaa, -EINVAL, 0, NULL); - - aaa[SUN_PATH_LEN - 1] = '\0'; - test_socket_address_parse_one(aaa, 0, AF_UNIX, NULL); - } - - test_socket_address_parse_one("vsock:2:1234", 0, AF_VSOCK, NULL); - test_socket_address_parse_one("vsock::1234", 0, AF_VSOCK, NULL); - test_socket_address_parse_one("vsock:2:1234x", -EINVAL, 0, NULL); - test_socket_address_parse_one("vsock:2x:1234", -EINVAL, 0, NULL); - test_socket_address_parse_one("vsock:2", -EINVAL, 0, NULL); -} - static void test_socket_print_unix_one(const char *in, size_t len_in, const char *expected) { _cleanup_free_ char *out = NULL, *c = NULL; @@ -157,141 +84,6 @@ static void test_socket_print_unix(void) { test_socket_print_unix_one("\0\a\b\n\255", 6, "@\\a\\b\\n\\255\\000"); } -static void test_socket_address_parse_netlink(void) { - SocketAddress a; - - log_info("/* %s */", __func__); - - assert_se(socket_address_parse_netlink(&a, "junk") < 0); - assert_se(socket_address_parse_netlink(&a, "") < 0); - - assert_se(socket_address_parse_netlink(&a, "route") >= 0); - assert_se(a.sockaddr.nl.nl_family == AF_NETLINK); - assert_se(a.sockaddr.nl.nl_groups == 0); - assert_se(a.protocol == NETLINK_ROUTE); - assert_se(socket_address_parse_netlink(&a, "route") >= 0); - assert_se(socket_address_parse_netlink(&a, "route 10") >= 0); - assert_se(a.sockaddr.nl.nl_family == AF_NETLINK); - assert_se(a.sockaddr.nl.nl_groups == 10); - assert_se(a.protocol == NETLINK_ROUTE); - - /* With spaces and tabs */ - assert_se(socket_address_parse_netlink(&a, " kobject-uevent ") >= 0); - assert_se(a.sockaddr.nl.nl_family == AF_NETLINK); - assert_se(a.sockaddr.nl.nl_groups == 0); - assert_se(a.protocol == NETLINK_KOBJECT_UEVENT); - assert_se(socket_address_parse_netlink(&a, " \t kobject-uevent \t 10") >= 0); - assert_se(a.sockaddr.nl.nl_family == AF_NETLINK); - assert_se(a.sockaddr.nl.nl_groups == 10); - assert_se(a.protocol == NETLINK_KOBJECT_UEVENT); - assert_se(socket_address_parse_netlink(&a, "kobject-uevent\t10") >= 0); - assert_se(a.sockaddr.nl.nl_family == AF_NETLINK); - assert_se(a.sockaddr.nl.nl_groups == 10); - assert_se(a.protocol == NETLINK_KOBJECT_UEVENT); - - /* trailing space is not supported */ - assert_se(socket_address_parse_netlink(&a, "kobject-uevent\t10 ") < 0); - - /* Group must be unsigned */ - assert_se(socket_address_parse_netlink(&a, "kobject-uevent -1") < 0); - - /* oss-fuzz #6884 */ - assert_se(socket_address_parse_netlink(&a, "\xff") < 0); -} - -static void test_socket_address_equal(void) { - SocketAddress a, b; - - log_info("/* %s */", __func__); - - assert_se(socket_address_parse(&a, "192.168.1.1:8888") >= 0); - assert_se(socket_address_parse(&b, "192.168.1.1:888") >= 0); - assert_se(!socket_address_equal(&a, &b)); - - assert_se(socket_address_parse(&a, "192.168.1.1:8888") >= 0); - assert_se(socket_address_parse(&b, "192.16.1.1:8888") >= 0); - assert_se(!socket_address_equal(&a, &b)); - - assert_se(socket_address_parse(&a, "192.168.1.1:8888") >= 0); - assert_se(socket_address_parse(&b, "8888") >= 0); - assert_se(!socket_address_equal(&a, &b)); - - assert_se(socket_address_parse(&a, "192.168.1.1:8888") >= 0); - assert_se(socket_address_parse(&b, "/foo/bar/") >= 0); - assert_se(!socket_address_equal(&a, &b)); - - assert_se(socket_address_parse(&a, "192.168.1.1:8888") >= 0); - assert_se(socket_address_parse(&b, "192.168.1.1:8888") >= 0); - assert_se(socket_address_equal(&a, &b)); - - assert_se(socket_address_parse(&a, "/foo/bar") >= 0); - assert_se(socket_address_parse(&b, "/foo/bar") >= 0); - assert_se(socket_address_equal(&a, &b)); - - assert_se(socket_address_parse(&a, "[::1]:8888") >= 0); - assert_se(socket_address_parse(&b, "[::1]:8888") >= 0); - assert_se(socket_address_equal(&a, &b)); - - assert_se(socket_address_parse(&a, "@abstract") >= 0); - assert_se(socket_address_parse(&b, "@abstract") >= 0); - assert_se(socket_address_equal(&a, &b)); - - assert_se(socket_address_parse_netlink(&a, "firewall") >= 0); - assert_se(socket_address_parse_netlink(&b, "firewall") >= 0); - assert_se(socket_address_equal(&a, &b)); - - assert_se(socket_address_parse(&a, "vsock:2:1234") >= 0); - assert_se(socket_address_parse(&b, "vsock:2:1234") >= 0); - assert_se(socket_address_equal(&a, &b)); - assert_se(socket_address_parse(&b, "vsock:2:1235") >= 0); - assert_se(!socket_address_equal(&a, &b)); - assert_se(socket_address_parse(&b, "vsock:3:1234") >= 0); - assert_se(!socket_address_equal(&a, &b)); -} - -static void test_socket_address_get_path(void) { - SocketAddress a; - - log_info("/* %s */", __func__); - - assert_se(socket_address_parse(&a, "192.168.1.1:8888") >= 0); - assert_se(!socket_address_get_path(&a)); - - assert_se(socket_address_parse(&a, "@abstract") >= 0); - assert_se(!socket_address_get_path(&a)); - - assert_se(socket_address_parse(&a, "[::1]:8888") >= 0); - assert_se(!socket_address_get_path(&a)); - - assert_se(socket_address_parse(&a, "/foo/bar") >= 0); - assert_se(streq(socket_address_get_path(&a), "/foo/bar")); - - assert_se(socket_address_parse(&a, "vsock:2:1234") >= 0); - assert_se(!socket_address_get_path(&a)); -} - -static void test_socket_address_is(void) { - SocketAddress a; - - log_info("/* %s */", __func__); - - assert_se(socket_address_parse(&a, "192.168.1.1:8888") >= 0); - assert_se(socket_address_is(&a, "192.168.1.1:8888", SOCK_STREAM)); - assert_se(!socket_address_is(&a, "route", SOCK_STREAM)); - assert_se(!socket_address_is(&a, "192.168.1.1:8888", SOCK_RAW)); -} - -static void test_socket_address_is_netlink(void) { - SocketAddress a; - - log_info("/* %s */", __func__); - - assert_se(socket_address_parse_netlink(&a, "route 10") >= 0); - assert_se(socket_address_is_netlink(&a, "route 10")); - assert_se(!socket_address_is_netlink(&a, "192.168.1.1:8888")); - assert_se(!socket_address_is_netlink(&a, "route 1")); -} - static void test_in_addr_is_null(void) { union in_addr_union i = {}; @@ -876,13 +668,7 @@ int main(int argc, char *argv[]) { test_ifname_valid(); - test_socket_address_parse(); test_socket_print_unix(); - test_socket_address_parse_netlink(); - test_socket_address_equal(); - test_socket_address_get_path(); - test_socket_address_is(); - test_socket_address_is_netlink(); test_in_addr_is_null(); test_in_addr_prefix_intersect();