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