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