commit 5d8336c182777c36ebff561b420d67fcafb9a9f7
parent ef106ce7884b0af7adcf9f3965ebbe843a47912c
Author: Nick Mathewson <nickm@torproject.org>
Date: Tue, 10 Jul 2018 12:50:38 -0400
Refactor ipv[46].[ch]
These are now combined into an inaddr.[ch], since their purpose is
to implement functions for struct in_addr and struct in6_addr.
The definitions for in6_addr and its allies are now in a separate
header, inaddr_st.h.
Closes ticket 26532.
Diffstat:
12 files changed, 393 insertions(+), 406 deletions(-)
diff --git a/src/core/or/or.h b/src/core/or/or.h
@@ -49,8 +49,7 @@
#include "lib/log/util_bug.h"
#include "lib/malloc/util_malloc.h"
#include "lib/net/address.h"
-#include "lib/net/ipv4.h"
-#include "lib/net/ipv6.h"
+#include "lib/net/inaddr.h"
#include "lib/net/resolve.h"
#include "lib/net/socket.h"
#include "lib/string/compat_ctype.h"
diff --git a/src/lib/net/address.c b/src/lib/net/address.c
@@ -43,7 +43,7 @@
#include "lib/log/torlog.h"
#include "lib/log/escape.h"
#include "lib/malloc/util_malloc.h"
-#include "lib/net/ipv4.h"
+#include "lib/net/inaddr.h"
#include "lib/string/compat_ctype.h"
#include "lib/string/compat_string.h"
#include "lib/string/parse_int.h"
diff --git a/src/lib/net/address.h b/src/lib/net/address.h
@@ -14,7 +14,7 @@
#include "orconfig.h"
#include "lib/cc/torint.h"
#include "lib/log/util_bug.h"
-#include "lib/net/ipv6.h"
+#include "lib/net/inaddr_st.h"
#include "lib/net/nettypes.h"
#ifdef HAVE_NETINET_IN_H
diff --git a/src/lib/net/inaddr.c b/src/lib/net/inaddr.c
@@ -0,0 +1,267 @@
+/* Copyright (c) 2003-2004, Roger Dingledine
+ * Copyright (c) 2004-2006, Roger Dingledine, Nick Mathewson.
+ * Copyright (c) 2007-2018, The Tor Project, Inc. */
+/* See LICENSE for licensing information */
+
+/**
+ * \file inaddr.c
+ * \brief Convert in_addr and in6_addr to and from strings.
+ **/
+
+#include "lib/net/inaddr.h"
+
+#include "lib/cc/torint.h"
+#include "lib/log/util_bug.h"
+#include "lib/net/inaddr_st.h"
+#include "lib/string/compat_ctype.h"
+#include "lib/string/compat_string.h"
+#include "lib/string/printf.h"
+#include "lib/string/scanf.h"
+#include "lib/string/util_string.h"
+
+#ifdef HAVE_ARPA_INET_H
+#include <arpa/inet.h>
+#endif
+
+#include <stdlib.h>
+#include <string.h>
+
+#ifdef _WIN32
+#include <winsock2.h>
+#endif
+
+/** Set *addr to the IP address (in dotted-quad notation) stored in *str.
+ * Return 1 on success, 0 if *str is badly formatted.
+ * (Like inet_aton(str,addr), but works on Windows and Solaris.)
+ */
+int
+tor_inet_aton(const char *str, struct in_addr* addr)
+{
+ unsigned a,b,c,d;
+ char more;
+ if (tor_sscanf(str, "%3u.%3u.%3u.%3u%c", &a,&b,&c,&d,&more) != 4)
+ return 0;
+ if (a > 255) return 0;
+ if (b > 255) return 0;
+ if (c > 255) return 0;
+ if (d > 255) return 0;
+ addr->s_addr = htonl((a<<24) | (b<<16) | (c<<8) | d);
+ return 1;
+}
+
+/** Given an IPv4 in_addr struct *<b>in</b> (in network order, as usual),
+ * write it as a string into the <b>buf_len</b>-byte buffer in
+ * <b>buf</b>. Returns a non-negative integer on success.
+ * Returns -1 on failure.
+ */
+int
+tor_inet_ntoa(const struct in_addr *in, char *buf, size_t buf_len)
+{
+ uint32_t a = ntohl(in->s_addr);
+ return tor_snprintf(buf, buf_len, "%d.%d.%d.%d",
+ (int)(uint8_t)((a>>24)&0xff),
+ (int)(uint8_t)((a>>16)&0xff),
+ (int)(uint8_t)((a>>8 )&0xff),
+ (int)(uint8_t)((a )&0xff));
+}
+
+/** Given <b>af</b>==AF_INET and <b>src</b> a struct in_addr, or
+ * <b>af</b>==AF_INET6 and <b>src</b> a struct in6_addr, try to format the
+ * address and store it in the <b>len</b>-byte buffer <b>dst</b>. Returns
+ * <b>dst</b> on success, NULL on failure.
+ *
+ * (Like inet_ntop(af,src,dst,len), but works on platforms that don't have it:
+ * Tor sometimes needs to format ipv6 addresses even on platforms without ipv6
+ * support.) */
+const char *
+tor_inet_ntop(int af, const void *src, char *dst, size_t len)
+{
+ if (af == AF_INET) {
+ if (tor_inet_ntoa(src, dst, len) < 0)
+ return NULL;
+ else
+ return dst;
+ } else if (af == AF_INET6) {
+ const struct in6_addr *addr = src;
+ char buf[64], *cp;
+ int longestGapLen = 0, longestGapPos = -1, i,
+ curGapPos = -1, curGapLen = 0;
+ uint16_t words[8];
+ for (i = 0; i < 8; ++i) {
+ words[i] = (((uint16_t)addr->s6_addr[2*i])<<8) + addr->s6_addr[2*i+1];
+ }
+ if (words[0] == 0 && words[1] == 0 && words[2] == 0 && words[3] == 0 &&
+ words[4] == 0 && ((words[5] == 0 && words[6] && words[7]) ||
+ (words[5] == 0xffff))) {
+ /* This is an IPv4 address. */
+ if (words[5] == 0) {
+ tor_snprintf(buf, sizeof(buf), "::%d.%d.%d.%d",
+ addr->s6_addr[12], addr->s6_addr[13],
+ addr->s6_addr[14], addr->s6_addr[15]);
+ } else {
+ tor_snprintf(buf, sizeof(buf), "::%x:%d.%d.%d.%d", words[5],
+ addr->s6_addr[12], addr->s6_addr[13],
+ addr->s6_addr[14], addr->s6_addr[15]);
+ }
+ if ((strlen(buf) + 1) > len) /* +1 for \0 */
+ return NULL;
+ strlcpy(dst, buf, len);
+ return dst;
+ }
+ i = 0;
+ while (i < 8) {
+ if (words[i] == 0) {
+ curGapPos = i++;
+ curGapLen = 1;
+ while (i<8 && words[i] == 0) {
+ ++i; ++curGapLen;
+ }
+ if (curGapLen > longestGapLen) {
+ longestGapPos = curGapPos;
+ longestGapLen = curGapLen;
+ }
+ } else {
+ ++i;
+ }
+ }
+ if (longestGapLen<=1)
+ longestGapPos = -1;
+
+ cp = buf;
+ for (i = 0; i < 8; ++i) {
+ if (words[i] == 0 && longestGapPos == i) {
+ if (i == 0)
+ *cp++ = ':';
+ *cp++ = ':';
+ while (i < 8 && words[i] == 0)
+ ++i;
+ --i; /* to compensate for loop increment. */
+ } else {
+ tor_snprintf(cp, sizeof(buf)-(cp-buf), "%x", (unsigned)words[i]);
+ cp += strlen(cp);
+ if (i != 7)
+ *cp++ = ':';
+ }
+ }
+ *cp = '\0';
+ if ((strlen(buf) + 1) > len) /* +1 for \0 */
+ return NULL;
+ strlcpy(dst, buf, len);
+ return dst;
+ } else {
+ return NULL;
+ }
+}
+
+/** Given <b>af</b>==AF_INET or <b>af</b>==AF_INET6, and a string <b>src</b>
+ * encoding an IPv4 address or IPv6 address correspondingly, try to parse the
+ * address and store the result in <b>dst</b> (which must have space for a
+ * struct in_addr or a struct in6_addr, as appropriate). Return 1 on success,
+ * 0 on a bad parse, and -1 on a bad <b>af</b>.
+ *
+ * (Like inet_pton(af,src,dst) but works on platforms that don't have it: Tor
+ * sometimes needs to format ipv6 addresses even on platforms without ipv6
+ * support.) */
+int
+tor_inet_pton(int af, const char *src, void *dst)
+{
+ if (af == AF_INET) {
+ return tor_inet_aton(src, dst);
+ } else if (af == AF_INET6) {
+ struct in6_addr *out = dst;
+ uint16_t words[8];
+ int gapPos = -1, i, setWords=0;
+ const char *dot = strchr(src, '.');
+ const char *eow; /* end of words. */
+ memset(words, 0xf8, sizeof(words));
+ if (dot == src)
+ return 0;
+ else if (!dot)
+ eow = src+strlen(src);
+ else {
+ unsigned byte1,byte2,byte3,byte4;
+ char more;
+ for (eow = dot-1; eow > src && TOR_ISDIGIT(*eow); --eow)
+ ;
+ if (*eow != ':')
+ return 0;
+ ++eow;
+
+ /* We use "scanf" because some platform inet_aton()s are too lax
+ * about IPv4 addresses of the form "1.2.3" */
+ if (tor_sscanf(eow, "%3u.%3u.%3u.%3u%c",
+ &byte1,&byte2,&byte3,&byte4,&more) != 4)
+ return 0;
+
+ if (byte1 > 255 || byte2 > 255 || byte3 > 255 || byte4 > 255)
+ return 0;
+
+ words[6] = (byte1<<8) | byte2;
+ words[7] = (byte3<<8) | byte4;
+ setWords += 2;
+ }
+
+ i = 0;
+ while (src < eow) {
+ if (i > 7)
+ return 0;
+ if (TOR_ISXDIGIT(*src)) {
+ char *next;
+ ssize_t len;
+ long r = strtol(src, &next, 16);
+ if (next == NULL || next == src) {
+ /* The 'next == src' error case can happen on versions of openbsd
+ * which treat "0xfoo" as an error, rather than as "0" followed by
+ * "xfoo". */
+ return 0;
+ }
+
+ len = *next == '\0' ? eow - src : next - src;
+ if (len > 4)
+ return 0;
+ if (len > 1 && !TOR_ISXDIGIT(src[1]))
+ return 0; /* 0x is not valid */
+
+ tor_assert(r >= 0);
+ tor_assert(r < 65536);
+ words[i++] = (uint16_t)r;
+ setWords++;
+ src = next;
+ if (*src != ':' && src != eow)
+ return 0;
+ ++src;
+ } else if (*src == ':' && i > 0 && gapPos == -1) {
+ gapPos = i;
+ ++src;
+ } else if (*src == ':' && i == 0 && src+1 < eow && src[1] == ':' &&
+ gapPos == -1) {
+ gapPos = i;
+ src += 2;
+ } else {
+ return 0;
+ }
+ }
+
+ if (setWords > 8 ||
+ (setWords == 8 && gapPos != -1) ||
+ (setWords < 8 && gapPos == -1))
+ return 0;
+
+ if (gapPos >= 0) {
+ int nToMove = setWords - (dot ? 2 : 0) - gapPos;
+ int gapLen = 8 - setWords;
+ tor_assert(nToMove >= 0);
+ memmove(&words[gapPos+gapLen], &words[gapPos],
+ sizeof(uint16_t)*nToMove);
+ memset(&words[gapPos], 0, sizeof(uint16_t)*gapLen);
+ }
+ for (i = 0; i < 8; ++i) {
+ out->s6_addr[2*i ] = words[i] >> 8;
+ out->s6_addr[2*i+1] = words[i] & 0xff;
+ }
+
+ return 1;
+ } else {
+ return -1;
+ }
+}
diff --git a/src/lib/net/inaddr.h b/src/lib/net/inaddr.h
@@ -0,0 +1,27 @@
+/* Copyright (c) 2003-2004, Roger Dingledine
+ * Copyright (c) 2004-2006, Roger Dingledine, Nick Mathewson.
+ * Copyright (c) 2007-2018, The Tor Project, Inc. */
+/* See LICENSE for licensing information */
+
+/**
+ * \file inaddr.h
+ * \brief Header for inaddr.c.
+ **/
+
+#ifndef TOR_INADDR_H
+#define TOR_INADDR_H
+
+#include "orconfig.h"
+#include <stddef.h>
+
+struct in_addr;
+
+int tor_inet_aton(const char *str, struct in_addr *addr);
+/** Length of a buffer to allocate to hold the results of tor_inet_ntoa.*/
+#define INET_NTOA_BUF_LEN 16
+int tor_inet_ntoa(const struct in_addr *in, char *buf, size_t buf_len);
+
+const char *tor_inet_ntop(int af, const void *src, char *dst, size_t len);
+int tor_inet_pton(int af, const char *src, void *dst);
+
+#endif
diff --git a/src/lib/net/inaddr_st.h b/src/lib/net/inaddr_st.h
@@ -0,0 +1,92 @@
+/* Copyright (c) 2003-2004, Roger Dingledine
+ * Copyright (c) 2004-2006, Roger Dingledine, Nick Mathewson.
+ * Copyright (c) 2007-2018, The Tor Project, Inc. */
+/* See LICENSE for licensing information */
+
+/**
+ * \file inaddr_st.h
+ *
+ * \brief Define in6_addr, its members, and related types on platforms that
+ * lack it.
+ **/
+
+#ifndef TOR_INADDR_ST_H
+#define TOR_INADDR_ST_H
+
+#ifdef HAVE_NETINET_IN6_H
+#include <netinet/in6.h>
+#endif
+
+#ifdef _WIN32
+#include <winsock2.h>
+#include <ws2tcpip.h>
+#include <windows.h>
+#endif
+
+#include "lib/cc/torint.h"
+
+struct in_addr;
+
+/** Implementation of struct in6_addr for platforms that do not have it.
+ * Generally, these platforms are ones without IPv6 support, but we want to
+ * have a working in6_addr there anyway, so we can use it to parse IPv6
+ * addresses. */
+#if !defined(HAVE_STRUCT_IN6_ADDR)
+struct in6_addr
+{
+ union {
+ uint8_t u6_addr8[16];
+ uint16_t u6_addr16[8];
+ uint32_t u6_addr32[4];
+ } in6_u;
+#define s6_addr in6_u.u6_addr8
+#define s6_addr16 in6_u.u6_addr16
+#define s6_addr32 in6_u.u6_addr32
+};
+#endif /* !defined(HAVE_STRUCT_IN6_ADDR) */
+
+/** @{ */
+/** Many BSD variants seem not to define these. */
+#if defined(__APPLE__) || defined(__darwin__) || \
+ defined(__FreeBSD__) || defined(__NetBSD__) || defined(__OpenBSD__)
+#ifndef s6_addr16
+#define s6_addr16 __u6_addr.__u6_addr16
+#endif
+#ifndef s6_addr32
+#define s6_addr32 __u6_addr.__u6_addr32
+#endif
+#endif /* defined(__APPLE__) || defined(__darwin__) || ... */
+/** @} */
+
+#ifndef HAVE_SA_FAMILY_T
+typedef uint16_t sa_family_t;
+#endif
+
+/** @{ */
+/** Apparently, MS and Solaris don't define s6_addr16 or s6_addr32; these
+ * macros get you a pointer to s6_addr32 or local equivalent. */
+#ifdef HAVE_STRUCT_IN6_ADDR_S6_ADDR32
+#define S6_ADDR32(x) ((uint32_t*)(x).s6_addr32)
+#else
+#define S6_ADDR32(x) ((uint32_t*)((char*)&(x).s6_addr))
+#endif
+#ifdef HAVE_STRUCT_IN6_ADDR_S6_ADDR16
+#define S6_ADDR16(x) ((uint16_t*)(x).s6_addr16)
+#else
+#define S6_ADDR16(x) ((uint16_t*)((char*)&(x).s6_addr))
+#endif
+/** @} */
+
+/** Implementation of struct sockaddr_in6 on platforms that do not have
+ * it. See notes on struct in6_addr. */
+#if !defined(HAVE_STRUCT_SOCKADDR_IN6)
+struct sockaddr_in6 {
+ sa_family_t sin6_family;
+ uint16_t sin6_port;
+ // uint32_t sin6_flowinfo;
+ struct in6_addr sin6_addr;
+ // uint32_t sin6_scope_id;
+};
+#endif /* !defined(HAVE_STRUCT_SOCKADDR_IN6) */
+
+#endif /* TOR_INADDR_ST_H */
diff --git a/src/lib/net/include.am b/src/lib/net/include.am
@@ -10,8 +10,7 @@ src_lib_libtor_net_a_SOURCES = \
src/lib/net/alertsock.c \
src/lib/net/buffers_net.c \
src/lib/net/gethostname.c \
- src/lib/net/ipv4.c \
- src/lib/net/ipv6.c \
+ src/lib/net/inaddr.c \
src/lib/net/resolve.c \
src/lib/net/socket.c
@@ -25,8 +24,8 @@ noinst_HEADERS += \
src/lib/net/alertsock.h \
src/lib/net/buffers_net.h \
src/lib/net/gethostname.h \
- src/lib/net/ipv4.h \
- src/lib/net/ipv6.h \
+ src/lib/net/inaddr.h \
+ src/lib/net/inaddr_st.h \
src/lib/net/nettypes.h \
src/lib/net/resolve.h \
src/lib/net/socket.h \
diff --git a/src/lib/net/ipv4.c b/src/lib/net/ipv4.c
@@ -1,57 +0,0 @@
-/* Copyright (c) 2003-2004, Roger Dingledine
- * Copyright (c) 2004-2006, Roger Dingledine, Nick Mathewson.
- * Copyright (c) 2007-2018, The Tor Project, Inc. */
-/* See LICENSE for licensing information */
-
-/**
- * \file ipv4.c
- * \brief Functions for encoding and decoding IPv4 addresses into strings
- **/
-
-#include "orconfig.h"
-#include "lib/cc/torint.h"
-#include "lib/net/ipv4.h"
-#include "lib/string/printf.h"
-#include "lib/string/scanf.h"
-
-#ifdef HAVE_ARPA_INET_H
-#include <arpa/inet.h>
-#endif
-#ifdef _WIN32
-#include <winsock2.h>
-#endif
-
-/** Set *addr to the IP address (in dotted-quad notation) stored in *str.
- * Return 1 on success, 0 if *str is badly formatted.
- * (Like inet_aton(str,addr), but works on Windows and Solaris.)
- */
-int
-tor_inet_aton(const char *str, struct in_addr* addr)
-{
- unsigned a,b,c,d;
- char more;
- if (tor_sscanf(str, "%3u.%3u.%3u.%3u%c", &a,&b,&c,&d,&more) != 4)
- return 0;
- if (a > 255) return 0;
- if (b > 255) return 0;
- if (c > 255) return 0;
- if (d > 255) return 0;
- addr->s_addr = htonl((a<<24) | (b<<16) | (c<<8) | d);
- return 1;
-}
-
-/** Given an IPv4 in_addr struct *<b>in</b> (in network order, as usual),
- * write it as a string into the <b>buf_len</b>-byte buffer in
- * <b>buf</b>. Returns a non-negative integer on success.
- * Returns -1 on failure.
- */
-int
-tor_inet_ntoa(const struct in_addr *in, char *buf, size_t buf_len)
-{
- uint32_t a = ntohl(in->s_addr);
- return tor_snprintf(buf, buf_len, "%d.%d.%d.%d",
- (int)(uint8_t)((a>>24)&0xff),
- (int)(uint8_t)((a>>16)&0xff),
- (int)(uint8_t)((a>>8 )&0xff),
- (int)(uint8_t)((a )&0xff));
-}
diff --git a/src/lib/net/ipv4.h b/src/lib/net/ipv4.h
@@ -1,21 +0,0 @@
-/* Copyright (c) 2003-2004, Roger Dingledine
- * Copyright (c) 2004-2006, Roger Dingledine, Nick Mathewson.
- * Copyright (c) 2007-2018, The Tor Project, Inc. */
-/* See LICENSE for licensing information */
-
-/**
- * \file ipv4.h
- * \brief Header for ipv4.c
- **/
-#ifndef TOR_IPV4_H
-#define TOR_IPV4_H
-
-#include <stddef.h>
-
-struct in_addr;
-int tor_inet_aton(const char *str, struct in_addr *addr);
-/** Length of a buffer to allocate to hold the results of tor_inet_ntoa.*/
-#define INET_NTOA_BUF_LEN 16
-int tor_inet_ntoa(const struct in_addr *in, char *buf, size_t buf_len);
-
-#endif
diff --git a/src/lib/net/ipv6.c b/src/lib/net/ipv6.c
@@ -1,228 +0,0 @@
-/* Copyright (c) 2003-2004, Roger Dingledine
- * Copyright (c) 2004-2006, Roger Dingledine, Nick Mathewson.
- * Copyright (c) 2007-2018, The Tor Project, Inc. */
-/* See LICENSE for licensing information */
-
-/**
- * \file ipv6.c
- * \brief Functions for encoding and decoding IPv6 addresses
- *
- * (Because these functions are generic, they can also handle IPv4 addresses).
- **/
-
-#include "lib/net/ipv6.h"
-#include "lib/net/ipv4.h"
-#include "lib/string/util_string.h"
-#include "lib/string/compat_string.h"
-#include "lib/string/compat_ctype.h"
-#include "lib/string/printf.h"
-#include "lib/string/scanf.h"
-#include "lib/log/util_bug.h"
-
-#ifdef HAVE_ARPA_INET_H
-#include <arpa/inet.h>
-#endif
-
-#include <stdlib.h>
-#include <string.h>
-
-/** Given <b>af</b>==AF_INET and <b>src</b> a struct in_addr, or
- * <b>af</b>==AF_INET6 and <b>src</b> a struct in6_addr, try to format the
- * address and store it in the <b>len</b>-byte buffer <b>dst</b>. Returns
- * <b>dst</b> on success, NULL on failure.
- *
- * (Like inet_ntop(af,src,dst,len), but works on platforms that don't have it:
- * Tor sometimes needs to format ipv6 addresses even on platforms without ipv6
- * support.) */
-const char *
-tor_inet_ntop(int af, const void *src, char *dst, size_t len)
-{
- if (af == AF_INET) {
- if (tor_inet_ntoa(src, dst, len) < 0)
- return NULL;
- else
- return dst;
- } else if (af == AF_INET6) {
- const struct in6_addr *addr = src;
- char buf[64], *cp;
- int longestGapLen = 0, longestGapPos = -1, i,
- curGapPos = -1, curGapLen = 0;
- uint16_t words[8];
- for (i = 0; i < 8; ++i) {
- words[i] = (((uint16_t)addr->s6_addr[2*i])<<8) + addr->s6_addr[2*i+1];
- }
- if (words[0] == 0 && words[1] == 0 && words[2] == 0 && words[3] == 0 &&
- words[4] == 0 && ((words[5] == 0 && words[6] && words[7]) ||
- (words[5] == 0xffff))) {
- /* This is an IPv4 address. */
- if (words[5] == 0) {
- tor_snprintf(buf, sizeof(buf), "::%d.%d.%d.%d",
- addr->s6_addr[12], addr->s6_addr[13],
- addr->s6_addr[14], addr->s6_addr[15]);
- } else {
- tor_snprintf(buf, sizeof(buf), "::%x:%d.%d.%d.%d", words[5],
- addr->s6_addr[12], addr->s6_addr[13],
- addr->s6_addr[14], addr->s6_addr[15]);
- }
- if ((strlen(buf) + 1) > len) /* +1 for \0 */
- return NULL;
- strlcpy(dst, buf, len);
- return dst;
- }
- i = 0;
- while (i < 8) {
- if (words[i] == 0) {
- curGapPos = i++;
- curGapLen = 1;
- while (i<8 && words[i] == 0) {
- ++i; ++curGapLen;
- }
- if (curGapLen > longestGapLen) {
- longestGapPos = curGapPos;
- longestGapLen = curGapLen;
- }
- } else {
- ++i;
- }
- }
- if (longestGapLen<=1)
- longestGapPos = -1;
-
- cp = buf;
- for (i = 0; i < 8; ++i) {
- if (words[i] == 0 && longestGapPos == i) {
- if (i == 0)
- *cp++ = ':';
- *cp++ = ':';
- while (i < 8 && words[i] == 0)
- ++i;
- --i; /* to compensate for loop increment. */
- } else {
- tor_snprintf(cp, sizeof(buf)-(cp-buf), "%x", (unsigned)words[i]);
- cp += strlen(cp);
- if (i != 7)
- *cp++ = ':';
- }
- }
- *cp = '\0';
- if ((strlen(buf) + 1) > len) /* +1 for \0 */
- return NULL;
- strlcpy(dst, buf, len);
- return dst;
- } else {
- return NULL;
- }
-}
-
-/** Given <b>af</b>==AF_INET or <b>af</b>==AF_INET6, and a string <b>src</b>
- * encoding an IPv4 address or IPv6 address correspondingly, try to parse the
- * address and store the result in <b>dst</b> (which must have space for a
- * struct in_addr or a struct in6_addr, as appropriate). Return 1 on success,
- * 0 on a bad parse, and -1 on a bad <b>af</b>.
- *
- * (Like inet_pton(af,src,dst) but works on platforms that don't have it: Tor
- * sometimes needs to format ipv6 addresses even on platforms without ipv6
- * support.) */
-int
-tor_inet_pton(int af, const char *src, void *dst)
-{
- if (af == AF_INET) {
- return tor_inet_aton(src, dst);
- } else if (af == AF_INET6) {
- struct in6_addr *out = dst;
- uint16_t words[8];
- int gapPos = -1, i, setWords=0;
- const char *dot = strchr(src, '.');
- const char *eow; /* end of words. */
- memset(words, 0xf8, sizeof(words));
- if (dot == src)
- return 0;
- else if (!dot)
- eow = src+strlen(src);
- else {
- unsigned byte1,byte2,byte3,byte4;
- char more;
- for (eow = dot-1; eow > src && TOR_ISDIGIT(*eow); --eow)
- ;
- if (*eow != ':')
- return 0;
- ++eow;
-
- /* We use "scanf" because some platform inet_aton()s are too lax
- * about IPv4 addresses of the form "1.2.3" */
- if (tor_sscanf(eow, "%3u.%3u.%3u.%3u%c",
- &byte1,&byte2,&byte3,&byte4,&more) != 4)
- return 0;
-
- if (byte1 > 255 || byte2 > 255 || byte3 > 255 || byte4 > 255)
- return 0;
-
- words[6] = (byte1<<8) | byte2;
- words[7] = (byte3<<8) | byte4;
- setWords += 2;
- }
-
- i = 0;
- while (src < eow) {
- if (i > 7)
- return 0;
- if (TOR_ISXDIGIT(*src)) {
- char *next;
- ssize_t len;
- long r = strtol(src, &next, 16);
- if (next == NULL || next == src) {
- /* The 'next == src' error case can happen on versions of openbsd
- * which treat "0xfoo" as an error, rather than as "0" followed by
- * "xfoo". */
- return 0;
- }
-
- len = *next == '\0' ? eow - src : next - src;
- if (len > 4)
- return 0;
- if (len > 1 && !TOR_ISXDIGIT(src[1]))
- return 0; /* 0x is not valid */
-
- tor_assert(r >= 0);
- tor_assert(r < 65536);
- words[i++] = (uint16_t)r;
- setWords++;
- src = next;
- if (*src != ':' && src != eow)
- return 0;
- ++src;
- } else if (*src == ':' && i > 0 && gapPos == -1) {
- gapPos = i;
- ++src;
- } else if (*src == ':' && i == 0 && src+1 < eow && src[1] == ':' &&
- gapPos == -1) {
- gapPos = i;
- src += 2;
- } else {
- return 0;
- }
- }
-
- if (setWords > 8 ||
- (setWords == 8 && gapPos != -1) ||
- (setWords < 8 && gapPos == -1))
- return 0;
-
- if (gapPos >= 0) {
- int nToMove = setWords - (dot ? 2 : 0) - gapPos;
- int gapLen = 8 - setWords;
- tor_assert(nToMove >= 0);
- memmove(&words[gapPos+gapLen], &words[gapPos],
- sizeof(uint16_t)*nToMove);
- memset(&words[gapPos], 0, sizeof(uint16_t)*gapLen);
- }
- for (i = 0; i < 8; ++i) {
- out->s6_addr[2*i ] = words[i] >> 8;
- out->s6_addr[2*i+1] = words[i] & 0xff;
- }
-
- return 1;
- } else {
- return -1;
- }
-}
diff --git a/src/lib/net/ipv6.h b/src/lib/net/ipv6.h
@@ -1,91 +0,0 @@
-/* Copyright (c) 2003-2004, Roger Dingledine
- * Copyright (c) 2004-2006, Roger Dingledine, Nick Mathewson.
- * Copyright (c) 2007-2018, The Tor Project, Inc. */
-/* See LICENSE for licensing information */
-
-/**
- * \file ipv6.h
- * \brief Header for ipv6.c
- **/
-
-#ifndef TOR_IPV6_H
-#define TOR_IPV6_H
-
-#include "orconfig.h"
-#include <stddef.h>
-#ifdef HAVE_NETINET_IN6_H
-#include <netinet/in6.h>
-#endif
-#ifdef _WIN32
-#include <winsock2.h>
-#include <ws2tcpip.h>
-#include <windows.h>
-#endif
-#include "lib/cc/torint.h"
-
-/** Implementation of struct in6_addr for platforms that do not have it.
- * Generally, these platforms are ones without IPv6 support, but we want to
- * have a working in6_addr there anyway, so we can use it to parse IPv6
- * addresses. */
-#if !defined(HAVE_STRUCT_IN6_ADDR)
-struct in6_addr
-{
- union {
- uint8_t u6_addr8[16];
- uint16_t u6_addr16[8];
- uint32_t u6_addr32[4];
- } in6_u;
-#define s6_addr in6_u.u6_addr8
-#define s6_addr16 in6_u.u6_addr16
-#define s6_addr32 in6_u.u6_addr32
-};
-#endif /* !defined(HAVE_STRUCT_IN6_ADDR) */
-
-/** @{ */
-/** Many BSD variants seem not to define these. */
-#if defined(__APPLE__) || defined(__darwin__) || \
- defined(__FreeBSD__) || defined(__NetBSD__) || defined(__OpenBSD__)
-#ifndef s6_addr16
-#define s6_addr16 __u6_addr.__u6_addr16
-#endif
-#ifndef s6_addr32
-#define s6_addr32 __u6_addr.__u6_addr32
-#endif
-#endif /* defined(__APPLE__) || defined(__darwin__) || ... */
-/** @} */
-
-#ifndef HAVE_SA_FAMILY_T
-typedef uint16_t sa_family_t;
-#endif
-
-/** @{ */
-/** Apparently, MS and Solaris don't define s6_addr16 or s6_addr32; these
- * macros get you a pointer to s6_addr32 or local equivalent. */
-#ifdef HAVE_STRUCT_IN6_ADDR_S6_ADDR32
-#define S6_ADDR32(x) ((uint32_t*)(x).s6_addr32)
-#else
-#define S6_ADDR32(x) ((uint32_t*)((char*)&(x).s6_addr))
-#endif
-#ifdef HAVE_STRUCT_IN6_ADDR_S6_ADDR16
-#define S6_ADDR16(x) ((uint16_t*)(x).s6_addr16)
-#else
-#define S6_ADDR16(x) ((uint16_t*)((char*)&(x).s6_addr))
-#endif
-/** @} */
-
-/** Implementation of struct sockaddr_in6 on platforms that do not have
- * it. See notes on struct in6_addr. */
-#if !defined(HAVE_STRUCT_SOCKADDR_IN6)
-struct sockaddr_in6 {
- sa_family_t sin6_family;
- uint16_t sin6_port;
- // uint32_t sin6_flowinfo;
- struct in6_addr sin6_addr;
- // uint32_t sin6_scope_id;
-};
-#endif /* !defined(HAVE_STRUCT_SOCKADDR_IN6) */
-
-const char *tor_inet_ntop(int af, const void *src, char *dst, size_t len);
-int tor_inet_pton(int af, const char *src, void *dst);
-
-#endif
diff --git a/src/tools/tor-gencert.c b/src/tools/tor-gencert.c
@@ -41,7 +41,7 @@ ENABLE_GCC_WARNING(redundant-decls)
#include "lib/log/torlog.h"
#include "lib/malloc/util_malloc.h"
#include "lib/net/address.h"
-#include "lib/net/ipv4.h"
+#include "lib/net/inaddr.h"
#include "lib/string/compat_string.h"
#include "lib/string/printf.h"