1 /* SPDX-License-Identifier: BSD-2-Clause */ 2 /* 3 * dhcpcd - DHCP client daemon 4 * Copyright (c) 2006-2025 Roy Marples <roy (at) marples.name> 5 * All rights reserved 6 7 * Redistribution and use in source and binary forms, with or without 8 * modification, are permitted provided that the following conditions 9 * are met: 10 * 1. Redistributions of source code must retain the above copyright 11 * notice, this list of conditions and the following disclaimer. 12 * 2. Redistributions in binary form must reproduce the above copyright 13 * notice, this list of conditions and the following disclaimer in the 14 * documentation and/or other materials provided with the distribution. 15 * 16 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND 17 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 18 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 19 * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE 20 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 21 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 22 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 23 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 24 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 25 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 26 * SUCH DAMAGE. 27 */ 28 29 #ifndef IPV4_H 30 #define IPV4_H 31 32 #include "dhcpcd.h" 33 34 /* Prefer our macro */ 35 #ifdef HTONL 36 #undef HTONL 37 #endif 38 39 #ifndef BYTE_ORDER 40 #define BIG_ENDIAN 1234 41 #define LITTLE_ENDIAN 4321 42 #if defined(_BIG_ENDIAN) 43 #define BYTE_ORDER BIG_ENDIAN 44 #elif defined(_LITTLE_ENDIAN) 45 #define BYTE_ORDER LITTLE_ENDIAN 46 #else 47 #error Endian unknown 48 #endif 49 #endif 50 51 #if BYTE_ORDER == BIG_ENDIAN 52 #define HTONL(A) (A) 53 #elif BYTE_ORDER == LITTLE_ENDIAN 54 #define HTONL(A) \ 55 ((((uint32_t)(A) & 0xff000000) >> 24) | \ 56 (((uint32_t)(A) & 0x00ff0000) >> 8) | \ 57 (((uint32_t)(A) & 0x0000ff00) << 8) | \ 58 (((uint32_t)(A) & 0x000000ff) << 24)) 59 #endif /* BYTE_ORDER */ 60 61 #ifndef IPV4_MMTU 62 #define IPV4_MMTU 68 63 #endif 64 65 #ifdef __sun 66 /* Solaris lacks these defines. 67 * While it supports DaD, to seems to only expose IFF_DUPLICATE 68 * so we have no way of knowing if it's tentative or not. 69 * I don't even know if Solaris has any special treatment for tentative. */ 70 # define IN_IFF_TENTATIVE 0x01 71 # define IN_IFF_DUPLICATED 0x02 72 # define IN_IFF_DETACHED 0x00 73 #endif 74 75 #ifdef IN_IFF_TENTATIVE 76 #define IN_IFF_NOTUSEABLE \ 77 (IN_IFF_TENTATIVE | IN_IFF_DUPLICATED | IN_IFF_DETACHED) 78 #endif 79 80 #define IN_ARE_ADDR_EQUAL(a, b) ((a)->s_addr == (b)->s_addr) 81 #define IN_IS_ADDR_UNSPECIFIED(a) ((a)->s_addr == INADDR_ANY) 82 83 #ifdef __linux__ 84 #define IP_LIFETIME 85 #endif 86 87 struct ipv4_addr { 88 TAILQ_ENTRY(ipv4_addr) next; 89 struct in_addr addr; 90 struct in_addr mask; 91 struct in_addr brd; 92 struct interface *iface; 93 int addr_flags; 94 unsigned int flags; 95 #ifdef IP_LIFETIME 96 uint32_t vltime; 97 uint32_t pltime; 98 #endif 99 char saddr[INET_ADDRSTRLEN + 3]; 100 #ifdef ALIAS_ADDR 101 char alias[IF_NAMESIZE]; 102 #endif 103 }; 104 TAILQ_HEAD(ipv4_addrhead, ipv4_addr); 105 106 #define IPV4_AF_STALE (1U << 0) 107 #define IPV4_AF_NEW (1U << 1) 108 109 #define IPV4_ADDR_EQ(a1, a2) ((a1) && (a1)->addr.s_addr == (a2)->addr.s_addr) 110 #define IPV4_MASK1_EQ(a1, a2) ((a1) && (a1)->mask.s_addr == (a2)->mask.s_addr) 111 #define IPV4_MASK_EQ(a1, a2) (IPV4_ADDR_EQ(a1, a2) && IPV4_MASK1_EQ(a1, a2)) 112 #define IPV4_BRD1_EQ(a1, a2) ((a1) && (a1)->brd.s_addr == (a2)->brd.s_addr) 113 #define IPV4_BRD_EQ(a1, a2) (IPV4_MASK_EQ(a1, a2) && IPV4_BRD1_EQ(a1, a2)) 114 115 struct ipv4_state { 116 struct ipv4_addrhead addrs; 117 }; 118 119 #define IPV4_STATE(ifp) \ 120 ((struct ipv4_state *)(ifp)->if_data[IF_DATA_IPV4]) 121 #define IPV4_CSTATE(ifp) \ 122 ((const struct ipv4_state *)(ifp)->if_data[IF_DATA_IPV4]) 123 124 #ifdef INET 125 struct ipv4_state *ipv4_getstate(struct interface *); 126 int ipv4_ifcmp(const struct interface *, const struct interface *); 127 uint8_t inet_ntocidr(struct in_addr); 128 int inet_cidrtoaddr(int, struct in_addr *); 129 uint32_t ipv4_getnetmask(uint32_t); 130 int ipv4_hasaddr(const struct interface *); 131 132 bool inet_getroutes(struct dhcpcd_ctx *, rb_tree_t *); 133 134 #define STATE_ADDED 0x01 135 #define STATE_FAKE 0x02 136 #define STATE_EXPIRED 0x04 137 138 int ipv4_deladdr(struct ipv4_addr *, int); 139 struct ipv4_addr *ipv4_addaddr(struct interface *, 140 const struct in_addr *, const struct in_addr *, const struct in_addr *, 141 uint32_t, uint32_t); 142 struct ipv4_addr *ipv4_applyaddr(void *); 143 144 struct ipv4_addr *ipv4_iffindaddr(struct interface *, 145 const struct in_addr *, const struct in_addr *); 146 struct ipv4_addr *ipv4_iffindlladdr(struct interface *); 147 struct ipv4_addr *ipv4_findaddr(struct dhcpcd_ctx *, const struct in_addr *); 148 struct ipv4_addr *ipv4_findmaskaddr(struct dhcpcd_ctx *, 149 const struct in_addr *); 150 struct ipv4_addr *ipv4_findmaskbrd(struct dhcpcd_ctx *, 151 const struct in_addr *); 152 void ipv4_markaddrsstale(struct interface *); 153 void ipv4_deletestaleaddrs(struct interface *); 154 void ipv4_handleifa(struct dhcpcd_ctx *, int, struct if_head *, const char *, 155 const struct in_addr *, const struct in_addr *, const struct in_addr *, 156 int, pid_t); 157 158 void ipv4_free(struct interface *); 159 #endif /* INET */ 160 161 #endif /* IPV4_H */ 162