2 * Copyright (c) 2011-2013, 2016-2018 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
43 #define NWI_IFSTATE_FLAGS_HAS_CLAT46 0x0040 /* has CLAT46 configured */
46 * NWI_IFSTATE_FLAGS_MASK
47 * - these are the bits that get preserved, all others are
48 * control (last item, diff)
50 #define NWI_IFSTATE_FLAGS_MASK 0x00ff
53 #define NWI_IFSTATE_FLAGS_DIFF_MASK 0x0f00
54 #define NWI_IFSTATE_FLAGS_LAST_ITEM 0x1000
57 knwi_ifstate_difference_none
= 0,
58 knwi_ifstate_difference_changed
= 1,
59 knwi_ifstate_difference_removed
= 2
60 } nwi_ifstate_difference_t
;
66 * A 32-bit value to encode the relative rank of a service.
68 * The top 8 bits are used to hold the rank assertion (first, default, last,
71 * The bottom 24 bits are used to store the service index (i.e. the
72 * position within the service order array).
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)
87 typedef int32_t nwi_ifindex_t
;
90 typedef struct _nwi_ifstate
{
91 char ifname
[IFNAMSIZ
];
93 nwi_ifindex_t af_alias_offset
; /* relative index to alias */
98 struct in6_addr iaddr6
;
100 uint64_t if_generation_count
;
101 uint32_t reach_flags
;
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
];
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 */
126 static __inline__
int
129 return ((af
== AF_INET
) ? (AF_INET6
) : (AF_INET
));
132 static __inline__
size_t
133 nwi_state_compute_size(unsigned int max_if_count
)
137 size
= offsetof(nwi_state
, ifstate_list
[max_if_count
* 2])
138 + sizeof(nwi_ifindex_t
) * max_if_count
;
142 static __inline__
size_t
143 nwi_state_size(nwi_state_t state
)
145 return (nwi_state_compute_size(state
->max_if_count
));
148 static __inline__ nwi_ifstate_t
149 nwi_state_ifstate_list(nwi_state_t state
, int af
)
152 return (state
->ifstate_list
);
154 return (state
->ifstate_list
+ state
->max_if_count
);
157 static __inline__ nwi_ifindex_t
*
158 nwi_state_if_list(nwi_state_t state
)
160 return ((nwi_ifindex_t
*)&state
->ifstate_list
[state
->max_if_count
* 2]);
163 static __inline__
int
164 uint32_cmp(uint32_t a
, uint32_t b
)
180 static __inline__
int
181 RankCompare(Rank a
, Rank b
)
183 return (uint32_cmp(a
, b
));
187 * Function: nwi_state_get_ifstate_count
189 * Return the number of ifstate elements for the specified address family
190 * 'af'. 'af' is either AF_INET or AF_INET6.
192 * Returns zero if there are no elements.
196 nwi_state_get_ifstate_count(nwi_state_t state
, int af
)
198 return (af
== AF_INET
)?state
->ipv4_count
:state
->ipv6_count
;
201 static __inline__ nwi_ifstate_t
202 nwi_ifstate_get_alias(nwi_ifstate_t ifstate
, int af
)
204 if (ifstate
->af
== af
) {
207 if (ifstate
->af_alias_offset
== 0) {
210 return (ifstate
+ ifstate
->af_alias_offset
);
214 * The ifstate list is sorted in order of decreasing priority, with the
215 * highest priority element appearing at index zero.
217 * If 'idx' is outside of the bounds of the corresponding array, returns NULL.
221 nwi_state_get_ifstate_with_index(nwi_state_t state
, int af
, int idx
)
225 if (idx
>= nwi_state_get_ifstate_count(state
, af
)) {
229 if (af
== AF_INET6
) {
230 i_idx
= idx
+ state
->max_if_count
;
233 return &state
->ifstate_list
[i_idx
];
237 * Function: nwi_state_get_ifstate_with_name
239 * Return the ifstate for the specified ifstate for the specified address
240 * family 'af'. 'af' is either AF_INET or AF_INET6.
242 * Returns NULL if no such information exists.
246 nwi_state_get_ifstate_with_name(nwi_state_t state
,
247 int af
, const char * name
)
251 nwi_ifstate_t ifstate
= NULL
;
257 count
= (af
== AF_INET
)
258 ?state
->ipv4_count
:state
->ipv6_count
;
261 while (idx
< count
) {
262 ifstate
= nwi_state_get_ifstate_with_index(state
, af
, idx
);
263 if (ifstate
== NULL
) {
267 nwi_ifstate_get_ifname(ifstate
)) == 0) {
277 _nwi_ifstate_set_vpn_server(nwi_ifstate_t ifstate
, struct sockaddr
*serv_addr
)
281 if (serv_addr
== NULL
) {
282 bzero(&ifstate
->vpn_server_address
,
283 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_sha1_hash(nwi_state_t state
,
353 unsigned char hash
[CC_SHA1_DIGEST_LENGTH
]);
355 #endif // _NETWORK_STATE_INFORMATION_PRIV_H_