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