xref: /xnu-11215.41.3/bsd/net/sockaddr_utils.h (revision 33de042d024d46de5ff4e89f2471de6608e37fa4)
1 /*
2  * Copyright (c) 2023 Apple Inc. All rights reserved.
3  *
4  * @APPLE_OSREFERENCE_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. The rights granted to you under the License
10  * may not be used to create, or enable the creation or redistribution of,
11  * unlawful or unlicensed copies of an Apple operating system, or to
12  * circumvent, violate, or enable the circumvention or violation of, any
13  * terms of an Apple operating system software license agreement.
14  *
15  * Please obtain a copy of the License at
16  * http://www.opensource.apple.com/apsl/ and read it before using this file.
17  *
18  * The Original Code and all software distributed under the License are
19  * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
20  * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
21  * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
22  * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT.
23  * Please see the License for the specific language governing rights and
24  * limitations under the License.
25  *
26  * @APPLE_OSREFERENCE_LICENSE_HEADER_END@
27  */
28 #ifndef _NET_SOCKADDR_UTILS_H_
29 #define _NET_SOCKADDR_UTILS_H_
30 
31 #ifdef XNU_KERNEL_PRIVATE
32 
33 #include <sys/socket.h>
34 
35 /*
36  * Type conversion rules for socket address types
37  *
38  * 1. Context:
39  *
40  * XNU networking uses the "socket address" abstraction to represent
41  * the addresses for the different protocol families, e.g. IPv4, IPv6,
42  * UNIX domain sockets, ARP etc.
43  *
44  * Historically, the socket addresses were represented as a byte array,
45  * starting with a uint16_t "family" discriminator.
46  *
47  * This was changed with the advent of XOpen UNIX standard: the uint16_t
48  * "family" discriminator was split into 2 uint8_t fields: the length
49  * and the protocol family.
50  *
51  * Since the different protocols have different addressing semantics,
52  * the different addresses are represented by multiple structures.
53  * For example, the IPv6 addresses are represented by `struct sockaddr_in6',
54  * while the IPv4 addresses can be represented by `struct sockaddr_in' or by
55  * `struct sockaddr_inifscope', depending on whether the address is bound
56  * to a particular interface.
57  *
58  * The type `struct sockaddr' can be used interchangeably to represent any
59  * of the above addresses. Essentially, the C types that represent
60  * the different socket address families form a type hierarchy,
61  * with the `struct sockaddr' being the root type.
62  *
63  * There are some exceptions to the hierarchy. Sometimes the socket addresses
64  * are represented by a "container" type, e.g. `struct sockaddr_storage'
65  * or `union sockaddr_in_4_6'. Finally, some protocol families, such as
66  * the routing sockets, are represented by the plain `struct sockaddr'.
67  *
68  *
69  *
70  *                         +-------+                           +-----------+
71  *      +------------------+ Base  |      +. - - . - - . - - . |Containers |
72  *      | struct sockaddr  +----+--+      .                    +-----------+
73  *      +-----------------------+         | +----------------------------+ |
74  *                     ^                  . | union sockaddr_in_4_6      | .
75  *                     +------------------+ +----------------------------+ |
76  *                     |                  . +----------------------------+ .
77  *                     |                  | | struct sockaddr_storage    | |
78  *                     |                  . +----------------------------+ .
79  *                     |    +----------+  | +----------------------------+ |
80  *   + . - - . - - . - + - .| Concrete |  . | uint8_t * __bidi_indexable | .
81  *   .                      +----------+  | +----------------------------+ |
82  *   |  +---------------------------+ |   .                                .
83  *   .  | struct sockaddr_ctl       | .   +. - - . - - . - - . - - . - - . +
84  *   |  +---------------------------+ |
85  *   .  +---------------------------+ .
86  *   |  | struct sockaddr_dl        | |
87  *   .  +---------------------------+ .
88  *   |  +---------------------------+ |
89  *   .  | struct sockaddr_in        | .
90  *   |  +---------------------------+ |
91  *   .  +---------------------------+ .
92  *   |  | struct sockaddr_inarp     | |
93  *   .  +---------------------------+ .
94  *   |  +---------------------------+ |
95  *   .  | struct sockaddr_inifscope | .
96  *   |  +---------------------------+ |
97  *   .  +---------------------------+ .
98  *   |  | struct sockaddr_in6       | |
99  *   .  +---------------------------+ .
100  *   |  +---------------------------+ |
101  *   .  | struct sockaddr_ndrv      | .
102  *   |  +---------------------------+ |
103  *   .  +---------------------------+ .
104  *   |  | struct sockaddr_sys       | |
105  *   .  +---------------------------+ .
106  *   |  +---------------------------+ |
107  *   .   | struct sockaddr_un       | .
108  *   |  +---------------------------+ |
109  *   .                                .
110  *   + . - - . - - . - - . - - . - - .+
111  *
112  *
113  * 2. Challenges
114  *
115  * 2.1. Type safety challenges
116  *
117  * Since the pointer type `struct sockaddr *' can represent a pointer
118  * to any concrete derived type, or to a container type,
119  * the enforcement of bound checks can be tricky.
120  *
121  * In particular, one needs to safely support the following conversions:
122  *
123  * - From `struct sockaddr *' to any of the derived types, and vice versa.
124  * - From `uint8_t *' to any of the derived types, and vice versa.
125  * - From `union sockaddr_in_4_6 *' to either `struct sockaddr_in *'
126  *   or to `struct sockaddr_in6 *', and vice versa.
127  * - From `struct sockaddr_in *' to `struct sockaddr_inifscope *',
128  *   and vice versa.
129  *
130  * At the same time, the system needs to make accidental conversions between
131  * unrelated types difficult. Examples of such conversions include:
132  *
133  * - From `struct sockaddr_in *' to `struct sockaddr_un *' or vice versa.
134  * - From `struct sockaddr_sys *' to `struct sockaddr_ndrv *' or vice versa.
135  *
136  * 2.2. ABI constraints.
137  *
138  * The concrete types that are listed above are used both in the kernel space,
139  * the user space and by the drivers.
140  *
141  * 2.3. Pointer boundary challenges
142  *
143  * The transition between `__single' pointers, e.g. between
144  * `struct sockaddr * __single' to `struct sockaddr_in6 * __single'
145  * is currently assumed to be safe, as long as the concrete types
146  * have determined sizes.
147  *
148  * The challenge occurs whenever one needs to serialize or to deserialize
149  * the concrete socket address types into a byte arrays.
150  *
151  * 2.4. Runtime cost challenges
152  *
153  * The transition between the different socket address types
154  * should not incure a significant CPU or memory cost in runtime.
155  *
156  *
157  * 3. Implementation.
158  *
159  * This file implements a mechanism that:
160  * - Enforces the type safety by ensuring that only the valid
161  *   type conversions can be made.
162  * - Ensures the ABI compatibility for the socket address types.
163  * - Implements the conversion between the socket address types
164  *   and the container types (including byte arrays) in a way
165  *   that allows enforcing the boundary checks.
166  * - Does not have a significant runtime impact.
167  *
168  * To achive that, the mechanism relies on the C generic dispatch
169  * mechanism, which allows converting variables to and from
170  * the desired types.
171  *
172  *
173  * 4. Usage.
174  *
175  * In order to use the sockaddr_utils, the implementation
176  * code needs to include this file *after* including the files
177  * which define the relevant sockaddr structures.
178  *
179  * For example:
180  *
181  *    #include <netinet/in.h>
182  *    #include <netinet/in_private.h>
183  *    #include <net/sockaddr_utils.h>
184  *
185  *
186  * Doing so will redefine the canonical macros such as `SA(s)`
187  * and will allow for mostly seamless adoption.
188  *
189  * Once the adoption is mostly complete,
190  * this file can be included in the "private" versions
191  * of the header files, such as <netinet/in_private.h>
192  */
193 
194 #define __NET_SOCKADDR_UTILS_H_INCLUDED
195 #include <net/strict_type_cnv_private.h>
196 #undef __NET_SOCKADDR_UTILS_H_INCLUDED
197 
198 #include <net/if_dl.h>
199 #include <sys/un.h>
200 #include <net/ndrv.h>
201 #include <netinet/in_private.h>
202 #include <netinet/if_ether.h>
203 #include <net/necp.h>
204 
205 /*
206  * Building blocks for the cast operations
207  */
208 
209 
210 /*
211  * Generic static cast for sockaddr subtypes.
212  *
213  * Defines a static cast expression that, given the expression EXPR
214  * and the destination type DST_TYPENAME will:
215  * 0. If EXPR represents a byte array, attempt to convert EXPR
216  *    to DST_TYPENAME.
217  * 1. If EXPR is compatible with `struct DST_TYPENAME *': return EXPR.
218  * 2. If EXPR is compatible with `struct sockaddr *', perform type conversion
219  *    from `struct sockaddr *' to `struct DST_TYPENAME  *'
220  * 3. If EXPR is compatible with  `struct sockaddr_storage *',
221  *    perform type conversion from `struct sockaddr_storage *'
222  *    to `struct DST_TYPENAME *'.
223  * 4. If additional conversions are enabled, attempt to apply those
224  *    to the EXPR, and if successful, return the result of conversion.
225  *
226  * NOTE: The static cast preserves the CV qualifiers.
227  */
228 #define __SA_UTILS_STATIC_CAST(EXPR, DST_TYPENAME, ...)  _Generic((EXPR),                         \
229 	__STC_BYTES_TO_OBJ_CNV_CLAUSE(DST_TYPENAME),                                     /* [0] */    \
230 	__STC_IDENTITY_CNV_CLAUSE(struct, DST_TYPENAME),                                 /* [1] */    \
231 	__STC_TYPE_TO_OBJ_CNV_CLAUSE(struct, sockaddr, DST_TYPENAME),                    /* [2] */    \
232 	__STC_TYPE_TO_OBJ_CNV_CLAUSE(struct, sockaddr_storage, DST_TYPENAME),            /* [3] */    \
233     ##__VA_ARGS__                                                                    /* [4] */    \
234 )((EXPR))
235 
236 
237 /*
238  * Generic const cast for sockaddr subtypes.
239  *
240  * Defines a const cast expression that, given the expression EXPR
241  * and the destination type DST_TYPENAME will:
242  * 0. If EXPR is compatible with `const struct DST_TYPENAME *':
243  *    deconst EXPR and return the result.
244  * 1. If EXPR is compatible with `const struct sockaddr  s*':
245  *    convert EXPR to `const struct DST_TYPENAME *' and return deconsted result.
246  * 2. If EXPR is compatible with `const struct sockaddr_storage *':
247  *    convert EXPR to `const struct DST_TYPENAME* ' and return deconsted result.
248  * 3. If additional conversions are enabled, attempt to apply those
249  *    to the EXPR, and if successful, return the result of conversion.
250  *
251  * NOTE: The static cast preserves the CV qualifiers.
252  */
253 #define __SA_UTILS_DECONST_CAST(EXPR, DST_TYPENAME, ...)  _Generic((EXPR),                        \
254 	__STC_CONST_IDENTITY_CNV_CLAUSE(struct, DST_TYPENAME),                           /* [0] */    \
255 	__STC_CONST_TYPE_TO_OBJ_CNV_CLAUSE(struct, sockaddr, DST_TYPENAME),              /* [1] */    \
256 	__STC_CONST_TYPE_TO_OBJ_CNV_CLAUSE(struct, sockaddr_storage, DST_TYPENAME),      /* [2] */    \
257     ##__VA_ARGS__                                                                    /* [3] */    \
258 )((EXPR))
259 
260 
261 /*
262  * Strict replacement for struct sockaddr
263  */
264 
265 /* Register the base types: struct sockaddr and struct sockaddr_storage */
266 __STC_DEFINE_SELF_CONVERTERS(struct, sockaddr);
267 __STC_DEFINE_OBJECT_CONVERTERS(struct, sockaddr, struct, sockaddr_storage);
268 __STC_DEFINE_OBJECT_CONVERTERS(struct, sockaddr, union, sockaddr_in_4_6);
269 __STC_DEFINE_OBJECT_CONVERTERS(struct, sockaddr, union, necp_sockaddr_union);
270 __STC_DEFINE_BYTE_TO_OBJ_CNVS(struct, sockaddr, 2, 255);
271 
272 __STC_DEFINE_SELF_CONVERTERS(struct, sockaddr_storage);
273 __STC_DEFINE_BYTE_TO_OBJ_CNVS(struct, sockaddr_storage,
274     sizeof(struct sockaddr_storage), sizeof(struct sockaddr_storage));
275 __STC_DEFINE_BYTE_TO_OBJ_CNVS(union, sockaddr_in_4_6,
276     sizeof(union sockaddr_in_4_6), sizeof(union sockaddr_in_4_6));
277 __STC_DEFINE_BYTE_TO_OBJ_CNVS(union, necp_sockaddr_union,
278     sizeof(union necp_sockaddr_union), sizeof(union necp_sockaddr_union));
279 
280 
281 /*************************************************************************************************
282  *  Generic converter to bytes.
283  */
284 #define __SA_UTILS_CONV_TO_BYTES(X) _Generic((X),                                                 \
285 	        __STC_OBJ_TO_BYTES_CNV_CLAUSE(struct, sockaddr),                                      \
286 	        __STC_OBJ_TO_BYTES_CNV_CLAUSE(struct, sockaddr_storage),                              \
287 	        __STC_OBJ_TO_BYTES_CNV_CLAUSE(union, sockaddr_in_4_6),                                \
288 	        __STC_OBJ_TO_BYTES_CNV_CLAUSE(union, necp_sockaddr_union),                            \
289 	        __STC_OBJ_TO_BYTES_CNV_CLAUSE(struct, sockaddr_ctl),                                  \
290 	        __STC_OBJ_TO_BYTES_CNV_CLAUSE(struct, sockaddr_dl),                                   \
291 	        __STC_OBJ_TO_BYTES_CNV_CLAUSE(struct, sockaddr_in),                                   \
292 	        __STC_OBJ_TO_BYTES_CNV_CLAUSE(struct, sockaddr_in6),                                  \
293 	        __STC_OBJ_TO_BYTES_CNV_CLAUSE(struct, sockaddr_inarp),                                \
294 	        __STC_OBJ_TO_BYTES_CNV_CLAUSE(struct, sockaddr_inifscope),                            \
295 	        __STC_OBJ_TO_BYTES_CNV_CLAUSE(struct, sockaddr_ndrv),                                 \
296 	        __STC_OBJ_TO_BYTES_CNV_CLAUSE(struct, sockaddr_sys),                                  \
297 	        __STC_OBJ_TO_BYTES_CNV_CLAUSE(struct, sockaddr_un),                                   \
298 	        __STC_BYTES_TO_BYTES_CNV_CLAUSE()                                                     \
299 	)((X))
300 
301 
302 /*************************************************************************************************
303  * Converters to `struct sockaddr *'
304  */
305 #define __SA_UTILS_CONV_TO_SOCKADDR(X) _Generic((X),                                              \
306 	        __STC_BYTES_TO_OBJ_CNV_CLAUSE(sockaddr),                                              \
307 	        __STC_TYPE_TO_OBJ_CNV_CLAUSE(struct, sockaddr_storage, sockaddr),                     \
308 	        __STC_TYPE_TO_OBJ_CNV_CLAUSE(union, sockaddr_in_4_6, sockaddr),                       \
309 	        __STC_TYPE_TO_OBJ_CNV_CLAUSE(union, necp_sockaddr_union, sockaddr),                   \
310 	        __STC_TYPE_TO_OBJ_CNV_CLAUSE(struct, sockaddr_ctl, sockaddr),                         \
311 	        __STC_TYPE_TO_OBJ_CNV_CLAUSE(struct, sockaddr_dl, sockaddr),                          \
312 	        __STC_TYPE_TO_OBJ_CNV_CLAUSE(struct, sockaddr_in, sockaddr),                          \
313 	        __STC_TYPE_TO_OBJ_CNV_CLAUSE(struct, sockaddr_in6, sockaddr),                         \
314 	        __STC_TYPE_TO_OBJ_CNV_CLAUSE(struct, sockaddr_inarp, sockaddr),                       \
315 	        __STC_TYPE_TO_OBJ_CNV_CLAUSE(struct, sockaddr_inifscope, sockaddr),                   \
316 	        __STC_TYPE_TO_OBJ_CNV_CLAUSE(struct, sockaddr_ndrv, sockaddr),                        \
317 	        __STC_TYPE_TO_OBJ_CNV_CLAUSE(struct, sockaddr_sys, sockaddr),                         \
318 	        __STC_TYPE_TO_OBJ_CNV_CLAUSE(struct, sockaddr_un, sockaddr),                          \
319 	        __STC_IDENTITY_CNV_CLAUSE(struct, sockaddr)                                           \
320 	)((X))
321 
322 #define __SA_UTILS_DECONST_AND_CONV_TO_SOCKADDR(X) _Generic((X),                                  \
323 	        __STC_CONST_TYPE_TO_OBJ_CNV_CLAUSE(struct, sockaddr_storage, sockaddr),               \
324 	        __STC_CONST_TYPE_TO_OBJ_CNV_CLAUSE(union, sockaddr_in_4_6, sockaddr),                 \
325 	        __STC_CONST_TYPE_TO_OBJ_CNV_CLAUSE(union, necp_sockaddr_union, sockaddr),             \
326 	        __STC_CONST_TYPE_TO_OBJ_CNV_CLAUSE(struct, sockaddr_ctl, sockaddr),                   \
327 	        __STC_CONST_TYPE_TO_OBJ_CNV_CLAUSE(struct, sockaddr_dl, sockaddr),                    \
328 	        __STC_CONST_TYPE_TO_OBJ_CNV_CLAUSE(struct, sockaddr_in, sockaddr),                    \
329 	        __STC_CONST_TYPE_TO_OBJ_CNV_CLAUSE(struct, sockaddr_in6, sockaddr),                   \
330 	        __STC_CONST_TYPE_TO_OBJ_CNV_CLAUSE(struct, sockaddr_inarp, sockaddr),                 \
331 	        __STC_CONST_TYPE_TO_OBJ_CNV_CLAUSE(struct, sockaddr_inifscope, sockaddr),             \
332 	        __STC_CONST_TYPE_TO_OBJ_CNV_CLAUSE(struct, sockaddr_ndrv, sockaddr),                  \
333 	        __STC_CONST_TYPE_TO_OBJ_CNV_CLAUSE(struct, sockaddr_sys, sockaddr),                   \
334 	        __STC_CONST_TYPE_TO_OBJ_CNV_CLAUSE(struct, sockaddr_un, sockaddr),                    \
335 	        __STC_CONST_IDENTITY_CNV_CLAUSE(struct, sockaddr)                                     \
336 	)((X))
337 
338 
339 #if defined(SA)
340 #undef SA
341 #endif /* defined(SA) */
342 #define SA(s)                          __SA_UTILS_CONV_TO_SOCKADDR((s))
343 #define __DECONST_SA(s)                __SA_UTILS_DECONST_AND_CONV_TO_SOCKADDR((s))
344 
345 #define SA_BYTES(s) __SA_UTILS_CONV_TO_BYTES(s)
346 
347 /*************************************************************************************************
348  * Replacements for `bcopy', `bcmp' and `bzero'.
349  */
350 #define SOCKADDR_COPY(SRC, DST, LEN)  do {                                                        \
351 	const uint8_t* __sau_sbytes = __SA_UTILS_CONV_TO_BYTES((SRC));                                \
352 	uint8_t* __sau_dbytes = __SA_UTILS_CONV_TO_BYTES((DST));                                      \
353 	bcopy(__sau_sbytes, __sau_dbytes, (LEN));                                                     \
354 } while(0)
355 
356 
357 #define SOCKADDR_ZERO(SRC, LEN)  do {                                                             \
358 	uint8_t* __sau_src_bytes = __SA_UTILS_CONV_TO_BYTES((SRC));                                   \
359 	bzero(__sau_src_bytes, (LEN));                                                                \
360 } while(0)
361 
362 
363 #define SOCKADDR_CMP(LH, RH, LEN)  ({                                                             \
364 	int __sac_rv = 0;                                                                             \
365 	const uint8_t* __sau_lhb = __SA_UTILS_CONV_TO_BYTES((LH));                                    \
366 	const uint8_t* __sau_rhb = __SA_UTILS_CONV_TO_BYTES((RH));                                    \
367 	__sac_rv = bcmp(__sau_lhb, __sau_rhb, (LEN));                                                 \
368 	__sac_rv;                                                                                     \
369 })
370 
371 /*************************************************************************************************
372  * Strict replacement for `struct sockaddr_ctl *'
373  */
374 __SA_UTILS_DEFINE_FIXED_SIZE_SUBTYPE(struct, sockaddr_ctl)
375 
376 #define __SA_UTILS_CONV_TO_SOCKADDR_CTL(X)              __SA_UTILS_STATIC_CAST(X, sockaddr_ctl)
377 #define __SA_UTILS_DECONST_AND_CONV_TO_SOCKADDR_CTL(X)  __SA_UTILS_DECONST_CAST(X, sockaddr_ctl)
378 
379 #define SCTL(s)                        __SA_UTILS_CONV_TO_SOCKADDR_CTL((s))
380 #define __DECONST_SCTL(s)              __SA_UTILS_DECONST_AND_CONV_TO_SOCKADDR_CTL((s))
381 
382 
383 /*************************************************************************************************
384  * Strict replacement for `struct sockaddr_dl *'
385  */
386 __SA_UTILS_DEFINE_VARIABLE_SIZE_SUBTYPE(struct, sockaddr_dl)
387 
388 
389 #define __SA_UTILS_CONV_TO_SOCKADDR_DL(X)             __SA_UTILS_STATIC_CAST(X, sockaddr_dl)
390 #define __SA_UTILS_DECONST_AND_CONV_TO_SOCKADDR_DL(X) __SA_UTILS_DECONST_CAST (X, sockaddr_dl)
391 
392 #if defined(SDL)
393 #undef SDL
394 #endif /* defined(SDL) */
395 #define SDL(s)                         __SA_UTILS_CONV_TO_SOCKADDR_DL((s))
396 #define __DECONST_SDL(s)               __SA_UTILS_DECONST_AND_CONV_TO_SOCKADDR_DL((s))
397 
398 #if defined(LLADDR)
399 #undef LLADDR
400 #endif /* defined(LLADDR) */
401 #define LLADDR(s) ((caddr_t)(__SA_UTILS_CONV_TO_BYTES((s)) + __offsetof(struct sockaddr_dl, sdl_data) + (s)->sdl_nlen))
402 
403 #if defined(CONST_LLADDR)
404 #undef CONST_LLADDR
405 #endif /* defined(CONST_LLADDR) */
406 #define CONST_LLADDR(s) ((const uint8_t *)LLADDR((s)))
407 
408 /*************************************************************************************************
409  * Strict replacement for `struct sockaddr_in *'
410  */
411 __SA_UTILS_DEFINE_FIXED_SIZE_SUBTYPE(struct, sockaddr_in,                                         \
412         union, sockaddr_in_4_6,                                                                   \
413         union, necp_sockaddr_union)
414 
415 #define __SA_UTILS_CONV_TO_SOCKADDR_IN(X)                                                         \
416     __SA_UTILS_STATIC_CAST(X, sockaddr_in,                                                        \
417 	__STC_ENABLE_STATIC_CAST(union, sockaddr_in_4_6, sockaddr_in),                                \
418 	__STC_ENABLE_STATIC_CAST(union, necp_sockaddr_union, sockaddr_in))
419 
420 
421 #define __SA_UTILS_DECONST_AND_CONV_TO_SOCKADDR_IN(X)                                             \
422     __SA_UTILS_DECONST_CAST (X, sockaddr_in,                                                      \
423 	    __STC_ENABLE_DECONST_CAST(union, sockaddr_in_4_6, sockaddr_in),                           \
424 	    __STC_ENABLE_DECONST_CAST(union, necp_sockaddr_union, sockaddr_in))
425 
426 #if defined(SIN)
427 #undef SIN
428 #endif /* defined(SIN) */
429 #define SIN(s)                   __SA_UTILS_CONV_TO_SOCKADDR_IN((s))
430 #define __DECONST_SIN(s)         __SA_UTILS_DECONST_AND_CONV_TO_SOCKADDR_IN((s))
431 
432 #if defined(satosin)
433 #undef satosin
434 #endif /* defined(satosin) */
435 #define satosin(sa)     SIN(sa)
436 
437 #if defined(sintosa)
438 #undef sintosa
439 #endif /* defined(sintosa) */
440 #define sintosa(sin)     SA(sin)
441 
442 
443 /*************************************************************************************************
444  * Strict replacement for `struct sockaddr_inarp *'
445  */
446 __SA_UTILS_DEFINE_FIXED_SIZE_SUBTYPE(struct, sockaddr_inarp)
447 
448 #define __SA_UTILS_CONV_TO_SOCKADDR_INARP(X)                                                      \
449     __SA_UTILS_STATIC_CAST(X, sockaddr_inarp)
450 
451 #define __SA_UTILS_DECONST_AND_CONV_TO_SOCKADDR_INARP(X)                                          \
452     __SA_UTILS_DECONST_CAST(X, sockaddr_inarp)
453 
454 #define SINARP(s)                __SA_UTILS_CONV_TO_SOCKADDR_INARP((s))
455 #define __DECONST_SINARP(s)      __SA_UTILS_DECONST_AND_CONV_TO_SOCKADDR_INARP((s))
456 
457 
458 /*************************************************************************************************
459  * Strict replacement for `struct sockaddr_inifscope *'
460  */
461 __SA_UTILS_DEFINE_FIXED_SIZE_SUBTYPE(struct, sockaddr_inifscope,                                  \
462         union, sockaddr_in_4_6,                                                                   \
463         union, necp_sockaddr_union)
464 
465 #define __SA_UTILS_CONV_TO_SOCKADDR_INIFSCOPE(X)                                                  \
466     __SA_UTILS_STATIC_CAST(X, sockaddr_inifscope,                                                 \
467 	   __STC_ENABLE_STATIC_CAST(union, sockaddr_in_4_6, sockaddr_inifscope),                      \
468 	   __STC_ENABLE_STATIC_CAST(union, necp_sockaddr_union, sockaddr_inifscope))
469 
470 #define __SA_UTILS_DECONST_AND_CONV_TO_SOCKADDR_INIFSCOPE(X)                                      \
471     __SA_UTILS_DECONST_CAST(X, sockaddr_inifscope,                                                \
472 	    __STC_ENABLE_DECONST_CAST(union, sockaddr_in_4_6, sockaddr_inifscope),                    \
473 	    __STC_ENABLE_DECONST_CAST(union, necp_sockaddr_union, sockaddr_inifscope))
474 
475 #if defined(SINIFSCOPE)
476 #undef SINIFSCOPE
477 #endif /* defined(SINIFSCOPE) */
478 #define SINIFSCOPE(s)            __SA_UTILS_CONV_TO_SOCKADDR_INIFSCOPE((s))
479 #define __DECONST_SINIFSCOPE(s)  __SA_UTILS_DECONST_AND_CONV_TO_SOCKADDR_INIFSCOPE((s))
480 
481 
482 /*************************************************************************************************
483  * Strict replacement for `struct sockaddr_in6 *'
484  */
485 __SA_UTILS_DEFINE_FIXED_SIZE_SUBTYPE(struct, sockaddr_in6,                                        \
486         union, sockaddr_in_4_6,                                                                   \
487         union, necp_sockaddr_union)
488 
489 #define __SA_UTILS_CONV_TO_SOCKADDR_IN6(X)                                                        \
490     __SA_UTILS_STATIC_CAST(X, sockaddr_in6,                                                       \
491 	__STC_ENABLE_STATIC_CAST(union, sockaddr_in_4_6, sockaddr_in6),                               \
492 	__STC_ENABLE_STATIC_CAST(union, necp_sockaddr_union, sockaddr_in6))
493 
494 #define __SA_UTILS_DECONST_AND_CONV_TO_SOCKADDR_IN6(X)                                            \
495     __SA_UTILS_DECONST_CAST(X, sockaddr_in6,                                                      \
496 	    __STC_ENABLE_DECONST_CAST(union, sockaddr_in_4_6, sockaddr_in6),                          \
497 	    __STC_ENABLE_DECONST_CAST(union, necp_sockaddr_union, sockaddr_in6))
498 
499 #if defined(SIN6)
500 #undef SIN6
501 #endif /* defined(SIN6) */
502 #define SIN6(s)                  __SA_UTILS_CONV_TO_SOCKADDR_IN6((s))
503 #define __DECONST_SIN6(s)        __SA_UTILS_DECONST_AND_CONV_TO_SOCKADDR_IN6((s))
504 
505 #if defined(satosin6)
506 #undef satosin6
507 #endif /* defined(satosin6) */
508 #define satosin6(sa)    SIN6(sa)
509 
510 #if defined(sin6tosa)
511 #undef sin6tosa
512 #endif /* defined(sin6tosa) */
513 #define sin6tosa(sin6)   SA((sin6))
514 
515 #if defined(SIN6IFSCOPE)
516 #undef SIN6IFSCOPE
517 #endif /* defined(SIN6IFSCOPE) */
518 #define SIN6IFSCOPE(s)  SIN6(s)
519 
520 
521 /*************************************************************************************************
522  * Strict replacement for `struct sockaddr_ndrv *'
523  */
524 __SA_UTILS_DEFINE_FIXED_SIZE_SUBTYPE(struct, sockaddr_ndrv)
525 
526 #define __SA_UTILS_CONV_TO_SOCKADDR_NDRV(X)                                                       \
527     __SA_UTILS_STATIC_CAST(X, sockaddr_ndrv)
528 
529 #define __SA_UTILS_DECONST_AND_CONV_TO_SOCKADDR_NDRV(X)                                           \
530     __SA_UTILS_DECONST_CAST(X, sockaddr_ndrv)
531 
532 #define SNDRV(s)                 __SA_UTILS_CONV_TO_SOCKADDR_NDRV((s))
533 #define __DECONST_SNDRV(s)       __SA_UTILS_DECONST_AND_CONV_TO_SOCKADDR_NDRV((s))
534 
535 
536 /*************************************************************************************************
537  * Strict replacement for `struct sockaddr_sys *'
538  */
539 __SA_UTILS_DEFINE_FIXED_SIZE_SUBTYPE(struct, sockaddr_sys)
540 
541 #define __SA_UTILS_CONV_TO_SOCKADDR_SYS(X)                                                        \
542     __SA_UTILS_STATIC_CAST(X, sockaddr_sys)
543 
544 #define __SA_UTILS_DECONST_AND_CONV_TO_SOCKADDR_SYS(X)                                            \
545     __SA_UTILS_DECONST_CAST(X, sockaddr_sys)
546 
547 #define SSYS(s)                  __SA_UTILS_CONV_TO_SOCKADDR_SYS((s))
548 #define __DECONST_SSYS(s)        __SA_UTILS_DECONST_AND_CONV_TO_SOCKADDR_SYS((s))
549 
550 
551 /*************************************************************************************************
552  * Strict replacement for `struct sockaddr_un *'
553  */
554 __SA_UTILS_DEFINE_VARIABLE_SIZE_SUBTYPE(struct, sockaddr_un)
555 
556 #define __SA_UTILS_CONV_TO_SOCKADDR_UN(X)                                                         \
557     __SA_UTILS_STATIC_CAST(X, sockaddr_un)
558 
559 #define __SA_UTILS_DECONST_AND_CONV_TO_SOCKADDR_UN(X)                                             \
560     __SA_UTILS_DECONST_CAST(X, sockaddr_un)
561 
562 #define SUN(s)                   __SA_UTILS_CONV_TO_SOCKADDR_UN((s))
563 #define __DECONST_SUN(s)         __SA_UTILS_DECONST_AND_CONV_TO_SOCKADDR_UN((s))
564 
565 
566 #endif /* XNU_KERNEL_PRIVATE */
567 
568 #endif /* _NET_SOCKADDR_UTILS_H_ */
569