]> git.saurik.com Git - apple/configd.git/blob - nwi/network_information_priv.h
configd-596.12.tar.gz
[apple/configd.git] / nwi / network_information_priv.h
1 /*
2 * Copyright (c) 2011-2013 Apple Inc. All rights reserved.
3 *
4 * @APPLE_LICENSE_HEADER_START@
5 *
6 * This file contains Original Code and/or Modifications of Original Code
7 * as defined in and that are subject to the Apple Public Source License
8 * Version 2.0 (the 'License'). You may not use this file except in
9 * compliance with the License. Please obtain a copy of the License at
10 * http://www.opensource.apple.com/apsl/ and read it before using this
11 * file.
12 *
13 * The Original Code and all software distributed under the License are
14 * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
15 * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
16 * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
17 * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT.
18 * Please see the License for the specific language governing rights and
19 * limitations under the License.
20 *
21 * @APPLE_LICENSE_HEADER_END@
22 */
23
24 #ifndef _NETWORK_INFORMATION_PRIV_H_
25 #define _NETWORK_INFORMATION_PRIV_H_
26
27 #include <CommonCrypto/CommonDigest.h>
28 #include <net/if.h>
29 #include <stdbool.h>
30 #include <stdint.h>
31 #include <string.h>
32 #include <netinet/in.h>
33 #include <sys/socket.h>
34
35 #include "network_information.h"
36
37 extern const sa_family_t nwi_af_list[2];
38
39 #define NWI_IFSTATE_FLAGS_NOT_IN_LIST 0x8
40 #define NWI_IFSTATE_FLAGS_HAS_SIGNATURE 0x10
41
42 #define NWI_PTR(type, name) \
43 union { \
44 type name; \
45 uint64_t _ ## name ## _p; \
46 }
47
48 typedef uint32_t Rank;
49
50 #pragma pack(4)
51 typedef struct _nwi_ifstate {
52 char ifname[IFNAMSIZ];
53 uint64_t flags;
54 NWI_PTR(nwi_ifstate_t, af_alias);
55 Rank rank;
56 sa_family_t af;
57 union {
58 struct in_addr iaddr;
59 struct in6_addr iaddr6;
60 };
61 NWI_PTR(const char *, diff_str);
62 uint64_t if_generation_count;
63 uint32_t reach_flags;
64 union {
65 struct sockaddr_in vpn_server_address4;
66 struct sockaddr_in6 vpn_server_address6;
67 } vpn_server_address;
68 unsigned char signature[CC_SHA1_DIGEST_LENGTH];
69 } nwi_ifstate;
70 #pragma pack()
71
72 /*
73 * nwi_state
74 *
75 *+---------------------------------------------+
76 *| generation_count |
77 *| |
78 *----------------------------------------------+
79 *| size |
80 *| |
81 *|---------------------------------------------+
82 *| ipv4_count |
83 *| |
84 *|---------------------------------------------+
85 *| ipv6_count |
86 *| |
87 *|---------------------------------------------+
88 *| ipv6_start |-------+
89 *| | |
90 *|---------------------------------------------+ |ipv6_start stores the index of the start of the v6 list.
91 *| ref (reference count) | |
92 *| | |
93 *|---------------------------------------------+ |
94 *| svr (TRUE if copied from server) | |
95 *| | |
96 *|---------------------------------------------+ |
97 *| reach_flags_v4 | |
98 *| | |
99 *|---------------------------------------------+ |
100 *| reach_flags_v6 | |
101 *| | |
102 *|---------------------------------------------+ |
103 *| IPv4 nwi_ifstates | |
104 *| |<------|-------+
105 *| ... | | |
106 *|---------------------------------------------+ | |
107 *| Sentinel nwi_ifstates | | |
108 *| flags =NWI_IFSTATE_FLAGS_RANK_NEVER) | | | af_alias points to the same ifstate in the
109 *| | | | opposite (v4 -> v6 and vice versa) af list.
110 *|---------------------------------------------+ | |
111 *| IPv6 nwi_ifstates |<------+ |
112 *| |<--------------+
113 *| ... |
114 *|---------------------------------------------+
115 *| Sentinel nwi_ifstates |
116 *| flags =NWI_IFSTATE_FLAGS_RANK_NEVER) |
117 *| |
118 *|---------------------------------------------+
119 *
120 */
121 #pragma pack(4)
122 typedef struct _nwi_state {
123 uint64_t generation_count;
124 uint32_t size;
125 uint32_t ipv4_count;
126 uint32_t ipv6_count;
127 uint32_t ipv6_start;
128 uint32_t ref;
129 _Bool svr;
130 uint32_t reach_flags_v4;
131 uint32_t reach_flags_v6;
132 nwi_ifstate nwi_ifstates[0];
133 } nwi_state;
134 #pragma pack()
135
136 static __inline__ int
137 uint32_cmp(uint32_t a, uint32_t b)
138 {
139 int ret;
140
141 if (a == b) {
142 ret = 0;
143 }
144 else if (a < b) {
145 ret = -1;
146 }
147 else {
148 ret = 1;
149 }
150 return (ret);
151 }
152
153 static __inline__ int
154 RankCompare(Rank a, Rank b)
155 {
156 return (uint32_cmp(a, b));
157 }
158
159 /*
160 * Function: nwi_state_get_ifstate_count
161 * Purpose:
162 * Return the number of ifstate elements for the specified address family
163 * 'af'. 'af' is either AF_INET or AF_INET6.
164 *
165 * Returns zero if there are no elements.
166 */
167 static __inline__
168 int
169 nwi_state_get_ifstate_count(nwi_state_t state, int af)
170 {
171 return (af == AF_INET)?state->ipv4_count:state->ipv6_count;
172 }
173
174 /*
175 * The ifstate list is sorted in order of decreasing priority, with the
176 * highest priority element appearing at index zero.
177 *
178 * If 'idx' is outside of the bounds of the corresponding array, returns NULL.
179 */
180 static __inline__
181 nwi_ifstate_t
182 nwi_state_get_ifstate_with_index(nwi_state_t state, int af, int idx)
183 {
184 nwi_ifstate_t nwi_ifstate = NULL;
185 int i_idx = idx;
186
187 if (idx > nwi_state_get_ifstate_count(state, af)) {
188 return (nwi_ifstate);
189 }
190
191 if (af == AF_INET6) {
192 i_idx = idx + state->ipv6_start;
193 }
194
195 return &state->nwi_ifstates[i_idx];
196 }
197
198 /*
199 * Function: nwi_state_get_ifstate_with_name
200 * Purpose:
201 * Return the ifstate for the specified ifstate for the specified address
202 * family 'af'. 'af' is either AF_INET or AF_INET6.
203 *
204 * Returns NULL if no such information exists.
205 */
206 static __inline__
207 nwi_ifstate_t
208 nwi_state_get_ifstate_with_name(nwi_state_t state,
209 int af, const char * name)
210 {
211 int idx = 0;
212 int count;
213 nwi_ifstate_t ifstate = NULL;
214
215 if (state == NULL) {
216 return ifstate;
217 }
218
219 count = (af == AF_INET)
220 ?state->ipv4_count:state->ipv6_count;
221
222
223 while (idx < count) {
224 ifstate = nwi_state_get_ifstate_with_index(state, af, idx);
225 if (ifstate == NULL) {
226 break;
227 }
228 if (strcmp(name,
229 nwi_ifstate_get_ifname(ifstate)) == 0) {
230 return (ifstate);
231 }
232 idx++;
233 }
234 return (NULL);
235 }
236
237 static __inline__
238 void
239 _nwi_ifstate_set_vpn_server(nwi_ifstate_t ifstate, struct sockaddr *serv_addr)
240 {
241 size_t len;
242
243 if (serv_addr == NULL) {
244 bzero(&ifstate->vpn_server_address,
245 sizeof(ifstate->vpn_server_address));
246 return;
247 }
248
249 len = serv_addr->sa_len;
250
251 if (len == 0 || len > sizeof(ifstate->vpn_server_address)) {
252 return;
253 }
254
255 memcpy(&ifstate->vpn_server_address,
256 serv_addr,
257 len);
258 return;
259
260 }
261
262 static __inline__
263 void
264 _nwi_state_set_reachability_flags(nwi_state_t state, uint32_t reach_flags_v4, uint32_t reach_flags_v6)
265 {
266 state->reach_flags_v4 = reach_flags_v4;
267 state->reach_flags_v6 = reach_flags_v6;
268 return;
269 }
270
271 nwi_state_t
272 nwi_state_new(nwi_state_t old_state, int elems);
273
274 nwi_state_t
275 nwi_state_copy_priv(nwi_state_t old_state);
276
277 nwi_ifstate_t
278 nwi_insert_ifstate(nwi_state_t state, const char* ifname, int af,
279 uint64_t flags, Rank rank,
280 void * ifa, struct sockaddr * vpn_server_addr, uint32_t reach_flags);
281
282 void
283 nwi_ifstate_set_signature(nwi_ifstate_t ifstate, uint8_t * signature);
284
285 void
286 nwi_state_clear(nwi_state_t state, int af);
287
288 void
289 nwi_state_set_last(nwi_state_t state, int af);
290
291 nwi_state_t
292 nwi_state_diff(nwi_state_t old_state, nwi_state_t new_state);
293
294 void *
295 nwi_ifstate_get_address(nwi_ifstate_t ifstate);
296
297 const char *
298 nwi_ifstate_get_diff_str(nwi_ifstate_t ifstate);
299
300 void
301 _nwi_state_update_interface_generations(nwi_state_t old_state, nwi_state_t state, nwi_state_t changes);
302
303 void
304 _nwi_state_force_refresh();
305
306 #endif