2 * Copyright (c) 2011-2013, 2016-2019 Apple Inc. All rights reserved.
4 * @APPLE_LICENSE_HEADER_START@
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
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.
21 * @APPLE_LICENSE_HEADER_END@
24 #ifndef _NETWORK_STATE_INFORMATION_PRIV_H_
25 #define _NETWORK_STATE_INFORMATION_PRIV_H_
27 #include <CommonCrypto/CommonDigest.h>
32 #include <netinet/in.h>
33 #include <sys/socket.h>
35 #include "network_information.h"
37 #define NWI_STATE_VERSION ((uint32_t)0x20170601)
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
45 * NWI_IFSTATE_FLAGS_MASK
46 * - these are the bits that get preserved, all others are
47 * control (last item, diff)
49 #define NWI_IFSTATE_FLAGS_MASK 0x00ff
52 #define NWI_IFSTATE_FLAGS_DIFF_MASK 0x0f00
53 #define NWI_IFSTATE_FLAGS_LAST_ITEM 0x1000
56 knwi_ifstate_difference_none
= 0,
57 knwi_ifstate_difference_changed
= 1,
58 knwi_ifstate_difference_removed
= 2
59 } nwi_ifstate_difference_t
;
65 * A 32-bit value to encode the relative rank of a service.
67 * The top 8 bits are used to hold the rank assertion (first, default, last,
70 * The bottom 24 bits are used to store the service index (i.e. the
71 * position within the service order array).
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)
86 typedef int32_t nwi_ifindex_t
;
88 #define NWI_SIGNATURE_LENGTH 20
91 typedef struct _nwi_ifstate
{
92 char ifname
[IFNAMSIZ
];
94 nwi_ifindex_t af_alias_offset
; /* relative index to alias */
99 struct in6_addr iaddr6
;
101 uint64_t if_generation_count
;
102 uint32_t reach_flags
;
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
];
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 */
127 static __inline__
int
130 return ((af
== AF_INET
) ? (AF_INET6
) : (AF_INET
));
133 static __inline__
size_t
134 nwi_state_compute_size(unsigned int max_if_count
)
138 size
= offsetof(nwi_state
, ifstate_list
[max_if_count
* 2])
139 + sizeof(nwi_ifindex_t
) * max_if_count
;
143 static __inline__
size_t
144 nwi_state_size(nwi_state_t state
)
146 return (nwi_state_compute_size(state
->max_if_count
));
149 static __inline__ nwi_ifstate_t
150 nwi_state_ifstate_list(nwi_state_t state
, int af
)
153 return (state
->ifstate_list
);
155 return (state
->ifstate_list
+ state
->max_if_count
);
158 static __inline__ nwi_ifindex_t
*
159 nwi_state_if_list(nwi_state_t state
)
161 return ((nwi_ifindex_t
*)&state
->ifstate_list
[state
->max_if_count
* 2]);
164 static __inline__
int
165 uint32_cmp(uint32_t a
, uint32_t b
)
181 static __inline__
int
182 RankCompare(Rank a
, Rank b
)
184 return (uint32_cmp(a
, b
));
188 * Function: nwi_state_get_ifstate_count
190 * Return the number of ifstate elements for the specified address family
191 * 'af'. 'af' is either AF_INET or AF_INET6.
193 * Returns zero if there are no elements.
197 nwi_state_get_ifstate_count(nwi_state_t state
, int af
)
199 return (af
== AF_INET
)?state
->ipv4_count
:state
->ipv6_count
;
202 static __inline__ nwi_ifstate_t
203 nwi_ifstate_get_alias(nwi_ifstate_t ifstate
, int af
)
205 if (ifstate
->af
== af
) {
208 if (ifstate
->af_alias_offset
== 0) {
211 return (ifstate
+ ifstate
->af_alias_offset
);
215 * The ifstate list is sorted in order of decreasing priority, with the
216 * highest priority element appearing at index zero.
218 * If 'idx' is outside of the bounds of the corresponding array, returns NULL.
222 nwi_state_get_ifstate_with_index(nwi_state_t state
, int af
, int idx
)
226 if (idx
>= nwi_state_get_ifstate_count(state
, af
)) {
230 if (af
== AF_INET6
) {
231 i_idx
= idx
+ state
->max_if_count
;
234 return &state
->ifstate_list
[i_idx
];
238 * Function: nwi_state_get_ifstate_with_name
240 * Return the ifstate for the specified ifstate for the specified address
241 * family 'af'. 'af' is either AF_INET or AF_INET6.
243 * Returns NULL if no such information exists.
247 nwi_state_get_ifstate_with_name(nwi_state_t state
,
248 int af
, const char * name
)
252 nwi_ifstate_t ifstate
= NULL
;
258 count
= (af
== AF_INET
)
259 ?state
->ipv4_count
:state
->ipv6_count
;
262 while (idx
< count
) {
263 ifstate
= nwi_state_get_ifstate_with_index(state
, af
, idx
);
264 if (ifstate
== NULL
) {
268 nwi_ifstate_get_ifname(ifstate
)) == 0) {
278 _nwi_ifstate_set_vpn_server(nwi_ifstate_t ifstate
, struct sockaddr
*serv_addr
)
282 if (serv_addr
== NULL
) {
283 memset(&ifstate
->vpn_server_address
, 0, sizeof(ifstate
->vpn_server_address
));
287 len
= serv_addr
->sa_len
;
289 if (len
== 0 || len
> sizeof(ifstate
->vpn_server_address
)) {
293 memcpy(&ifstate
->vpn_server_address
,
302 _nwi_state_set_reachability_flags(nwi_state_t state
, uint32_t reach_flags_v4
, uint32_t reach_flags_v6
)
304 state
->reach_flags_v4
= reach_flags_v4
;
305 state
->reach_flags_v6
= reach_flags_v6
;
310 nwi_state_new(nwi_state_t old_state
, int elems
);
313 nwi_state_make_copy(nwi_state_t state
);
315 static __inline__
void
316 nwi_state_free(nwi_state_t state
)
323 nwi_state_finalize(nwi_state_t state
);
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
);
331 nwi_ifstate_set_signature(nwi_ifstate_t ifstate
, uint8_t * signature
);
334 nwi_state_clear(nwi_state_t state
, int af
);
337 nwi_state_diff(nwi_state_t old_state
, nwi_state_t new_state
);
340 nwi_ifstate_get_address(nwi_ifstate_t ifstate
);
343 nwi_ifstate_get_diff_str(nwi_ifstate_t ifstate
);
345 nwi_ifstate_difference_t
346 nwi_ifstate_get_difference(nwi_ifstate_t diff_ifstate
);
349 _nwi_state_update_interface_generations(nwi_state_t old_state
, nwi_state_t state
, nwi_state_t changes
);
352 _nwi_state_compute_sha256_hash(nwi_state_t state
,
353 unsigned char hash
[CC_SHA256_DIGEST_LENGTH
]);
355 #endif // _NETWORK_STATE_INFORMATION_PRIV_H_