#ifndef TOR_ADDRESS_H
#define TOR_ADDRESS_H
#include "orconfig.h"
#include "lib/cc/torint.h"
#include "lib/log/util_bug.h"
#include "lib/net/inaddr_st.h"
#include "lib/net/nettypes.h"
#ifdef HAVE_NETINET_IN_H
#include <netinet/in.h>
#endif
#ifdef _WIN32
#include <winsock2.h>
#include <windows.h>
#endif
#include <stddef.h>
#include <stdlib.h>
#ifdef ADDRESS_PRIVATE
#if defined(HAVE_SYS_IOCTL_H)
#include <sys/ioctl.h>
#endif
#ifdef HAVE_GETIFADDRS
#define HAVE_IFADDRS_TO_SMARTLIST
#endif
#ifdef _WIN32
#define HAVE_IP_ADAPTER_TO_SMARTLIST
#endif
#if defined(SIOCGIFCONF) && defined(HAVE_IOCTL)
#define HAVE_IFCONF_TO_SMARTLIST
#endif
#if defined(HAVE_NET_IF_H)
#include <net/if.h>
#endif
#if defined(HAVE_IFADDRS_TO_SMARTLIST)
#include <ifaddrs.h>
#endif
#endif
typedef uint8_t maskbits_t;
struct in_addr;
typedef struct tor_addr_t
{
sa_family_t family;
union {
uint32_t dummy_;
struct in_addr in_addr;
struct in6_addr in6_addr;
} addr;
} tor_addr_t;
typedef struct tor_addr_port_t
{
tor_addr_t addr;
uint16_t port;
} tor_addr_port_t;
#define TOR_ADDR_NULL {AF_UNSPEC, {0}}
static inline const struct in6_addr *tor_addr_to_in6(const tor_addr_t *a);
static inline const struct in6_addr *tor_addr_to_in6_assert(
const tor_addr_t *a);
static inline uint32_t tor_addr_to_ipv4n(const tor_addr_t *a);
static inline uint32_t tor_addr_to_ipv4h(const tor_addr_t *a);
static inline uint32_t tor_addr_to_mapped_ipv4h(const tor_addr_t *a);
static inline sa_family_t tor_addr_family(const tor_addr_t *a);
static inline const struct in_addr *tor_addr_to_in(const tor_addr_t *a);
static inline int tor_addr_eq_ipv4h(const tor_addr_t *a, uint32_t u);
socklen_t tor_addr_to_sockaddr(const tor_addr_t *a, uint16_t port,
struct sockaddr *sa_out, socklen_t len);
int tor_addr_from_sockaddr(tor_addr_t *a, const struct sockaddr *sa,
uint16_t *port_out);
void tor_addr_make_unspec(tor_addr_t *a);
void tor_addr_make_null(tor_addr_t *a, sa_family_t family);
#define tor_addr_port_make_null(addr, port, family) \
(void)(tor_addr_make_null(addr, family), (port) = 0)
#define tor_addr_port_make_null_ap(ap, family) \
tor_addr_port_make_null(&(ap)->addr, (ap)->port, family)
char *tor_sockaddr_to_str(const struct sockaddr *sa);
static inline const struct in6_addr *
tor_addr_to_in6(const tor_addr_t *a)
{
return a->family == AF_INET6 ? &a->addr.in6_addr : NULL;
}
static inline const struct in6_addr *
tor_addr_to_in6_assert(const tor_addr_t *a)
{
tor_assert(a->family == AF_INET6);
return &a->addr.in6_addr;
}
#define tor_addr_to_in6_addr8(x) tor_addr_to_in6_assert(x)->s6_addr
#define tor_addr_to_in6_addr16(x) S6_ADDR16(*tor_addr_to_in6_assert(x))
#define tor_addr_to_in6_addr32(x) S6_ADDR32(*tor_addr_to_in6_assert(x))
static inline uint32_t
tor_addr_to_ipv4n(const tor_addr_t *a)
{
return a->family == AF_INET ? a->addr.in_addr.s_addr : 0;
}
static inline uint32_t
tor_addr_to_ipv4h(const tor_addr_t *a)
{
return ntohl(tor_addr_to_ipv4n(a));
}
static inline uint32_t
tor_addr_to_mapped_ipv4h(const tor_addr_t *a)
{
if (a->family == AF_INET6) {
uint32_t *addr32 = NULL;
addr32 = tor_addr_to_in6_addr32(a);
tor_assert(addr32);
return ntohl(addr32[3]);
} else {
return 0;
}
}
static inline sa_family_t
tor_addr_family(const tor_addr_t *a)
{
return a->family;
}
static inline const struct in_addr *
tor_addr_to_in(const tor_addr_t *a)
{
return a->family == AF_INET ? &a->addr.in_addr : NULL;
}
static inline int
tor_addr_eq_ipv4h(const tor_addr_t *a, uint32_t u)
{
return a->family == AF_INET ? (tor_addr_to_ipv4h(a) == u) : 0;
}
#define TOR_ADDR_BUF_LEN 48
#define TOR_ADDRPORT_BUF_LEN (TOR_ADDR_BUF_LEN + 6)
char *tor_addr_to_str_dup(const tor_addr_t *addr) ATTR_MALLOC;
#define fmt_addr(a) fmt_addr_impl((a), 0)
#define fmt_and_decorate_addr(a) fmt_addr_impl((a), 1)
const char *fmt_addr_impl(const tor_addr_t *addr, int decorate);
const char *fmt_addrport(const tor_addr_t *addr, uint16_t port);
#define fmt_addrport_ap(ap) fmt_addrport(&(ap)->addr, (ap)->port)
const char *fmt_addr32(uint32_t addr);
const char *fmt_addr_family(const tor_addr_t *addr);
MOCK_DECL(int,get_interface_address6,(int severity, sa_family_t family,
tor_addr_t *addr));
struct smartlist_t;
void interface_address6_list_free_(struct smartlist_t * addrs);
#define interface_address6_list_free(addrs) \
FREE_AND_NULL(struct smartlist_t, interface_address6_list_free_, (addrs))
MOCK_DECL(struct smartlist_t *,get_interface_address6_list,(int severity,
sa_family_t family,
int include_internal));
typedef enum {
CMP_EXACT,
CMP_SEMANTIC,
} tor_addr_comparison_t;
int tor_addr_compare(const tor_addr_t *addr1, const tor_addr_t *addr2,
tor_addr_comparison_t how);
int tor_addr_compare_masked(const tor_addr_t *addr1, const tor_addr_t *addr2,
maskbits_t mask, tor_addr_comparison_t how);
#define tor_addr_eq(a,b) (0==tor_addr_compare((a),(b),CMP_EXACT))
uint64_t tor_addr_hash(const tor_addr_t *addr);
struct sipkey;
uint64_t tor_addr_keyed_hash(const struct sipkey *key, const tor_addr_t *addr);
int tor_addr_is_v4(const tor_addr_t *addr);
int tor_addr_is_internal_(const tor_addr_t *ip, int for_listening,
const char *filename, int lineno);
#define tor_addr_is_internal(addr, for_listening) \
tor_addr_is_internal_((addr), (for_listening), SHORT_FILE__, __LINE__)
int tor_addr_is_multicast(const tor_addr_t *a);
#define REVERSE_LOOKUP_NAME_BUF_LEN 73
int tor_addr_to_PTR_name(char *out, size_t outlen,
const tor_addr_t *addr);
int tor_addr_parse_PTR_name(tor_addr_t *result, const char *address,
int family, int accept_regular);
#define TAPMP_EXTENDED_STAR 1
#define TAPMP_STAR_IPV4_ONLY (1 << 1)
#define TAPMP_STAR_IPV6_ONLY (1 << 2)
int tor_addr_parse_mask_ports(const char *s, unsigned flags,
tor_addr_t *addr_out, maskbits_t *mask_out,
uint16_t *port_min_out, uint16_t *port_max_out);
const char * tor_addr_to_str(char *dest, const tor_addr_t *addr, size_t len,
int decorate);
int tor_addr_parse(tor_addr_t *addr, const char *src);
void tor_addr_copy(tor_addr_t *dest, const tor_addr_t *src);
void tor_addr_copy_tight(tor_addr_t *dest, const tor_addr_t *src);
void tor_addr_from_ipv4n(tor_addr_t *dest, uint32_t v4addr);
#define tor_addr_from_ipv4h(dest, v4addr) \
tor_addr_from_ipv4n((dest), htonl(v4addr))
void tor_addr_from_ipv6_bytes(tor_addr_t *dest, const uint8_t *bytes);
#define tor_addr_from_in(dest, in) \
tor_addr_from_ipv4n((dest), (in)->s_addr);
void tor_addr_from_in6(tor_addr_t *dest, const struct in6_addr *in6);
void tor_addr_copy_ipv6_bytes(uint8_t *dest, const tor_addr_t *src);
int tor_addr_is_null(const tor_addr_t *addr);
int tor_addr_is_loopback(const tor_addr_t *addr);
int tor_addr_is_valid(const tor_addr_t *addr, int for_listening);
int tor_addr_is_valid_ipv4n(uint32_t v4n_addr, int for_listening);
#define tor_addr_is_valid_ipv4h(v4h_addr, for_listening) \
tor_addr_is_valid_ipv4n(htonl(v4h_addr), (for_listening))
int tor_port_is_valid(uint16_t port, int for_listening);
#define tor_addr_port_is_valid(addr, port, for_listening) \
(tor_addr_is_valid((addr), (for_listening)) && \
tor_port_is_valid((port), (for_listening)))
#define tor_addr_port_is_valid_ap(ap, for_listening) \
tor_addr_port_is_valid(&(ap)->addr, (ap)->port, (for_listening))
#define tor_addr_port_is_valid_ipv4n(v4n_addr, port, for_listening) \
(tor_addr_is_valid_ipv4n((v4n_addr), (for_listening)) && \
tor_port_is_valid((port), (for_listening)))
#define tor_addr_port_is_valid_ipv4h(v4h_addr, port, for_listening) \
(tor_addr_is_valid_ipv4h((v4h_addr), (for_listening)) && \
tor_port_is_valid((port), (for_listening)))
int tor_addr_port_split(int severity, const char *addrport,
char **address_out, uint16_t *port_out);
int tor_addr_port_parse(int severity, const char *addrport,
tor_addr_t *address_out, uint16_t *port_out,
int default_port);
int tor_addr_hostname_is_local(const char *name);
int parse_port_range(const char *port, uint16_t *port_min_out,
uint16_t *port_max_out);
int addr_mask_get_bits(uint32_t mask);
char *tor_dup_ip(uint32_t addr) ATTR_MALLOC;
MOCK_DECL(int,get_interface_address,(int severity, uint32_t *addr));
#define interface_address_list_free(lst)\
interface_address6_list_free(lst)
static inline struct smartlist_t *
get_interface_address_list(int severity, int include_internal)
{
return get_interface_address6_list(severity, AF_INET, include_internal);
}
tor_addr_port_t *tor_addr_port_new(const tor_addr_t *addr, uint16_t port);
int tor_addr_port_eq(const tor_addr_port_t *a,
const tor_addr_port_t *b);
int string_is_valid_dest(const char *string);
int string_is_valid_nonrfc_hostname(const char *string);
int string_is_valid_ipv4_address(const char *string);
int string_is_valid_ipv6_address(const char *string);
#ifdef ADDRESS_PRIVATE
MOCK_DECL(struct smartlist_t *,get_interface_addresses_raw,(int severity,
sa_family_t family));
MOCK_DECL(int,get_interface_address6_via_udp_socket_hack,(int severity,
sa_family_t family,
tor_addr_t *addr));
#ifdef HAVE_IFADDRS_TO_SMARTLIST
STATIC struct smartlist_t *ifaddrs_to_smartlist(const struct ifaddrs *ifa,
sa_family_t family);
STATIC struct smartlist_t *get_interface_addresses_ifaddrs(int severity,
sa_family_t family);
#endif
#ifdef HAVE_IP_ADAPTER_TO_SMARTLIST
STATIC struct smartlist_t *ip_adapter_addresses_to_smartlist(
const IP_ADAPTER_ADDRESSES *addresses);
STATIC struct smartlist_t *get_interface_addresses_win32(int severity,
sa_family_t family);
#endif
#ifdef HAVE_IFCONF_TO_SMARTLIST
STATIC struct smartlist_t *ifreq_to_smartlist(const uint8_t *ifr,
size_t buflen);
STATIC struct smartlist_t *get_interface_addresses_ioctl(int severity,
sa_family_t family);
#endif
#endif
#endif