diff options
author | Luca Boccassi <bluca@debian.org> | 2023-01-03 18:01:28 +0100 |
---|---|---|
committer | Luca Boccassi <bluca@debian.org> | 2023-01-05 18:43:47 +0100 |
commit | 747b5d963ef8078032e1f6f7ee98f8725d8fb454 (patch) | |
tree | cb8107ba0df346e61b1020785786f3bc2eefb234 /src/shared/socket-netlink.c | |
parent | vconsole: permit configuration of vconsole settings via credentials (diff) | |
download | systemd-747b5d963ef8078032e1f6f7ee98f8725d8fb454.tar.xz systemd-747b5d963ef8078032e1f6f7ee98f8725d8fb454.zip |
src/shared/: split AF_UNIX/AF_VSOCK address parsing into src/basic/
We'll use it from libsystemd0 later, but AF_INET/6 requires some
netlink calls and thus the additional library dependency
Diffstat (limited to '')
-rw-r--r-- | src/shared/socket-netlink.c | 158 |
1 files changed, 56 insertions, 102 deletions
diff --git a/src/shared/socket-netlink.c b/src/shared/socket-netlink.c index 494047a5d1..e115dff506 100644 --- a/src/shared/socket-netlink.c +++ b/src/shared/socket-netlink.c @@ -17,120 +17,74 @@ #include "string-util.h" int socket_address_parse(SocketAddress *a, const char *s) { - _cleanup_free_ char *n = NULL; - char *e; + uint16_t port; int r; assert(a); assert(s); - if (IN_SET(*s, '/', '@')) { - /* AF_UNIX socket */ - struct sockaddr_un un; - - r = sockaddr_un_set_path(&un, s); - if (r < 0) - return r; - - *a = (SocketAddress) { - .sockaddr.un = un, - .size = r, - }; + r = socket_address_parse_unix(a, s); + if (r == -EPROTO) + r = socket_address_parse_vsock(a, s); + if (r != -EPROTO) + return r; - } else if (startswith(s, "vsock:")) { - /* AF_VSOCK socket in vsock:cid:port notation */ - const char *cid_start = s + STRLEN("vsock:"); - unsigned port, cid; + r = parse_ip_port(s, &port); + if (r == -ERANGE) + return r; /* Valid port syntax, but the numerical value is wrong for a port. */ + if (r >= 0) { + /* Just a port */ + if (socket_ipv6_is_supported()) + *a = (SocketAddress) { + .sockaddr.in6 = { + .sin6_family = AF_INET6, + .sin6_port = htobe16(port), + .sin6_addr = in6addr_any, + }, + .size = sizeof(struct sockaddr_in6), + }; + else + *a = (SocketAddress) { + .sockaddr.in = { + .sin_family = AF_INET, + .sin_port = htobe16(port), + .sin_addr.s_addr = INADDR_ANY, + }, + .size = sizeof(struct sockaddr_in), + }; - e = strchr(cid_start, ':'); - if (!e) - return -EINVAL; + } else { + union in_addr_union address; + int family, ifindex; - r = safe_atou(e+1, &port); + r = in_addr_port_ifindex_name_from_string_auto(s, &family, &address, &port, &ifindex, NULL); if (r < 0) return r; - n = strndup(cid_start, e - cid_start); - if (!n) - return -ENOMEM; - - if (isempty(n)) - cid = VMADDR_CID_ANY; - else { - r = safe_atou(n, &cid); - if (r < 0) - return r; - } - - *a = (SocketAddress) { - .sockaddr.vm = { - .svm_cid = cid, - .svm_family = AF_VSOCK, - .svm_port = port, - }, - .size = sizeof(struct sockaddr_vm), - }; - - } else { - uint16_t port; - - r = parse_ip_port(s, &port); - if (r == -ERANGE) - return r; /* Valid port syntax, but the numerical value is wrong for a port. */ - if (r >= 0) { - /* Just a port */ - if (socket_ipv6_is_supported()) - *a = (SocketAddress) { - .sockaddr.in6 = { - .sin6_family = AF_INET6, - .sin6_port = htobe16(port), - .sin6_addr = in6addr_any, - }, - .size = sizeof(struct sockaddr_in6), - }; - else - *a = (SocketAddress) { - .sockaddr.in = { - .sin_family = AF_INET, - .sin_port = htobe16(port), - .sin_addr.s_addr = INADDR_ANY, - }, - .size = sizeof(struct sockaddr_in), - }; - - } else { - union in_addr_union address; - int family, ifindex; - - r = in_addr_port_ifindex_name_from_string_auto(s, &family, &address, &port, &ifindex, NULL); - if (r < 0) - return r; - - if (port == 0) /* No port, no go. */ - return -EINVAL; + if (port == 0) /* No port, no go. */ + return -EINVAL; - if (family == AF_INET) - *a = (SocketAddress) { - .sockaddr.in = { - .sin_family = AF_INET, - .sin_addr = address.in, - .sin_port = htobe16(port), - }, - .size = sizeof(struct sockaddr_in), - }; - else if (family == AF_INET6) - *a = (SocketAddress) { - .sockaddr.in6 = { - .sin6_family = AF_INET6, - .sin6_addr = address.in6, - .sin6_port = htobe16(port), - .sin6_scope_id = ifindex, - }, - .size = sizeof(struct sockaddr_in6), - }; - else - assert_not_reached(); - } + if (family == AF_INET) + *a = (SocketAddress) { + .sockaddr.in = { + .sin_family = AF_INET, + .sin_addr = address.in, + .sin_port = htobe16(port), + }, + .size = sizeof(struct sockaddr_in), + }; + else if (family == AF_INET6) + *a = (SocketAddress) { + .sockaddr.in6 = { + .sin6_family = AF_INET6, + .sin6_addr = address.in6, + .sin6_port = htobe16(port), + .sin6_scope_id = ifindex, + }, + .size = sizeof(struct sockaddr_in6), + }; + else + assert_not_reached(); } return 0; |