]> git.saurik.com Git - apple/configd.git/blob - nwi/network_state_information_priv.h
configd-1109.40.9.tar.gz
[apple/configd.git] / nwi / network_state_information_priv.h
1 /*
2 * Copyright (c) 2011-2013, 2016-2020 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 #define NWI_SIGNATURE_LENGTH 20
89
90 #pragma pack(4)
91 typedef struct _nwi_ifstate {
92 char ifname[IFNAMSIZ];
93 uint64_t flags;
94 nwi_ifindex_t af_alias_offset; /* relative index to alias */
95 Rank rank;
96 sa_family_t af;
97 union {
98 struct in_addr iaddr;
99 struct in6_addr iaddr6;
100 };
101 uint64_t if_generation_count;
102 uint32_t reach_flags;
103 union {
104 struct sockaddr_in vpn_server_address4;
105 struct sockaddr_in6 vpn_server_address6;
106 } vpn_server_address;
107 unsigned char signature[NWI_SIGNATURE_LENGTH];
108 } nwi_ifstate;
109 #pragma pack()
110
111 #pragma pack(4)
112 typedef struct _nwi_state {
113 uint32_t version; /* NWI_STATE_VERSION */
114 nwi_ifindex_t max_if_count; /* available slots per protocol */
115 nwi_ifindex_t ipv4_count; /* # of v4 ifstates in use */
116 nwi_ifindex_t ipv6_count; /* # of v6 ifstates in use */
117 nwi_ifindex_t if_list_count; /* # of if_list[] slots in use */
118 uint32_t ref; /* reference count */
119 uint32_t reach_flags_v4;
120 uint32_t reach_flags_v6;
121 uint64_t generation_count;
122 nwi_ifstate ifstate_list[1];/* (max_if_count * 2) ifstates */
123 /* nwi_ifindex_t if_list[0]; max_if_count indices */
124 } nwi_state;
125 #pragma pack()
126
127 static __inline__ int
128 nwi_other_af(int af)
129 {
130 return ((af == AF_INET) ? (AF_INET6) : (AF_INET));
131 }
132
133 static __inline__ size_t
134 nwi_state_compute_size(unsigned int max_if_count)
135 {
136 size_t size;
137
138 size = offsetof(nwi_state, ifstate_list[max_if_count * 2])
139 + sizeof(nwi_ifindex_t) * max_if_count;
140 return (size);
141 }
142
143 static __inline__ size_t
144 nwi_state_size(nwi_state_t state)
145 {
146 return (nwi_state_compute_size(state->max_if_count));
147 }
148
149 static __inline__ nwi_ifstate_t
150 nwi_state_ifstate_list(nwi_state_t state, int af)
151 {
152 if (af == AF_INET) {
153 return (state->ifstate_list);
154 }
155 return (state->ifstate_list + state->max_if_count);
156 }
157
158 static __inline__ nwi_ifindex_t *
159 nwi_state_if_list(nwi_state_t state)
160 {
161 return ((nwi_ifindex_t *)&state->ifstate_list[state->max_if_count * 2]);
162 }
163
164 static __inline__ int
165 uint32_cmp(uint32_t a, uint32_t b)
166 {
167 int ret;
168
169 if (a == b) {
170 ret = 0;
171 }
172 else if (a < b) {
173 ret = -1;
174 }
175 else {
176 ret = 1;
177 }
178 return (ret);
179 }
180
181 static __inline__ int
182 RankCompare(Rank a, Rank b)
183 {
184 return (uint32_cmp(a, b));
185 }
186
187 /*
188 * Function: nwi_state_get_ifstate_count
189 * Purpose:
190 * Return the number of ifstate elements for the specified address family
191 * 'af'. 'af' is either AF_INET or AF_INET6.
192 *
193 * Returns zero if there are no elements.
194 */
195 static __inline__
196 int
197 nwi_state_get_ifstate_count(nwi_state_t state, int af)
198 {
199 return (af == AF_INET)?state->ipv4_count:state->ipv6_count;
200 }
201
202 static __inline__ nwi_ifstate_t
203 nwi_ifstate_get_alias(nwi_ifstate_t ifstate, int af)
204 {
205 if (ifstate->af == af) {
206 return (ifstate);
207 }
208 if (ifstate->af_alias_offset == 0) {
209 return (NULL);
210 }
211 return (ifstate + ifstate->af_alias_offset);
212 }
213
214 /*
215 * The ifstate list is sorted in order of decreasing priority, with the
216 * highest priority element appearing at index zero.
217 *
218 * If 'idx' is outside of the bounds of the corresponding array, returns NULL.
219 */
220 static __inline__
221 nwi_ifstate_t
222 nwi_state_get_ifstate_with_index(nwi_state_t state, int af, int idx)
223 {
224 int i_idx = idx;
225
226 if (idx >= state->max_if_count) {
227 return (NULL);
228 }
229
230 if (idx >= nwi_state_get_ifstate_count(state, af)) {
231 return (NULL);
232 }
233
234 if (af == AF_INET6) {
235 i_idx = idx + state->max_if_count;
236 }
237
238 return &state->ifstate_list[i_idx];
239 }
240
241 /*
242 * Function: nwi_state_get_ifstate_with_name
243 * Purpose:
244 * Return the ifstate for the specified ifstate for the specified address
245 * family 'af'. 'af' is either AF_INET or AF_INET6.
246 *
247 * Returns NULL if no such information exists.
248 */
249 static __inline__
250 nwi_ifstate_t
251 nwi_state_get_ifstate_with_name(nwi_state_t state,
252 int af, const char * name)
253 {
254 int idx = 0;
255 int count;
256 nwi_ifstate_t ifstate = NULL;
257
258 if (state == NULL) {
259 return (NULL);
260 }
261
262 count = (af == AF_INET) ? state->ipv4_count : state->ipv6_count;
263 if (count > state->max_if_count) {
264 return (NULL);
265 }
266
267 while (idx < count) {
268 ifstate = nwi_state_get_ifstate_with_index(state, af, idx);
269 if (ifstate == NULL) {
270 break;
271 }
272 if (strcmp(name,
273 nwi_ifstate_get_ifname(ifstate)) == 0) {
274 return (ifstate);
275 }
276 idx++;
277 }
278 return (NULL);
279 }
280
281 static __inline__
282 void
283 _nwi_ifstate_set_vpn_server(nwi_ifstate_t ifstate, struct sockaddr *serv_addr)
284 {
285 size_t len;
286
287 if (serv_addr == NULL) {
288 memset(&ifstate->vpn_server_address, 0, sizeof(ifstate->vpn_server_address));
289 return;
290 }
291
292 len = serv_addr->sa_len;
293
294 if (len == 0 || len > sizeof(ifstate->vpn_server_address)) {
295 return;
296 }
297
298 memcpy(&ifstate->vpn_server_address,
299 serv_addr,
300 len);
301 return;
302
303 }
304
305 static __inline__
306 void
307 _nwi_state_set_reachability_flags(nwi_state_t state, uint32_t reach_flags_v4, uint32_t reach_flags_v6)
308 {
309 state->reach_flags_v4 = reach_flags_v4;
310 state->reach_flags_v6 = reach_flags_v6;
311 return;
312 }
313
314 nwi_state_t
315 nwi_state_new(nwi_state_t old_state, int elems);
316
317 nwi_state_t
318 nwi_state_make_copy(nwi_state_t state);
319
320 static __inline__ void
321 nwi_state_free(nwi_state_t state)
322 {
323 free(state);
324 return;
325 }
326
327 void
328 nwi_state_finalize(nwi_state_t state);
329
330 nwi_ifstate_t
331 nwi_state_add_ifstate(nwi_state_t state, const char* ifname, int af,
332 uint64_t flags, Rank rank,
333 void * ifa, struct sockaddr * vpn_server_addr, uint32_t reach_flags);
334
335 void
336 nwi_ifstate_set_signature(nwi_ifstate_t ifstate, uint8_t * signature);
337
338 void
339 nwi_state_clear(nwi_state_t state, int af);
340
341 nwi_state_t
342 nwi_state_diff(nwi_state_t old_state, nwi_state_t new_state);
343
344 void *
345 nwi_ifstate_get_address(nwi_ifstate_t ifstate);
346
347 const char *
348 nwi_ifstate_get_diff_str(nwi_ifstate_t ifstate);
349
350 nwi_ifstate_difference_t
351 nwi_ifstate_get_difference(nwi_ifstate_t diff_ifstate);
352
353 void
354 _nwi_state_update_interface_generations(nwi_state_t old_state, nwi_state_t state, nwi_state_t changes);
355
356 void
357 _nwi_state_compute_sha256_hash(nwi_state_t state,
358 unsigned char hash[CC_SHA256_DIGEST_LENGTH]);
359
360 #endif // _NETWORK_STATE_INFORMATION_PRIV_H_