1/*
2 * Copyright 2009-2010, Axel D��rfler, axeld@pinc-software.de.
3 * Copyright 2008, Ingo Weinhold, ingo_weinhold@gmx.de.
4 * Distributed under the terms of the MIT License.
5 */
6
7
8#include <sys/socket.h>
9
10#include <errno.h>
11#include <limits.h>
12
13#include <module.h>
14
15#include <AutoDeleter.h>
16#include <AutoDeleterDrivers.h>
17
18#include <syscall_utils.h>
19
20#include <fd.h>
21#include <kernel.h>
22#include <lock.h>
23#include <syscall_restart.h>
24#include <util/AutoLock.h>
25#include <util/iovec_support.h>
26#include <vfs.h>
27
28#include <net_stack_interface.h>
29#include <net_stat.h>
30
31
32#define MAX_SOCKET_ADDRESS_LENGTH	(sizeof(sockaddr_storage))
33#define MAX_SOCKET_OPTION_LENGTH	128
34#define MAX_ANCILLARY_DATA_LENGTH	1024
35
36#define GET_SOCKET_FD_OR_RETURN(fd, kernel, descriptor)	\
37	do {												\
38		status_t getError = get_socket_descriptor(fd, kernel, descriptor); \
39		if (getError != B_OK)							\
40			return getError;							\
41	} while (false)
42
43
44static net_stack_interface_module_info* sStackInterface = NULL;
45static vint32 sStackInterfaceInitialized = 0;
46static mutex sLock = MUTEX_INITIALIZER("stack interface");
47
48
49static net_stack_interface_module_info*
50get_stack_interface_module()
51{
52	MutexLocker _(sLock);
53
54	if (sStackInterfaceInitialized++ == 0) {
55		// load module
56		net_stack_interface_module_info* module;
57		// TODO: Add driver settings option to load the userland net stack.
58		status_t error = get_module(NET_STACK_INTERFACE_MODULE_NAME,
59			(module_info**)&module);
60		if (error == B_OK)
61			sStackInterface = module;
62		else
63			sStackInterface = NULL;
64	}
65
66	return sStackInterface;
67}
68
69
70static void
71put_stack_interface_module()
72{
73	MutexLocker _(sLock);
74
75	if (sStackInterfaceInitialized-- == 1)
76		put_module(NET_STACK_INTERFACE_MODULE_NAME);
77}
78
79
80static status_t
81prepare_userland_address_result(struct sockaddr* userAddress,
82	socklen_t* _addressLength, socklen_t& addressLength, bool addressRequired)
83{
84	// check parameters
85	if (_addressLength == NULL)
86		return B_BAD_VALUE;
87	if (userAddress == NULL) {
88		if (addressRequired)
89			return B_BAD_VALUE;
90	} else if (!IS_USER_ADDRESS(userAddress)
91			|| !IS_USER_ADDRESS(_addressLength)) {
92		return B_BAD_ADDRESS;
93	}
94
95	// copy the buffer size from userland
96	addressLength = 0;
97	if (userAddress != NULL
98			&& user_memcpy(&addressLength, _addressLength, sizeof(socklen_t))
99				!= B_OK) {
100		return B_BAD_ADDRESS;
101	}
102
103	if (addressLength > MAX_SOCKET_ADDRESS_LENGTH)
104		addressLength = MAX_SOCKET_ADDRESS_LENGTH;
105
106	return B_OK;
107}
108
109
110static status_t
111copy_address_to_userland(const void* address, socklen_t addressLength,
112	sockaddr* userAddress, socklen_t userAddressBufferSize,
113	socklen_t* userAddressLength)
114{
115	// copy address size and address back to userland
116	if (user_memcpy(userAddressLength, &addressLength,
117			sizeof(socklen_t)) != B_OK
118		|| (userAddress != NULL
119			&& user_memcpy(userAddress, address,
120				min_c(addressLength, userAddressBufferSize)) != B_OK)) {
121		return B_BAD_ADDRESS;
122	}
123
124	return B_OK;
125}
126
127
128static status_t
129prepare_userland_msghdr(const msghdr* userMessage, msghdr& message,
130	iovec*& userVecs, MemoryDeleter& vecsDeleter, void*& userAddress,
131	char* address)
132{
133	if (userMessage == NULL)
134		return B_BAD_VALUE;
135
136	// copy message from userland
137	if (!IS_USER_ADDRESS(userMessage)
138			|| user_memcpy(&message, userMessage, sizeof(msghdr)) != B_OK) {
139		return B_BAD_ADDRESS;
140	}
141
142	userVecs = message.msg_iov;
143	userAddress = message.msg_name;
144
145	// copy iovecs from userland
146	if (message.msg_iovlen < 0 || message.msg_iovlen > IOV_MAX)
147		return EMSGSIZE;
148	if (userVecs != NULL && message.msg_iovlen > 0) {
149		iovec* vecs;
150		status_t error = get_iovecs_from_user(message.msg_iov, message.msg_iovlen, vecs);
151		if (error != B_OK)
152			return error;
153		vecsDeleter.SetTo(vecs);
154		message.msg_iov = vecs;
155	} else {
156		message.msg_iov = NULL;
157		message.msg_iovlen = 0;
158	}
159
160	// prepare the address field
161	userAddress = message.msg_name;
162	if (userAddress != NULL) {
163		if (!IS_USER_ADDRESS(message.msg_name))
164			return B_BAD_ADDRESS;
165		if (message.msg_namelen > MAX_SOCKET_ADDRESS_LENGTH)
166			message.msg_namelen = MAX_SOCKET_ADDRESS_LENGTH;
167
168		message.msg_name = address;
169	}
170
171	return B_OK;
172}
173
174
175static status_t
176get_socket_descriptor(int fd, bool kernel, file_descriptor*& descriptor)
177{
178	if (fd < 0)
179		return EBADF;
180
181	descriptor = get_fd(get_current_io_context(kernel), fd);
182	if (descriptor == NULL)
183		return EBADF;
184
185	if (descriptor->type != FDTYPE_SOCKET) {
186		put_fd(descriptor);
187		return ENOTSOCK;
188	}
189
190	return B_OK;
191}
192
193
194// #pragma mark - socket file descriptor
195
196
197static status_t
198socket_read(struct file_descriptor *descriptor, off_t pos, void *buffer,
199	size_t *_length)
200{
201	ssize_t bytesRead = sStackInterface->recv(descriptor->u.socket, buffer,
202		*_length, 0);
203	*_length = bytesRead >= 0 ? bytesRead : 0;
204	return bytesRead >= 0 ? B_OK : bytesRead;
205}
206
207
208static status_t
209socket_write(struct file_descriptor *descriptor, off_t pos, const void *buffer,
210	size_t *_length)
211{
212	ssize_t bytesWritten = sStackInterface->send(descriptor->u.socket, buffer,
213		*_length, 0);
214	*_length = bytesWritten >= 0 ? bytesWritten : 0;
215	return bytesWritten >= 0 ? B_OK : bytesWritten;
216}
217
218
219static status_t
220socket_ioctl(struct file_descriptor *descriptor, ulong op, void *buffer,
221	size_t length)
222{
223	return sStackInterface->ioctl(descriptor->u.socket, op, buffer, length);
224}
225
226
227static status_t
228socket_set_flags(struct file_descriptor *descriptor, int flags)
229{
230	// we ignore O_APPEND, but O_NONBLOCK we need to translate
231	uint32 op = (flags & O_NONBLOCK) != 0
232		? B_SET_NONBLOCKING_IO : B_SET_BLOCKING_IO;
233
234	return sStackInterface->ioctl(descriptor->u.socket, op, NULL, 0);
235}
236
237
238static status_t
239socket_select(struct file_descriptor *descriptor, uint8 event,
240	struct selectsync *sync)
241{
242	return sStackInterface->select(descriptor->u.socket, event, sync);
243}
244
245
246static status_t
247socket_deselect(struct file_descriptor *descriptor, uint8 event,
248	struct selectsync *sync)
249{
250	return sStackInterface->deselect(descriptor->u.socket, event, sync);
251}
252
253
254static status_t
255socket_read_stat(struct file_descriptor *descriptor, struct stat *st)
256{
257	st->st_dev = 0;
258	st->st_ino = (addr_t)descriptor->u.socket;
259	st->st_mode = S_IFSOCK | 0666;
260	st->st_nlink = 1;
261	st->st_uid = 0;
262	st->st_gid = 0;
263	st->st_size = 0;
264	st->st_rdev = 0;
265	st->st_blksize = 1024;	// use MTU for datagram sockets?
266	st->st_type = 0;
267
268	timespec now;
269	now.tv_sec = time(NULL);
270	now.tv_nsec = 0;
271
272	st->st_atim = now;
273	st->st_mtim = now;
274	st->st_ctim = now;
275	st->st_crtim = now;
276
277	return B_OK;
278}
279
280
281static status_t
282socket_close(struct file_descriptor *descriptor)
283{
284	return sStackInterface->close(descriptor->u.socket);
285}
286
287
288static void
289socket_free(struct file_descriptor *descriptor)
290{
291	sStackInterface->free(descriptor->u.socket);
292	put_stack_interface_module();
293}
294
295
296static struct fd_ops sSocketFDOps = {
297	&socket_read,
298	&socket_write,
299	NULL,	// fd_seek
300	&socket_ioctl,
301	&socket_set_flags,
302	&socket_select,
303	&socket_deselect,
304	NULL,	// fd_read_dir
305	NULL,	// fd_rewind_dir
306	&socket_read_stat,
307	NULL,	// fd_write_stat
308	&socket_close,
309	&socket_free
310};
311
312
313static int
314create_socket_fd(net_socket* socket, bool kernel)
315{
316	// Get the socket's non-blocking flag, so we can set the respective
317	// open mode flag.
318	int32 nonBlock;
319	socklen_t nonBlockLen = sizeof(int32);
320	status_t error = sStackInterface->getsockopt(socket, SOL_SOCKET,
321		SO_NONBLOCK, &nonBlock, &nonBlockLen);
322	if (error != B_OK)
323		return error;
324
325	// allocate a file descriptor
326	file_descriptor* descriptor = alloc_fd();
327	if (descriptor == NULL)
328		return B_NO_MEMORY;
329
330	// init it
331	descriptor->type = FDTYPE_SOCKET;
332	descriptor->ops = &sSocketFDOps;
333	descriptor->u.socket = socket;
334	descriptor->open_mode = O_RDWR | (nonBlock ? O_NONBLOCK : 0);
335
336	// publish it
337	int fd = new_fd(get_current_io_context(kernel), descriptor);
338	if (fd < 0) {
339		descriptor->ops = NULL;
340		put_fd(descriptor);
341	}
342
343	return fd;
344}
345
346
347// #pragma mark - common sockets API implementation
348
349
350static int
351common_socket(int family, int type, int protocol, bool kernel)
352{
353	if (!get_stack_interface_module())
354		return B_UNSUPPORTED;
355
356	// create the socket
357	net_socket* socket;
358	status_t error = sStackInterface->open(family, type, protocol, &socket);
359	if (error != B_OK) {
360		put_stack_interface_module();
361		return error;
362	}
363
364	// allocate the FD
365	int fd = create_socket_fd(socket, kernel);
366	if (fd < 0) {
367		sStackInterface->close(socket);
368		sStackInterface->free(socket);
369		put_stack_interface_module();
370	}
371
372	return fd;
373}
374
375
376static status_t
377common_bind(int fd, const struct sockaddr *address, socklen_t addressLength,
378	bool kernel)
379{
380	file_descriptor* descriptor;
381	GET_SOCKET_FD_OR_RETURN(fd, kernel, descriptor);
382	FileDescriptorPutter _(descriptor);
383
384	return sStackInterface->bind(descriptor->u.socket, address, addressLength);
385}
386
387
388static status_t
389common_shutdown(int fd, int how, bool kernel)
390{
391	file_descriptor* descriptor;
392	GET_SOCKET_FD_OR_RETURN(fd, kernel, descriptor);
393	FileDescriptorPutter _(descriptor);
394
395	return sStackInterface->shutdown(descriptor->u.socket, how);
396}
397
398
399static status_t
400common_connect(int fd, const struct sockaddr *address,
401	socklen_t addressLength, bool kernel)
402{
403	file_descriptor* descriptor;
404	GET_SOCKET_FD_OR_RETURN(fd, kernel, descriptor);
405	FileDescriptorPutter _(descriptor);
406
407	return sStackInterface->connect(descriptor->u.socket, address,
408		addressLength);
409}
410
411
412static status_t
413common_listen(int fd, int backlog, bool kernel)
414{
415	file_descriptor* descriptor;
416	GET_SOCKET_FD_OR_RETURN(fd, kernel, descriptor);
417	FileDescriptorPutter _(descriptor);
418
419	return sStackInterface->listen(descriptor->u.socket, backlog);
420}
421
422
423static int
424common_accept(int fd, struct sockaddr *address, socklen_t *_addressLength,
425	bool kernel)
426{
427	file_descriptor* descriptor;
428	GET_SOCKET_FD_OR_RETURN(fd, kernel, descriptor);
429	FileDescriptorPutter _(descriptor);
430
431	net_socket* acceptedSocket;
432	status_t error = sStackInterface->accept(descriptor->u.socket, address,
433		_addressLength, &acceptedSocket);
434	if (error != B_OK)
435		return error;
436
437	// allocate the FD
438	int acceptedFD = create_socket_fd(acceptedSocket, kernel);
439	if (acceptedFD < 0) {
440		sStackInterface->close(acceptedSocket);
441		sStackInterface->free(acceptedSocket);
442	} else {
443		// we need a reference for the new FD
444		get_stack_interface_module();
445	}
446
447	return acceptedFD;
448}
449
450
451static ssize_t
452common_recv(int fd, void *data, size_t length, int flags, bool kernel)
453{
454	file_descriptor* descriptor;
455	GET_SOCKET_FD_OR_RETURN(fd, kernel, descriptor);
456	FileDescriptorPutter _(descriptor);
457
458	return sStackInterface->recv(descriptor->u.socket, data, length, flags);
459}
460
461
462static ssize_t
463common_recvfrom(int fd, void *data, size_t length, int flags,
464	struct sockaddr *address, socklen_t *_addressLength, bool kernel)
465{
466	file_descriptor* descriptor;
467	GET_SOCKET_FD_OR_RETURN(fd, kernel, descriptor);
468	FileDescriptorPutter _(descriptor);
469
470	return sStackInterface->recvfrom(descriptor->u.socket, data, length,
471		flags, address, _addressLength);
472}
473
474
475static ssize_t
476common_recvmsg(int fd, struct msghdr *message, int flags, bool kernel)
477{
478	file_descriptor* descriptor;
479	GET_SOCKET_FD_OR_RETURN(fd, kernel, descriptor);
480	FileDescriptorPutter _(descriptor);
481
482	return sStackInterface->recvmsg(descriptor->u.socket, message, flags);
483}
484
485
486static ssize_t
487common_send(int fd, const void *data, size_t length, int flags, bool kernel)
488{
489	file_descriptor* descriptor;
490	GET_SOCKET_FD_OR_RETURN(fd, kernel, descriptor);
491	FileDescriptorPutter _(descriptor);
492
493	return sStackInterface->send(descriptor->u.socket, data, length, flags);
494}
495
496
497static ssize_t
498common_sendto(int fd, const void *data, size_t length, int flags,
499	const struct sockaddr *address, socklen_t addressLength, bool kernel)
500{
501	file_descriptor* descriptor;
502	GET_SOCKET_FD_OR_RETURN(fd, kernel, descriptor);
503	FileDescriptorPutter _(descriptor);
504
505	return sStackInterface->sendto(descriptor->u.socket, data, length, flags,
506		address, addressLength);
507}
508
509
510static ssize_t
511common_sendmsg(int fd, const struct msghdr *message, int flags, bool kernel)
512{
513	file_descriptor* descriptor;
514	GET_SOCKET_FD_OR_RETURN(fd, kernel, descriptor);
515	FileDescriptorPutter _(descriptor);
516
517	return sStackInterface->sendmsg(descriptor->u.socket, message, flags);
518}
519
520
521static status_t
522common_getsockopt(int fd, int level, int option, void *value,
523	socklen_t *_length, bool kernel)
524{
525	file_descriptor* descriptor;
526	GET_SOCKET_FD_OR_RETURN(fd, kernel, descriptor);
527	FileDescriptorPutter _(descriptor);
528
529	return sStackInterface->getsockopt(descriptor->u.socket, level, option,
530		value, _length);
531}
532
533
534static status_t
535common_setsockopt(int fd, int level, int option, const void *value,
536	socklen_t length, bool kernel)
537{
538	file_descriptor* descriptor;
539	GET_SOCKET_FD_OR_RETURN(fd, kernel, descriptor);
540	FileDescriptorPutter _(descriptor);
541
542	return sStackInterface->setsockopt(descriptor->u.socket, level, option,
543		value, length);
544}
545
546
547static status_t
548common_getpeername(int fd, struct sockaddr *address,
549	socklen_t *_addressLength, bool kernel)
550{
551	file_descriptor* descriptor;
552	GET_SOCKET_FD_OR_RETURN(fd, kernel, descriptor);
553	FileDescriptorPutter _(descriptor);
554
555	return sStackInterface->getpeername(descriptor->u.socket, address,
556		_addressLength);
557}
558
559
560static status_t
561common_getsockname(int fd, struct sockaddr *address,
562	socklen_t *_addressLength, bool kernel)
563{
564	file_descriptor* descriptor;
565	GET_SOCKET_FD_OR_RETURN(fd, kernel, descriptor);
566	FileDescriptorPutter _(descriptor);
567
568	return sStackInterface->getsockname(descriptor->u.socket, address,
569		_addressLength);
570}
571
572
573static int
574common_sockatmark(int fd, bool kernel)
575{
576	file_descriptor* descriptor;
577	GET_SOCKET_FD_OR_RETURN(fd, kernel, descriptor);
578	FileDescriptorPutter _(descriptor);
579
580	return sStackInterface->sockatmark(descriptor->u.socket);
581}
582
583
584static status_t
585common_socketpair(int family, int type, int protocol, int fds[2], bool kernel)
586{
587	if (!get_stack_interface_module())
588		return B_UNSUPPORTED;
589
590	net_socket* sockets[2];
591	status_t error = sStackInterface->socketpair(family, type, protocol,
592		sockets);
593	if (error != B_OK) {
594		put_stack_interface_module();
595		return error;
596	}
597
598	// allocate the FDs
599	for (int i = 0; i < 2; i++) {
600		fds[i] = create_socket_fd(sockets[i], kernel);
601		if (fds[i] < 0) {
602			sStackInterface->close(sockets[i]);
603			sStackInterface->free(sockets[i]);
604			put_stack_interface_module();
605			return fds[i];
606		}
607	}
608
609	// We need another reference for the second socket
610	get_stack_interface_module();
611	return B_OK;
612}
613
614
615static status_t
616common_get_next_socket_stat(int family, uint32 *cookie, struct net_stat *stat)
617{
618	if (!get_stack_interface_module())
619		return B_UNSUPPORTED;
620
621	status_t status = sStackInterface->get_next_socket_stat(family, cookie,
622		stat);
623
624	put_stack_interface_module();
625	return status;
626}
627
628
629// #pragma mark - kernel sockets API
630
631
632int
633socket(int family, int type, int protocol)
634{
635	SyscallFlagUnsetter _;
636	RETURN_AND_SET_ERRNO(common_socket(family, type, protocol, true));
637}
638
639
640int
641bind(int socket, const struct sockaddr *address, socklen_t addressLength)
642{
643	SyscallFlagUnsetter _;
644	RETURN_AND_SET_ERRNO(common_bind(socket, address, addressLength, true));
645}
646
647
648int
649shutdown(int socket, int how)
650{
651	SyscallFlagUnsetter _;
652	RETURN_AND_SET_ERRNO(common_shutdown(socket, how, true));
653}
654
655
656int
657connect(int socket, const struct sockaddr *address, socklen_t addressLength)
658{
659	SyscallFlagUnsetter _;
660	RETURN_AND_SET_ERRNO(common_connect(socket, address, addressLength, true));
661}
662
663
664int
665listen(int socket, int backlog)
666{
667	SyscallFlagUnsetter _;
668	RETURN_AND_SET_ERRNO(common_listen(socket, backlog, true));
669}
670
671
672int
673accept(int socket, struct sockaddr *address, socklen_t *_addressLength)
674{
675	SyscallFlagUnsetter _;
676	RETURN_AND_SET_ERRNO(common_accept(socket, address, _addressLength, true));
677}
678
679
680ssize_t
681recv(int socket, void *data, size_t length, int flags)
682{
683	SyscallFlagUnsetter _;
684	RETURN_AND_SET_ERRNO(common_recv(socket, data, length, flags, true));
685}
686
687
688ssize_t
689recvfrom(int socket, void *data, size_t length, int flags,
690	struct sockaddr *address, socklen_t *_addressLength)
691{
692	SyscallFlagUnsetter _;
693	RETURN_AND_SET_ERRNO(common_recvfrom(socket, data, length, flags, address,
694		_addressLength, true));
695}
696
697
698ssize_t
699recvmsg(int socket, struct msghdr *message, int flags)
700{
701	SyscallFlagUnsetter _;
702	RETURN_AND_SET_ERRNO(common_recvmsg(socket, message, flags, true));
703}
704
705
706ssize_t
707send(int socket, const void *data, size_t length, int flags)
708{
709	SyscallFlagUnsetter _;
710	RETURN_AND_SET_ERRNO(common_send(socket, data, length, flags, true));
711}
712
713
714ssize_t
715sendto(int socket, const void *data, size_t length, int flags,
716	const struct sockaddr *address, socklen_t addressLength)
717{
718	SyscallFlagUnsetter _;
719	RETURN_AND_SET_ERRNO(common_sendto(socket, data, length, flags, address,
720		addressLength, true));
721}
722
723
724ssize_t
725sendmsg(int socket, const struct msghdr *message, int flags)
726{
727	SyscallFlagUnsetter _;
728	RETURN_AND_SET_ERRNO(common_sendmsg(socket, message, flags, true));
729}
730
731
732int
733getsockopt(int socket, int level, int option, void *value, socklen_t *_length)
734{
735	SyscallFlagUnsetter _;
736	RETURN_AND_SET_ERRNO(common_getsockopt(socket, level, option, value,
737		_length, true));
738}
739
740
741int
742setsockopt(int socket, int level, int option, const void *value,
743	socklen_t length)
744{
745	SyscallFlagUnsetter _;
746	RETURN_AND_SET_ERRNO(common_setsockopt(socket, level, option, value,
747		length, true));
748}
749
750
751int
752getpeername(int socket, struct sockaddr *address, socklen_t *_addressLength)
753{
754	SyscallFlagUnsetter _;
755	RETURN_AND_SET_ERRNO(common_getpeername(socket, address, _addressLength,
756		true));
757}
758
759
760int
761getsockname(int socket, struct sockaddr *address, socklen_t *_addressLength)
762{
763	SyscallFlagUnsetter _;
764	RETURN_AND_SET_ERRNO(common_getsockname(socket, address, _addressLength,
765		true));
766}
767
768
769int
770sockatmark(int socket)
771{
772	SyscallFlagUnsetter _;
773	RETURN_AND_SET_ERRNO(common_sockatmark(socket, true));
774}
775
776
777int
778socketpair(int family, int type, int protocol, int socketVector[2])
779{
780	SyscallFlagUnsetter _;
781	RETURN_AND_SET_ERRNO(common_socketpair(family, type, protocol,
782		socketVector, true));
783}
784
785
786// #pragma mark - syscalls
787
788
789int
790_user_socket(int family, int type, int protocol)
791{
792	SyscallRestartWrapper<int> result;
793	return result = common_socket(family, type, protocol, false);
794}
795
796
797status_t
798_user_bind(int socket, const struct sockaddr *userAddress,
799	socklen_t addressLength)
800{
801	// check parameters and copy address from userland
802	if (userAddress == NULL || addressLength > MAX_SOCKET_ADDRESS_LENGTH)
803		return B_BAD_VALUE;
804
805	sockaddr_storage address;
806	memset(&address, 0, sizeof(address));
807	if (!IS_USER_ADDRESS(userAddress)
808			|| user_memcpy(&address, userAddress, addressLength) != B_OK) {
809		return B_BAD_ADDRESS;
810	}
811
812	address.ss_len = addressLength;
813		// make sure the sa_len field is set correctly
814
815	SyscallRestartWrapper<status_t> error;
816	return error = common_bind(socket, (sockaddr*)&address, addressLength,
817		false);
818}
819
820
821status_t
822_user_shutdown_socket(int socket, int how)
823{
824	SyscallRestartWrapper<status_t> error;
825	return error = common_shutdown(socket, how, false);
826}
827
828
829status_t
830_user_connect(int socket, const struct sockaddr *userAddress,
831	socklen_t addressLength)
832{
833	// check parameters and copy address from userland
834	if (userAddress == NULL || addressLength > MAX_SOCKET_ADDRESS_LENGTH)
835		return B_BAD_VALUE;
836
837	sockaddr_storage address;
838	memset(&address, 0, sizeof(address));
839	if (!IS_USER_ADDRESS(userAddress)
840			|| user_memcpy(&address, userAddress, addressLength) != B_OK) {
841		return B_BAD_ADDRESS;
842	}
843
844	address.ss_len = addressLength;
845		// make sure the sa_len field is set correctly
846
847	SyscallRestartWrapper<status_t> error;
848
849	return error = common_connect(socket, (sockaddr*)&address, addressLength,
850		false);
851}
852
853
854status_t
855_user_listen(int socket, int backlog)
856{
857	SyscallRestartWrapper<status_t> error;
858	return error = common_listen(socket, backlog, false);
859}
860
861
862int
863_user_accept(int socket, struct sockaddr *userAddress,
864	socklen_t *_addressLength)
865{
866	// check parameters
867	socklen_t addressLength = 0;
868	status_t error = prepare_userland_address_result(userAddress,
869		_addressLength, addressLength, false);
870	if (error != B_OK)
871		return error;
872
873	// accept()
874	SyscallRestartWrapper<int> result;
875
876	char address[MAX_SOCKET_ADDRESS_LENGTH];
877	socklen_t userAddressBufferSize = addressLength;
878	result = common_accept(socket,
879		userAddress != NULL ? (sockaddr*)address : NULL, &addressLength, false);
880
881	// copy address size and address back to userland
882	if (copy_address_to_userland(address, addressLength, userAddress,
883			userAddressBufferSize, _addressLength) != B_OK) {
884		_user_close(result);
885		return B_BAD_ADDRESS;
886	}
887
888	return result;
889}
890
891
892ssize_t
893_user_recv(int socket, void *data, size_t length, int flags)
894{
895	if (data == NULL || !is_user_address_range(data, length))
896		return B_BAD_ADDRESS;
897
898	SyscallRestartWrapper<ssize_t> result;
899	return result = common_recv(socket, data, length, flags, false);
900}
901
902
903ssize_t
904_user_recvfrom(int socket, void *data, size_t length, int flags,
905	struct sockaddr *userAddress, socklen_t *_addressLength)
906{
907	if (data == NULL || !is_user_address_range(data, length))
908		return B_BAD_ADDRESS;
909
910	// check parameters
911	socklen_t addressLength = 0;
912	status_t error = prepare_userland_address_result(userAddress,
913		_addressLength, addressLength, false);
914	if (error != B_OK)
915		return error;
916
917	// recvfrom()
918	SyscallRestartWrapper<ssize_t> result;
919
920	char address[MAX_SOCKET_ADDRESS_LENGTH];
921	socklen_t userAddressBufferSize = addressLength;
922	result = common_recvfrom(socket, data, length, flags,
923		userAddress != NULL ? (sockaddr*)address : NULL, &addressLength, false);
924	if (result < 0)
925		return result;
926
927	// copy address size and address back to userland
928	if (copy_address_to_userland(address, addressLength, userAddress,
929			userAddressBufferSize, _addressLength) != B_OK) {
930		return B_BAD_ADDRESS;
931	}
932
933	return result;
934}
935
936
937ssize_t
938_user_recvmsg(int socket, struct msghdr *userMessage, int flags)
939{
940	// copy message from userland
941	msghdr message;
942	iovec* userVecs;
943	MemoryDeleter vecsDeleter;
944	void* userAddress;
945	char address[MAX_SOCKET_ADDRESS_LENGTH];
946
947	status_t error = prepare_userland_msghdr(userMessage, message, userVecs,
948		vecsDeleter, userAddress, address);
949	if (error != B_OK)
950		return error;
951
952	// prepare a buffer for ancillary data
953	MemoryDeleter ancillaryDeleter;
954	void* ancillary = NULL;
955	void* userAncillary = message.msg_control;
956	if (userAncillary != NULL) {
957		if (!IS_USER_ADDRESS(userAncillary))
958			return B_BAD_ADDRESS;
959		if (message.msg_controllen < 0)
960			return B_BAD_VALUE;
961		if (message.msg_controllen > MAX_ANCILLARY_DATA_LENGTH)
962			message.msg_controllen = MAX_ANCILLARY_DATA_LENGTH;
963
964		message.msg_control = ancillary = malloc(message.msg_controllen);
965		if (message.msg_control == NULL)
966			return B_NO_MEMORY;
967
968		ancillaryDeleter.SetTo(ancillary);
969	}
970
971	// recvmsg()
972	SyscallRestartWrapper<ssize_t> result;
973
974	result = common_recvmsg(socket, &message, flags, false);
975	if (result < 0)
976		return result;
977
978	// copy the address, the ancillary data, and the message header back to
979	// userland
980	message.msg_name = userAddress;
981	message.msg_iov = userVecs;
982	message.msg_control = userAncillary;
983	if ((userAddress != NULL && user_memcpy(userAddress, address,
984				message.msg_namelen) != B_OK)
985		|| (userAncillary != NULL && user_memcpy(userAncillary, ancillary,
986				message.msg_controllen) != B_OK)
987		|| user_memcpy(userMessage, &message, sizeof(msghdr)) != B_OK) {
988		return B_BAD_ADDRESS;
989	}
990
991	return result;
992}
993
994
995ssize_t
996_user_send(int socket, const void *data, size_t length, int flags)
997{
998	if (data == NULL || !is_user_address_range(data, length))
999		return B_BAD_ADDRESS;
1000
1001	SyscallRestartWrapper<ssize_t> result;
1002	return result = common_send(socket, data, length, flags, false);
1003}
1004
1005
1006ssize_t
1007_user_sendto(int socket, const void *data, size_t length, int flags,
1008	const struct sockaddr *userAddress, socklen_t addressLength)
1009{
1010	if (data == NULL || !is_user_address_range(data, length))
1011		return B_BAD_ADDRESS;
1012
1013	if (addressLength <= 0
1014			|| addressLength > MAX_SOCKET_ADDRESS_LENGTH) {
1015		return B_BAD_VALUE;
1016	}
1017
1018	// copy address from userland
1019	char address[MAX_SOCKET_ADDRESS_LENGTH];
1020	if (userAddress != NULL) {
1021		if (!IS_USER_ADDRESS(userAddress)
1022			|| user_memcpy(address, userAddress, addressLength) != B_OK) {
1023			return B_BAD_ADDRESS;
1024		}
1025	} else {
1026		addressLength = 0;
1027	}
1028
1029	// sendto()
1030	SyscallRestartWrapper<ssize_t> result;
1031
1032	return result = common_sendto(socket, data, length, flags,
1033		userAddress != NULL ? (sockaddr*)address : NULL, addressLength, false);
1034}
1035
1036
1037ssize_t
1038_user_sendmsg(int socket, const struct msghdr *userMessage, int flags)
1039{
1040	// copy message from userland
1041	msghdr message;
1042	iovec* userVecs;
1043	MemoryDeleter vecsDeleter;
1044	void* userAddress;
1045	char address[MAX_SOCKET_ADDRESS_LENGTH];
1046
1047	status_t error = prepare_userland_msghdr(userMessage, message, userVecs,
1048		vecsDeleter, userAddress, address);
1049	if (error != B_OK)
1050		return error;
1051
1052	// copy the address from userland
1053	if (userAddress != NULL
1054			&& user_memcpy(address, userAddress, message.msg_namelen) != B_OK) {
1055		return B_BAD_ADDRESS;
1056	}
1057
1058	// copy ancillary data from userland
1059	MemoryDeleter ancillaryDeleter;
1060	void* userAncillary = message.msg_control;
1061	if (userAncillary != NULL) {
1062		if (!IS_USER_ADDRESS(userAncillary))
1063			return B_BAD_ADDRESS;
1064		if (message.msg_controllen < 0
1065				|| message.msg_controllen > MAX_ANCILLARY_DATA_LENGTH) {
1066			return B_BAD_VALUE;
1067		}
1068
1069		message.msg_control = malloc(message.msg_controllen);
1070		if (message.msg_control == NULL)
1071			return B_NO_MEMORY;
1072		ancillaryDeleter.SetTo(message.msg_control);
1073
1074		if (user_memcpy(message.msg_control, userAncillary,
1075				message.msg_controllen) != B_OK) {
1076			return B_BAD_ADDRESS;
1077		}
1078	}
1079
1080	// sendmsg()
1081	SyscallRestartWrapper<ssize_t> result;
1082
1083	return result = common_sendmsg(socket, &message, flags, false);
1084}
1085
1086
1087status_t
1088_user_getsockopt(int socket, int level, int option, void *userValue,
1089	socklen_t *_length)
1090{
1091	// check params
1092	if (userValue == NULL || _length == NULL)
1093		return B_BAD_VALUE;
1094	if (!IS_USER_ADDRESS(userValue) || !IS_USER_ADDRESS(_length))
1095		return B_BAD_ADDRESS;
1096
1097	// copy length from userland
1098	socklen_t length;
1099	if (user_memcpy(&length, _length, sizeof(socklen_t)) != B_OK)
1100		return B_BAD_ADDRESS;
1101
1102	if (length > MAX_SOCKET_OPTION_LENGTH)
1103		return B_BAD_VALUE;
1104
1105	// getsockopt()
1106	char value[MAX_SOCKET_OPTION_LENGTH];
1107	SyscallRestartWrapper<status_t> error;
1108	error = common_getsockopt(socket, level, option, value, &length,
1109		false);
1110	if (error != B_OK)
1111		return error;
1112
1113	// copy value back to userland
1114	if (user_memcpy(userValue, value, length) != B_OK)
1115		return B_BAD_ADDRESS;
1116
1117	return B_OK;
1118}
1119
1120
1121status_t
1122_user_setsockopt(int socket, int level, int option, const void *userValue,
1123	socklen_t length)
1124{
1125	// check params
1126	if (userValue == NULL || length > MAX_SOCKET_OPTION_LENGTH)
1127		return B_BAD_VALUE;
1128
1129	// copy value from userland
1130	char value[MAX_SOCKET_OPTION_LENGTH];
1131	if (!IS_USER_ADDRESS(userValue)
1132			|| user_memcpy(value, userValue, length) != B_OK) {
1133		return B_BAD_ADDRESS;
1134	}
1135
1136	// setsockopt();
1137	SyscallRestartWrapper<status_t> error;
1138	return error = common_setsockopt(socket, level, option, value, length,
1139		false);
1140}
1141
1142
1143status_t
1144_user_getpeername(int socket, struct sockaddr *userAddress,
1145	socklen_t *_addressLength)
1146{
1147	// check parameters
1148	socklen_t addressLength = 0;
1149	SyscallRestartWrapper<status_t> error;
1150	error = prepare_userland_address_result(userAddress, _addressLength,
1151		addressLength, true);
1152	if (error != B_OK)
1153		return error;
1154
1155	// getpeername()
1156	char address[MAX_SOCKET_ADDRESS_LENGTH];
1157	socklen_t userAddressBufferSize = addressLength;
1158	error = common_getpeername(socket, (sockaddr*)address, &addressLength,
1159		false);
1160	if (error != B_OK)
1161		return error;
1162
1163	// copy address size and address back to userland
1164	if (copy_address_to_userland(address, addressLength, userAddress,
1165			userAddressBufferSize, _addressLength) != B_OK) {
1166		return B_BAD_ADDRESS;
1167	}
1168
1169	return B_OK;
1170}
1171
1172
1173status_t
1174_user_getsockname(int socket, struct sockaddr *userAddress,
1175	socklen_t *_addressLength)
1176{
1177	// check parameters
1178	socklen_t addressLength = 0;
1179	SyscallRestartWrapper<status_t> error;
1180	error = prepare_userland_address_result(userAddress, _addressLength,
1181		addressLength, true);
1182	if (error != B_OK)
1183		return error;
1184
1185	// getsockname()
1186	char address[MAX_SOCKET_ADDRESS_LENGTH];
1187	socklen_t userAddressBufferSize = addressLength;
1188	error = common_getsockname(socket, (sockaddr*)address, &addressLength,
1189		false);
1190	if (error != B_OK)
1191		return error;
1192
1193	// copy address size and address back to userland
1194	if (copy_address_to_userland(address, addressLength, userAddress,
1195			userAddressBufferSize, _addressLength) != B_OK) {
1196		return B_BAD_ADDRESS;
1197	}
1198
1199	return B_OK;
1200}
1201
1202
1203int
1204_user_sockatmark(int socket)
1205{
1206	SyscallRestartWrapper<status_t> error;
1207	return error = common_sockatmark(socket, false);
1208}
1209
1210
1211status_t
1212_user_socketpair(int family, int type, int protocol, int *userSocketVector)
1213{
1214	// check parameters
1215	if (userSocketVector == NULL)
1216		return B_BAD_VALUE;
1217	if (!IS_USER_ADDRESS(userSocketVector))
1218		return B_BAD_ADDRESS;
1219
1220	// socketpair()
1221	int socketVector[2];
1222	SyscallRestartWrapper<status_t> error;
1223	error = common_socketpair(family, type, protocol, socketVector, false);
1224	if (error != B_OK)
1225		return error;
1226
1227	// copy FDs back to userland
1228	if (user_memcpy(userSocketVector, socketVector,
1229			sizeof(socketVector)) != B_OK) {
1230		_user_close(socketVector[0]);
1231		_user_close(socketVector[1]);
1232		return B_BAD_ADDRESS;
1233	}
1234
1235	return B_OK;
1236}
1237
1238
1239status_t
1240_user_get_next_socket_stat(int family, uint32 *_cookie, struct net_stat *_stat)
1241{
1242	// check parameters and copy cookie from userland
1243	if (_cookie == NULL || _stat == NULL)
1244		return B_BAD_VALUE;
1245
1246	uint32 cookie;
1247	if (!IS_USER_ADDRESS(_stat) || !IS_USER_ADDRESS(_cookie)
1248		|| user_memcpy(&cookie, _cookie, sizeof(cookie)) != B_OK) {
1249		return B_BAD_ADDRESS;
1250	}
1251
1252	net_stat stat;
1253	SyscallRestartWrapper<status_t> error;
1254	error = common_get_next_socket_stat(family, &cookie, &stat);
1255	if (error != B_OK)
1256		return error;
1257
1258	// copy cookie and data back to userland
1259	if (user_memcpy(_cookie, &cookie, sizeof(cookie)) != B_OK
1260		|| user_memcpy(_stat, &stat, sizeof(net_stat)) != B_OK) {
1261		return B_BAD_ADDRESS;
1262	}
1263
1264	return B_OK;
1265}
1266