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, sizeof(struct sockaddr), 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 | |
399 | /************************************************************************************************* |
400 | * Strict replacement for `struct sockaddr_in *' |
401 | */ |
402 | __SA_UTILS_DEFINE_FIXED_SIZE_SUBTYPE(struct, sockaddr_in, \ |
403 | union, sockaddr_in_4_6, \ |
404 | union, necp_sockaddr_union) |
405 | |
406 | #define __SA_UTILS_CONV_TO_SOCKADDR_IN(X) \ |
407 | __SA_UTILS_STATIC_CAST(X, sockaddr_in, \ |
408 | __STC_ENABLE_STATIC_CAST(union, sockaddr_in_4_6, sockaddr_in), \ |
409 | __STC_ENABLE_STATIC_CAST(union, necp_sockaddr_union, sockaddr_in)) |
410 | |
411 | |
412 | #define __SA_UTILS_DECONST_AND_CONV_TO_SOCKADDR_IN(X) \ |
413 | __SA_UTILS_DECONST_CAST (X, sockaddr_in, \ |
414 | __STC_ENABLE_DECONST_CAST(union, sockaddr_in_4_6, sockaddr_in), \ |
415 | __STC_ENABLE_DECONST_CAST(union, necp_sockaddr_union, sockaddr_in)) |
416 | |
417 | #if defined(SIN) |
418 | #undef SIN |
419 | #endif /* defined(SIN) */ |
420 | #define SIN(s) __SA_UTILS_CONV_TO_SOCKADDR_IN((s)) |
421 | #define __DECONST_SIN(s) __SA_UTILS_DECONST_AND_CONV_TO_SOCKADDR_IN((s)) |
422 | |
423 | #if defined(satosin) |
424 | #undef satosin |
425 | #endif /* defined(satosin) */ |
426 | #define satosin(sa) SIN(sa) |
427 | |
428 | #if defined(sintosa) |
429 | #undef sintosa |
430 | #endif /* defined(sintosa) */ |
431 | #define sintosa(sin) SA(sin) |
432 | |
433 | |
434 | /************************************************************************************************* |
435 | * Strict replacement for `struct sockaddr_inarp *' |
436 | */ |
437 | __SA_UTILS_DEFINE_FIXED_SIZE_SUBTYPE(struct, sockaddr_inarp) |
438 | |
439 | #define __SA_UTILS_CONV_TO_SOCKADDR_INARP(X) \ |
440 | __SA_UTILS_STATIC_CAST(X, sockaddr_inarp) |
441 | |
442 | #define __SA_UTILS_DECONST_AND_CONV_TO_SOCKADDR_INARP(X) \ |
443 | __SA_UTILS_DECONST_CAST(X, sockaddr_inarp) |
444 | |
445 | #define SINARP(s) __SA_UTILS_CONV_TO_SOCKADDR_INARP((s)) |
446 | #define __DECONST_SINARP(s) __SA_UTILS_DECONST_AND_CONV_TO_SOCKADDR_INARP((s)) |
447 | |
448 | |
449 | /************************************************************************************************* |
450 | * Strict replacement for `struct sockaddr_inifscope *' |
451 | */ |
452 | __SA_UTILS_DEFINE_FIXED_SIZE_SUBTYPE(struct, sockaddr_inifscope, \ |
453 | union, sockaddr_in_4_6, \ |
454 | union, necp_sockaddr_union) |
455 | |
456 | #define __SA_UTILS_CONV_TO_SOCKADDR_INIFSCOPE(X) \ |
457 | __SA_UTILS_STATIC_CAST(X, sockaddr_inifscope, \ |
458 | __STC_ENABLE_STATIC_CAST(union, sockaddr_in_4_6, sockaddr_inifscope), \ |
459 | __STC_ENABLE_STATIC_CAST(union, necp_sockaddr_union, sockaddr_inifscope)) |
460 | |
461 | #define __SA_UTILS_DECONST_AND_CONV_TO_SOCKADDR_INIFSCOPE(X) \ |
462 | __SA_UTILS_DECONST_CAST(X, sockaddr_inifscope, \ |
463 | __STC_ENABLE_DECONST_CAST(union, sockaddr_in_4_6, sockaddr_inifscope), \ |
464 | __STC_ENABLE_DECONST_CAST(union, necp_sockaddr_union, sockaddr_inifscope)) |
465 | |
466 | #if defined(SINIFSCOPE) |
467 | #undef SINIFSCOPE |
468 | #endif /* defined(SINIFSCOPE) */ |
469 | #define SINIFSCOPE(s) __SA_UTILS_CONV_TO_SOCKADDR_INIFSCOPE((s)) |
470 | #define __DECONST_SINIFSCOPE(s) __SA_UTILS_DECONST_AND_CONV_TO_SOCKADDR_INIFSCOPE((s)) |
471 | |
472 | |
473 | /************************************************************************************************* |
474 | * Strict replacement for `struct sockaddr_in6 *' |
475 | */ |
476 | __SA_UTILS_DEFINE_FIXED_SIZE_SUBTYPE(struct, sockaddr_in6, \ |
477 | union, sockaddr_in_4_6, \ |
478 | union, necp_sockaddr_union) |
479 | |
480 | #define __SA_UTILS_CONV_TO_SOCKADDR_IN6(X) \ |
481 | __SA_UTILS_STATIC_CAST(X, sockaddr_in6, \ |
482 | __STC_ENABLE_STATIC_CAST(union, sockaddr_in_4_6, sockaddr_in6), \ |
483 | __STC_ENABLE_STATIC_CAST(union, necp_sockaddr_union, sockaddr_in6)) |
484 | |
485 | #define __SA_UTILS_DECONST_AND_CONV_TO_SOCKADDR_IN6(X) \ |
486 | __SA_UTILS_DECONST_CAST(X, sockaddr_in6, \ |
487 | __STC_ENABLE_DECONST_CAST(union, sockaddr_in_4_6, sockaddr_in6), \ |
488 | __STC_ENABLE_DECONST_CAST(union, necp_sockaddr_union, sockaddr_in6)) |
489 | |
490 | #if defined(SIN6) |
491 | #undef SIN6 |
492 | #endif /* defined(SIN6) */ |
493 | #define SIN6(s) __SA_UTILS_CONV_TO_SOCKADDR_IN6((s)) |
494 | #define __DECONST_SIN6(s) __SA_UTILS_DECONST_AND_CONV_TO_SOCKADDR_IN6((s)) |
495 | |
496 | #if defined(satosin6) |
497 | #undef satosin6 |
498 | #endif /* defined(satosin6) */ |
499 | #define satosin6(sa) SIN6(sa) |
500 | |
501 | #if defined(sin6tosa) |
502 | #undef sin6tosa |
503 | #endif /* defined(sin6tosa) */ |
504 | #define sin6tosa(sin6) SA((sin6)) |
505 | |
506 | #if defined(SIN6IFSCOPE) |
507 | #undef SIN6IFSCOPE |
508 | #endif /* defined(SIN6IFSCOPE) */ |
509 | #define SIN6IFSCOPE(s) SIN6(s) |
510 | |
511 | |
512 | /************************************************************************************************* |
513 | * Strict replacement for `struct sockaddr_ndrv *' |
514 | */ |
515 | __SA_UTILS_DEFINE_FIXED_SIZE_SUBTYPE(struct, sockaddr_ndrv) |
516 | |
517 | #define __SA_UTILS_CONV_TO_SOCKADDR_NDRV(X) \ |
518 | __SA_UTILS_STATIC_CAST(X, sockaddr_ndrv) |
519 | |
520 | #define __SA_UTILS_DECONST_AND_CONV_TO_SOCKADDR_NDRV(X) \ |
521 | __SA_UTILS_DECONST_CAST(X, sockaddr_ndrv) |
522 | |
523 | #define SNDRV(s) __SA_UTILS_CONV_TO_SOCKADDR_NDRV((s)) |
524 | #define __DECONST_SNDRV(s) __SA_UTILS_DECONST_AND_CONV_TO_SOCKADDR_NDRV((s)) |
525 | |
526 | |
527 | /************************************************************************************************* |
528 | * Strict replacement for `struct sockaddr_sys *' |
529 | */ |
530 | __SA_UTILS_DEFINE_FIXED_SIZE_SUBTYPE(struct, sockaddr_sys) |
531 | |
532 | #define __SA_UTILS_CONV_TO_SOCKADDR_SYS(X) \ |
533 | __SA_UTILS_STATIC_CAST(X, sockaddr_sys) |
534 | |
535 | #define __SA_UTILS_DECONST_AND_CONV_TO_SOCKADDR_SYS(X) \ |
536 | __SA_UTILS_DECONST_CAST(X, sockaddr_sys) |
537 | |
538 | #define SSYS(s) __SA_UTILS_CONV_TO_SOCKADDR_SYS((s)) |
539 | #define __DECONST_SSYS(s) __SA_UTILS_DECONST_AND_CONV_TO_SOCKADDR_SYS((s)) |
540 | |
541 | |
542 | /************************************************************************************************* |
543 | * Strict replacement for `struct sockaddr_un *' |
544 | */ |
545 | __SA_UTILS_DEFINE_VARIABLE_SIZE_SUBTYPE(struct, sockaddr_un) |
546 | |
547 | #define __SA_UTILS_CONV_TO_SOCKADDR_UN(X) \ |
548 | __SA_UTILS_STATIC_CAST(X, sockaddr_un) |
549 | |
550 | #define __SA_UTILS_DECONST_AND_CONV_TO_SOCKADDR_UN(X) \ |
551 | __SA_UTILS_DECONST_CAST(X, sockaddr_un) |
552 | |
553 | #define SUN(s) __SA_UTILS_CONV_TO_SOCKADDR_UN((s)) |
554 | #define __DECONST_SUN(s) __SA_UTILS_DECONST_AND_CONV_TO_SOCKADDR_UN((s)) |
555 | |
556 | |
557 | #endif /* XNU_KERNEL_PRIVATE */ |
558 | |
559 | #endif /* _NET_SOCKADDR_UTILS_H_ */ |
560 | |