[systemd-devel] [PATCH 4/6] make in_addr_from_string() accept ipv4 addresses even when using AF_INET6
Shawn Landden
shawn at churchofgit.com
Wed Mar 11 08:13:47 PDT 2015
if we are going to have a function to fix up the deficiencies of
inet_pton(), better go all the way.
---
src/shared/in-addr-util.c | 17 +++++++++++++++++
src/shared/in-addr-util.h | 1 +
2 files changed, 18 insertions(+)
diff --git a/src/shared/in-addr-util.c b/src/shared/in-addr-util.c
index ade4012..b7532a6 100644
--- a/src/shared/in-addr-util.c
+++ b/src/shared/in-addr-util.c
@@ -206,7 +206,18 @@ int in_addr_to_string(int family, const union in_addr_union *u, char **ret) {
return 0;
}
+struct in6_addr in_addr_to_in6_addr(struct in_addr ipv4) {
+ struct in6_addr r = { { {
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0xFF, 0xFF, 0, 0, 0, 0
+ } } };
+
+ r.s6_addr32[3] = ipv4.s_addr;
+
+ return r;
+}
+
int in_addr_from_string(int family, const char *s, void *ret) {
+ struct in_addr v4mapped;
assert(s);
assert(ret);
@@ -214,6 +225,12 @@ int in_addr_from_string(int family, const char *s, void *ret) {
if (!IN_SET(family, AF_INET, AF_INET6))
return -EAFNOSUPPORT;
+ if (family == AF_INET6)
+ if (inet_pton(AF_INET, s, &v4mapped) == 1) {
+ *((struct in6_addr *)ret) = in_addr_to_in6_addr(v4mapped);
+ return 0;
+ }
+
errno = 0;
if (inet_pton(family, s, ret) <= 0)
return errno ? -errno : -EINVAL;
diff --git a/src/shared/in-addr-util.h b/src/shared/in-addr-util.h
index 8b3a07c..f140ec9 100644
--- a/src/shared/in-addr-util.h
+++ b/src/shared/in-addr-util.h
@@ -37,6 +37,7 @@ int in_addr_equal(int family, const union in_addr_union *a, const union in_addr_
int in_addr_prefix_intersect(int family, const union in_addr_union *a, unsigned aprefixlen, const union in_addr_union *b, unsigned bprefixlen);
int in_addr_prefix_next(int family, union in_addr_union *u, unsigned prefixlen);
int in_addr_to_string(int family, const union in_addr_union *u, char **ret);
+struct in6_addr in_addr_to_in6_addr(struct in_addr ipv4) _const_;
int in_addr_from_string(int family, const char *s, void *ret);
int in_addr_from_string_auto(const char *s, int *family, union in_addr_union *ret);
unsigned char in_addr_netmask_to_prefixlen(const struct in_addr *addr);
--
2.2.1.209.g41e5f3a
More information about the systemd-devel
mailing list