1 | /* |
---|
2 | * dhcpcd - DHCP client daemon |
---|
3 | * Copyright (c) 2006-2013 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 IPV6_H |
---|
29 | #define IPV6_H |
---|
30 | |
---|
31 | #include <sys/queue.h> |
---|
32 | |
---|
33 | #include <netinet/in.h> |
---|
34 | |
---|
35 | #define ALLROUTERS "ff02::2" |
---|
36 | #define HOPLIMIT 255 |
---|
37 | |
---|
38 | #define ROUNDUP8(a) (1 + (((a) - 1) | 7)) |
---|
39 | |
---|
40 | #ifndef ND6_INFINITE_LIFETIME |
---|
41 | # define ND6_INFINITE_LIFETIME ((uint32_t)~0) |
---|
42 | #endif |
---|
43 | |
---|
44 | /* |
---|
45 | * BSD kernels don't inform userland of DAD results. |
---|
46 | * Also, for RTM_NEWADDR messages the address flags could be |
---|
47 | * undefined leading to false positive duplicate address errors. |
---|
48 | * As such we listen for duplicate addresses on the wire and |
---|
49 | * wait the maxium possible length of time as dictated by the DAD transmission |
---|
50 | * counter and RFC timings. |
---|
51 | * See the discussion here: |
---|
52 | * http://mail-index.netbsd.org/tech-net/2013/03/15/msg004019.html |
---|
53 | */ |
---|
54 | #ifndef __linux__ |
---|
55 | /* We guard here to avoid breaking a compile on linux ppc-64 headers */ |
---|
56 | # include <sys/param.h> |
---|
57 | #endif |
---|
58 | #ifdef BSD |
---|
59 | # define LISTEN_DAD |
---|
60 | #endif |
---|
61 | |
---|
62 | /* This was fixed in NetBSD */ |
---|
63 | #ifdef __NetBSD_Prereq__ |
---|
64 | # if __NetBSD_Prereq__(6, 99, 20) |
---|
65 | # undef LISTEN_DAD |
---|
66 | # endif |
---|
67 | #endif |
---|
68 | |
---|
69 | struct ipv6_addr { |
---|
70 | TAILQ_ENTRY(ipv6_addr) next; |
---|
71 | struct interface *iface; |
---|
72 | struct in6_addr prefix; |
---|
73 | int prefix_len; |
---|
74 | uint32_t prefix_vltime; |
---|
75 | uint32_t prefix_pltime; |
---|
76 | struct in6_addr addr; |
---|
77 | short flags; |
---|
78 | char saddr[INET6_ADDRSTRLEN]; |
---|
79 | uint8_t iaid[4]; |
---|
80 | struct interface *delegating_iface; |
---|
81 | |
---|
82 | void (*dadcallback)(void *); |
---|
83 | uint8_t *ns; |
---|
84 | size_t nslen; |
---|
85 | int nsprobes; |
---|
86 | }; |
---|
87 | TAILQ_HEAD(ipv6_addrhead, ipv6_addr); |
---|
88 | |
---|
89 | #define IPV6_AF_ONLINK 0x0001 |
---|
90 | #define IPV6_AF_NEW 0x0002 |
---|
91 | #define IPV6_AF_STALE 0x0004 |
---|
92 | #define IPV6_AF_ADDED 0x0008 |
---|
93 | #define IPV6_AF_AUTOCONF 0x0010 |
---|
94 | #define IPV6_AF_DUPLICATED 0x0020 |
---|
95 | #define IPV6_AF_DADCOMPLETED 0x0040 |
---|
96 | #define IPV6_AF_DELEGATED 0x0080 |
---|
97 | |
---|
98 | struct rt6 { |
---|
99 | TAILQ_ENTRY(rt6) next; |
---|
100 | struct in6_addr dest; |
---|
101 | struct in6_addr net; |
---|
102 | struct in6_addr gate; |
---|
103 | const struct interface *iface; |
---|
104 | int metric; |
---|
105 | unsigned int mtu; |
---|
106 | }; |
---|
107 | TAILQ_HEAD(rt6head, rt6); |
---|
108 | |
---|
109 | struct ipv6_addr_l { |
---|
110 | TAILQ_ENTRY(ipv6_addr_l) next; |
---|
111 | struct in6_addr addr; |
---|
112 | }; |
---|
113 | |
---|
114 | TAILQ_HEAD(ipv6_addr_l_head, ipv6_addr_l); |
---|
115 | |
---|
116 | struct ll_callback { |
---|
117 | TAILQ_ENTRY(ll_callback) next; |
---|
118 | void (*callback)(void *); |
---|
119 | void *arg; |
---|
120 | }; |
---|
121 | TAILQ_HEAD(ll_callback_head, ll_callback); |
---|
122 | |
---|
123 | struct ipv6_state { |
---|
124 | struct ipv6_addr_l_head addrs; |
---|
125 | struct ll_callback_head ll_callbacks; |
---|
126 | }; |
---|
127 | |
---|
128 | #define IPV6_STATE(ifp) \ |
---|
129 | ((struct ipv6_state *)(ifp)->if_data[IF_DATA_IPV6]) |
---|
130 | #define IPV6_CSTATE(ifp) \ |
---|
131 | ((const struct ipv6_state *)(ifp)->if_data[IF_DATA_IPV6]) |
---|
132 | |
---|
133 | #ifdef INET6 |
---|
134 | int ipv6_init(void); |
---|
135 | ssize_t ipv6_printaddr(char *, ssize_t, const uint8_t *, const char *); |
---|
136 | int ipv6_makeaddr(struct in6_addr *, const struct interface *, |
---|
137 | const struct in6_addr *, int); |
---|
138 | int ipv6_makeprefix(struct in6_addr *, const struct in6_addr *, int); |
---|
139 | int ipv6_mask(struct in6_addr *, int); |
---|
140 | int ipv6_prefixlen(const struct in6_addr *); |
---|
141 | int ipv6_userprefix( const struct in6_addr *, short prefix_len, |
---|
142 | uint64_t user_number, struct in6_addr *result, short result_len); |
---|
143 | int ipv6_addaddr(struct ipv6_addr *); |
---|
144 | void ipv6_freedrop_addrs(struct ipv6_addrhead *, int, |
---|
145 | const struct interface *); |
---|
146 | void ipv6_handleifa(int, struct if_head *, |
---|
147 | const char *, const struct in6_addr *, int); |
---|
148 | int ipv6_handleifa_addrs(int, struct ipv6_addrhead *, |
---|
149 | const struct in6_addr *, int); |
---|
150 | const struct ipv6_addr_l *ipv6_linklocal(const struct interface *); |
---|
151 | const struct ipv6_addr_l *ipv6_findaddr(const struct interface *, |
---|
152 | const struct in6_addr *); |
---|
153 | int ipv6_addlinklocalcallback(struct interface *, void (*)(void *), void *); |
---|
154 | void ipv6_free_ll_callbacks(struct interface *); |
---|
155 | void ipv6_free(struct interface *); |
---|
156 | int ipv6_removesubnet(const struct interface *, struct ipv6_addr *); |
---|
157 | void ipv6_buildroutes(void); |
---|
158 | |
---|
159 | int if_address6(const struct ipv6_addr *, int); |
---|
160 | #define add_address6(a) if_address6(a, 1) |
---|
161 | #define del_address6(a) if_address6(a, -1) |
---|
162 | int in6_addr_flags(const char *, const struct in6_addr *); |
---|
163 | |
---|
164 | int if_route6(const struct rt6 *rt, int); |
---|
165 | #define add_route6(rt) if_route6(rt, 1) |
---|
166 | #define change_route6(rt) if_route6(rt, 0) |
---|
167 | #define del_route6(rt) if_route6(rt, -1) |
---|
168 | #define del_src_route6(rt) if_route6(rt, -2); |
---|
169 | |
---|
170 | #else |
---|
171 | #define ipv6_init() -1 |
---|
172 | #define ipv6_free_ll_callbacks(a) |
---|
173 | #define ipv6_free(a) |
---|
174 | #endif |
---|
175 | |
---|
176 | #endif |
---|