xref: /netbsd/external/bsd/dhcpcd/dist/src/if.h (revision 3ee74c9a)
10d34b412Sroy /* SPDX-License-Identifier: BSD-2-Clause */
24e3ebfccSroy /*
34e3ebfccSroy  * dhcpcd - DHCP client daemon
4*3ee74c9aSroy  * Copyright (c) 2006-2023 Roy Marples <roy@marples.name>
54e3ebfccSroy  * All rights reserved
64e3ebfccSroy 
74e3ebfccSroy  * Redistribution and use in source and binary forms, with or without
84e3ebfccSroy  * modification, are permitted provided that the following conditions
94e3ebfccSroy  * are met:
104e3ebfccSroy  * 1. Redistributions of source code must retain the above copyright
114e3ebfccSroy  *    notice, this list of conditions and the following disclaimer.
124e3ebfccSroy  * 2. Redistributions in binary form must reproduce the above copyright
134e3ebfccSroy  *    notice, this list of conditions and the following disclaimer in the
144e3ebfccSroy  *    documentation and/or other materials provided with the distribution.
154e3ebfccSroy  *
164e3ebfccSroy  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
174e3ebfccSroy  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
184e3ebfccSroy  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
194e3ebfccSroy  * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
204e3ebfccSroy  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
214e3ebfccSroy  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
224e3ebfccSroy  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
234e3ebfccSroy  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
244e3ebfccSroy  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
254e3ebfccSroy  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
264e3ebfccSroy  * SUCH DAMAGE.
274e3ebfccSroy  */
284e3ebfccSroy 
294e3ebfccSroy #ifndef INTERFACE_H
304e3ebfccSroy #define INTERFACE_H
314e3ebfccSroy 
324e3ebfccSroy #include <net/if.h>
334e3ebfccSroy #include <net/route.h>		/* for RTM_ADD et all */
344e3ebfccSroy #include <netinet/in.h>
354e3ebfccSroy #ifdef BSD
364e3ebfccSroy #include <netinet/in_var.h>	/* for IN_IFF_TENTATIVE et all */
374e3ebfccSroy #endif
384e3ebfccSroy 
39e86140c7Sroy #include <ifaddrs.h>
40e86140c7Sroy 
410c09469fSroy /* If the interface does not support carrier status (ie PPP),
420c09469fSroy  * dhcpcd can poll it for the relevant flags periodically */
430c09469fSroy #define IF_POLL_UP	100	/* milliseconds */
440c09469fSroy 
454e3ebfccSroy /*
464e3ebfccSroy  * Systems which handle 1 address per alias.
474e3ebfccSroy  * Currenly this is just Solaris.
484e3ebfccSroy  * While Linux can do aliased addresses, it is only useful for their
494e3ebfccSroy  * legacy ifconfig(8) tool which cannot display >1 IPv4 address
504e3ebfccSroy  * (it can display many IPv6 addresses which makes the limitation odd).
514e3ebfccSroy  * Linux has ip(8) which is a more feature rich tool, without the above
524e3ebfccSroy  * restriction.
534e3ebfccSroy  */
544e3ebfccSroy #ifndef ALIAS_ADDR
554e3ebfccSroy #  ifdef __sun
564e3ebfccSroy #    define ALIAS_ADDR
574e3ebfccSroy #  endif
584e3ebfccSroy #endif
594e3ebfccSroy 
604e3ebfccSroy #include "config.h"
6122f7cecaSroy 
6222f7cecaSroy /* POSIX defines ioctl request as an int, which Solaris and musl use.
6322f7cecaSroy  * Everyone else use an unsigned long, which happens to be the bigger one
6422f7cecaSroy  * so we use that in our on wire API. */
6522f7cecaSroy #ifdef IOCTL_REQUEST_TYPE
6622f7cecaSroy typedef IOCTL_REQUEST_TYPE	ioctl_request_t;
6722f7cecaSroy #else
6822f7cecaSroy typedef unsigned long		ioctl_request_t;
6922f7cecaSroy #endif
7022f7cecaSroy 
714e3ebfccSroy #include "dhcpcd.h"
724e3ebfccSroy #include "ipv4.h"
734e3ebfccSroy #include "ipv6.h"
744e3ebfccSroy #include "route.h"
754e3ebfccSroy 
764e3ebfccSroy #define EUI64_ADDR_LEN			8
774e3ebfccSroy #define INFINIBAND_ADDR_LEN		20
784e3ebfccSroy 
794e3ebfccSroy /* Linux 2.4 doesn't define this */
804e3ebfccSroy #ifndef ARPHRD_IEEE1394
814e3ebfccSroy #  define ARPHRD_IEEE1394		24
824e3ebfccSroy #endif
834e3ebfccSroy 
844e3ebfccSroy /* The BSD's don't define this yet */
854e3ebfccSroy #ifndef ARPHRD_INFINIBAND
864e3ebfccSroy #  define ARPHRD_INFINIBAND		32
874e3ebfccSroy #endif
884e3ebfccSroy 
8922f7cecaSroy /* Maximum frame length.
9022f7cecaSroy  * Support jumbo frames and some extra. */
9122f7cecaSroy #define	FRAMEHDRLEN_MAX			14	/* only ethernet support */
9222f7cecaSroy #define	FRAMELEN_MAX			(FRAMEHDRLEN_MAX + 9216)
9322f7cecaSroy 
9454b96bebSroy #define UDPLEN_MAX			64 * 1024
9554b96bebSroy 
964e3ebfccSroy /* Work out if we have a private address or not
974e3ebfccSroy  * 10/8
984e3ebfccSroy  * 172.16/12
994e3ebfccSroy  * 192.168/16
1004e3ebfccSroy  */
1014e3ebfccSroy #ifndef IN_PRIVATE
1024e3ebfccSroy # define IN_PRIVATE(addr) (((addr & IN_CLASSA_NET) == 0x0a000000) ||	      \
1034e3ebfccSroy 	    ((addr & 0xfff00000)    == 0xac100000) ||			      \
1044e3ebfccSroy 	    ((addr & IN_CLASSB_NET) == 0xc0a80000))
1054e3ebfccSroy #endif
1064e3ebfccSroy 
1074e3ebfccSroy #ifndef CLLADDR
1084e3ebfccSroy #ifdef AF_LINK
1094e3ebfccSroy #  define CLLADDR(sdl) (const void *)((sdl)->sdl_data + (sdl)->sdl_nlen)
1104e3ebfccSroy #endif
1114e3ebfccSroy #endif
1124e3ebfccSroy 
1134e3ebfccSroy #ifdef __sun
1144e3ebfccSroy /* Solaris stupidly defines this for compat with BSD
1154e3ebfccSroy  * but then ignores it. */
1164e3ebfccSroy #undef RTF_CLONING
1174e3ebfccSroy 
11854b96bebSroy /* This interface is busted on DilOS at least.
11954b96bebSroy  * It used to work, but lukily Solaris can fall back to
12054b96bebSroy  * IP_PKTINFO. */
12154b96bebSroy #undef IP_RECVIF
122*3ee74c9aSroy #endif
12354b96bebSroy 
124*3ee74c9aSroy /* Private structures specific to an OS */
125*3ee74c9aSroy #ifdef BSD
126*3ee74c9aSroy struct priv {
127*3ee74c9aSroy #ifdef INET6
128*3ee74c9aSroy 	int pf_inet6_fd;
129*3ee74c9aSroy #endif
130*3ee74c9aSroy #if defined(SIOCALIFADDR) && defined(IFLR_ACTIVE) /*NetBSD */
131*3ee74c9aSroy 	int pf_link_fd;
132*3ee74c9aSroy #endif
133*3ee74c9aSroy };
134*3ee74c9aSroy #endif
135*3ee74c9aSroy #ifdef __linux__
136*3ee74c9aSroy struct priv {
137*3ee74c9aSroy 	int route_fd;
138*3ee74c9aSroy 	int generic_fd;
139*3ee74c9aSroy 	uint32_t route_pid;
140*3ee74c9aSroy };
141*3ee74c9aSroy #endif
142*3ee74c9aSroy #ifdef __sun
143*3ee74c9aSroy struct priv {
144*3ee74c9aSroy #ifdef INET6
145*3ee74c9aSroy 	int pf_inet6_fd;
146*3ee74c9aSroy #endif
147*3ee74c9aSroy };
148*3ee74c9aSroy #endif
149*3ee74c9aSroy 
150*3ee74c9aSroy #ifdef __sun
1514e3ebfccSroy /* Solaris getifaddrs is very un-suitable for dhcpcd.
1524e3ebfccSroy  * See if-sun.c for details why. */
1534e3ebfccSroy struct ifaddrs;
1544e3ebfccSroy int if_getifaddrs(struct ifaddrs **);
1554e3ebfccSroy #define	getifaddrs	if_getifaddrs
1560e276282Sroy int if_getsubnet(struct dhcpcd_ctx *, const char *, int, void *, size_t);
1574e3ebfccSroy #endif
1584e3ebfccSroy 
15922f7cecaSroy int if_ioctl(struct dhcpcd_ctx *, ioctl_request_t, void *, size_t);
16054b96bebSroy #ifdef HAVE_PLEDGE
16154b96bebSroy #define	pioctl(ctx, req, data, len) if_ioctl((ctx), (req), (data), (len))
16254b96bebSroy #else
16354b96bebSroy #define	pioctl(ctx, req, data, len) ioctl((ctx)->pf_inet_fd, (req),(data),(len))
16454b96bebSroy #endif
16522f7cecaSroy int if_getflags(struct interface *);
16622f7cecaSroy int if_setflag(struct interface *, short, short);
16722f7cecaSroy #define if_up(ifp) if_setflag((ifp), (IFF_UP | IFF_RUNNING), 0)
16822f7cecaSroy #define if_down(ifp) if_setflag((ifp), 0, IFF_UP);
16962451a3fSroy bool if_is_link_up(const struct interface *);
17052de4619Sroy bool if_valid_hwaddr(const uint8_t *, size_t);
171e86140c7Sroy struct if_head *if_discover(struct dhcpcd_ctx *, struct ifaddrs **,
172e86140c7Sroy     int, char * const *);
173*3ee74c9aSroy void if_freeifaddrs(struct dhcpcd_ctx *ctx, struct ifaddrs **);
1745021de5dSroy void if_markaddrsstale(struct if_head *);
175e86140c7Sroy void if_learnaddrs(struct dhcpcd_ctx *, struct if_head *, struct ifaddrs **);
1765021de5dSroy void if_deletestaleaddrs(struct if_head *);
1774e3ebfccSroy struct interface *if_find(struct if_head *, const char *);
1784e3ebfccSroy struct interface *if_findindex(struct if_head *, unsigned int);
1794e3ebfccSroy struct interface *if_loopback(struct dhcpcd_ctx *);
1804e3ebfccSroy void if_free(struct interface *);
1814e3ebfccSroy int if_domtu(const struct interface *, short int);
1824e3ebfccSroy #define if_getmtu(ifp) if_domtu((ifp), 0)
1834e3ebfccSroy #define if_setmtu(ifp, mtu) if_domtu((ifp), (mtu))
184c73d34bfSroy int if_carrier(struct interface *, const void *);
185ff6d9aefSroy bool if_roaming(struct interface *);
1864e3ebfccSroy 
187f04bcf37Sroy #ifdef ALIAS_ADDR
188f04bcf37Sroy int if_makealias(char *, size_t, const char *, int);
189f04bcf37Sroy #endif
190f04bcf37Sroy 
191f04bcf37Sroy int if_mtu_os(const struct interface *);
192f04bcf37Sroy 
1934e3ebfccSroy /*
1944e3ebfccSroy  * Helper to decode an interface name of bge0:1 to
1954e3ebfccSroy  * devname = bge0, drvname = bge0, ppa = 0, lun = 1.
1964e3ebfccSroy  * If ppa or lun are invalid they are set to -1.
1974e3ebfccSroy  */
1984e3ebfccSroy struct if_spec {
1994e3ebfccSroy 	char ifname[IF_NAMESIZE];
2004e3ebfccSroy 	char devname[IF_NAMESIZE];
2014e3ebfccSroy 	char drvname[IF_NAMESIZE];
2024e3ebfccSroy 	int ppa;
20322f7cecaSroy 	int vlid;
2044e3ebfccSroy 	int lun;
2054e3ebfccSroy };
2064e3ebfccSroy int if_nametospec(const char *, struct if_spec *);
2074e3ebfccSroy 
2084e3ebfccSroy /* The below functions are provided by if-KERNEL.c */
209c73d34bfSroy int os_init(void);
2104e3ebfccSroy int if_conf(struct interface *);
2114e3ebfccSroy int if_init(struct interface *);
2124e3ebfccSroy int if_getssid(struct interface *);
213708ac11bSroy int if_ignoregroup(int, const char *);
21429025585Sroy bool if_ignore(struct dhcpcd_ctx *, const char *);
21554b96bebSroy int if_vimaster(struct dhcpcd_ctx *ctx, const char *);
2165fed7375Sroy unsigned short if_vlanid(const struct interface *);
217c73d34bfSroy char * if_getnetworknamespace(char *, size_t);
2184e3ebfccSroy int if_opensockets(struct dhcpcd_ctx *);
2194e3ebfccSroy int if_opensockets_os(struct dhcpcd_ctx *);
2204e3ebfccSroy void if_closesockets(struct dhcpcd_ctx *);
2214e3ebfccSroy void if_closesockets_os(struct dhcpcd_ctx *);
2224e3ebfccSroy int if_handlelink(struct dhcpcd_ctx *);
22322f7cecaSroy int if_randomisemac(struct interface *);
22422f7cecaSroy int if_setmac(struct interface *ifp, void *, uint8_t);
2254e3ebfccSroy 
2264e3ebfccSroy /* dhcpcd uses the same routing flags as BSD.
2274e3ebfccSroy  * If the platform doesn't use these flags,
2284e3ebfccSroy  * map them in the platform interace file. */
2294e3ebfccSroy #ifndef RTM_ADD
2304e3ebfccSroy #define RTM_ADD		0x1	/* Add Route */
2314e3ebfccSroy #define RTM_DELETE	0x2	/* Delete Route */
2324e3ebfccSroy #define RTM_CHANGE	0x3	/* Change Metrics or flags */
2334e3ebfccSroy #define RTM_GET		0x4	/* Report Metrics */
2344e3ebfccSroy #endif
2354e3ebfccSroy 
2364e3ebfccSroy /* Define SOCK_CLOEXEC and SOCK_NONBLOCK for systems that lack it.
2374e3ebfccSroy  * xsocket() in if.c will map them to fctnl FD_CLOEXEC and O_NONBLOCK. */
2384e3ebfccSroy #ifdef SOCK_CLOEXEC
2394e3ebfccSroy # define HAVE_SOCK_CLOEXEC
2404e3ebfccSroy #else
2414e3ebfccSroy # define SOCK_CLOEXEC	0x10000000
2424e3ebfccSroy #endif
2434e3ebfccSroy #ifdef SOCK_NONBLOCK
2444e3ebfccSroy # define HAVE_SOCK_NONBLOCK
2454e3ebfccSroy #else
2464e3ebfccSroy # define SOCK_NONBLOCK	0x20000000
2474e3ebfccSroy #endif
24854b96bebSroy #ifndef SOCK_CXNB
24954b96bebSroy #define	SOCK_CXNB	SOCK_CLOEXEC | SOCK_NONBLOCK
25054b96bebSroy #endif
251e2db0f19Sroy int xsocket(int, int, int);
252e2db0f19Sroy int xsocketpair(int, int, int, int[2]);
2534e3ebfccSroy 
2544e3ebfccSroy int if_route(unsigned char, const struct rt *rt);
2550d34b412Sroy int if_initrt(struct dhcpcd_ctx *, rb_tree_t *, int);
2564e3ebfccSroy 
25722f7cecaSroy int if_missfilter(struct interface *, struct sockaddr *);
25822f7cecaSroy int if_missfilter_apply(struct dhcpcd_ctx *);
25922f7cecaSroy 
2604e3ebfccSroy #ifdef INET
2614e3ebfccSroy int if_address(unsigned char, const struct ipv4_addr *);
2624e3ebfccSroy int if_addrflags(const struct interface *, const struct in_addr *,
2634e3ebfccSroy     const char *);
2644e3ebfccSroy 
2654e3ebfccSroy #endif
2664e3ebfccSroy 
2674e3ebfccSroy #ifdef INET6
268a5ecc274Sroy void if_disable_rtadv(void);
2695021de5dSroy void if_setup_inet6(const struct interface *);
2702b9a0e7aSroy int ip6_forwarding(const char *ifname);
2714e3ebfccSroy 
27222f7cecaSroy struct ra;
27322f7cecaSroy struct ipv6_addr;
27422f7cecaSroy 
275a5ecc274Sroy int if_applyra(const struct ra *);
2764e3ebfccSroy int if_address6(unsigned char, const struct ipv6_addr *);
2774e3ebfccSroy int if_addrflags6(const struct interface *, const struct in6_addr *,
2784e3ebfccSroy     const char *);
2794e3ebfccSroy int if_getlifetime6(struct ipv6_addr *);
2804e3ebfccSroy 
2814e3ebfccSroy #else
2824e3ebfccSroy #define if_checkipv6(a, b, c) (-1)
2834e3ebfccSroy #endif
2844e3ebfccSroy 
2854e3ebfccSroy int if_machinearch(char *, size_t);
286f04bcf37Sroy struct interface *if_findifpfromcmsg(struct dhcpcd_ctx *,
287f04bcf37Sroy     struct msghdr *, int *);
28822f7cecaSroy 
28922f7cecaSroy #ifdef __linux__
29054b96bebSroy int if_linksocket(struct sockaddr_nl *, int, int);
29122f7cecaSroy int if_getnetlink(struct dhcpcd_ctx *, struct iovec *, int, int,
29222f7cecaSroy     int (*)(struct dhcpcd_ctx *, void *, struct nlmsghdr *), void *);
29322f7cecaSroy #endif
2944e3ebfccSroy #endif
295