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