2 * Copyright 2009-2010, Axel Dörfler, axeld@pinc-software.de.
3 * Copyright 2008, Ingo Weinhold, ingo_weinhold@gmx.de.
5 * Distributed under the terms of the MIT License.
9 #include <sys/socket.h>
16 #include <AutoDeleter.h>
18 #include <syscall_utils.h>
23 #include <syscall_restart.h>
24 #include <util/AutoLock.h>
27 #include <net_stack_interface.h>
31 #define MAX_SOCKET_ADDRESS_LENGTH (sizeof(sockaddr_storage))
32 #define MAX_SOCKET_OPTION_LENGTH 128
33 #define MAX_ANCILLARY_DATA_LENGTH 1024
35 #define GET_SOCKET_FD_OR_RETURN(fd, kernel, descriptor) \
37 status_t getError = get_socket_descriptor(fd, kernel, descriptor); \
38 if (getError != B_OK) \
43 static net_stack_interface_module_info
* sStackInterface
= NULL
;
44 static vint32 sStackInterfaceInitialized
= 0;
45 static mutex sLock
= MUTEX_INITIALIZER("stack interface");
49 FDPutter(file_descriptor
* descriptor
)
50 : descriptor(descriptor
)
56 if (descriptor
!= NULL
)
60 file_descriptor
* descriptor
;
64 static net_stack_interface_module_info
*
65 get_stack_interface_module()
69 if (sStackInterfaceInitialized
++ == 0) {
71 net_stack_interface_module_info
* module
;
72 // TODO: Add driver settings option to load the userland net stack.
73 status_t error
= get_module(NET_STACK_INTERFACE_MODULE_NAME
,
74 (module_info
**)&module
);
76 sStackInterface
= module
;
78 sStackInterface
= NULL
;
81 return sStackInterface
;
86 put_stack_interface_module()
90 if (sStackInterfaceInitialized
-- == 1)
91 put_module(NET_STACK_INTERFACE_MODULE_NAME
);
96 prepare_userland_address_result(struct sockaddr
* userAddress
,
97 socklen_t
* _addressLength
, socklen_t
& addressLength
, bool addressRequired
)
100 if (_addressLength
== NULL
)
102 if (userAddress
== NULL
) {
105 } else if (!IS_USER_ADDRESS(userAddress
)
106 || !IS_USER_ADDRESS(_addressLength
)) {
107 return B_BAD_ADDRESS
;
110 // copy the buffer size from userland
112 if (userAddress
!= NULL
113 && user_memcpy(&addressLength
, _addressLength
, sizeof(socklen_t
))
115 return B_BAD_ADDRESS
;
118 if (addressLength
> MAX_SOCKET_ADDRESS_LENGTH
)
119 addressLength
= MAX_SOCKET_ADDRESS_LENGTH
;
126 copy_address_to_userland(const void* address
, socklen_t addressLength
,
127 sockaddr
* userAddress
, socklen_t userAddressBufferSize
,
128 socklen_t
* userAddressLength
)
130 // copy address size and address back to userland
131 if (user_memcpy(userAddressLength
, &addressLength
,
132 sizeof(socklen_t
)) != B_OK
133 || (userAddress
!= NULL
134 && user_memcpy(userAddress
, address
,
135 min_c(addressLength
, userAddressBufferSize
)) != B_OK
)) {
136 return B_BAD_ADDRESS
;
144 prepare_userland_msghdr(const msghdr
* userMessage
, msghdr
& message
,
145 iovec
*& userVecs
, MemoryDeleter
& vecsDeleter
, void*& userAddress
,
148 if (userMessage
== NULL
)
151 // copy message from userland
152 if (!IS_USER_ADDRESS(userMessage
)
153 || user_memcpy(&message
, userMessage
, sizeof(msghdr
)) != B_OK
) {
154 return B_BAD_ADDRESS
;
157 userVecs
= message
.msg_iov
;
158 userAddress
= message
.msg_name
;
160 // copy iovecs from userland
161 if (message
.msg_iovlen
< 0 || message
.msg_iovlen
> IOV_MAX
)
163 if (userVecs
!= NULL
&& message
.msg_iovlen
> 0) {
164 iovec
* vecs
= (iovec
*)malloc(sizeof(iovec
) * message
.msg_iovlen
);
167 vecsDeleter
.SetTo(vecs
);
169 if (!IS_USER_ADDRESS(message
.msg_iov
)
170 || user_memcpy(vecs
, message
.msg_iov
,
171 message
.msg_iovlen
* sizeof(iovec
)) != B_OK
) {
172 return B_BAD_ADDRESS
;
175 for (int i
= 0; i
< message
.msg_iovlen
; i
++) {
176 if (!IS_USER_ADDRESS(vecs
[i
].iov_base
))
177 return B_BAD_ADDRESS
;
180 message
.msg_iov
= vecs
;
182 message
.msg_iov
= NULL
;
183 message
.msg_iovlen
= 0;
186 // prepare the address field
187 userAddress
= message
.msg_name
;
188 if (userAddress
!= NULL
) {
189 if (!IS_USER_ADDRESS(message
.msg_name
))
190 return B_BAD_ADDRESS
;
191 if (message
.msg_namelen
> MAX_SOCKET_ADDRESS_LENGTH
)
192 message
.msg_namelen
= MAX_SOCKET_ADDRESS_LENGTH
;
194 message
.msg_name
= address
;
202 get_socket_descriptor(int fd
, bool kernel
, file_descriptor
*& descriptor
)
207 descriptor
= get_fd(get_current_io_context(kernel
), fd
);
208 if (descriptor
== NULL
)
211 if (descriptor
->type
!= FDTYPE_SOCKET
) {
220 // #pragma mark - socket file descriptor
224 socket_read(struct file_descriptor
*descriptor
, off_t pos
, void *buffer
,
227 ssize_t bytesRead
= sStackInterface
->recv(descriptor
->u
.socket
, buffer
,
229 *_length
= bytesRead
>= 0 ? bytesRead
: 0;
230 return bytesRead
>= 0 ? B_OK
: bytesRead
;
235 socket_write(struct file_descriptor
*descriptor
, off_t pos
, const void *buffer
,
238 ssize_t bytesWritten
= sStackInterface
->send(descriptor
->u
.socket
, buffer
,
240 *_length
= bytesWritten
>= 0 ? bytesWritten
: 0;
241 return bytesWritten
>= 0 ? B_OK
: bytesWritten
;
246 socket_ioctl(struct file_descriptor
*descriptor
, ulong op
, void *buffer
,
249 return sStackInterface
->ioctl(descriptor
->u
.socket
, op
, buffer
, length
);
254 socket_set_flags(struct file_descriptor
*descriptor
, int flags
)
256 // we ignore O_APPEND, but O_NONBLOCK we need to translate
257 uint32 op
= (flags
& O_NONBLOCK
) != 0
258 ? B_SET_NONBLOCKING_IO
: B_SET_BLOCKING_IO
;
260 return sStackInterface
->ioctl(descriptor
->u
.socket
, op
, NULL
, 0);
265 socket_select(struct file_descriptor
*descriptor
, uint8 event
,
266 struct selectsync
*sync
)
268 return sStackInterface
->select(descriptor
->u
.socket
, event
, sync
);
273 socket_deselect(struct file_descriptor
*descriptor
, uint8 event
,
274 struct selectsync
*sync
)
276 return sStackInterface
->deselect(descriptor
->u
.socket
, event
, sync
);
281 socket_read_stat(struct file_descriptor
*descriptor
, struct stat
*st
)
284 st
->st_ino
= (addr_t
)descriptor
->u
.socket
;
285 st
->st_mode
= S_IFSOCK
| 0666;
291 st
->st_blksize
= 1024; // use MTU for datagram sockets?
295 now
.tv_sec
= time(NULL
);
308 socket_close(struct file_descriptor
*descriptor
)
310 return sStackInterface
->close(descriptor
->u
.socket
);
315 socket_free(struct file_descriptor
*descriptor
)
317 sStackInterface
->free(descriptor
->u
.socket
);
318 put_stack_interface_module();
322 static struct fd_ops sSocketFDOps
= {
331 NULL
, // fd_rewind_dir
333 NULL
, // fd_write_stat
340 create_socket_fd(net_socket
* socket
, bool kernel
)
342 // Get the socket's non-blocking flag, so we can set the respective
345 socklen_t nonBlockLen
= sizeof(int32
);
346 status_t error
= sStackInterface
->getsockopt(socket
, SOL_SOCKET
,
347 SO_NONBLOCK
, &nonBlock
, &nonBlockLen
);
351 // allocate a file descriptor
352 file_descriptor
* descriptor
= alloc_fd();
353 if (descriptor
== NULL
)
357 descriptor
->type
= FDTYPE_SOCKET
;
358 descriptor
->ops
= &sSocketFDOps
;
359 descriptor
->u
.socket
= socket
;
360 descriptor
->open_mode
= O_RDWR
| (nonBlock
? O_NONBLOCK
: 0);
363 int fd
= new_fd(get_current_io_context(kernel
), descriptor
);
371 // #pragma mark - common sockets API implementation
375 common_socket(int family
, int type
, int protocol
, bool kernel
)
377 if (!get_stack_interface_module())
378 return B_UNSUPPORTED
;
382 status_t error
= sStackInterface
->open(family
, type
, protocol
, &socket
);
384 put_stack_interface_module();
389 int fd
= create_socket_fd(socket
, kernel
);
391 sStackInterface
->close(socket
);
392 sStackInterface
->free(socket
);
393 put_stack_interface_module();
401 common_bind(int fd
, const struct sockaddr
*address
, socklen_t addressLength
,
404 file_descriptor
* descriptor
;
405 GET_SOCKET_FD_OR_RETURN(fd
, kernel
, descriptor
);
406 FDPutter
_(descriptor
);
408 return sStackInterface
->bind(descriptor
->u
.socket
, address
, addressLength
);
413 common_shutdown(int fd
, int how
, bool kernel
)
415 file_descriptor
* descriptor
;
416 GET_SOCKET_FD_OR_RETURN(fd
, kernel
, descriptor
);
417 FDPutter
_(descriptor
);
419 return sStackInterface
->shutdown(descriptor
->u
.socket
, how
);
424 common_connect(int fd
, const struct sockaddr
*address
,
425 socklen_t addressLength
, bool kernel
)
427 file_descriptor
* descriptor
;
428 GET_SOCKET_FD_OR_RETURN(fd
, kernel
, descriptor
);
429 FDPutter
_(descriptor
);
431 return sStackInterface
->connect(descriptor
->u
.socket
, address
,
437 common_listen(int fd
, int backlog
, bool kernel
)
439 file_descriptor
* descriptor
;
440 GET_SOCKET_FD_OR_RETURN(fd
, kernel
, descriptor
);
441 FDPutter
_(descriptor
);
443 return sStackInterface
->listen(descriptor
->u
.socket
, backlog
);
448 common_accept(int fd
, struct sockaddr
*address
, socklen_t
*_addressLength
,
451 file_descriptor
* descriptor
;
452 GET_SOCKET_FD_OR_RETURN(fd
, kernel
, descriptor
);
453 FDPutter
_(descriptor
);
455 net_socket
* acceptedSocket
;
456 status_t error
= sStackInterface
->accept(descriptor
->u
.socket
, address
,
457 _addressLength
, &acceptedSocket
);
462 int acceptedFD
= create_socket_fd(acceptedSocket
, kernel
);
463 if (acceptedFD
< 0) {
464 sStackInterface
->close(acceptedSocket
);
465 sStackInterface
->free(acceptedSocket
);
467 // we need a reference for the new FD
468 get_stack_interface_module();
476 common_recv(int fd
, void *data
, size_t length
, int flags
, bool kernel
)
478 file_descriptor
* descriptor
;
479 GET_SOCKET_FD_OR_RETURN(fd
, kernel
, descriptor
);
480 FDPutter
_(descriptor
);
482 return sStackInterface
->recv(descriptor
->u
.socket
, data
, length
, flags
);
487 common_recvfrom(int fd
, void *data
, size_t length
, int flags
,
488 struct sockaddr
*address
, socklen_t
*_addressLength
, bool kernel
)
490 file_descriptor
* descriptor
;
491 GET_SOCKET_FD_OR_RETURN(fd
, kernel
, descriptor
);
492 FDPutter
_(descriptor
);
494 return sStackInterface
->recvfrom(descriptor
->u
.socket
, data
, length
,
495 flags
, address
, _addressLength
);
500 common_recvmsg(int fd
, struct msghdr
*message
, int flags
, bool kernel
)
502 file_descriptor
* descriptor
;
503 GET_SOCKET_FD_OR_RETURN(fd
, kernel
, descriptor
);
504 FDPutter
_(descriptor
);
506 return sStackInterface
->recvmsg(descriptor
->u
.socket
, message
, flags
);
511 common_send(int fd
, const void *data
, size_t length
, int flags
, bool kernel
)
513 file_descriptor
* descriptor
;
514 GET_SOCKET_FD_OR_RETURN(fd
, kernel
, descriptor
);
515 FDPutter
_(descriptor
);
517 return sStackInterface
->send(descriptor
->u
.socket
, data
, length
, flags
);
522 common_sendto(int fd
, const void *data
, size_t length
, int flags
,
523 const struct sockaddr
*address
, socklen_t addressLength
, bool kernel
)
525 file_descriptor
* descriptor
;
526 GET_SOCKET_FD_OR_RETURN(fd
, kernel
, descriptor
);
527 FDPutter
_(descriptor
);
529 return sStackInterface
->sendto(descriptor
->u
.socket
, data
, length
, flags
,
530 address
, addressLength
);
535 common_sendmsg(int fd
, const struct msghdr
*message
, int flags
, bool kernel
)
537 file_descriptor
* descriptor
;
538 GET_SOCKET_FD_OR_RETURN(fd
, kernel
, descriptor
);
539 FDPutter
_(descriptor
);
541 return sStackInterface
->sendmsg(descriptor
->u
.socket
, message
, flags
);
546 common_getsockopt(int fd
, int level
, int option
, void *value
,
547 socklen_t
*_length
, bool kernel
)
549 file_descriptor
* descriptor
;
550 GET_SOCKET_FD_OR_RETURN(fd
, kernel
, descriptor
);
551 FDPutter
_(descriptor
);
553 return sStackInterface
->getsockopt(descriptor
->u
.socket
, level
, option
,
559 common_setsockopt(int fd
, int level
, int option
, const void *value
,
560 socklen_t length
, bool kernel
)
562 file_descriptor
* descriptor
;
563 GET_SOCKET_FD_OR_RETURN(fd
, kernel
, descriptor
);
564 FDPutter
_(descriptor
);
566 return sStackInterface
->setsockopt(descriptor
->u
.socket
, level
, option
,
572 common_getpeername(int fd
, struct sockaddr
*address
,
573 socklen_t
*_addressLength
, bool kernel
)
575 file_descriptor
* descriptor
;
576 GET_SOCKET_FD_OR_RETURN(fd
, kernel
, descriptor
);
577 FDPutter
_(descriptor
);
579 return sStackInterface
->getpeername(descriptor
->u
.socket
, address
,
585 common_getsockname(int fd
, struct sockaddr
*address
,
586 socklen_t
*_addressLength
, bool kernel
)
588 file_descriptor
* descriptor
;
589 GET_SOCKET_FD_OR_RETURN(fd
, kernel
, descriptor
);
590 FDPutter
_(descriptor
);
592 return sStackInterface
->getsockname(descriptor
->u
.socket
, address
,
598 common_sockatmark(int fd
, bool kernel
)
600 file_descriptor
* descriptor
;
601 GET_SOCKET_FD_OR_RETURN(fd
, kernel
, descriptor
);
602 FDPutter
_(descriptor
);
604 return sStackInterface
->sockatmark(descriptor
->u
.socket
);
609 common_socketpair(int family
, int type
, int protocol
, int fds
[2], bool kernel
)
611 if (!get_stack_interface_module())
612 return B_UNSUPPORTED
;
614 net_socket
* sockets
[2];
615 status_t error
= sStackInterface
->socketpair(family
, type
, protocol
,
618 put_stack_interface_module();
623 for (int i
= 0; i
< 2; i
++) {
624 fds
[i
] = create_socket_fd(sockets
[i
], kernel
);
626 sStackInterface
->close(sockets
[i
]);
627 sStackInterface
->free(sockets
[i
]);
628 put_stack_interface_module();
633 // We need another reference for the second socket
634 get_stack_interface_module();
640 common_get_next_socket_stat(int family
, uint32
*cookie
, struct net_stat
*stat
)
642 if (!get_stack_interface_module())
643 return B_UNSUPPORTED
;
645 status_t status
= sStackInterface
->get_next_socket_stat(family
, cookie
,
648 put_stack_interface_module();
653 // #pragma mark - kernel sockets API
657 socket(int family
, int type
, int protocol
)
659 SyscallFlagUnsetter _
;
660 RETURN_AND_SET_ERRNO(common_socket(family
, type
, protocol
, true));
665 bind(int socket
, const struct sockaddr
*address
, socklen_t addressLength
)
667 SyscallFlagUnsetter _
;
668 RETURN_AND_SET_ERRNO(common_bind(socket
, address
, addressLength
, true));
673 shutdown(int socket
, int how
)
675 SyscallFlagUnsetter _
;
676 RETURN_AND_SET_ERRNO(common_shutdown(socket
, how
, true));
681 connect(int socket
, const struct sockaddr
*address
, socklen_t addressLength
)
683 SyscallFlagUnsetter _
;
684 RETURN_AND_SET_ERRNO(common_connect(socket
, address
, addressLength
, true));
689 listen(int socket
, int backlog
)
691 SyscallFlagUnsetter _
;
692 RETURN_AND_SET_ERRNO(common_listen(socket
, backlog
, true));
697 accept(int socket
, struct sockaddr
*address
, socklen_t
*_addressLength
)
699 SyscallFlagUnsetter _
;
700 RETURN_AND_SET_ERRNO(common_accept(socket
, address
, _addressLength
, true));
705 recv(int socket
, void *data
, size_t length
, int flags
)
707 SyscallFlagUnsetter _
;
708 RETURN_AND_SET_ERRNO(common_recv(socket
, data
, length
, flags
, true));
713 recvfrom(int socket
, void *data
, size_t length
, int flags
,
714 struct sockaddr
*address
, socklen_t
*_addressLength
)
716 SyscallFlagUnsetter _
;
717 RETURN_AND_SET_ERRNO(common_recvfrom(socket
, data
, length
, flags
, address
,
718 _addressLength
, true));
723 recvmsg(int socket
, struct msghdr
*message
, int flags
)
725 SyscallFlagUnsetter _
;
726 RETURN_AND_SET_ERRNO(common_recvmsg(socket
, message
, flags
, true));
731 send(int socket
, const void *data
, size_t length
, int flags
)
733 SyscallFlagUnsetter _
;
734 RETURN_AND_SET_ERRNO(common_send(socket
, data
, length
, flags
, true));
739 sendto(int socket
, const void *data
, size_t length
, int flags
,
740 const struct sockaddr
*address
, socklen_t addressLength
)
742 SyscallFlagUnsetter _
;
743 RETURN_AND_SET_ERRNO(common_sendto(socket
, data
, length
, flags
, address
,
744 addressLength
, true));
749 sendmsg(int socket
, const struct msghdr
*message
, int flags
)
751 SyscallFlagUnsetter _
;
752 RETURN_AND_SET_ERRNO(common_sendmsg(socket
, message
, flags
, true));
757 getsockopt(int socket
, int level
, int option
, void *value
, socklen_t
*_length
)
759 SyscallFlagUnsetter _
;
760 RETURN_AND_SET_ERRNO(common_getsockopt(socket
, level
, option
, value
,
766 setsockopt(int socket
, int level
, int option
, const void *value
,
769 SyscallFlagUnsetter _
;
770 RETURN_AND_SET_ERRNO(common_setsockopt(socket
, level
, option
, value
,
776 getpeername(int socket
, struct sockaddr
*address
, socklen_t
*_addressLength
)
778 SyscallFlagUnsetter _
;
779 RETURN_AND_SET_ERRNO(common_getpeername(socket
, address
, _addressLength
,
785 getsockname(int socket
, struct sockaddr
*address
, socklen_t
*_addressLength
)
787 SyscallFlagUnsetter _
;
788 RETURN_AND_SET_ERRNO(common_getsockname(socket
, address
, _addressLength
,
794 sockatmark(int socket
)
796 SyscallFlagUnsetter _
;
797 RETURN_AND_SET_ERRNO(common_sockatmark(socket
, true));
802 socketpair(int family
, int type
, int protocol
, int socketVector
[2])
804 SyscallFlagUnsetter _
;
805 RETURN_AND_SET_ERRNO(common_socketpair(family
, type
, protocol
,
806 socketVector
, true));
810 // #pragma mark - syscalls
814 _user_socket(int family
, int type
, int protocol
)
816 SyscallRestartWrapper
<int> result
;
817 return result
= common_socket(family
, type
, protocol
, false);
822 _user_bind(int socket
, const struct sockaddr
*userAddress
,
823 socklen_t addressLength
)
825 // check parameters and copy address from userland
826 if (userAddress
== NULL
|| addressLength
> MAX_SOCKET_ADDRESS_LENGTH
)
829 sockaddr_storage address
;
830 memset(&address
, 0, sizeof(address
));
831 if (!IS_USER_ADDRESS(userAddress
)
832 || user_memcpy(&address
, userAddress
, addressLength
) != B_OK
) {
833 return B_BAD_ADDRESS
;
836 address
.ss_len
= addressLength
;
837 // make sure the sa_len field is set correctly
839 SyscallRestartWrapper
<status_t
> error
;
840 return error
= common_bind(socket
, (sockaddr
*)&address
, addressLength
,
846 _user_shutdown_socket(int socket
, int how
)
848 SyscallRestartWrapper
<status_t
> error
;
849 return error
= common_shutdown(socket
, how
, false);
854 _user_connect(int socket
, const struct sockaddr
*userAddress
,
855 socklen_t addressLength
)
857 // check parameters and copy address from userland
858 if (userAddress
== NULL
|| addressLength
> MAX_SOCKET_ADDRESS_LENGTH
)
861 sockaddr_storage address
;
862 memset(&address
, 0, sizeof(address
));
863 if (!IS_USER_ADDRESS(userAddress
)
864 || user_memcpy(&address
, userAddress
, addressLength
) != B_OK
) {
865 return B_BAD_ADDRESS
;
868 address
.ss_len
= addressLength
;
869 // make sure the sa_len field is set correctly
871 SyscallRestartWrapper
<status_t
> error
;
873 return error
= common_connect(socket
, (sockaddr
*)&address
, addressLength
,
879 _user_listen(int socket
, int backlog
)
881 SyscallRestartWrapper
<status_t
> error
;
882 return error
= common_listen(socket
, backlog
, false);
887 _user_accept(int socket
, struct sockaddr
*userAddress
,
888 socklen_t
*_addressLength
)
891 socklen_t addressLength
= 0;
892 status_t error
= prepare_userland_address_result(userAddress
,
893 _addressLength
, addressLength
, false);
898 SyscallRestartWrapper
<int> result
;
900 char address
[MAX_SOCKET_ADDRESS_LENGTH
];
901 socklen_t userAddressBufferSize
= addressLength
;
902 result
= common_accept(socket
,
903 userAddress
!= NULL
? (sockaddr
*)address
: NULL
, &addressLength
, false);
905 // copy address size and address back to userland
906 if (copy_address_to_userland(address
, addressLength
, userAddress
,
907 userAddressBufferSize
, _addressLength
) != B_OK
) {
909 return B_BAD_ADDRESS
;
917 _user_recv(int socket
, void *data
, size_t length
, int flags
)
919 if (data
== NULL
|| !IS_USER_ADDRESS(data
))
920 return B_BAD_ADDRESS
;
922 SyscallRestartWrapper
<ssize_t
> result
;
923 return result
= common_recv(socket
, data
, length
, flags
, false);
928 _user_recvfrom(int socket
, void *data
, size_t length
, int flags
,
929 struct sockaddr
*userAddress
, socklen_t
*_addressLength
)
931 if (data
== NULL
|| !IS_USER_ADDRESS(data
))
932 return B_BAD_ADDRESS
;
935 socklen_t addressLength
= 0;
936 status_t error
= prepare_userland_address_result(userAddress
,
937 _addressLength
, addressLength
, false);
942 SyscallRestartWrapper
<ssize_t
> result
;
944 char address
[MAX_SOCKET_ADDRESS_LENGTH
];
945 socklen_t userAddressBufferSize
= addressLength
;
946 result
= common_recvfrom(socket
, data
, length
, flags
,
947 userAddress
!= NULL
? (sockaddr
*)address
: NULL
, &addressLength
, false);
951 // copy address size and address back to userland
952 if (copy_address_to_userland(address
, addressLength
, userAddress
,
953 userAddressBufferSize
, _addressLength
) != B_OK
) {
954 return B_BAD_ADDRESS
;
962 _user_recvmsg(int socket
, struct msghdr
*userMessage
, int flags
)
964 // copy message from userland
967 MemoryDeleter vecsDeleter
;
969 char address
[MAX_SOCKET_ADDRESS_LENGTH
];
971 status_t error
= prepare_userland_msghdr(userMessage
, message
, userVecs
,
972 vecsDeleter
, userAddress
, address
);
976 // prepare a buffer for ancillary data
977 MemoryDeleter ancillaryDeleter
;
978 void* ancillary
= NULL
;
979 void* userAncillary
= message
.msg_control
;
980 if (userAncillary
!= NULL
) {
981 if (!IS_USER_ADDRESS(userAncillary
))
982 return B_BAD_ADDRESS
;
983 if (message
.msg_controllen
< 0)
985 if (message
.msg_controllen
> MAX_ANCILLARY_DATA_LENGTH
)
986 message
.msg_controllen
= MAX_ANCILLARY_DATA_LENGTH
;
988 message
.msg_control
= ancillary
= malloc(message
.msg_controllen
);
989 if (message
.msg_control
== NULL
)
992 ancillaryDeleter
.SetTo(ancillary
);
996 SyscallRestartWrapper
<ssize_t
> result
;
998 result
= common_recvmsg(socket
, &message
, flags
, false);
1002 // copy the address, the ancillary data, and the message header back to
1004 message
.msg_name
= userAddress
;
1005 message
.msg_iov
= userVecs
;
1006 message
.msg_control
= userAncillary
;
1007 if ((userAddress
!= NULL
&& user_memcpy(userAddress
, address
,
1008 message
.msg_namelen
) != B_OK
)
1009 || (userAncillary
!= NULL
&& user_memcpy(userAncillary
, ancillary
,
1010 message
.msg_controllen
) != B_OK
)
1011 || user_memcpy(userMessage
, &message
, sizeof(msghdr
)) != B_OK
) {
1012 return B_BAD_ADDRESS
;
1020 _user_send(int socket
, const void *data
, size_t length
, int flags
)
1022 if (data
== NULL
|| !IS_USER_ADDRESS(data
))
1023 return B_BAD_ADDRESS
;
1025 SyscallRestartWrapper
<ssize_t
> result
;
1026 return result
= common_send(socket
, data
, length
, flags
, false);
1031 _user_sendto(int socket
, const void *data
, size_t length
, int flags
,
1032 const struct sockaddr
*userAddress
, socklen_t addressLength
)
1034 if (data
== NULL
|| !IS_USER_ADDRESS(data
))
1035 return B_BAD_ADDRESS
;
1037 // TODO: If this is a connection-mode socket, the address parameter is
1038 // supposed to be ignored.
1039 if (userAddress
== NULL
|| addressLength
<= 0
1040 || addressLength
> MAX_SOCKET_ADDRESS_LENGTH
) {
1044 // copy address from userland
1045 char address
[MAX_SOCKET_ADDRESS_LENGTH
];
1046 if (!IS_USER_ADDRESS(userAddress
)
1047 || user_memcpy(address
, userAddress
, addressLength
) != B_OK
) {
1048 return B_BAD_ADDRESS
;
1052 SyscallRestartWrapper
<ssize_t
> result
;
1054 return result
= common_sendto(socket
, data
, length
, flags
,
1055 (sockaddr
*)address
, addressLength
, false);
1060 _user_sendmsg(int socket
, const struct msghdr
*userMessage
, int flags
)
1062 // copy message from userland
1065 MemoryDeleter vecsDeleter
;
1067 char address
[MAX_SOCKET_ADDRESS_LENGTH
];
1069 status_t error
= prepare_userland_msghdr(userMessage
, message
, userVecs
,
1070 vecsDeleter
, userAddress
, address
);
1074 // copy the address from userland
1075 if (userAddress
!= NULL
1076 && user_memcpy(address
, userAddress
, message
.msg_namelen
) != B_OK
) {
1077 return B_BAD_ADDRESS
;
1080 // copy ancillary data from userland
1081 MemoryDeleter ancillaryDeleter
;
1082 void* userAncillary
= message
.msg_control
;
1083 if (userAncillary
!= NULL
) {
1084 if (!IS_USER_ADDRESS(userAncillary
))
1085 return B_BAD_ADDRESS
;
1086 if (message
.msg_controllen
< 0
1087 || message
.msg_controllen
> MAX_ANCILLARY_DATA_LENGTH
) {
1091 message
.msg_control
= malloc(message
.msg_controllen
);
1092 if (message
.msg_control
== NULL
)
1094 ancillaryDeleter
.SetTo(message
.msg_control
);
1096 if (user_memcpy(message
.msg_control
, userAncillary
,
1097 message
.msg_controllen
) != B_OK
) {
1098 return B_BAD_ADDRESS
;
1103 SyscallRestartWrapper
<ssize_t
> result
;
1105 return result
= common_sendmsg(socket
, &message
, flags
, false);
1110 _user_getsockopt(int socket
, int level
, int option
, void *userValue
,
1114 if (userValue
== NULL
|| _length
== NULL
)
1116 if (!IS_USER_ADDRESS(userValue
) || !IS_USER_ADDRESS(_length
))
1117 return B_BAD_ADDRESS
;
1119 // copy length from userland
1121 if (user_memcpy(&length
, _length
, sizeof(socklen_t
)) != B_OK
)
1122 return B_BAD_ADDRESS
;
1124 if (length
> MAX_SOCKET_OPTION_LENGTH
)
1128 char value
[MAX_SOCKET_OPTION_LENGTH
];
1129 SyscallRestartWrapper
<status_t
> error
;
1130 error
= common_getsockopt(socket
, level
, option
, value
, &length
,
1135 // copy value back to userland
1136 if (user_memcpy(userValue
, value
, length
) != B_OK
)
1137 return B_BAD_ADDRESS
;
1144 _user_setsockopt(int socket
, int level
, int option
, const void *userValue
,
1148 if (userValue
== NULL
|| length
> MAX_SOCKET_OPTION_LENGTH
)
1151 // copy value from userland
1152 char value
[MAX_SOCKET_OPTION_LENGTH
];
1153 if (!IS_USER_ADDRESS(userValue
)
1154 || user_memcpy(value
, userValue
, length
) != B_OK
) {
1155 return B_BAD_ADDRESS
;
1159 SyscallRestartWrapper
<status_t
> error
;
1160 return error
= common_setsockopt(socket
, level
, option
, value
, length
,
1166 _user_getpeername(int socket
, struct sockaddr
*userAddress
,
1167 socklen_t
*_addressLength
)
1170 socklen_t addressLength
= 0;
1171 SyscallRestartWrapper
<status_t
> error
;
1172 error
= prepare_userland_address_result(userAddress
, _addressLength
,
1173 addressLength
, true);
1178 char address
[MAX_SOCKET_ADDRESS_LENGTH
];
1179 socklen_t userAddressBufferSize
= addressLength
;
1180 error
= common_getpeername(socket
, (sockaddr
*)address
, &addressLength
,
1185 // copy address size and address back to userland
1186 if (copy_address_to_userland(address
, addressLength
, userAddress
,
1187 userAddressBufferSize
, _addressLength
) != B_OK
) {
1188 return B_BAD_ADDRESS
;
1196 _user_getsockname(int socket
, struct sockaddr
*userAddress
,
1197 socklen_t
*_addressLength
)
1200 socklen_t addressLength
= 0;
1201 SyscallRestartWrapper
<status_t
> error
;
1202 error
= prepare_userland_address_result(userAddress
, _addressLength
,
1203 addressLength
, true);
1208 char address
[MAX_SOCKET_ADDRESS_LENGTH
];
1209 socklen_t userAddressBufferSize
= addressLength
;
1210 error
= common_getsockname(socket
, (sockaddr
*)address
, &addressLength
,
1215 // copy address size and address back to userland
1216 if (copy_address_to_userland(address
, addressLength
, userAddress
,
1217 userAddressBufferSize
, _addressLength
) != B_OK
) {
1218 return B_BAD_ADDRESS
;
1226 _user_sockatmark(int socket
)
1228 SyscallRestartWrapper
<status_t
> error
;
1229 return error
= common_sockatmark(socket
, false);
1234 _user_socketpair(int family
, int type
, int protocol
, int *userSocketVector
)
1237 if (userSocketVector
== NULL
)
1239 if (!IS_USER_ADDRESS(userSocketVector
))
1240 return B_BAD_ADDRESS
;
1243 int socketVector
[2];
1244 SyscallRestartWrapper
<status_t
> error
;
1245 error
= common_socketpair(family
, type
, protocol
, socketVector
, false);
1249 // copy FDs back to userland
1250 if (user_memcpy(userSocketVector
, socketVector
,
1251 sizeof(socketVector
)) != B_OK
) {
1252 _user_close(socketVector
[0]);
1253 _user_close(socketVector
[1]);
1254 return B_BAD_ADDRESS
;
1262 _user_get_next_socket_stat(int family
, uint32
*_cookie
, struct net_stat
*_stat
)
1264 // check parameters and copy cookie from userland
1265 if (_cookie
== NULL
|| _stat
== NULL
)
1269 if (!IS_USER_ADDRESS(_stat
) || !IS_USER_ADDRESS(_cookie
)
1270 || user_memcpy(&cookie
, _cookie
, sizeof(cookie
)) != B_OK
) {
1271 return B_BAD_ADDRESS
;
1275 SyscallRestartWrapper
<status_t
> error
;
1276 error
= common_get_next_socket_stat(family
, &cookie
, &stat
);
1280 // copy cookie and data back to userland
1281 if (user_memcpy(_cookie
, &cookie
, sizeof(cookie
)) != B_OK
1282 || user_memcpy(_stat
, &stat
, sizeof(net_stat
)) != B_OK
) {
1283 return B_BAD_ADDRESS
;