1/* 2 * Copyright (c) 2002 Apple Computer, 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/*! 29 @header kpi_socketfilter.h 30 This header defines an API for intercepting communications at the 31 socket layer. 32 33 For the most part, socket filters want to do three things: Filter 34 data in and out, watch for state changes, and intercept a few calls 35 for security. The number of function pointers supplied by a socket 36 filter has been significantly reduced. The filter no longer has any 37 knowledge of socket buffers. The filter no longer intercepts nearly 38 every internal socket call. There are two data filters, an in 39 filter, and an out filter. The in filter occurs before data is 40 placed in the receive socket buffer. This is done to avoid waking 41 the process unnecessarily. The out filter occurs before the data is 42 appended to the send socket buffer. This should cover inbound and 43 outbound data. For monitoring state changes, we've added a notify 44 function that will be called when various events that the filter can 45 not intercept occur. In addition, we've added a few functions that a 46 filter may use to intercept common operations. These functions are: 47 connect (inbound), connect (outbound), bind, set socket option, 48 get socket option, and listen. Bind, listen, connect in, and connect 49 out could be used together to build a fairly comprehensive firewall 50 without having to do much with individual packets. 51 */ 52#ifndef __KPI_SOCKETFILTER__ 53#define __KPI_SOCKETFILTER__ 54 55#include <sys/kernel_types.h> 56#include <sys/kpi_socket.h> 57 58struct sockaddr; 59 60/*! 61 @enum sflt_flags 62 @abstract Constants defining mbuf flags. Only the flags listed below 63 can be set or retrieved. 64 @constant SFLT_GLOBAL Indicates this socket filter should be 65 attached to all new sockets when they're created. 66 @constant SFLT_PROG Indicates this socket filter should be attached 67 only when request by the application using the SO_NKE socket 68 option. 69 @constant SFLT_EXTENDED Indicates that this socket filter utilizes 70 the extended fields within the sflt_filter structure. 71*/ 72enum { 73 SFLT_GLOBAL = 0x01, 74 SFLT_PROG = 0x02, 75 SFLT_EXTENDED = 0x04 76}; 77typedef u_int32_t sflt_flags; 78 79/*! 80 @typedef sflt_handle 81 @abstract A 4 byte identifier used with the SO_NKE socket option to 82 identify the socket filter to be attached. 83*/ 84typedef u_int32_t sflt_handle; 85 86/*! 87 @enum sflt_event_t 88 @abstract Events notify a filter of state changes and other various 89 events related to the socket. These events cannot be prevented 90 or intercepted, only observed. 91 @constant sock_evt_connected Indicates this socket has moved to the 92 connected state. 93 @constant sock_evt_disconnected Indicates this socket has moved to 94 the disconnected state. 95 @constant sock_evt_flush_read The read socket buffer has been 96 flushed. 97 @constant sock_evt_shutdown The read and or write side(s) of the 98 connection have been shutdown. The param will point to an 99 integer that indicates the direction that has been shutdown. See 100 'man 2 shutdown' for more information. 101 @constant sock_evt_cantrecvmore Indicates the socket cannot receive 102 more data. 103 @constant sock_evt_cantsendmore Indicates the socket cannot send 104 more data. 105 @constant sock_evt_closing Indicates the socket is closing. 106 @constant sock_evt_bound Indicates this socket has moved to the 107 bound state (only for PF_INET/PF_INET6 domain). 108*/ 109enum { 110 sock_evt_connecting = 1, 111 sock_evt_connected = 2, 112 sock_evt_disconnecting = 3, 113 sock_evt_disconnected = 4, 114 sock_evt_flush_read = 5, 115 sock_evt_shutdown = 6, /* param points to an integer specifying how (read, write, or both) see man 2 shutdown */ 116 sock_evt_cantrecvmore = 7, 117 sock_evt_cantsendmore = 8, 118 sock_evt_closing = 9, 119 sock_evt_bound = 10 120}; 121typedef u_int32_t sflt_event_t; 122 123/*! 124 @enum sflt_data_flag_t 125 @abstract Inbound and outbound data filters may handle many 126 different types of incoming and outgoing data. These flags help 127 distinguish between normal data, out-of-band data, and records. 128 @constant sock_data_filt_flag_oob Indicates this data is out-of-band 129 data. 130 @constant sock_data_filt_flag_record Indicates this data is a 131 record. This flag is only ever seen on inbound data. 132*/ 133enum { 134 sock_data_filt_flag_oob = 1, 135 sock_data_filt_flag_record = 2 136}; 137typedef u_int32_t sflt_data_flag_t; 138 139__BEGIN_DECLS 140 141/*! 142 @typedef sf_unregistered_func 143 144 @discussion sf_unregistered_func is called to notify the filter it 145 has been unregistered. This is the last function the stack will 146 call and this function will only be called once all other 147 function calls in to your filter have completed. Once this 148 function has been called, your kext may safely unload. 149 @param handle The socket filter handle used to identify this filter. 150*/ 151typedef void (*sf_unregistered_func)(sflt_handle handle); 152 153/*! 154 @typedef sf_attach_func 155 156 @discussion sf_attach_func is called to notify the filter it has 157 been attached to a socket. The filter may allocate memory for 158 this attachment and use the cookie to track it. This filter is 159 called in one of two cases: 160 1) You've installed a global filter and a new socket was created. 161 2) Your non-global socket filter is being attached using the SO_NKE 162 socket option. 163 @param cookie Used to allow the socket filter to set the cookie for 164 this attachment. 165 @param so The socket the filter is being attached to. 166 @result If you return a non-zero value, your filter will not be 167 attached to this socket. 168*/ 169typedef errno_t (*sf_attach_func)(void **cookie, socket_t so); 170 171/*! 172 @typedef sf_detach_func 173 174 @discussion sf_detach_func is called to notify the filter it has 175 been detached from a socket. If the filter allocated any memory 176 for this attachment, it should be freed. This function will 177 be called when the socket is disposed of. 178 @param cookie Cookie value specified when the filter attach was 179 called. 180 @param so The socket the filter is attached to. 181 @result If you return a non-zero value, your filter will not be 182 attached to this socket. 183*/ 184typedef void (*sf_detach_func)(void *cookie, socket_t so); 185 186/*! 187 @typedef sf_notify_func 188 189 @discussion sf_notify_func is called to notify the filter of various 190 state changes and other events occuring on the socket. 191 @param cookie Cookie value specified when the filter attach was 192 called. 193 @param so The socket the filter is attached to. 194 @param event The type of event that has occurred. 195 @param param Additional information about the event. 196*/ 197typedef void (*sf_notify_func)(void *cookie, socket_t so, 198 sflt_event_t event, void *param); 199 200/*! 201 @typedef sf_getpeername_func 202 203 @discussion sf_getpeername_func is called to allow a filter to 204 to intercept the getpeername function. When called, sa will 205 point to a pointer to a socket address that was malloced 206 in zone M_SONAME. If you want to replace this address, either 207 modify the currenty copy or allocate a new one and free the 208 old one. 209 @param cookie Cookie value specified when the filter attach was 210 called. 211 @param so The socket the filter is attached to. 212 @param sa A pointer to a socket address pointer. 213 @result If you return a non-zero value, processing will stop. If 214 you return EJUSTRETURN, no further filters will be called 215 but a result of zero will be returned to the caller of 216 getpeername. 217*/ 218typedef int (*sf_getpeername_func)(void *cookie, socket_t so, 219 struct sockaddr **sa); 220 221/*! 222 @typedef sf_getsockname_func 223 224 @discussion sf_getsockname_func is called to allow a filter to 225 to intercept the getsockname function. When called, sa will 226 point to a pointer to a socket address that was malloced 227 in zone M_SONAME. If you want to replace this address, either 228 modify the currenty copy or allocate a new one and free the 229 old one. 230 @param cookie Cookie value specified when the filter attach was 231 called. 232 @param so The socket the filter is attached to. 233 @param sa A pointer to a socket address pointer. 234 @result If you return a non-zero value, processing will stop. If 235 you return EJUSTRETURN, no further filters will be called 236 but a result of zero will be returned to the caller of 237 getsockname. 238*/ 239typedef int (*sf_getsockname_func)(void *cookie, socket_t so, 240 struct sockaddr **sa); 241 242/*! 243 @typedef sf_data_in_func 244 245 @discussion sf_data_in_func is called to filter incoming data. If your 246 filter intercepts data for later reinjection, it must queue all incoming 247 data to preserve the order of the data. Use sock_inject_data_in to later 248 reinject this data if you return EJUSTRETURN. Warning: This filter is on 249 the data path. Do not spend excesive time. Do not wait for data on 250 another socket. 251 @param cookie Cookie value specified when the filter attach was 252 called. 253 @param so The socket the filter is attached to. 254 @param from The addres the data is from, may be NULL if the socket 255 is connected. 256 @param data The data being received. Control data may appear in the 257 mbuf chain, be sure to check the mbuf types to find control 258 data. 259 @param control Control data being passed separately from the data. 260 @param flags Flags to indicate if this is out of band data or a 261 record. 262 @result Return: 263 0 - The caller will continue with normal processing of the data. 264 EJUSTRETURN - The caller will stop processing the data, the data will not be freed. 265 Anything Else - The caller will free the data and stop processing. 266*/ 267typedef errno_t (*sf_data_in_func)(void *cookie, socket_t so, 268 const struct sockaddr *from, mbuf_t *data, 269 mbuf_t *control, sflt_data_flag_t flags); 270 271/*! 272 @typedef sf_data_out_func 273 274 @discussion sf_data_out_func is called to filter outbound data. If 275 your filter intercepts data for later reinjection, it must queue 276 all outbound data to preserve the order of the data when 277 reinjecting. Use sock_inject_data_out to later reinject this 278 data. 279 @param cookie Cookie value specified when the filter attach was 280 called. 281 @param so The socket the filter is attached to. 282 @param from The address the data is from, may be NULL if the socket 283 is connected. 284 @param data The data being received. Control data may appear in the 285 mbuf chain, be sure to check the mbuf types to find control 286 data. 287 @param control Control data being passed separately from the data. 288 @param flags Flags to indicate if this is out of band data or a 289 record. 290 @result Return: 291 0 - The caller will continue with normal processing of the data. 292 EJUSTRETURN - The caller will stop processing the data, the data will not be freed. 293 Anything Else - The caller will free the data and stop processing. 294*/ 295typedef errno_t (*sf_data_out_func)(void *cookie, socket_t so, 296 const struct sockaddr *to, mbuf_t *data, 297 mbuf_t *control, sflt_data_flag_t flags); 298 299/*! 300 @typedef sf_connect_in_func 301 302 @discussion sf_connect_in_func is called to filter inbound connections. A 303 protocol will call this before accepting an incoming connection and 304 placing it on the queue of completed connections. Warning: This filter 305 is on the data path. Do not spend excesive time. Do not wait for data on 306 another socket. 307 @param cookie Cookie value specified when the filter attach was 308 called. 309 @param so The socket the filter is attached to. 310 @param from The address the incoming connection is from. 311 @result Return: 312 0 - The caller will continue with normal processing of the connection. 313 Anything Else - The caller will rejecting the incoming connection. 314*/ 315typedef errno_t (*sf_connect_in_func)(void *cookie, socket_t so, 316 const struct sockaddr *from); 317 318/*! 319 @typedef sf_connect_out_func 320 321 @discussion sf_connect_out_func is called to filter outbound 322 connections. A protocol will call this before initiating an 323 outbound connection. 324 @param cookie Cookie value specified when the filter attach was 325 called. 326 @param so The socket the filter is attached to. 327 @param to The remote address of the outbound connection. 328 @result Return: 329 0 - The caller will continue with normal processing of the connection. 330 Anything Else - The caller will rejecting the outbound connection. 331*/ 332typedef errno_t (*sf_connect_out_func)(void *cookie, socket_t so, 333 const struct sockaddr *to); 334 335/*! 336 @typedef sf_bind_func 337 338 @discussion sf_bind_func is called before performing a bind 339 operation on a socket. 340 @param cookie Cookie value specified when the filter attach was 341 called. 342 @param so The socket the filter is attached to. 343 @param to The local address of the socket will be bound to. 344 @result Return: 345 0 - The caller will continue with normal processing of the bind. 346 Anything Else - The caller will rejecting the bind. 347*/ 348typedef errno_t (*sf_bind_func)(void *cookie, socket_t so, 349 const struct sockaddr *to); 350 351/*! 352 @typedef sf_setoption_func 353 354 @discussion sf_setoption_func is called before performing setsockopt 355 on a socket. 356 @param cookie Cookie value specified when the filter attach was 357 called. 358 @param so The socket the filter is attached to. 359 @param opt The socket option to set. 360 @result Return: 361 0 - The caller will continue with normal processing of the setsockopt. 362 Anything Else - The caller will stop processing and return this error. 363*/ 364typedef errno_t (*sf_setoption_func)(void *cookie, socket_t so, 365 sockopt_t opt); 366 367/*! 368 @typedef sf_getoption_func 369 370 @discussion sf_getoption_func is called before performing getsockopt 371 on a socket. 372 @param cookie Cookie value specified when the filter attach was 373 called. 374 @param so The socket the filter is attached to. 375 @param opt The socket option to get. 376 @result Return: 377 0 - The caller will continue with normal processing of the getsockopt. 378 Anything Else - The caller will stop processing and return this error. 379*/ 380typedef errno_t (*sf_getoption_func)(void *cookie, socket_t so, 381 sockopt_t opt); 382 383/*! 384 @typedef sf_listen_func 385 386 @discussion sf_listen_func is called before performing listen 387 on a socket. 388 @param cookie Cookie value specified when the filter attach was 389 called. 390 @param so The socket the filter is attached to. 391 @result Return: 392 0 - The caller will continue with normal processing of listen. 393 Anything Else - The caller will stop processing and return this error. 394*/ 395typedef errno_t (*sf_listen_func)(void *cookie, socket_t so); 396 397/*! 398 @typedef sf_ioctl_func 399 400 @discussion sf_ioctl_func is called before performing an ioctl 401 on a socket. 402 403 All undefined ioctls are reserved for future use by Apple. If 404 you need to communicate with your kext using an ioctl, please 405 use SIOCSIFKPI and SIOCGIFKPI. 406 @param cookie Cookie value specified when the filter attach was 407 called. 408 @param so The socket the filter is attached to. 409 @param request The ioctl name. 410 @param argp A pointer to the ioctl parameter. 411 @result Return: 412 0 - The caller will continue with normal processing of this ioctl. 413 Anything Else - The caller will stop processing and return this error. 414*/ 415typedef errno_t (*sf_ioctl_func)(void *cookie, socket_t so, 416 u_int32_t request, const char* argp); 417 418/*! 419 @typedef sf_accept_func 420 421 @discussion sf_accept_func is called after a socket is dequeued 422 off the completed (incoming) connection list and before 423 the file descriptor is associated with it. A filter can 424 utilize this callback to intercept the accepted socket 425 in order to examine it, prior to returning the socket to 426 the caller of accept. Such a filter may also choose to 427 discard the accepted socket if it wishes to do so. 428 @param cookie Cookie value specified when the filter attach was called. 429 @param so_listen The listening socket. 430 @param so The socket that is about to be accepted. 431 @param local The local address of the about to be accepted socket. 432 @param remote The remote address of the about to be accepted socket. 433 @result Return: 434 0 - The caller will continue with normal processing of accept. 435 EJUSTRETURN - The to be accepted socket will be disconnected 436 prior to being returned to the caller of accept. No further 437 control or data operations on the socket will be allowed. 438 This is the recommended return value as it has the least 439 amount of impact, especially to applications which don't 440 check the error value returned by accept. 441 Anything Else - The to be accepted socket will be closed and 442 the error will be returned to the caller of accept. 443 Note that socket filter developers are advised to exercise 444 caution when returning non-zero values to the caller, 445 since some applications don't check the error value 446 returned by accept and therefore risk breakage. 447 */ 448typedef errno_t (*sf_accept_func)(void *cookie, socket_t so_listen, socket_t so, 449 const struct sockaddr *local, const struct sockaddr *remote); 450 451/*! 452 @struct sflt_filter 453 @discussion This structure is used to define a socket filter. 454 @field sf_handle A value used to find socket filters by 455 applications. An application can use this value to specify that 456 this filter should be attached when using the SO_NKE socket 457 option. 458 @field sf_flags Indicate whether this filter should be attached to 459 all new sockets or just those that request the filter be 460 attached using the SO_NKE socket option. If this filter 461 utilizes the socket filter extension fields, it must also 462 set SFLT_EXTENDED. 463 @field sf_name A name used for debug purposes. 464 @field sf_unregistered Your function for being notified when your 465 filter has been unregistered. 466 @field sf_attach Your function for handling attaches to sockets. 467 @field sf_detach Your function for handling detaches from sockets. 468 @field sf_notify Your function for handling events. May be null. 469 @field sf_data_in Your function for handling incoming data. May be 470 null. 471 @field sf_data_out Your function for handling outgoing data. May be 472 null. 473 @field sf_connect_in Your function for handling inbound 474 connections. May be null. 475 @field sf_connect_out Your function for handling outbound 476 connections. May be null. 477 @field sf_bind Your function for handling binds. May be null. 478 @field sf_setoption Your function for handling setsockopt. May be null. 479 @field sf_getoption Your function for handling getsockopt. May be null. 480 @field sf_listen Your function for handling listen. May be null. 481 @field sf_ioctl Your function for handling ioctls. May be null. 482 @field sf_len Length of socket filter extension structure; developers 483 must initialize this to sizeof sflt_filter_ext structure. 484 This field and all fields following it will only be valid 485 if SFLT_EXTENDED flag is set in sf_flags field. 486 @field sf_ext_accept Your function for handling inbound connections 487 at accept time. May be null. 488 @field sf_ext_rsvd Reserved for future use; you must initialize 489 the reserved fields with zeroes. 490*/ 491struct sflt_filter { 492 sflt_handle sf_handle; 493 int sf_flags; 494 char *sf_name; 495 496 sf_unregistered_func sf_unregistered; 497 sf_attach_func sf_attach; 498 sf_detach_func sf_detach; 499 500 sf_notify_func sf_notify; 501 sf_getpeername_func sf_getpeername; 502 sf_getsockname_func sf_getsockname; 503 sf_data_in_func sf_data_in; 504 sf_data_out_func sf_data_out; 505 sf_connect_in_func sf_connect_in; 506 sf_connect_out_func sf_connect_out; 507 sf_bind_func sf_bind; 508 sf_setoption_func sf_setoption; 509 sf_getoption_func sf_getoption; 510 sf_listen_func sf_listen; 511 sf_ioctl_func sf_ioctl; 512 /* 513 * The following are valid only if SFLT_EXTENDED flag is set. 514 * Initialize sf_ext_len to sizeof sflt_filter_ext structure. 515 * Filters must also initialize reserved fields with zeroes. 516 */ 517 struct sflt_filter_ext { 518 unsigned int sf_ext_len; 519 sf_accept_func sf_ext_accept; 520 void *sf_ext_rsvd[5]; /* Reserved */ 521 } sf_ext; 522#define sf_len sf_ext.sf_ext_len 523#define sf_accept sf_ext.sf_ext_accept 524}; 525 526/*! 527 @function sflt_register 528 @discussion Registers a socket filter. See 'man 2 socket' for a 529 desciption of domain, type, and protocol. 530 @param filter A structure describing the filter. 531 @param domain The protocol domain these filters will be attached to. 532 @param type The socket type these filters will be attached to. 533 @param protocol The protocol these filters will be attached to. 534 @result 0 on success otherwise the errno error. 535 */ 536errno_t sflt_register(const struct sflt_filter *filter, int domain, 537 int type, int protocol); 538 539/*! 540 @function sflt_unregister 541 @discussion Unregisters a socket filter. This will not detach the 542 socket filter from all sockets it may be attached to at the 543 time, it will just prevent the socket filter from being attached 544 to any new sockets. 545 @param handle The sf_handle of the socket filter to unregister. 546 @result 0 on success otherwise the errno error. 547 */ 548errno_t sflt_unregister(sflt_handle handle); 549 550/*! 551 @function sflt_attach 552 @discussion Attaches a socket filter to the specified socket. A 553 filter must be registered before it can be attached. 554 @param socket The socket the filter should be attached to. 555 @param handle The handle of the registered filter to be attached. 556 @result 0 on success otherwise the errno error. 557 */ 558errno_t sflt_attach(socket_t so, sflt_handle); 559 560/*! 561 @function sflt_detach 562 @discussion Detaches a socket filter from a specified socket. 563 @param socket The socket the filter should be detached from. 564 @param handle The handle of the registered filter to be detached. 565 @result 0 on success otherwise the errno error. 566 */ 567errno_t sflt_detach(socket_t so, sflt_handle); 568 569/* Functions for manipulating sockets */ 570/* 571 * Inject data in to the receive buffer of the socket as if it 572 * had come from the network. 573 * 574 * flags should match sflt_data_flag_t 575 */ 576 577/*! 578 @function sock_inject_data_in 579 @discussion Inject data in to the receive buffer of the socket as if 580 it had come from the network. 581 @param so The socket to inject the data on. 582 @param from The address the data is from, only necessary on 583 un-connected sockets. A copy of the address will be made, caller 584 is responsible for freeing the address after calling this 585 function. 586 @param data The data and possibly control mbufs. 587 @param control The separate control mbufs. 588 @param flags Flags indicating the type of data. 589 @result 0 on success otherwise the errno error. If the function 590 returns an error, the caller is responsible for freeing the 591 mbuf. 592 */ 593errno_t sock_inject_data_in(socket_t so, const struct sockaddr* from, 594 mbuf_t data, mbuf_t control, sflt_data_flag_t flags); 595 596/*! 597 @function sock_inject_data_out 598 @discussion Inject data in to the send buffer of the socket as if it 599 had come from the client. 600 @param so The socket to inject the data on. 601 @param to The address the data should be sent to, only necessary on 602 un-connected sockets. The caller is responsible for freeing the 603 to address after sock_inject_data_out returns. 604 @param data The data and possibly control mbufs. 605 @param control The separate control mbufs. 606 @param flags Flags indicating the type of data. 607 @result 0 on success otherwise the errno error. The data and control 608 values are always freed regardless of return value. 609 */ 610errno_t sock_inject_data_out(socket_t so, const struct sockaddr* to, 611 mbuf_t data, mbuf_t control, sflt_data_flag_t flags); 612 613 614/* 615 * sockopt_t accessors 616 */ 617 618enum { 619 sockopt_get = 1, 620 sockopt_set = 2 621}; 622typedef u_int8_t sockopt_dir; 623 624/*! 625 @function sockopt_direction 626 @discussion Retrieves the direction of the socket option (Get or 627 Set). 628 @param sopt The socket option. 629 @result sock_opt_get or sock_opt_set. 630 */ 631sockopt_dir sockopt_direction(sockopt_t sopt); 632 633/*! 634 @function sockopt_level 635 @discussion Retrieves the socket option level. (SOL_SOCKET, etc). 636 @param sopt The socket option. 637 @result The socket option level. See man 2 setsockopt 638 */ 639int sockopt_level(sockopt_t sopt); 640 641/*! 642 @function sockopt_name 643 @discussion Retrieves the socket option name. (SO_SNDBUF, etc). 644 @param sopt The socket option. 645 @result The socket option name. See man 2 setsockopt 646 */ 647int sockopt_name(sockopt_t sopt); 648 649/*! 650 @function sockopt_valsize 651 @discussion Retrieves the size of the socket option data. 652 @param sopt The socket option. 653 @result The length, in bytes, of the data. 654 */ 655size_t sockopt_valsize(sockopt_t sopt); 656 657/*! 658 @function sockopt_copyin 659 @discussion Copies the data from the socket option to a buffer. 660 @param sopt The socket option. 661 @param data A pointer to the buffer to copy the data in to. 662 @param length The number of bytes to copy. 663 @result An errno error or zero upon success. 664 */ 665errno_t sockopt_copyin(sockopt_t sopt, void *data, size_t length); 666 667/*! 668 @function sockopt_copyout 669 @discussion Copies the data from a buffer to a socket option. 670 @param sopt The socket option. 671 @param data A pointer to the buffer to copy the data out of. 672 @param length The number of bytes to copy. 673 @result An errno error or zero upon success. 674 */ 675errno_t sockopt_copyout(sockopt_t sopt, void *data, size_t length); 676 677__END_DECLS 678#endif 679