1/*
2 * dhcpcd - DHCP client daemon
3 * Copyright (c) 2006-2019 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 INTERFACE_H
29#define INTERFACE_H
30
31#include <net/if.h>
32#include <net/route.h> /* for RTM_ADD et all */
33#include <netinet/in.h>
34#ifdef BSD
35#include <netinet/in_var.h> /* for IN_IFF_TENTATIVE et all */
36#endif
37
38#include <ifaddrs.h>
39
40/* Some systems have in-built IPv4 DAD.
41 * However, we need them to do DAD at carrier up as well. */
42#ifdef IN_IFF_TENTATIVE
43# ifdef __NetBSD__
44# define NOCARRIER_PRESERVE_IP
45# endif
46#endif
47
48/*
49 * Systems which handle 1 address per alias.
50 * Currenly this is just Solaris.
51 * While Linux can do aliased addresses, it is only useful for their
52 * legacy ifconfig(8) tool which cannot display >1 IPv4 address
53 * (it can display many IPv6 addresses which makes the limitation odd).
54 * Linux has ip(8) which is a more feature rich tool, without the above
55 * restriction.
56 */
57#ifndef ALIAS_ADDR
58# ifdef __sun
59# define ALIAS_ADDR
60# endif
61#endif
62
63#include "config.h"
64#include "dhcpcd.h"
65#include "ipv4.h"
66#include "ipv6.h"
67#include "route.h"
68
69#define EUI64_ADDR_LEN 8
70#define INFINIBAND_ADDR_LEN 20
71
72/* Linux 2.4 doesn't define this */
73#ifndef ARPHRD_IEEE1394
74# define ARPHRD_IEEE1394 24
75#endif
76
77/* The BSD's don't define this yet */
78#ifndef ARPHRD_INFINIBAND
79# define ARPHRD_INFINIBAND 32
80#endif
81
82/* Work out if we have a private address or not
83 * 10/8
84 * 172.16/12
85 * 192.168/16
86 */
87#ifndef IN_PRIVATE
88# define IN_PRIVATE(addr) (((addr & IN_CLASSA_NET) == 0x0a000000) || \
89 ((addr & 0xfff00000) == 0xac100000) || \
90 ((addr & IN_CLASSB_NET) == 0xc0a80000))
91#endif
92
93#define RAW_EOF 1 << 0
94#define RAW_PARTIALCSUM 2 << 0
95
96#ifndef CLLADDR
97#ifdef AF_LINK
98# define CLLADDR(sdl) (const void *)((sdl)->sdl_data + (sdl)->sdl_nlen)
99#endif
100#endif
101
102#ifdef __sun
103/* Solaris stupidly defines this for compat with BSD
104 * but then ignores it. */
105#undef RTF_CLONING
106
107/* Solaris getifaddrs is very un-suitable for dhcpcd.
108 * See if-sun.c for details why. */
109struct ifaddrs;
110int if_getifaddrs(struct ifaddrs **);
111#define getifaddrs if_getifaddrs
112#endif
113
114int if_getflags(struct interface *ifp);
115int if_setflag(struct interface *ifp, short flag);
116#define if_up(ifp) if_setflag((ifp), (IFF_UP | IFF_RUNNING))
117bool if_valid_hwaddr(const uint8_t *, size_t);
118struct if_head *if_discover(struct dhcpcd_ctx *, struct ifaddrs **,
119 int, char * const *);
120void if_markaddrsstale(struct if_head *);
121void if_learnaddrs(struct dhcpcd_ctx *, struct if_head *, struct ifaddrs **);
122void if_deletestaleaddrs(struct if_head *);
123struct interface *if_find(struct if_head *, const char *);
124struct interface *if_findindex(struct if_head *, unsigned int);
125struct interface *if_loopback(struct dhcpcd_ctx *);
126void if_sortinterfaces(struct dhcpcd_ctx *);
127void if_free(struct interface *);
128int if_domtu(const struct interface *, short int);
129#define if_getmtu(ifp) if_domtu((ifp), 0)
130#define if_setmtu(ifp, mtu) if_domtu((ifp), (mtu))
131int if_carrier(struct interface *);
132
133#ifdef ALIAS_ADDR
134int if_makealias(char *, size_t, const char *, int);
135#endif
136
137int if_mtu_os(const struct interface *);
138
139/*
140 * Helper to decode an interface name of bge0:1 to
141 * devname = bge0, drvname = bge0, ppa = 0, lun = 1.
142 * If ppa or lun are invalid they are set to -1.
143 */
144struct if_spec {
145 char ifname[IF_NAMESIZE];
146 char devname[IF_NAMESIZE];
147 char drvname[IF_NAMESIZE];
148 int ppa;
149 int lun;
150};
151int if_nametospec(const char *, struct if_spec *);
152
153/* The below functions are provided by if-KERNEL.c */
154int if_conf(struct interface *);
155int if_init(struct interface *);
156int if_getssid(struct interface *);
157int if_vimaster(const struct dhcpcd_ctx *ctx, const char *);
158unsigned short if_vlanid(const struct interface *);
159int if_opensockets(struct dhcpcd_ctx *);
160int if_opensockets_os(struct dhcpcd_ctx *);
161void if_closesockets(struct dhcpcd_ctx *);
162void if_closesockets_os(struct dhcpcd_ctx *);
163int if_handlelink(struct dhcpcd_ctx *);
164
165/* dhcpcd uses the same routing flags as BSD.
166 * If the platform doesn't use these flags,
167 * map them in the platform interace file. */
168#ifndef RTM_ADD
169#define RTM_ADD 0x1 /* Add Route */
170#define RTM_DELETE 0x2 /* Delete Route */
171#define RTM_CHANGE 0x3 /* Change Metrics or flags */
172#define RTM_GET 0x4 /* Report Metrics */
173#endif
174
175/* Define SOCK_CLOEXEC and SOCK_NONBLOCK for systems that lack it.
176 * xsocket() in if.c will map them to fctnl FD_CLOEXEC and O_NONBLOCK. */
177#ifdef SOCK_CLOEXEC
178# define HAVE_SOCK_CLOEXEC
179#else
180# define SOCK_CLOEXEC 0x10000000
181#endif
182#ifdef SOCK_NONBLOCK
183# define HAVE_SOCK_NONBLOCK
184#else
185# define SOCK_NONBLOCK 0x20000000
186#endif
187
188int if_route(unsigned char, const struct rt *rt);
189int if_initrt(struct dhcpcd_ctx *, int);
190
191#ifdef INET
192int if_address(unsigned char, const struct ipv4_addr *);
193int if_addrflags(const struct interface *, const struct in_addr *,
194 const char *);
195
196#endif
197
198#ifdef INET6
199void if_setup_inet6(const struct interface *);
200#ifdef IPV6_MANAGETEMPADDR
201int ip6_use_tempaddr(const char *ifname);
202int ip6_temp_preferred_lifetime(const char *ifname);
203int ip6_temp_valid_lifetime(const char *ifname);
204#else
205#define ip6_use_tempaddr(a) (0)
206#endif
207int ip6_forwarding(const char *ifname);
208
209int if_address6(unsigned char, const struct ipv6_addr *);
210int if_addrflags6(const struct interface *, const struct in6_addr *,
211 const char *);
212int if_getlifetime6(struct ipv6_addr *);
213
214#else
215#define if_checkipv6(a, b, c) (-1)
216#endif
217
218int if_machinearch(char *, size_t);
219struct interface *if_findifpfromcmsg(struct dhcpcd_ctx *,
220 struct msghdr *, int *);
221int xsocket(int, int, int);
222#endif
223