if (r < 0)
return -ENOMEM;
} else {
- char a[INET6_ADDRSTRLEN];
-
- inet_ntop(AF_INET6, &sa->in6.sin6_addr, a, sizeof(a));
+ const char *a = IN6_ADDR_TO_STRING(&sa->in6.sin6_addr);
if (include_port) {
if (asprintf(&p,
}
static const char* const netlink_family_table[] = {
- [NETLINK_ROUTE] = "route",
- [NETLINK_FIREWALL] = "firewall",
- [NETLINK_INET_DIAG] = "inet-diag",
- [NETLINK_NFLOG] = "nflog",
- [NETLINK_XFRM] = "xfrm",
- [NETLINK_SELINUX] = "selinux",
- [NETLINK_ISCSI] = "iscsi",
- [NETLINK_AUDIT] = "audit",
- [NETLINK_FIB_LOOKUP] = "fib-lookup",
- [NETLINK_CONNECTOR] = "connector",
- [NETLINK_NETFILTER] = "netfilter",
- [NETLINK_IP6_FW] = "ip6-fw",
- [NETLINK_DNRTMSG] = "dnrtmsg",
+ [NETLINK_ROUTE] = "route",
+ [NETLINK_FIREWALL] = "firewall",
+ [NETLINK_INET_DIAG] = "inet-diag",
+ [NETLINK_NFLOG] = "nflog",
+ [NETLINK_XFRM] = "xfrm",
+ [NETLINK_SELINUX] = "selinux",
+ [NETLINK_ISCSI] = "iscsi",
+ [NETLINK_AUDIT] = "audit",
+ [NETLINK_FIB_LOOKUP] = "fib-lookup",
+ [NETLINK_CONNECTOR] = "connector",
+ [NETLINK_NETFILTER] = "netfilter",
+ [NETLINK_IP6_FW] = "ip6-fw",
+ [NETLINK_DNRTMSG] = "dnrtmsg",
[NETLINK_KOBJECT_UEVENT] = "kobject-uevent",
- [NETLINK_GENERIC] = "generic",
- [NETLINK_SCSITRANSPORT] = "scsitransport",
- [NETLINK_ECRYPTFS] = "ecryptfs",
- [NETLINK_RDMA] = "rdma",
+ [NETLINK_GENERIC] = "generic",
+ [NETLINK_SCSITRANSPORT] = "scsitransport",
+ [NETLINK_ECRYPTFS] = "ecryptfs",
+ [NETLINK_RDMA] = "rdma",
};
DEFINE_STRING_TABLE_LOOKUP_WITH_FALLBACK(netlink_family, int, INT_MAX);
}
static const char* const ip_tos_table[] = {
- [IPTOS_LOWDELAY] = "low-delay",
- [IPTOS_THROUGHPUT] = "throughput",
+ [IPTOS_LOWDELAY] = "low-delay",
+ [IPTOS_THROUGHPUT] = "throughput",
[IPTOS_RELIABILITY] = "reliability",
- [IPTOS_LOWCOST] = "low-cost",
+ [IPTOS_LOWCOST] = "low-cost",
};
DEFINE_STRING_TABLE_LOOKUP_WITH_FALLBACK(ip_tos, int, 0xff);
if (!ifname_valid_char(*t))
return false;
- numeric = numeric && (*t >= '0' && *t <= '9');
+ numeric = numeric && ascii_isdigit(*t);
}
/* It's fully numeric but didn't parse as valid ifindex above? if so, it must be too large or zero or
if (found)
*ret_fd = *(int*) CMSG_DATA(found);
else
- *ret_fd = -1;
+ *ret_fd = -EBADF;
return k;
}
*ret = (size_t) mtu;
return 0;
}
+
+int connect_unix_path(int fd, int dir_fd, const char *path) {
+ _cleanup_close_ int inode_fd = -EBADF;
+ union sockaddr_union sa = {
+ .un.sun_family = AF_UNIX,
+ };
+ size_t path_len;
+ socklen_t salen;
+
+ assert(fd >= 0);
+ assert(dir_fd == AT_FDCWD || dir_fd >= 0);
+ assert(path);
+
+ /* Connects to the specified AF_UNIX socket in the file system. Works around the 108 byte size limit
+ * in sockaddr_un, by going via O_PATH if needed. This hence works for any kind of path. */
+
+ path_len = strlen(path);
+
+ /* Refuse zero length path early, to make sure AF_UNIX stack won't mistake this for an abstract
+ * namespace path, since first char is NUL */
+ if (path_len <= 0)
+ return -EINVAL;
+
+ if (dir_fd == AT_FDCWD && path_len < sizeof(sa.un.sun_path)) {
+ memcpy(sa.un.sun_path, path, path_len + 1);
+ salen = offsetof(struct sockaddr_un, sun_path) + path_len + 1;
+ } else {
+ const char *proc;
+ size_t proc_len;
+
+ /* If dir_fd is specified, then we need to go the indirect O_PATH route, because connectat()
+ * does not exist. If the path is too long, we also need to take the indirect route, since we
+ * can't fit this into a sockaddr_un directly. */
+
+ inode_fd = openat(dir_fd, path, O_PATH|O_CLOEXEC);
+ if (inode_fd < 0)
+ return -errno;
+
+ proc = FORMAT_PROC_FD_PATH(inode_fd);
+ proc_len = strlen(proc);
+
+ assert(proc_len < sizeof(sa.un.sun_path));
+ memcpy(sa.un.sun_path, proc, proc_len + 1);
+ salen = offsetof(struct sockaddr_un, sun_path) + proc_len + 1;
+ }
+
+ return RET_NERRNO(connect(fd, &sa.sa, salen));
+}