summaryrefslogtreecommitdiff
path: root/src/shared
diff options
context:
space:
mode:
authorLennart Poettering <lennart@poettering.net>2014-07-10 21:15:26 +0200
committerLennart Poettering <lennart@poettering.net>2014-07-10 21:15:26 +0200
commit3b653205cf7bd3851befd0a9f6a3ded6e267c173 (patch)
tree1beb295a6455299a922d5cc9b4da2b44ed386890 /src/shared
parente80af1bdddbc7a51191e29b0c841e8dcafe7b1cc (diff)
shared: split out in_addr related calls from socket-util.[ch] into its private in-addr-util.[ch]
These are enough calls for a new file, and they are sufficiently different from the sockaddr-related calls, hence let's split this out.
Diffstat (limited to 'src/shared')
-rw-r--r--src/shared/in-addr-util.c211
-rw-r--r--src/shared/in-addr-util.h44
-rw-r--r--src/shared/socket-util.c187
-rw-r--r--src/shared/socket-util.h17
4 files changed, 255 insertions, 204 deletions
diff --git a/src/shared/in-addr-util.c b/src/shared/in-addr-util.c
new file mode 100644
index 000000000..98d2446e5
--- /dev/null
+++ b/src/shared/in-addr-util.c
@@ -0,0 +1,211 @@
+/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
+
+/***
+ This file is part of systemd.
+
+ Copyright 2014 Lennart Poettering
+
+ systemd is free software; you can redistribute it and/or modify it
+ under the terms of the GNU Lesser General Public License as published by
+ the Free Software Foundation; either version 2.1 of the License, or
+ (at your option) any later version.
+
+ systemd is distributed in the hope that it will be useful, but
+ WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public License
+ along with systemd; If not, see <http://www.gnu.org/licenses/>.
+***/
+
+#include <arpa/inet.h>
+
+#include "in-addr-util.h"
+
+int in_addr_null(unsigned family, union in_addr_union *u) {
+ assert(u);
+
+ if (family == AF_INET)
+ return u->in.s_addr == 0;
+
+ if (family == AF_INET6)
+ return
+ u->in6.s6_addr32[0] == 0 &&
+ u->in6.s6_addr32[1] == 0 &&
+ u->in6.s6_addr32[2] == 0 &&
+ u->in6.s6_addr32[3] == 0;
+
+ return -EAFNOSUPPORT;
+}
+
+
+int in_addr_equal(unsigned family, union in_addr_union *a, union in_addr_union *b) {
+ assert(a);
+ assert(b);
+
+ if (family == AF_INET)
+ return a->in.s_addr == b->in.s_addr;
+
+ if (family == AF_INET6)
+ return
+ a->in6.s6_addr32[0] == b->in6.s6_addr32[0] &&
+ a->in6.s6_addr32[1] == b->in6.s6_addr32[1] &&
+ a->in6.s6_addr32[2] == b->in6.s6_addr32[2] &&
+ a->in6.s6_addr32[3] == b->in6.s6_addr32[3];
+
+ return -EAFNOSUPPORT;
+}
+
+int in_addr_prefix_intersect(
+ unsigned family,
+ const union in_addr_union *a,
+ unsigned aprefixlen,
+ const union in_addr_union *b,
+ unsigned bprefixlen) {
+
+ unsigned m;
+
+ assert(a);
+ assert(b);
+
+ /* Checks whether there are any addresses that are in both
+ * networks */
+
+ m = MIN(aprefixlen, bprefixlen);
+
+ if (family == AF_INET) {
+ uint32_t x, nm;
+
+ x = be32toh(a->in.s_addr ^ b->in.s_addr);
+ nm = (m == 0) ? 0 : 0xFFFFFFFFUL << (32 - m);
+
+ return (x & nm) == 0;
+ }
+
+ if (family == AF_INET6) {
+ unsigned i;
+
+ if (m > 128)
+ m = 128;
+
+ for (i = 0; i < 16; i++) {
+ uint8_t x, nm;
+
+ x = a->in6.s6_addr[i] ^ b->in6.s6_addr[i];
+
+ if (m < 8)
+ nm = 0xFF << (8 - m);
+ else
+ nm = 0xFF;
+
+ if ((x & nm) != 0)
+ return 0;
+
+ if (m > 8)
+ m -= 8;
+ else
+ m = 0;
+ }
+
+ return 1;
+ }
+
+ return -EAFNOSUPPORT;
+}
+
+int in_addr_prefix_next(unsigned family, union in_addr_union *u, unsigned prefixlen) {
+ assert(u);
+
+ /* Increases the network part of an address by one. Returns
+ * positive it that succeeds, or 0 if this overflows. */
+
+ if (prefixlen <= 0)
+ return 0;
+
+ if (family == AF_INET) {
+ uint32_t c, n;
+
+ if (prefixlen > 32)
+ prefixlen = 32;
+
+ c = be32toh(u->in.s_addr);
+ n = c + (1UL << (32 - prefixlen));
+ if (n < c)
+ return 0;
+ n &= 0xFFFFFFFFUL << (32 - prefixlen);
+
+ u->in.s_addr = htobe32(n);
+ return 1;
+ }
+
+ if (family == AF_INET6) {
+ struct in6_addr add = {}, result;
+ uint8_t overflow = 0;
+ unsigned i;
+
+ if (prefixlen > 128)
+ prefixlen = 128;
+
+ /* First calculate what we have to add */
+ add.s6_addr[(prefixlen-1) / 8] = 1 << (7 - (prefixlen-1) % 8);
+
+ for (i = 16; i > 0; i--) {
+ unsigned j = i - 1;
+
+ result.s6_addr[j] = u->in6.s6_addr[j] + add.s6_addr[j] + overflow;
+ overflow = (result.s6_addr[j] < u->in6.s6_addr[j]);
+ }
+
+ if (overflow)
+ return 0;
+
+ u->in6 = result;
+ return 1;
+ }
+
+ return -EAFNOSUPPORT;
+}
+
+int in_addr_to_string(unsigned family, const union in_addr_union *u, char **ret) {
+ char *x;
+ size_t l;
+
+ assert(u);
+ assert(ret);
+
+ if (family == AF_INET)
+ l = INET_ADDRSTRLEN;
+ else if (family == AF_INET6)
+ l = INET6_ADDRSTRLEN;
+ else
+ return -EAFNOSUPPORT;
+
+ x = new(char, l);
+ if (!x)
+ return -ENOMEM;
+
+ errno = 0;
+ if (!inet_ntop(family, u, x, l)) {
+ free(x);
+ return errno ? -errno : -EINVAL;
+ }
+
+ *ret = x;
+ return 0;
+}
+
+int in_addr_from_string(unsigned family, const char *s, union in_addr_union *ret) {
+
+ assert(s);
+ assert(ret);
+
+ if (!IN_SET(family, AF_INET, AF_INET6))
+ return -EAFNOSUPPORT;
+
+ errno = 0;
+ if (inet_pton(family, s, ret) <= 0)
+ return errno ? -errno : -EINVAL;
+
+ return 0;
+}
diff --git a/src/shared/in-addr-util.h b/src/shared/in-addr-util.h
new file mode 100644
index 000000000..ae3aa9021
--- /dev/null
+++ b/src/shared/in-addr-util.h
@@ -0,0 +1,44 @@
+/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
+
+#pragma once
+
+/***
+ This file is part of systemd.
+
+ Copyright 2014 Lennart Poettering
+
+ systemd is free software; you can redistribute it and/or modify it
+ under the terms of the GNU Lesser General Public License as published by
+ the Free Software Foundation; either version 2.1 of the License, or
+ (at your option) any later version.
+
+ systemd is distributed in the hope that it will be useful, but
+ WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public License
+ along with systemd; If not, see <http://www.gnu.org/licenses/>.
+***/
+
+#include <netinet/in.h>
+
+#include "macro.h"
+#include "util.h"
+
+union in_addr_union {
+ struct in_addr in;
+ struct in6_addr in6;
+};
+
+int in_addr_null(unsigned family, union in_addr_union *u);
+int in_addr_equal(unsigned family, union in_addr_union *a, union in_addr_union *b);
+int in_addr_prefix_intersect(unsigned family, const union in_addr_union *a, unsigned aprefixlen, const union in_addr_union *b, unsigned bprefixlen);
+int in_addr_prefix_next(unsigned family, union in_addr_union *u, unsigned prefixlen);
+int in_addr_to_string(unsigned family, const union in_addr_union *u, char **ret);
+int in_addr_from_string(unsigned family, const char *s, union in_addr_union *ret);
+
+static inline size_t PROTO_ADDRESS_SIZE(int proto) {
+ assert(proto == AF_INET || proto == AF_INET6);
+ return proto == AF_INET6 ? 16 : 4;
+}
diff --git a/src/shared/socket-util.c b/src/shared/socket-util.c
index 6f4979853..92564e319 100644
--- a/src/shared/socket-util.c
+++ b/src/shared/socket-util.c
@@ -640,193 +640,6 @@ int socket_address_unlink(SocketAddress *a) {
return 1;
}
-int in_addr_null(unsigned family, union in_addr_union *u) {
- assert(u);
-
- if (family == AF_INET)
- return u->in.s_addr == 0;
-
- if (family == AF_INET6)
- return
- u->in6.s6_addr32[0] == 0 &&
- u->in6.s6_addr32[1] == 0 &&
- u->in6.s6_addr32[2] == 0 &&
- u->in6.s6_addr32[3] == 0;
-
- return -EAFNOSUPPORT;
-}
-
-
-int in_addr_equal(unsigned family, union in_addr_union *a, union in_addr_union *b) {
- assert(a);
- assert(b);
-
- if (family == AF_INET)
- return a->in.s_addr == b->in.s_addr;
-
- if (family == AF_INET6)
- return
- a->in6.s6_addr32[0] == b->in6.s6_addr32[0] &&
- a->in6.s6_addr32[1] == b->in6.s6_addr32[1] &&
- a->in6.s6_addr32[2] == b->in6.s6_addr32[2] &&
- a->in6.s6_addr32[3] == b->in6.s6_addr32[3];
-
- return -EAFNOSUPPORT;
-}
-
-int in_addr_prefix_intersect(
- unsigned family,
- const union in_addr_union *a,
- unsigned aprefixlen,
- const union in_addr_union *b,
- unsigned bprefixlen) {
-
- unsigned m;
-
- assert(a);
- assert(b);
-
- /* Checks whether there are any addresses that are in both
- * networks */
-
- m = MIN(aprefixlen, bprefixlen);
-
- if (family == AF_INET) {
- uint32_t x, nm;
-
- x = be32toh(a->in.s_addr ^ b->in.s_addr);
- nm = (m == 0) ? 0 : 0xFFFFFFFFUL << (32 - m);
-
- return (x & nm) == 0;
- }
-
- if (family == AF_INET6) {
- unsigned i;
-
- if (m > 128)
- m = 128;
-
- for (i = 0; i < 16; i++) {
- uint8_t x, nm;
-
- x = a->in6.s6_addr[i] ^ b->in6.s6_addr[i];
-
- if (m < 8)
- nm = 0xFF << (8 - m);
- else
- nm = 0xFF;
-
- if ((x & nm) != 0)
- return 0;
-
- if (m > 8)
- m -= 8;
- else
- m = 0;
- }
-
- return 1;
- }
-
- return -EAFNOSUPPORT;
-}
-
-int in_addr_prefix_next(unsigned family, union in_addr_union *u, unsigned prefixlen) {
- assert(u);
-
- /* Increases the network part of an address by one. Returns
- * positive it that succeeds, or 0 if this overflows. */
-
- if (prefixlen <= 0)
- return 0;
-
- if (family == AF_INET) {
- uint32_t c, n;
-
- if (prefixlen > 32)
- prefixlen = 32;
-
- c = be32toh(u->in.s_addr);
- n = c + (1UL << (32 - prefixlen));
- if (n < c)
- return 0;
- n &= 0xFFFFFFFFUL << (32 - prefixlen);
-
- u->in.s_addr = htobe32(n);
- return 1;
- }
-
- if (family == AF_INET6) {
- struct in6_addr add = {}, result;
- uint8_t overflow = 0;
- unsigned i;
-
- if (prefixlen > 128)
- prefixlen = 128;
-
- /* First calculate what we have to add */
- add.s6_addr[(prefixlen-1) / 8] = 1 << (7 - (prefixlen-1) % 8);
-
- for (i = 16; i > 0; i--) {
- unsigned j = i - 1;
-
- result.s6_addr[j] = u->in6.s6_addr[j] + add.s6_addr[j] + overflow;
- overflow = (result.s6_addr[j] < u->in6.s6_addr[j]);
- }
-
- if (overflow)
- return 0;
-
- u->in6 = result;
- return 1;
- }
-
- return -EAFNOSUPPORT;
-}
-
-int in_addr_to_string(unsigned family, const union in_addr_union *u, char **ret) {
- char *x;
- size_t l;
-
- assert(u);
- assert(ret);
-
- if (family == AF_INET)
- l = INET_ADDRSTRLEN;
- else if (family == AF_INET6)
- l = INET6_ADDRSTRLEN;
- else
- return -EAFNOSUPPORT;
-
- x = new(char, l);
- if (!x)
- return -ENOMEM;
-
- errno = 0;
- if (!inet_ntop(family, u, x, l)) {
- free(x);
- return errno ? -errno : -EINVAL;
- }
-
- *ret = x;
- return 0;
-}
-
-int in_addr_from_string(unsigned family, const char *s, union in_addr_union *ret) {
-
- assert(s);
- assert(ret);
-
- if (!IN_SET(family, AF_INET, AF_INET6))
- return -EAFNOSUPPORT;
-
- errno = 0;
- if (inet_pton(family, s, ret) <= 0)
- return errno ? -errno : -EINVAL;
-
- return 0;
-}
-
static const char* const netlink_family_table[] = {
[NETLINK_ROUTE] = "route",
[NETLINK_FIREWALL] = "firewall",
diff --git a/src/shared/socket-util.h b/src/shared/socket-util.h
index 8d521ae1a..ec85d949c 100644
--- a/src/shared/socket-util.h
+++ b/src/shared/socket-util.h
@@ -41,11 +41,6 @@ union sockaddr_union {
struct sockaddr_ll ll;
};
-union in_addr_union {
- struct in_addr in;
- struct in6_addr in6;
-};
-
typedef struct SocketAddress {
union sockaddr_union sockaddr;
@@ -111,15 +106,3 @@ SocketAddressBindIPv6Only socket_address_bind_ipv6_only_from_string(const char *
int netlink_family_to_string_alloc(int b, char **s);
int netlink_family_from_string(const char *s) _pure_;
-
-int in_addr_null(unsigned family, union in_addr_union *u);
-int in_addr_equal(unsigned family, union in_addr_union *a, union in_addr_union *b);
-int in_addr_prefix_intersect(unsigned family, const union in_addr_union *a, unsigned aprefixlen, const union in_addr_union *b, unsigned bprefixlen);
-int in_addr_prefix_next(unsigned family, union in_addr_union *u, unsigned prefixlen);
-int in_addr_to_string(unsigned family, const union in_addr_union *u, char **ret);
-int in_addr_from_string(unsigned family, const char *s, union in_addr_union *ret);
-
-static inline size_t PROTO_ADDRESS_SIZE(int proto) {
- assert(proto == AF_INET || proto == AF_INET6);
- return proto == AF_INET6 ? 16 : 4;
-}