]> git.saurik.com Git - apple/configd.git/blob - nwi/network_state_information_priv.h
configd-963.30.1.tar.gz
[apple/configd.git] / nwi / network_state_information_priv.h
1 /*
2 * Copyright (c) 2011-2013, 2016, 2017 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_STATE_INFORMATION_PRIV_H_
25 #define _NETWORK_STATE_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 #define NWI_STATE_VERSION ((uint32_t)0x20170601)
38
39
40 #define NWI_IFSTATE_FLAGS_NOT_IN_LIST 0x0008
41 #define NWI_IFSTATE_FLAGS_HAS_SIGNATURE 0x0010
42 #define NWI_IFSTATE_FLAGS_NOT_IN_IFLIST 0x0020
43
44 /*
45 * NWI_IFSTATE_FLAGS_MASK
46 * - these are the bits that get preserved, all others are
47 * control (last item, diff)
48 */
49 #define NWI_IFSTATE_FLAGS_MASK 0x00ff
50
51
52 #define NWI_IFSTATE_FLAGS_DIFF_MASK 0x0f00
53 #define NWI_IFSTATE_FLAGS_LAST_ITEM 0x1000
54
55 typedef enum {
56 knwi_ifstate_difference_none = 0,
57 knwi_ifstate_difference_changed = 1,
58 knwi_ifstate_difference_removed = 2
59 } nwi_ifstate_difference_t;
60
61
62 /*
63 * Type: Rank
64 * Purpose:
65 * A 32-bit value to encode the relative rank of a service.
66 *
67 * The top 8 bits are used to hold the rank assertion (first, default, last,
68 * never, scoped);
69 *
70 * The bottom 24 bits are used to store the service index (i.e. the
71 * position within the service order array).
72 */
73 typedef uint32_t Rank;
74 #define RANK_ASSERTION_MAKE(r) ((Rank)(r) << 24) // rank assertion (top 8 bits)
75 #define kRankAssertionFirst RANK_ASSERTION_MAKE(0)
76 #define kRankAssertionDefault RANK_ASSERTION_MAKE(1)
77 #define kRankAssertionLast RANK_ASSERTION_MAKE(2)
78 #define kRankAssertionNever RANK_ASSERTION_MAKE(3)
79 #define kRankAssertionScoped RANK_ASSERTION_MAKE(4)
80 #define kRankAssertionMask RANK_ASSERTION_MAKE(0xff)
81 #define RANK_ASSERTION_MASK(r) ((Rank)(r) & kRankAssertionMask)
82 #define RANK_INDEX_MAKE(r) ((Rank)(r)) // rank index (bottom 24 bits)
83 #define kRankIndexMask RANK_INDEX_MAKE(0xffffff)
84 #define RANK_INDEX_MASK(r) ((Rank)(r) & kRankIndexMask)
85
86 typedef int32_t nwi_ifindex_t;
87
88 #pragma pack(4)
89 typedef struct _nwi_ifstate {
90 char ifname[IFNAMSIZ];
91 uint64_t flags;
92 nwi_ifindex_t af_alias_offset; /* relative index to alias */
93 Rank rank;
94 sa_family_t af;
95 union {
96 struct in_addr iaddr;
97 struct in6_addr iaddr6;
98 };
99 uint64_t if_generation_count;
100 uint32_t reach_flags;
101 union {
102 struct sockaddr_in vpn_server_address4;
103 struct sockaddr_in6 vpn_server_address6;
104 } vpn_server_address;
105 unsigned char signature[CC_SHA1_DIGEST_LENGTH];
106 } nwi_ifstate;
107 #pragma pack()
108
109 #pragma pack(4)
110 typedef struct _nwi_state {
111 uint32_t version; /* NWI_STATE_VERSION */
112 nwi_ifindex_t max_if_count; /* available slots per protocol */
113 nwi_ifindex_t ipv4_count; /* # of v4 ifstates in use */
114 nwi_ifindex_t ipv6_count; /* # of v6 ifstates in use */
115 nwi_ifindex_t if_list_count; /* # of if_list[] slots in use */
116 uint32_t ref; /* reference count */
117 uint32_t reach_flags_v4;
118 uint32_t reach_flags_v6;
119 uint64_t generation_count;
120 nwi_ifstate ifstate_list[1];/* (max_if_count * 2) ifstates */
121 /* nwi_ifindex_t if_list[0]; max_if_count indices */
122 } nwi_state;
123 #pragma pack()
124
125 static __inline__ int
126 nwi_other_af(int af)
127 {
128 return ((af == AF_INET) ? (AF_INET6) : (AF_INET));
129 }
130
131 static __inline__ size_t
132 nwi_state_compute_size(unsigned int max_if_count)
133 {
134 size_t size;
135
136 size = offsetof(nwi_state, ifstate_list[max_if_count * 2])
137 + sizeof(nwi_ifindex_t) * max_if_count;
138 return (size);
139 }
140
141 static __inline__ size_t
142 nwi_state_size(nwi_state_t state)
143 {
144 return (nwi_state_compute_size(state->max_if_count));
145 }
146
147 static __inline__ nwi_ifstate_t
148 nwi_state_ifstate_list(nwi_state_t state, int af)
149 {
150 if (af == AF_INET) {
151 return (state->ifstate_list);
152 }
153 return (state->ifstate_list + state->max_if_count);
154 }
155
156 static __inline__ nwi_ifindex_t *
157 nwi_state_if_list(nwi_state_t state)
158 {
159 return ((nwi_ifindex_t *)&state->ifstate_list[state->max_if_count * 2]);
160 }
161
162 static __inline__ int
163 uint32_cmp(uint32_t a, uint32_t b)
164 {
165 int ret;
166
167 if (a == b) {
168 ret = 0;
169 }
170 else if (a < b) {
171 ret = -1;
172 }
173 else {
174 ret = 1;
175 }
176 return (ret);
177 }
178
179 static __inline__ int
180 RankCompare(Rank a, Rank b)
181 {
182 return (uint32_cmp(a, b));
183 }
184
185 /*
186 * Function: nwi_state_get_ifstate_count
187 * Purpose:
188 * Return the number of ifstate elements for the specified address family
189 * 'af'. 'af' is either AF_INET or AF_INET6.
190 *
191 * Returns zero if there are no elements.
192 */
193 static __inline__
194 int
195 nwi_state_get_ifstate_count(nwi_state_t state, int af)
196 {
197 return (af == AF_INET)?state->ipv4_count:state->ipv6_count;
198 }
199
200 static __inline__ nwi_ifstate_t
201 nwi_ifstate_get_alias(nwi_ifstate_t ifstate, int af)
202 {
203 if (ifstate->af == af) {
204 return (ifstate);
205 }
206 if (ifstate->af_alias_offset == 0) {
207 return (NULL);
208 }
209 return (ifstate + ifstate->af_alias_offset);
210 }
211
212 /*
213 * The ifstate list is sorted in order of decreasing priority, with the
214 * highest priority element appearing at index zero.
215 *
216 * If 'idx' is outside of the bounds of the corresponding array, returns NULL.
217 */
218 static __inline__
219 nwi_ifstate_t
220 nwi_state_get_ifstate_with_index(nwi_state_t state, int af, int idx)
221 {
222 int i_idx = idx;
223
224 if (idx >= nwi_state_get_ifstate_count(state, af)) {
225 return (NULL);
226 }
227
228 if (af == AF_INET6) {
229 i_idx = idx + state->max_if_count;
230 }
231
232 return &state->ifstate_list[i_idx];
233 }
234
235 /*
236 * Function: nwi_state_get_ifstate_with_name
237 * Purpose:
238 * Return the ifstate for the specified ifstate for the specified address
239 * family 'af'. 'af' is either AF_INET or AF_INET6.
240 *
241 * Returns NULL if no such information exists.
242 */
243 static __inline__
244 nwi_ifstate_t
245 nwi_state_get_ifstate_with_name(nwi_state_t state,
246 int af, const char * name)
247 {
248 int idx = 0;
249 int count;
250 nwi_ifstate_t ifstate = NULL;
251
252 if (state == NULL) {
253 return NULL;
254 }
255
256 count = (af == AF_INET)
257 ?state->ipv4_count:state->ipv6_count;
258
259
260 while (idx < count) {
261 ifstate = nwi_state_get_ifstate_with_index(state, af, idx);
262 if (ifstate == NULL) {
263 break;
264 }
265 if (strcmp(name,
266 nwi_ifstate_get_ifname(ifstate)) == 0) {
267 return (ifstate);
268 }
269 idx++;
270 }
271 return (NULL);
272 }
273
274 static __inline__
275 void
276 _nwi_ifstate_set_vpn_server(nwi_ifstate_t ifstate, struct sockaddr *serv_addr)
277 {
278 size_t len;
279
280 if (serv_addr == NULL) {
281 bzero(&ifstate->vpn_server_address,
282 sizeof(ifstate->vpn_server_address));
283 return;
284 }
285
286 len = serv_addr->sa_len;
287
288 if (len == 0 || len > sizeof(ifstate->vpn_server_address)) {
289 return;
290 }
291
292 memcpy(&ifstate->vpn_server_address,
293 serv_addr,
294 len);
295 return;
296
297 }
298
299 static __inline__
300 void
301 _nwi_state_set_reachability_flags(nwi_state_t state, uint32_t reach_flags_v4, uint32_t reach_flags_v6)
302 {
303 state->reach_flags_v4 = reach_flags_v4;
304 state->reach_flags_v6 = reach_flags_v6;
305 return;
306 }
307
308 nwi_state_t
309 nwi_state_new(nwi_state_t old_state, int elems);
310
311 nwi_state_t
312 nwi_state_make_copy(nwi_state_t state);
313
314 static __inline__ void
315 nwi_state_free(nwi_state_t state)
316 {
317 free(state);
318 return;
319 }
320
321 void
322 nwi_state_finalize(nwi_state_t state);
323
324 nwi_ifstate_t
325 nwi_state_add_ifstate(nwi_state_t state, const char* ifname, int af,
326 uint64_t flags, Rank rank,
327 void * ifa, struct sockaddr * vpn_server_addr, uint32_t reach_flags);
328
329 void
330 nwi_ifstate_set_signature(nwi_ifstate_t ifstate, uint8_t * signature);
331
332 void
333 nwi_state_clear(nwi_state_t state, int af);
334
335 nwi_state_t
336 nwi_state_diff(nwi_state_t old_state, nwi_state_t new_state);
337
338 void *
339 nwi_ifstate_get_address(nwi_ifstate_t ifstate);
340
341 const char *
342 nwi_ifstate_get_diff_str(nwi_ifstate_t ifstate);
343
344 nwi_ifstate_difference_t
345 nwi_ifstate_get_difference(nwi_ifstate_t diff_ifstate);
346
347 void
348 _nwi_state_update_interface_generations(nwi_state_t old_state, nwi_state_t state, nwi_state_t changes);
349
350 void
351 _nwi_state_force_refresh();
352
353 void
354 _nwi_state_compute_sha1_hash(nwi_state_t state,
355 unsigned char hash[CC_SHA1_DIGEST_LENGTH]);
356
357 #endif // _NETWORK_STATE_INFORMATION_PRIV_H_