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 #define NWI_IFSTATE_FLAGS_NOT_IN_LIST 0x0008
38 #define NWI_IFSTATE_FLAGS_HAS_SIGNATURE 0x0010
39 #define NWI_IFSTATE_FLAGS_NOT_IN_IFLIST 0x0020
42 * NWI_IFSTATE_FLAGS_MASK
43 * - these are the bits that get preserved, all others are
44 * control (last item, diff)
46 #define NWI_IFSTATE_FLAGS_MASK 0x00ff
49 #define NWI_IFSTATE_FLAGS_DIFF_MASK 0x0f00
50 #define NWI_IFSTATE_FLAGS_LAST_ITEM 0x1000
53 knwi_ifstate_difference_none
= 0,
54 knwi_ifstate_difference_changed
= 1,
55 knwi_ifstate_difference_removed
= 2
56 } nwi_ifstate_difference_t
;
59 typedef uint32_t Rank
;
60 typedef int32_t nwi_ifindex_t
;
63 typedef struct _nwi_ifstate
{
64 char ifname
[IFNAMSIZ
];
66 nwi_ifindex_t af_alias_offset
; /* relative index to alias */
71 struct in6_addr iaddr6
;
73 uint64_t if_generation_count
;
76 struct sockaddr_in vpn_server_address4
;
77 struct sockaddr_in6 vpn_server_address6
;
79 unsigned char signature
[CC_SHA1_DIGEST_LENGTH
];
83 #define NWI_STATE_VERSION ((uint32_t)0x20150214)
86 typedef struct _nwi_state
{
87 uint32_t version
; /* NWI_STATE_VERSION */
88 nwi_ifindex_t max_if_count
; /* available slots per protocol */
89 nwi_ifindex_t ipv4_count
; /* # of v4 ifstates in use */
90 nwi_ifindex_t ipv6_count
; /* # of v6 ifstates in use */
91 nwi_ifindex_t if_list_count
; /* # of if_list[] slots in use */
92 uint32_t ref
; /* reference count */
93 uint32_t reach_flags_v4
;
94 uint32_t reach_flags_v6
;
95 uint64_t generation_count
;
96 nwi_ifstate ifstate_list
[1];/* (max_if_count * 2) ifstates */
97 /* nwi_ifindex_t if_list[0]; max_if_count indices */
101 static __inline__
int
104 return ((af
== AF_INET
) ? (AF_INET6
) : (AF_INET
));
107 static __inline__
size_t
108 nwi_state_compute_size(unsigned int max_if_count
)
112 size
= offsetof(nwi_state
, ifstate_list
[max_if_count
* 2])
113 + sizeof(nwi_ifindex_t
) * max_if_count
;
117 static __inline__
size_t
118 nwi_state_size(nwi_state_t state
)
120 return (nwi_state_compute_size(state
->max_if_count
));
123 static __inline__ nwi_ifstate_t
124 nwi_state_ifstate_list(nwi_state_t state
, int af
)
127 return (state
->ifstate_list
);
129 return (state
->ifstate_list
+ state
->max_if_count
);
132 static __inline__ nwi_ifindex_t
*
133 nwi_state_if_list(nwi_state_t state
)
135 return ((nwi_ifindex_t
*)&state
->ifstate_list
[state
->max_if_count
* 2]);
138 static __inline__
int
139 uint32_cmp(uint32_t a
, uint32_t b
)
155 static __inline__
int
156 RankCompare(Rank a
, Rank b
)
158 return (uint32_cmp(a
, b
));
162 * Function: nwi_state_get_ifstate_count
164 * Return the number of ifstate elements for the specified address family
165 * 'af'. 'af' is either AF_INET or AF_INET6.
167 * Returns zero if there are no elements.
171 nwi_state_get_ifstate_count(nwi_state_t state
, int af
)
173 return (af
== AF_INET
)?state
->ipv4_count
:state
->ipv6_count
;
176 static __inline__ nwi_ifstate_t
177 nwi_ifstate_get_alias(nwi_ifstate_t ifstate
, int af
)
179 if (ifstate
->af
== af
) {
182 if (ifstate
->af_alias_offset
== 0) {
185 return (ifstate
+ ifstate
->af_alias_offset
);
189 * The ifstate list is sorted in order of decreasing priority, with the
190 * highest priority element appearing at index zero.
192 * If 'idx' is outside of the bounds of the corresponding array, returns NULL.
196 nwi_state_get_ifstate_with_index(nwi_state_t state
, int af
, int idx
)
200 if (idx
>= nwi_state_get_ifstate_count(state
, af
)) {
204 if (af
== AF_INET6
) {
205 i_idx
= idx
+ state
->max_if_count
;
208 return &state
->ifstate_list
[i_idx
];
212 * Function: nwi_state_get_ifstate_with_name
214 * Return the ifstate for the specified ifstate for the specified address
215 * family 'af'. 'af' is either AF_INET or AF_INET6.
217 * Returns NULL if no such information exists.
221 nwi_state_get_ifstate_with_name(nwi_state_t state
,
222 int af
, const char * name
)
226 nwi_ifstate_t ifstate
= NULL
;
232 count
= (af
== AF_INET
)
233 ?state
->ipv4_count
:state
->ipv6_count
;
236 while (idx
< count
) {
237 ifstate
= nwi_state_get_ifstate_with_index(state
, af
, idx
);
238 if (ifstate
== NULL
) {
242 nwi_ifstate_get_ifname(ifstate
)) == 0) {
252 _nwi_ifstate_set_vpn_server(nwi_ifstate_t ifstate
, struct sockaddr
*serv_addr
)
256 if (serv_addr
== NULL
) {
257 bzero(&ifstate
->vpn_server_address
,
258 sizeof(ifstate
->vpn_server_address
));
262 len
= serv_addr
->sa_len
;
264 if (len
== 0 || len
> sizeof(ifstate
->vpn_server_address
)) {
268 memcpy(&ifstate
->vpn_server_address
,
277 _nwi_state_set_reachability_flags(nwi_state_t state
, uint32_t reach_flags_v4
, uint32_t reach_flags_v6
)
279 state
->reach_flags_v4
= reach_flags_v4
;
280 state
->reach_flags_v6
= reach_flags_v6
;
285 nwi_state_new(nwi_state_t old_state
, int elems
);
288 nwi_state_make_copy(nwi_state_t state
);
290 static __inline__
void
291 nwi_state_free(nwi_state_t state
)
298 nwi_state_finalize(nwi_state_t state
);
301 nwi_state_add_ifstate(nwi_state_t state
, const char* ifname
, int af
,
302 uint64_t flags
, Rank rank
,
303 void * ifa
, struct sockaddr
* vpn_server_addr
, uint32_t reach_flags
);
306 nwi_ifstate_set_signature(nwi_ifstate_t ifstate
, uint8_t * signature
);
309 nwi_state_clear(nwi_state_t state
, int af
);
312 nwi_state_diff(nwi_state_t old_state
, nwi_state_t new_state
);
315 nwi_ifstate_get_address(nwi_ifstate_t ifstate
);
318 nwi_ifstate_get_diff_str(nwi_ifstate_t ifstate
);
320 nwi_ifstate_difference_t
321 nwi_ifstate_get_difference(nwi_ifstate_t diff_ifstate
);
324 _nwi_state_update_interface_generations(nwi_state_t old_state
, nwi_state_t state
, nwi_state_t changes
);
327 _nwi_state_force_refresh();
330 _nwi_state_compute_sha1_hash(nwi_state_t state
,
331 unsigned char hash
[CC_SHA1_DIGEST_LENGTH
]);