#include "socket-util.h"
#include "missing.h"
#include "fileio.h"
+#include "formats-util.h"
int socket_address_parse(SocketAddress *a, const char *s) {
char *e, *n;
if (*s == '[') {
/* IPv6 in [x:.....:z]:p notation */
- if (!socket_ipv6_is_supported()) {
- log_warning("Binding to IPv6 address not available since kernel does not support IPv6.");
- return -EAFNOSUPPORT;
- }
-
e = strchr(s+1, ']');
if (!e)
return -EINVAL;
if (idx == 0)
return -EINVAL;
- if (!socket_ipv6_is_supported()) {
- log_warning("Binding to interface is not available since kernel does not support IPv6.");
- return -EAFNOSUPPORT;
- }
-
a->sockaddr.in6.sin6_family = AF_INET6;
a->sockaddr.in6.sin6_port = htons((uint16_t) u);
a->sockaddr.in6.sin6_scope_id = idx;
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) {
int family;
unsigned group = 0;
int sockaddr_pretty(const struct sockaddr *_sa, socklen_t salen, bool translate_ipv6, bool include_port, char **ret) {
union sockaddr_union *sa = (union sockaddr_union*) _sa;
char *p;
+ int r;
assert(sa);
assert(salen >= sizeof(sa->sa.sa_family));
a = ntohl(sa->in.sin_addr.s_addr);
- if (include_port) {
- if (asprintf(&p,
+ if (include_port)
+ r = asprintf(&p,
"%u.%u.%u.%u:%u",
a >> 24, (a >> 16) & 0xFF, (a >> 8) & 0xFF, a & 0xFF,
- ntohs(sa->in.sin_port)) < 0)
- return -ENOMEM;
- } else {
- if (asprintf(&p,
+ ntohs(sa->in.sin_port));
+ else
+ r = asprintf(&p,
"%u.%u.%u.%u",
- a >> 24, (a >> 16) & 0xFF, (a >> 8) & 0xFF, a & 0xFF) < 0)
- return -ENOMEM;
- }
-
+ a >> 24, (a >> 16) & 0xFF, (a >> 8) & 0xFF, a & 0xFF);
+ if (r < 0)
+ return -ENOMEM;
break;
}
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0xFF, 0xFF
};
- if (translate_ipv6 && memcmp(&sa->in6.sin6_addr, ipv4_prefix, sizeof(ipv4_prefix)) == 0) {
+ if (translate_ipv6 &&
+ memcmp(&sa->in6.sin6_addr, ipv4_prefix, sizeof(ipv4_prefix)) == 0) {
const uint8_t *a = sa->in6.sin6_addr.s6_addr+12;
- if (include_port) {
- if (asprintf(&p,
+ if (include_port)
+ r = asprintf(&p,
"%u.%u.%u.%u:%u",
a[0], a[1], a[2], a[3],
- ntohs(sa->in6.sin6_port)) < 0)
- return -ENOMEM;
- } else {
- if (asprintf(&p,
+ ntohs(sa->in6.sin6_port));
+ else
+ r = asprintf(&p,
"%u.%u.%u.%u",
- a[0], a[1], a[2], a[3]) < 0)
- return -ENOMEM;
- }
+ a[0], a[1], a[2], a[3]);
+ if (r < 0)
+ return -ENOMEM;
} else {
char a[INET6_ADDRSTRLEN];
inet_ntop(AF_INET6, &sa->in6.sin6_addr, a, sizeof(a));
if (include_port) {
- if (asprintf(&p,
+ r = asprintf(&p,
"[%s]:%u",
a,
- ntohs(sa->in6.sin6_port)) < 0)
+ ntohs(sa->in6.sin6_port));
+ if (r < 0)
return -ENOMEM;
} else {
p = strdup(a);
break;
default:
- return -ENOTSUP;
+ return -EOPNOTSUPP;
}