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/basic/socket-util.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 'src/basic/socket-util.c')
-rw-r--r-- | src/basic/socket-util.c | 68 |
1 files changed, 68 insertions, 0 deletions
diff --git a/src/basic/socket-util.c b/src/basic/socket-util.c index 54f5f1cc5b..d7946a3641 100644 --- a/src/basic/socket-util.c +++ b/src/basic/socket-util.c @@ -1472,3 +1472,71 @@ int connect_unix_path(int fd, int dir_fd, const char *path) { return RET_NERRNO(connect(fd, &sa.sa, salen)); } + +int socket_address_parse_unix(SocketAddress *ret_address, const char *s) { + struct sockaddr_un un; + int r; + + assert(ret_address); + assert(s); + + if (!IN_SET(*s, '/', '@')) + return -EPROTO; + + r = sockaddr_un_set_path(&un, s); + if (r < 0) + return r; + + *ret_address = (SocketAddress) { + .sockaddr.un = un, + .size = r, + }; + + return 0; +} + +int socket_address_parse_vsock(SocketAddress *ret_address, const char *s) { + /* AF_VSOCK socket in vsock:cid:port notation */ + _cleanup_free_ char *n = NULL; + char *e, *cid_start; + unsigned port, cid; + int r; + + assert(ret_address); + assert(s); + + cid_start = startswith(s, "vsock:"); + if (!cid_start) + return -EPROTO; + + 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)) + cid = VMADDR_CID_ANY; + else { + r = safe_atou(n, &cid); + if (r < 0) + return r; + } + + *ret_address = (SocketAddress) { + .sockaddr.vm = { + .svm_cid = cid, + .svm_family = AF_VSOCK, + .svm_port = port, + }, + .size = sizeof(struct sockaddr_vm), + }; + + return 0; +} |