1/* 2 * ntp_net.h - definitions for NTP network stuff 3 */ 4 5#ifndef NTP_NET_H 6#define NTP_NET_H 7 8#include <sys/types.h> 9#ifdef HAVE_SYS_SOCKET_H 10#include <sys/socket.h> 11#endif 12#ifdef HAVE_NETINET_IN_H 13#include <netinet/in.h> 14#endif 15 16#include "ntp_rfc2553.h" 17 18typedef union { 19 struct sockaddr sa; 20 struct sockaddr_storage sas; 21 struct sockaddr_in sa4; 22 struct sockaddr_in6 sa6; 23} sockaddr_u; 24 25/* 26 * Utilities for manipulating sockaddr_u v4/v6 unions 27 */ 28#define SOCK_ADDR4(psau) ((psau)->sa4.sin_addr) 29#define SOCK_ADDR6(psau) ((psau)->sa6.sin6_addr) 30 31#define PSOCK_ADDR4(psau) (&SOCK_ADDR4(psau)) 32#define PSOCK_ADDR6(psau) (&SOCK_ADDR6(psau)) 33 34#define AF(psau) ((psau)->sas.ss_family) 35 36#define IS_IPV4(psau) (AF_INET == AF(psau)) 37#define IS_IPV6(psau) (AF_INET6 == AF(psau)) 38 39/* sockaddr_u v4 address in network byte order */ 40#define NSRCADR(psau) (SOCK_ADDR4(psau).s_addr) 41 42/* sockaddr_u v4 address in host byte order */ 43#define SRCADR(psau) (ntohl(NSRCADR(psau))) 44 45/* sockaddr_u v6 address in network byte order */ 46#define NSRCADR6(psau) (SOCK_ADDR6(psau).s6_addr) 47 48/* assign sockaddr_u v4 address from host byte order */ 49#define SET_ADDR4(psau, addr4) (NSRCADR(psau) = htonl(addr4)) 50 51/* assign sockaddr_u v4 address from network byte order */ 52#define SET_ADDR4N(psau, addr4n) (NSRCADR(psau) = (addr4n)); 53 54/* assign sockaddr_u v6 address from network byte order */ 55#define SET_ADDR6N(psau, s6_addr) \ 56 (SOCK_ADDR6(psau) = (s6_addr)) 57 58/* sockaddr_u v4/v6 port in network byte order */ 59#define NSRCPORT(psau) ((psau)->sa4.sin_port) 60 61/* sockaddr_u v4/v6 port in host byte order */ 62#define SRCPORT(psau) (ntohs(NSRCPORT(psau))) 63 64/* assign sockaddr_u v4/v6 port from host byte order */ 65#define SET_PORT(psau, port) (NSRCPORT(psau) = htons(port)) 66 67/* sockaddr_u v6 scope */ 68#define SCOPE_VAR(psau) ((psau)->sa6.sin6_scope_id) 69 70#ifdef ISC_PLATFORM_HAVESCOPEID 71/* v4/v6 scope (always zero for v4) */ 72# define SCOPE(psau) (IS_IPV4(psau) \ 73 ? 0 \ 74 : SCOPE_VAR(psau)) 75 76/* are two v6 sockaddr_u scopes equal? */ 77# define SCOPE_EQ(psau1, psau2) \ 78 (SCOPE_VAR(psau1) == SCOPE_VAR(psau2)) 79 80/* assign scope if supported */ 81# define SET_SCOPE(psau, s) \ 82 do \ 83 if (IS_IPV6(psau)) \ 84 SCOPE_VAR(psau) = (s); \ 85 while (0) 86#else /* ISC_PLATFORM_HAVESCOPEID not defined */ 87# define SCOPE(psau) (0) 88# define SCOPE_EQ(psau1, psau2) (1) 89# define SET_SCOPE(psau, s) do { } while (0) 90#endif /* ISC_PLATFORM_HAVESCOPEID */ 91 92/* v4/v6 is multicast address */ 93#define IS_MCAST(psau) \ 94 (IS_IPV4(psau) \ 95 ? IN_CLASSD(SRCADR(psau)) \ 96 : IN6_IS_ADDR_MULTICAST(PSOCK_ADDR6(psau))) 97 98#define SIZEOF_SOCKADDR(fam) \ 99 ((AF_INET == (fam)) \ 100 ? sizeof(struct sockaddr_in) \ 101 : sizeof(struct sockaddr_in6)) 102 103#define SOCKLEN(psau) \ 104 (IS_IPV4(psau) \ 105 ? sizeof((psau)->sa4) \ 106 : sizeof((psau)->sa6)) 107 108#define ZERO_SOCK(psau) \ 109 memset(&(psau)->sas, 0, sizeof((psau)->sas)) 110 111/* blast a byte value across sockaddr_u v6 address */ 112#define MEMSET_ADDR6(psau, v) \ 113 memset((void *)(psau)->sa6.sin6_addr.s6_addr, (v), \ 114 sizeof((psau)->sa6.sin6_addr.s6_addr)) 115 116#define SET_ONESMASK(psau) \ 117 do { \ 118 if (IS_IPV6(psau)) \ 119 MEMSET_ADDR6((psau), 0xff); \ 120 else \ 121 NSRCADR(psau) = 0xffffffff; \ 122 } while(0) 123 124/* zero sockaddr_u, fill in family and all-ones (host) mask */ 125#define SET_HOSTMASK(psau, family) \ 126 do { \ 127 ZERO_SOCK(psau); \ 128 AF(psau) = (family); \ 129 SET_ONESMASK(psau); \ 130 } while (0) 131 132/* compare a in6_addr with socket address */ 133#if !defined(SYS_WINNT) || !defined(in_addr6) 134#define S_ADDR6_EQ(psau, my_in6_addr) \ 135 (!memcmp(&(psau)->sa6.sin6_addr, \ 136 (my_in6_addr), \ 137 sizeof((psau)->sa6.sin6_addr))) 138#else 139#define S_ADDR6_EQ(psau, my_in6_addr) \ 140 IN6_ADDR_EQUAL(&(psau)->sa6.sin6_addr, \ 141 (my_in6_addr)) 142#endif 143 144/* are two sockaddr_u's addresses equal? */ 145#define SOCK_EQ(psau1, psau2) \ 146 ((AF(psau1) != AF(psau2)) \ 147 ? 0 \ 148 : IS_IPV4(psau1) \ 149 ? (NSRCADR(psau1) == NSRCADR(psau2)) \ 150 : (S_ADDR6_EQ((psau1), PSOCK_ADDR6(psau2)) \ 151 && SCOPE_EQ((psau1), (psau2)))) 152 153/* is sockaddr_u address unspecified? */ 154#define SOCK_UNSPEC(psau) \ 155 (IS_IPV4(psau) \ 156 ? !NSRCADR(psau) \ 157 : IN6_IS_ADDR_UNSPECIFIED(PSOCK_ADDR6(psau))) 158 159/* just how unspecified do you mean? (scope 0/unspec too) */ 160#define SOCK_UNSPEC_S(psau) \ 161 (SOCK_UNSPEC(psau) && !SCOPE(psau)) 162 163/* choose a default net interface (struct interface) for v4 or v6 */ 164#define ANY_INTERFACE_BYFAM(family) \ 165 ((AF_INET == family) \ 166 ? any_interface \ 167 : any6_interface) 168 169/* choose a default interface for addresses' protocol (addr family) */ 170#define ANY_INTERFACE_CHOOSE(psau) \ 171 ANY_INTERFACE_BYFAM(AF(psau)) 172 173 174/* 175 * We tell reference clocks from real peers by giving the reference 176 * clocks an address of the form 127.127.t.u, where t is the type and 177 * u is the unit number. We define some of this here since we will need 178 * some sanity checks to make sure this address isn't interpretted as 179 * that of a normal peer. 180 */ 181#define REFCLOCK_ADDR 0x7f7f0000 /* 127.127.0.0 */ 182#define REFCLOCK_MASK 0xffff0000 /* 255.255.0.0 */ 183 184#ifdef REFCLOCK 185#define ISREFCLOCKADR(srcadr) \ 186 (IS_IPV4(srcadr) && \ 187 (SRCADR(srcadr) & REFCLOCK_MASK) == REFCLOCK_ADDR) 188#else 189#define ISREFCLOCKADR(srcadr) (0) 190#endif 191 192/* 193 * Macro for checking for invalid addresses. This is really, really 194 * gross, but is needed so no one configures a host on net 127 now that 195 * we're encouraging it the the configuration file. 196 */ 197#define LOOPBACKADR 0x7f000001 198#define LOOPNETMASK 0xff000000 199 200#define ISBADADR(srcadr) \ 201 (IS_IPV4(srcadr) \ 202 && ((SRCADR(srcadr) & LOOPNETMASK) \ 203 == (LOOPBACKADR & LOOPNETMASK)) \ 204 && SRCADR(srcadr) != LOOPBACKADR) 205 206 207#endif /* NTP_NET_H */ 208