2 * Copyright (c) 2011-2013 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_INFORMATION_PRIV_H_
25 #define _NETWORK_INFORMATION_PRIV_H_
27 #include <CommonCrypto/CommonDigest.h>
32 #include <netinet/in.h>
33 #include <sys/socket.h>
35 #include "network_information.h"
37 extern const sa_family_t nwi_af_list
[2];
39 #define NWI_IFSTATE_FLAGS_NOT_IN_LIST 0x8
40 #define NWI_IFSTATE_FLAGS_HAS_SIGNATURE 0x10
42 #define NWI_PTR(type, name) \
45 uint64_t _ ## name ## _p; \
48 typedef uint32_t Rank
;
51 typedef struct _nwi_ifstate
{
52 char ifname
[IFNAMSIZ
];
54 NWI_PTR(nwi_ifstate_t
, af_alias
);
59 struct in6_addr iaddr6
;
61 NWI_PTR(const char *, diff_str
);
62 uint64_t if_generation_count
;
65 struct sockaddr_in vpn_server_address4
;
66 struct sockaddr_in6 vpn_server_address6
;
68 unsigned char signature
[CC_SHA1_DIGEST_LENGTH
];
75 *+---------------------------------------------+
78 *----------------------------------------------+
81 *|---------------------------------------------+
84 *|---------------------------------------------+
87 *|---------------------------------------------+
88 *| ipv6_start |-------+
90 *|---------------------------------------------+ |ipv6_start stores the index of the start of the v6 list.
91 *| ref (reference count) | |
93 *|---------------------------------------------+ |
94 *| svr (TRUE if copied from server) | |
96 *|---------------------------------------------+ |
99 *|---------------------------------------------+ |
100 *| reach_flags_v6 | |
102 *|---------------------------------------------+ |
103 *| IPv4 nwi_ifstates | |
106 *|---------------------------------------------+ | |
107 *| Sentinel nwi_ifstates | | |
108 *| flags =NWI_IFSTATE_FLAGS_RANK_NEVER) | | | af_alias points to the same ifstate in the
109 *| | | | opposite (v4 -> v6 and vice versa) af list.
110 *|---------------------------------------------+ | |
111 *| IPv6 nwi_ifstates |<------+ |
114 *|---------------------------------------------+
115 *| Sentinel nwi_ifstates |
116 *| flags =NWI_IFSTATE_FLAGS_RANK_NEVER) |
118 *|---------------------------------------------+
122 typedef struct _nwi_state
{
123 uint64_t generation_count
;
130 uint32_t reach_flags_v4
;
131 uint32_t reach_flags_v6
;
132 nwi_ifstate nwi_ifstates
[0];
136 static __inline__
int
137 uint32_cmp(uint32_t a
, uint32_t b
)
153 static __inline__
int
154 RankCompare(Rank a
, Rank b
)
156 return (uint32_cmp(a
, b
));
160 * Function: nwi_state_get_ifstate_count
162 * Return the number of ifstate elements for the specified address family
163 * 'af'. 'af' is either AF_INET or AF_INET6.
165 * Returns zero if there are no elements.
169 nwi_state_get_ifstate_count(nwi_state_t state
, int af
)
171 return (af
== AF_INET
)?state
->ipv4_count
:state
->ipv6_count
;
175 * The ifstate list is sorted in order of decreasing priority, with the
176 * highest priority element appearing at index zero.
178 * If 'idx' is outside of the bounds of the corresponding array, returns NULL.
182 nwi_state_get_ifstate_with_index(nwi_state_t state
, int af
, int idx
)
184 nwi_ifstate_t nwi_ifstate
= NULL
;
187 if (idx
> nwi_state_get_ifstate_count(state
, af
)) {
188 return (nwi_ifstate
);
191 if (af
== AF_INET6
) {
192 i_idx
= idx
+ state
->ipv6_start
;
195 return &state
->nwi_ifstates
[i_idx
];
199 * Function: nwi_state_get_ifstate_with_name
201 * Return the ifstate for the specified ifstate for the specified address
202 * family 'af'. 'af' is either AF_INET or AF_INET6.
204 * Returns NULL if no such information exists.
208 nwi_state_get_ifstate_with_name(nwi_state_t state
,
209 int af
, const char * name
)
213 nwi_ifstate_t ifstate
= NULL
;
219 count
= (af
== AF_INET
)
220 ?state
->ipv4_count
:state
->ipv6_count
;
223 while (idx
< count
) {
224 ifstate
= nwi_state_get_ifstate_with_index(state
, af
, idx
);
225 if (ifstate
== NULL
) {
229 nwi_ifstate_get_ifname(ifstate
)) == 0) {
239 _nwi_ifstate_set_vpn_server(nwi_ifstate_t ifstate
, struct sockaddr
*serv_addr
)
243 if (serv_addr
== NULL
) {
244 bzero(&ifstate
->vpn_server_address
,
245 sizeof(ifstate
->vpn_server_address
));
249 len
= serv_addr
->sa_len
;
251 if (len
== 0 || len
> sizeof(ifstate
->vpn_server_address
)) {
255 memcpy(&ifstate
->vpn_server_address
,
264 _nwi_state_set_reachability_flags(nwi_state_t state
, uint32_t reach_flags_v4
, uint32_t reach_flags_v6
)
266 state
->reach_flags_v4
= reach_flags_v4
;
267 state
->reach_flags_v6
= reach_flags_v6
;
272 nwi_state_new(nwi_state_t old_state
, int elems
);
275 nwi_state_copy_priv(nwi_state_t old_state
);
278 nwi_insert_ifstate(nwi_state_t state
, const char* ifname
, int af
,
279 uint64_t flags
, Rank rank
,
280 void * ifa
, struct sockaddr
* vpn_server_addr
, uint32_t reach_flags
);
283 nwi_ifstate_set_signature(nwi_ifstate_t ifstate
, uint8_t * signature
);
286 nwi_state_clear(nwi_state_t state
, int af
);
289 nwi_state_set_last(nwi_state_t state
, int af
);
292 nwi_state_diff(nwi_state_t old_state
, nwi_state_t new_state
);
295 nwi_ifstate_get_address(nwi_ifstate_t ifstate
);
298 nwi_ifstate_get_diff_str(nwi_ifstate_t ifstate
);
301 _nwi_state_update_interface_generations(nwi_state_t old_state
, nwi_state_t state
, nwi_state_t changes
);
304 _nwi_state_force_refresh();