xref: /dragonfly/contrib/dhcpcd/src/if.h (revision 89656a4e)
1 /* SPDX-License-Identifier: BSD-2-Clause */
2 /*
3  * dhcpcd - DHCP client daemon
4  * Copyright (c) 2006-2020 Roy Marples <roy@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 INTERFACE_H
30 #define INTERFACE_H
31 
32 #include <net/if.h>
33 #include <net/route.h>		/* for RTM_ADD et all */
34 #include <netinet/in.h>
35 #ifdef BSD
36 #include <netinet/in_var.h>	/* for IN_IFF_TENTATIVE et all */
37 #endif
38 
39 #include <ifaddrs.h>
40 
41 /* Some systems have in-built IPv4 DAD.
42  * However, we need them to do DAD at carrier up as well. */
43 #ifdef IN_IFF_TENTATIVE
44 #  ifdef __NetBSD__
45 #    define NOCARRIER_PRESERVE_IP
46 #  endif
47 #endif
48 
49 /*
50  * Systems which handle 1 address per alias.
51  * Currenly this is just Solaris.
52  * While Linux can do aliased addresses, it is only useful for their
53  * legacy ifconfig(8) tool which cannot display >1 IPv4 address
54  * (it can display many IPv6 addresses which makes the limitation odd).
55  * Linux has ip(8) which is a more feature rich tool, without the above
56  * restriction.
57  */
58 #ifndef ALIAS_ADDR
59 #  ifdef __sun
60 #    define ALIAS_ADDR
61 #  endif
62 #endif
63 
64 #include "config.h"
65 
66 /* POSIX defines ioctl request as an int, which Solaris and musl use.
67  * Everyone else use an unsigned long, which happens to be the bigger one
68  * so we use that in our on wire API. */
69 #ifdef IOCTL_REQUEST_TYPE
70 typedef IOCTL_REQUEST_TYPE	ioctl_request_t;
71 #else
72 typedef unsigned long		ioctl_request_t;
73 #endif
74 
75 #include "dhcpcd.h"
76 #include "ipv4.h"
77 #include "ipv6.h"
78 #include "route.h"
79 
80 #define EUI64_ADDR_LEN			8
81 #define INFINIBAND_ADDR_LEN		20
82 
83 /* Linux 2.4 doesn't define this */
84 #ifndef ARPHRD_IEEE1394
85 #  define ARPHRD_IEEE1394		24
86 #endif
87 
88 /* The BSD's don't define this yet */
89 #ifndef ARPHRD_INFINIBAND
90 #  define ARPHRD_INFINIBAND		32
91 #endif
92 
93 /* Maximum frame length.
94  * Support jumbo frames and some extra. */
95 #define	FRAMEHDRLEN_MAX			14	/* only ethernet support */
96 #define	FRAMELEN_MAX			(FRAMEHDRLEN_MAX + 9216)
97 
98 #define UDPLEN_MAX			64 * 1024
99 
100 /* Work out if we have a private address or not
101  * 10/8
102  * 172.16/12
103  * 192.168/16
104  */
105 #ifndef IN_PRIVATE
106 # define IN_PRIVATE(addr) (((addr & IN_CLASSA_NET) == 0x0a000000) ||	      \
107 	    ((addr & 0xfff00000)    == 0xac100000) ||			      \
108 	    ((addr & IN_CLASSB_NET) == 0xc0a80000))
109 #endif
110 
111 #ifndef CLLADDR
112 #ifdef AF_LINK
113 #  define CLLADDR(sdl) (const void *)((sdl)->sdl_data + (sdl)->sdl_nlen)
114 #endif
115 #endif
116 
117 #ifdef __sun
118 /* Solaris stupidly defines this for compat with BSD
119  * but then ignores it. */
120 #undef RTF_CLONING
121 
122 /* This interface is busted on DilOS at least.
123  * It used to work, but lukily Solaris can fall back to
124  * IP_PKTINFO. */
125 #undef IP_RECVIF
126 
127 /* Solaris getifaddrs is very un-suitable for dhcpcd.
128  * See if-sun.c for details why. */
129 struct ifaddrs;
130 int if_getifaddrs(struct ifaddrs **);
131 #define	getifaddrs	if_getifaddrs
132 int if_getsubnet(struct dhcpcd_ctx *, const char *, int, void *, size_t);
133 #endif
134 
135 int if_ioctl(struct dhcpcd_ctx *, ioctl_request_t, void *, size_t);
136 #ifdef HAVE_PLEDGE
137 #define	pioctl(ctx, req, data, len) if_ioctl((ctx), (req), (data), (len))
138 #else
139 #define	pioctl(ctx, req, data, len) ioctl((ctx)->pf_inet_fd, (req),(data),(len))
140 #endif
141 int if_getflags(struct interface *);
142 int if_setflag(struct interface *, short, short);
143 #define if_up(ifp) if_setflag((ifp), (IFF_UP | IFF_RUNNING), 0)
144 #define if_down(ifp) if_setflag((ifp), 0, IFF_UP);
145 bool if_valid_hwaddr(const uint8_t *, size_t);
146 struct if_head *if_discover(struct dhcpcd_ctx *, struct ifaddrs **,
147     int, char * const *);
148 void if_markaddrsstale(struct if_head *);
149 void if_learnaddrs(struct dhcpcd_ctx *, struct if_head *, struct ifaddrs **);
150 void if_deletestaleaddrs(struct if_head *);
151 struct interface *if_find(struct if_head *, const char *);
152 struct interface *if_findindex(struct if_head *, unsigned int);
153 struct interface *if_loopback(struct dhcpcd_ctx *);
154 void if_free(struct interface *);
155 int if_domtu(const struct interface *, short int);
156 #define if_getmtu(ifp) if_domtu((ifp), 0)
157 #define if_setmtu(ifp, mtu) if_domtu((ifp), (mtu))
158 int if_carrier(struct interface *);
159 
160 #ifdef ALIAS_ADDR
161 int if_makealias(char *, size_t, const char *, int);
162 #endif
163 
164 int if_mtu_os(const struct interface *);
165 
166 /*
167  * Helper to decode an interface name of bge0:1 to
168  * devname = bge0, drvname = bge0, ppa = 0, lun = 1.
169  * If ppa or lun are invalid they are set to -1.
170  */
171 struct if_spec {
172 	char ifname[IF_NAMESIZE];
173 	char devname[IF_NAMESIZE];
174 	char drvname[IF_NAMESIZE];
175 	int ppa;
176 	int vlid;
177 	int lun;
178 };
179 int if_nametospec(const char *, struct if_spec *);
180 
181 /* The below functions are provided by if-KERNEL.c */
182 int if_conf(struct interface *);
183 int if_init(struct interface *);
184 int if_getssid(struct interface *);
185 int if_ignoregroup(int, const char *);
186 bool if_ignore(struct dhcpcd_ctx *, const char *);
187 int if_vimaster(struct dhcpcd_ctx *ctx, const char *);
188 unsigned short if_vlanid(const struct interface *);
189 int if_opensockets(struct dhcpcd_ctx *);
190 int if_opensockets_os(struct dhcpcd_ctx *);
191 void if_closesockets(struct dhcpcd_ctx *);
192 void if_closesockets_os(struct dhcpcd_ctx *);
193 int if_handlelink(struct dhcpcd_ctx *);
194 int if_randomisemac(struct interface *);
195 int if_setmac(struct interface *ifp, void *, uint8_t);
196 
197 /* dhcpcd uses the same routing flags as BSD.
198  * If the platform doesn't use these flags,
199  * map them in the platform interace file. */
200 #ifndef RTM_ADD
201 #define RTM_ADD		0x1	/* Add Route */
202 #define RTM_DELETE	0x2	/* Delete Route */
203 #define RTM_CHANGE	0x3	/* Change Metrics or flags */
204 #define RTM_GET		0x4	/* Report Metrics */
205 #endif
206 
207 /* Define SOCK_CLOEXEC and SOCK_NONBLOCK for systems that lack it.
208  * xsocket() in if.c will map them to fctnl FD_CLOEXEC and O_NONBLOCK. */
209 #ifdef SOCK_CLOEXEC
210 # define HAVE_SOCK_CLOEXEC
211 #else
212 # define SOCK_CLOEXEC	0x10000000
213 #endif
214 #ifdef SOCK_NONBLOCK
215 # define HAVE_SOCK_NONBLOCK
216 #else
217 # define SOCK_NONBLOCK	0x20000000
218 #endif
219 #ifndef SOCK_CXNB
220 #define	SOCK_CXNB	SOCK_CLOEXEC | SOCK_NONBLOCK
221 #endif
222 
223 int if_route(unsigned char, const struct rt *rt);
224 int if_initrt(struct dhcpcd_ctx *, rb_tree_t *, int);
225 
226 int if_missfilter(struct interface *, struct sockaddr *);
227 int if_missfilter_apply(struct dhcpcd_ctx *);
228 
229 #ifdef INET
230 int if_address(unsigned char, const struct ipv4_addr *);
231 int if_addrflags(const struct interface *, const struct in_addr *,
232     const char *);
233 
234 #endif
235 
236 #ifdef INET6
237 void if_disable_rtadv(void);
238 void if_setup_inet6(const struct interface *);
239 int ip6_forwarding(const char *ifname);
240 
241 struct ra;
242 struct ipv6_addr;
243 
244 int if_applyra(const struct ra *);
245 int if_address6(unsigned char, const struct ipv6_addr *);
246 int if_addrflags6(const struct interface *, const struct in6_addr *,
247     const char *);
248 int if_getlifetime6(struct ipv6_addr *);
249 
250 #else
251 #define if_checkipv6(a, b, c) (-1)
252 #endif
253 
254 int if_machinearch(char *, size_t);
255 struct interface *if_findifpfromcmsg(struct dhcpcd_ctx *,
256     struct msghdr *, int *);
257 int xsocket(int, int, int);
258 
259 #ifdef __linux__
260 int if_linksocket(struct sockaddr_nl *, int, int);
261 int if_getnetlink(struct dhcpcd_ctx *, struct iovec *, int, int,
262     int (*)(struct dhcpcd_ctx *, void *, struct nlmsghdr *), void *);
263 #endif
264 #endif
265