1 /* $NetBSD: ipv6.h,v 1.14 2015/07/09 10:15:34 roy Exp $ */
4 * dhcpcd - DHCP client daemon
5 * Copyright (c) 2006-2015 Roy Marples <roy@marples.name>
8 * Redistribution and use in source and binary forms, with or without
9 * modification, are permitted provided that the following conditions
11 * 1. Redistributions of source code must retain the above copyright
12 * notice, this list of conditions and the following disclaimer.
13 * 2. Redistributions in binary form must reproduce the above copyright
14 * notice, this list of conditions and the following disclaimer in the
15 * documentation and/or other materials provided with the distribution.
17 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
18 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
19 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
20 * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
21 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
22 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
23 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
24 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
25 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
26 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
34 #include <netinet/in.h>
38 # include <sys/endian.h>
41 # ifdef __FreeBSD__ /* Needed so that including netinet6/in6_var.h works */
42 # include <net/if_var.h>
45 # include <netinet6/in6_var.h>
52 #define ALLROUTERS "ff02::2"
54 #define ROUNDUP8(a) (1 + (((a) - 1) | 7))
55 #define ROUNDUP16(a) (1 + (((a) - 1) | 16))
57 #define EUI64_GBIT 0x01
58 #define EUI64_UBIT 0x02
59 #define EUI64_TO_IFID(in6) do {(in6)->s6_addr[8] ^= EUI64_UBIT; } while (0)
60 #define EUI64_GROUP(in6) ((in6)->s6_addr[8] & EUI64_GBIT)
62 #ifndef ND6_INFINITE_LIFETIME
63 # define ND6_INFINITE_LIFETIME ((uint32_t)~0)
66 /* RFC4941 constants */
67 #define TEMP_VALID_LIFETIME 604800 /* 1 week */
68 #define TEMP_PREFERRED_LIFETIME 86400 /* 1 day */
69 #define REGEN_ADVANCE 5 /* seconds */
70 #define MAX_DESYNC_FACTOR 600 /* 10 minutes */
72 #define TEMP_IDGEN_RETRIES 3
73 #define GEN_TEMPID_RETRY_MAX 5
75 /* RFC7217 constants */
76 #define IDGEN_RETRIES 3
77 #define IDGEN_DELAY 1 /* second */
80 * BSD kernels don't inform userland of DAD results.
81 * See the discussion here:
82 * http://mail-index.netbsd.org/tech-net/2013/03/15/msg004019.html
85 /* We guard here to avoid breaking a compile on linux ppc-64 headers */
86 # include <sys/param.h>
89 # define IPV6_POLLADDRFLAG
92 /* This was fixed in NetBSD */
93 #if defined(__NetBSD_Version__) && __NetBSD_Version__ >= 699002000
94 # undef IPV6_POLLADDRFLAG
97 /* Linux-3.18 can manage temporary addresses even with RA
98 * processing disabled. */
99 //#undef IFA_F_MANAGETEMPADDR
100 #if defined(__linux__) && defined(IFA_F_MANAGETEMPADDR)
101 #define IPV6_MANAGETEMPADDR
104 /* Some BSDs do not allow userland to set temporary addresses. */
105 #if defined(BSD) && defined(IN6_IFF_TEMPORARY)
106 #define IPV6_MANAGETEMPADDR
110 TAILQ_ENTRY(ipv6_addr
) next
;
111 struct interface
*iface
;
112 struct in6_addr prefix
;
114 uint32_t prefix_vltime
;
115 uint32_t prefix_pltime
;
116 struct timespec created
;
117 struct timespec acquired
;
118 struct in6_addr addr
;
121 char saddr
[INET6_ADDRSTRLEN
];
124 struct interface
*delegating_iface
;
125 uint8_t prefix_exclude_len
;
126 struct in6_addr prefix_exclude
;
128 void (*dadcallback
)(void *);
134 TAILQ_HEAD(ipv6_addrhead
, ipv6_addr
);
136 #define IPV6_AF_ONLINK 0x0001
137 #define IPV6_AF_NEW 0x0002
138 #define IPV6_AF_STALE 0x0004
139 #define IPV6_AF_ADDED 0x0008
140 #define IPV6_AF_AUTOCONF 0x0010
141 #define IPV6_AF_DUPLICATED 0x0020
142 #define IPV6_AF_DADCOMPLETED 0x0040
143 #define IPV6_AF_DELEGATED 0x0080
144 #define IPV6_AF_DELEGATEDPFX 0x0100
145 #define IPV6_AF_DELEGATEDZERO 0x0200
146 #define IPV6_AF_REQUEST 0x0400
147 #ifdef IPV6_MANAGETEMPADDR
148 #define IPV6_AF_TEMPORARY 0X0800
152 TAILQ_ENTRY(rt6
) next
;
153 struct in6_addr dest
;
155 struct in6_addr gate
;
156 const struct interface
*iface
;
158 #ifdef HAVE_ROUTE_METRIC
163 TAILQ_HEAD(rt6_head
, rt6
);
166 TAILQ_ENTRY(ll_callback
) next
;
167 void (*callback
)(void *);
170 TAILQ_HEAD(ll_callback_head
, ll_callback
);
173 struct ipv6_addrhead addrs
;
174 struct ll_callback_head ll_callbacks
;
176 #ifdef IPV6_MANAGETEMPADDR
177 time_t desync_factor
;
178 uint8_t randomseed0
[8]; /* upper 64 bits of MD5 digest */
179 uint8_t randomseed1
[8]; /* lower 64 bits */
184 #define IPV6_STATE(ifp) \
185 ((struct ipv6_state *)(ifp)->if_data[IF_DATA_IPV6])
186 #define IPV6_CSTATE(ifp) \
187 ((const struct ipv6_state *)(ifp)->if_data[IF_DATA_IPV6])
189 /* dhcpcd requires CMSG_SPACE to evaluate to a compile time constant. */
195 #define ALIGNBYTES (sizeof(int) - 1)
198 #define ALIGN(p) (((unsigned int)(p) + ALIGNBYTES) & ~ALIGNBYTES)
201 #define CMSG_SPACE(len) (ALIGN(sizeof(struct cmsghdr)) + ALIGN(len))
204 #define IP6BUFLEN (CMSG_SPACE(sizeof(struct in6_pktinfo)) + \
205 CMSG_SPACE(sizeof(int)))
210 struct sockaddr_in6 from
;
211 struct msghdr sndhdr
;
212 struct iovec sndiov
[2];
213 unsigned char sndbuf
[CMSG_SPACE(sizeof(struct in6_pktinfo
))];
214 struct msghdr rcvhdr
;
215 struct iovec rcviov
[2];
216 unsigned char rcvbuf
[IP6BUFLEN
];
217 unsigned char ansbuf
[1500];
218 char ntopbuf
[INET6_ADDRSTRLEN
];
222 struct ra_head
*ra_routers
;
223 struct rt6_head
*routes
;
225 struct rt6_head kroutes
;
230 struct ipv6_ctx
*ipv6_init(struct dhcpcd_ctx
*);
231 ssize_t
ipv6_printaddr(char *, size_t, const uint8_t *, const char *);
232 int ipv6_makestableprivate(struct in6_addr
*addr
,
233 const struct in6_addr
*prefix
, int prefix_len
,
234 const struct interface
*ifp
, int *dad_counter
);
235 int ipv6_makeaddr(struct in6_addr
*, const struct interface
*,
236 const struct in6_addr
*, int);
237 int ipv6_makeprefix(struct in6_addr
*, const struct in6_addr
*, int);
238 int ipv6_mask(struct in6_addr
*, int);
239 uint8_t ipv6_prefixlen(const struct in6_addr
*);
240 int ipv6_userprefix( const struct in6_addr
*, short prefix_len
,
241 uint64_t user_number
, struct in6_addr
*result
, short result_len
);
242 void ipv6_checkaddrflags(void *);
243 int ipv6_addaddr(struct ipv6_addr
*, const struct timespec
*);
244 ssize_t
ipv6_addaddrs(struct ipv6_addrhead
*addrs
);
245 void ipv6_freedrop_addrs(struct ipv6_addrhead
*, int,
246 const struct interface
*);
247 void ipv6_handleifa(struct dhcpcd_ctx
*ctx
, int, struct if_head
*,
248 const char *, const struct in6_addr
*, uint8_t, int);
249 int ipv6_handleifa_addrs(int, struct ipv6_addrhead
*,
250 const struct in6_addr
*, int);
251 int ipv6_publicaddr(const struct ipv6_addr
*);
252 const struct ipv6_addr
*ipv6_iffindaddr(const struct interface
*,
253 const struct in6_addr
*);
254 int ipv6_hasaddr(const struct interface
*);
255 int ipv6_findaddrmatch(const struct ipv6_addr
*, const struct in6_addr
*,
257 struct ipv6_addr
*ipv6_findaddr(struct dhcpcd_ctx
*,
258 const struct in6_addr
*, short);
259 #define ipv6_linklocal(ifp) ipv6_iffindaddr((ifp), NULL)
260 int ipv6_addlinklocalcallback(struct interface
*, void (*)(void *), void *);
261 void ipv6_freeaddr(struct ipv6_addr
*);
262 void ipv6_freedrop(struct interface
*, int);
263 #define ipv6_free(ifp) ipv6_freedrop((ifp), 0)
264 #define ipv6_drop(ifp) ipv6_freedrop((ifp), 2)
266 #ifdef IPV6_MANAGETEMPADDR
267 void ipv6_gentempifid(struct interface
*);
268 void ipv6_settempstale(struct interface
*);
269 struct ipv6_addr
*ipv6_createtempaddr(struct ipv6_addr
*,
270 const struct timespec
*);
271 struct ipv6_addr
*ipv6_settemptime(struct ipv6_addr
*, int);
272 void ipv6_addtempaddrs(struct interface
*, const struct timespec
*);
274 #define ipv6_gentempifid(a) {}
275 #define ipv6_settempstale(a) {}
278 int ipv6_start(struct interface
*);
279 void ipv6_ctxfree(struct dhcpcd_ctx
*);
280 int ipv6_handlert(struct dhcpcd_ctx
*, int cmd
, struct rt6
*);
281 void ipv6_freerts(struct rt6_head
*);
282 void ipv6_buildroutes(struct dhcpcd_ctx
*);
285 #define ipv6_init(a) (NULL)
286 #define ipv6_start(a) (-1)
287 #define ipv6_hasaddr(a) (0)
288 #define ipv6_free_ll_callbacks(a) {}
289 #define ipv6_free(a) {}
290 #define ipv6_drop(a) {}
291 #define ipv6_ctxfree(a) {}
292 #define ipv6_gentempifid(a) {}