tor

The Tor anonymity network
git clone https://git.dasho.dev/tor.git
Log | Files | Refs | README | LICENSE

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:
Msrc/core/or/or.h | 3+--
Msrc/lib/net/address.c | 2+-
Msrc/lib/net/address.h | 2+-
Asrc/lib/net/inaddr.c | 267+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Asrc/lib/net/inaddr.h | 27+++++++++++++++++++++++++++
Asrc/lib/net/inaddr_st.h | 92+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Msrc/lib/net/include.am | 7+++----
Dsrc/lib/net/ipv4.c | 57---------------------------------------------------------
Dsrc/lib/net/ipv4.h | 21---------------------
Dsrc/lib/net/ipv6.c | 228-------------------------------------------------------------------------------
Dsrc/lib/net/ipv6.h | 91-------------------------------------------------------------------------------
Msrc/tools/tor-gencert.c | 2+-
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"