1/*
2 * Copyright 2008, Ingo Weinhold, ingo_weinhold@gmx.de.
3 * Distributed under the terms of the MIT License.
4 */
5
6#include "stack_private.h"
7
8
9/*!	Interface module providing networking to the kernel.
10*/
11
12
13static status_t
14stack_interface_open(int family, int type, int protocol, net_socket** _socket)
15{
16	return gNetSocketModule.open_socket(family, type, protocol, _socket);
17}
18
19
20static status_t
21stack_interface_close(net_socket* socket)
22{
23	return gNetSocketModule.close(socket);
24}
25
26
27static status_t
28stack_interface_free(net_socket* socket)
29{
30	gNetSocketModule.free(socket);
31	return B_OK;
32}
33
34
35static status_t
36stack_interface_bind(net_socket* socket, const struct sockaddr* address,
37	socklen_t addressLength)
38{
39	return gNetSocketModule.bind(socket, address, addressLength);
40}
41
42
43static status_t
44stack_interface_shutdown(net_socket* socket, int how)
45{
46	return gNetSocketModule.shutdown(socket, how);
47}
48
49
50static status_t
51stack_interface_connect(net_socket* socket, const struct sockaddr* address,
52	socklen_t addressLength)
53{
54	return gNetSocketModule.connect(socket, address, addressLength);
55}
56
57
58static status_t
59stack_interface_listen(net_socket* socket, int backlog)
60{
61	return gNetSocketModule.listen(socket, backlog);
62}
63
64
65static status_t
66stack_interface_accept(net_socket* socket, struct sockaddr* address,
67	socklen_t* _addressLength, net_socket** _acceptedSocket)
68{
69	return gNetSocketModule.accept(socket, address, _addressLength,
70		_acceptedSocket);
71}
72
73
74static ssize_t
75stack_interface_recv(net_socket* socket, void* data, size_t length, int flags)
76{
77	return gNetSocketModule.receive(socket, NULL, data, length, flags);
78}
79
80
81static ssize_t
82stack_interface_recvfrom(net_socket* socket, void* data, size_t length,
83	int flags, struct sockaddr* address, socklen_t* _addressLength)
84{
85	msghdr message;
86	iovec vec = { data, length };
87	message.msg_name = address;
88	if (_addressLength != NULL)
89		message.msg_namelen = *_addressLength;
90	else
91		message.msg_namelen = 0;
92	message.msg_iov = &vec;
93	message.msg_iovlen = 1;
94	message.msg_control = NULL;
95	message.msg_controllen = 0;
96	message.msg_flags = 0;
97
98	ssize_t received = gNetSocketModule.receive(socket, &message, data, length,
99		flags);
100
101	if (received >= 0 && _addressLength != NULL)
102		*_addressLength = message.msg_namelen;
103
104	return received;
105}
106
107
108static ssize_t
109stack_interface_recvmsg(net_socket* socket, struct msghdr* message, int flags)
110{
111	void* buffer = NULL;
112	size_t length = 0;
113	if (message->msg_iovlen > 0) {
114		buffer = message->msg_iov[0].iov_base;
115		length = message->msg_iov[0].iov_len;
116	}
117
118	return gNetSocketModule.receive(socket, message, buffer, length, flags);
119}
120
121
122static ssize_t
123stack_interface_send(net_socket* socket, const void* data, size_t length,
124	int flags)
125{
126	return gNetSocketModule.send(socket, NULL, data, length, flags);
127}
128
129
130static ssize_t
131stack_interface_sendto(net_socket* socket, const void* data, size_t length,
132	int flags, const struct sockaddr* address, socklen_t addressLength)
133{
134	msghdr message;
135	iovec vec = { (void*)data, length };
136	message.msg_name = (void*)address;
137	message.msg_namelen = addressLength;
138	message.msg_iov = &vec;
139	message.msg_iovlen = 1;
140	message.msg_control = NULL;
141	message.msg_controllen = 0;
142	message.msg_flags = 0;
143
144	return gNetSocketModule.send(socket, &message, data, length, flags);
145}
146
147
148static ssize_t
149stack_interface_sendmsg(net_socket* socket, const struct msghdr* message,
150	int flags)
151{
152	void* buffer = NULL;
153	size_t length = 0;
154	if (message->msg_iovlen > 0) {
155		buffer = message->msg_iov[0].iov_base;
156		length = message->msg_iov[0].iov_len;
157	}
158
159	return gNetSocketModule.send(socket, (msghdr*)message, buffer, length,
160		flags);
161}
162
163
164static status_t
165stack_interface_getsockopt(net_socket* socket, int level, int option,
166	void* value, socklen_t* _length)
167{
168	int length = *_length;
169	status_t error = gNetSocketModule.getsockopt(socket, level, option, value,
170		&length);
171	*_length = length;
172	return error;
173}
174
175
176static status_t
177stack_interface_setsockopt(net_socket* socket, int level, int option,
178	const void* value, socklen_t length)
179{
180	return gNetSocketModule.setsockopt(socket, level, option, value, length);
181}
182
183
184static status_t
185stack_interface_getpeername(net_socket* socket, struct sockaddr* address,
186	socklen_t* _addressLength)
187{
188	return gNetSocketModule.getpeername(socket, address, _addressLength);
189}
190
191
192static status_t
193stack_interface_getsockname(net_socket* socket, struct sockaddr* address,
194	socklen_t* _addressLength)
195{
196	return gNetSocketModule.getsockname(socket, address, _addressLength);
197}
198
199
200static int
201stack_interface_sockatmark(net_socket* socket)
202{
203	// TODO: sockatmark() missing
204	return B_UNSUPPORTED;
205}
206
207
208static status_t
209stack_interface_socketpair(int family, int type, int protocol,
210	net_socket* _sockets[2])
211{
212	return gNetSocketModule.socketpair(family, type, protocol, _sockets);
213}
214
215
216static status_t
217stack_interface_ioctl(net_socket* socket, uint32 op, void* buffer,
218	size_t length)
219{
220	return gNetSocketModule.control(socket, op, buffer, length);
221}
222
223
224static status_t
225stack_interface_select(net_socket* socket, uint8 event, struct selectsync* sync)
226{
227	return gNetSocketModule.request_notification(socket, event, sync);
228}
229
230
231static status_t
232stack_interface_deselect(net_socket* socket, uint8 event,
233	struct selectsync* sync)
234{
235	return gNetSocketModule.cancel_notification(socket, event, sync);
236}
237
238
239status_t
240stack_interface_get_next_socket_stat(int family, uint32* cookie,
241	struct net_stat* stat)
242{
243	return gNetSocketModule.get_next_stat(cookie, family, stat);
244}
245
246
247static status_t
248stack_interface_std_ops(int32 op, ...)
249{
250	switch (op) {
251		case B_MODULE_INIT:
252			return init_stack();
253		case B_MODULE_UNINIT:
254			return uninit_stack();
255
256		default:
257			return B_ERROR;
258	}
259}
260
261
262net_stack_interface_module_info gNetStackInterfaceModule = {
263	{
264		NET_STACK_INTERFACE_MODULE_NAME,
265		0,
266		stack_interface_std_ops
267	},
268
269	&stack_interface_open,
270	&stack_interface_close,
271	&stack_interface_free,
272
273	&stack_interface_bind,
274	&stack_interface_shutdown,
275	&stack_interface_connect,
276	&stack_interface_listen,
277	&stack_interface_accept,
278
279	&stack_interface_recv,
280	&stack_interface_recvfrom,
281	&stack_interface_recvmsg,
282
283	&stack_interface_send,
284	&stack_interface_sendto,
285	&stack_interface_sendmsg,
286
287	&stack_interface_getsockopt,
288	&stack_interface_setsockopt,
289
290	&stack_interface_getpeername,
291	&stack_interface_getsockname,
292
293	&stack_interface_sockatmark,
294
295	&stack_interface_socketpair,
296
297	&stack_interface_ioctl,
298	&stack_interface_select,
299	&stack_interface_deselect,
300
301	&stack_interface_get_next_socket_stat
302};
303