更新日期: 2022/06/01 来源: https://gitee.com/weharmony/kernel_liteos_a_note
net_syscall.c
浏览该文件的文档.
1/*
2 * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved.
3 * Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved.
4 *
5 * Redistribution and use in source and binary forms, with or without modification,
6 * are permitted provided that the following conditions are met:
7 *
8 * 1. Redistributions of source code must retain the above copyright notice, this list of
9 * conditions and the following disclaimer.
10 *
11 * 2. Redistributions in binary form must reproduce the above copyright notice, this list
12 * of conditions and the following disclaimer in the documentation and/or other materials
13 * provided with the distribution.
14 *
15 * 3. Neither the name of the copyright holder nor the names of its contributors may be used
16 * to endorse or promote products derived from this software without specific prior written
17 * permission.
18 *
19 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
20 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
21 * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
22 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
23 * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
24 * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
25 * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
26 * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
27 * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
28 * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
29 * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
30 */
31
32#include "syscall_pub.h"
33#include "stdlib.h"
34#include "fs/file.h"
35#include "los_process_pri.h"
36#include "los_signal.h"
37#include "los_syscall.h"
38#include "los_vm_map.h"
39#include "user_copy.h"
40
41#ifdef LOSCFG_NET_LWIP_SACK
42#include "lwip/sockets.h"
43//网络相关系统调用
44
45#define SOCKET_U2K(s) \
46 do { \
47 s = GetAssociatedSystemFd(s); \
48 if (s == VFS_ERROR) { \
49 set_errno(EBADF); \
50 return -get_errno(); \
51 } \
52 } while (0)
53
54#define SOCKET_K2U(s) \
55 do { \
56 int fd = AllocAndAssocProcessFd(s, MIN_START_FD); \
57 if (fd == -1) { \
58 closesocket(s); \
59 set_errno(EMFILE); \
60 s = -EMFILE; \
61 } else { \
62 s = fd; \
63 } \
64 } while (0)
65
66int SysSocket(int domain, int type, int protocol)
67{
68 int ret;
69
70 ret = socket(domain, type, protocol);
71 if (ret == -1) {
72 return -get_errno();
73 }
74
75 SOCKET_K2U(ret);
76 return ret;
77}
78
79int SysBind(int s, const struct sockaddr *name, socklen_t namelen)
80{
81 int ret;
82
83 SOCKET_U2K(s);
84 CHECK_ASPACE(name, namelen);
85
86 DUP_FROM_USER(name, namelen);
87
88 if (name == NULL) {
89 set_errno(EFAULT);
90 ret = -1;
91 } else {
92 ret = bind(s, name, namelen);
93 }
94 FREE_DUP(name);
95 if (ret == -1) {
96 return -get_errno();
97 }
98
99 return ret;
100}
101
102int SysConnect(int s, const struct sockaddr *name, socklen_t namelen)
103{
104 int ret;
105
106 SOCKET_U2K(s);
107 CHECK_ASPACE(name, namelen);
108
109 DUP_FROM_USER(name, namelen);
110
111 if (name == NULL) {
112 set_errno(EFAULT);
113 ret = -1;
114 } else {
115 ret = connect(s, name, namelen);
116 }
117 FREE_DUP(name);
118 if (ret == -1) {
119 return -get_errno();
120 }
121
122 return ret;
123}
124
125int SysListen(int sockfd, int backlog)
126{
127 int ret;
128
129 SOCKET_U2K(sockfd);
130 ret = listen(sockfd, backlog);
131 if (ret == -1) {
132 return -get_errno();
133 }
134
135 return ret;
136}
137
138int SysAccept(int socket, struct sockaddr *address,
139 socklen_t *addressLen)
140{
141 int ret;
142
143 SOCKET_U2K(socket);
144
145 CHECK_ASPACE(addressLen, sizeof(socklen_t));
146 CPY_FROM_USER(addressLen);
147
148 CHECK_ASPACE(address, LEN(addressLen));
149 DUP_FROM_USER_NOCOPY(address, LEN(addressLen));
150
151 ret = accept(socket, address, addressLen);
152 if (ret == -1) {
153 FREE_DUP(address);
154 return -get_errno();
155 }
156
157 CPY_TO_USER(addressLen, close(ret); FREE_DUP(address));
158 DUP_TO_USER(address, LEN(addressLen), close(ret); FREE_DUP(address));
159 FREE_DUP(address);
160
161 SOCKET_K2U(ret);
162 return ret;
163}
164
165int SysGetSockName(int s, struct sockaddr *name, socklen_t *namelen)
166{
167 int ret;
168
169 SOCKET_U2K(s);
170
171 CHECK_ASPACE(namelen, sizeof(socklen_t));
172 CPY_FROM_USER(namelen);
173
174 CHECK_ASPACE(name, LEN(namelen));
175 DUP_FROM_USER_NOCOPY(name, LEN(namelen));
176
177 if (name == NULL || namelen == NULL) {
178 set_errno(EFAULT);
179 ret = -1;
180 } else {
181 ret = getsockname(s, name, namelen);
182 }
183 if (ret == -1) {
184 FREE_DUP(name);
185 return -get_errno();
186 }
187
188 CPY_TO_USER(namelen, FREE_DUP(name));
189 DUP_TO_USER(name, LEN(namelen), FREE_DUP(name));
190 FREE_DUP(name);
191 return ret;
192}
193
194int SysGetPeerName(int s, struct sockaddr *name, socklen_t *namelen)
195{
196 int ret;
197
198 SOCKET_U2K(s);
199
200 CHECK_ASPACE(namelen, sizeof(socklen_t));
201 CPY_FROM_USER(namelen);
202
203 CHECK_ASPACE(name, LEN(namelen));
204 DUP_FROM_USER_NOCOPY(name, LEN(namelen));
205
206 if (name == NULL || namelen == NULL) {
207 set_errno(EFAULT);
208 ret = -1;
209 } else {
210 ret = getpeername(s, name, namelen);
211 }
212 if (ret == -1) {
213 FREE_DUP(name);
214 return -get_errno();
215 }
216
217 CPY_TO_USER(namelen, FREE_DUP(name));
218 DUP_TO_USER(name, LEN(namelen), FREE_DUP(name));
219 FREE_DUP(name);
220 return ret;
221}
222
223ssize_t SysSend(int s, const void *dataptr, size_t size, int flags)
224{
225 int ret;
226
227 SOCKET_U2K(s);
228 CHECK_ASPACE(dataptr, size);
229
230 DUP_FROM_USER(dataptr, size);
231
232 if (dataptr == NULL) {
233 set_errno(EFAULT);
234 ret = -1;
235 } else {
236 ret = send(s, dataptr, size, flags);
237 }
238 FREE_DUP(dataptr);
239 if (ret == -1) {
240 return -get_errno();
241 }
242
243 return ret;
244}
245
246ssize_t SysSendTo(int s, const void *dataptr, size_t size, int flags,
247 const struct sockaddr *to, socklen_t tolen)
248{
249 int ret;
250
251 SOCKET_U2K(s);
252 CHECK_ASPACE(dataptr, size);
253 CHECK_ASPACE(to, tolen);
254
255 DUP_FROM_USER(dataptr, size);
256 DUP_FROM_USER(to, tolen, FREE_DUP(dataptr));
257
258 if (dataptr == NULL) {
259 set_errno(EFAULT);
260 ret = -1;
261 } else {
262 ret = sendto(s, dataptr, size, flags, to, tolen);
263 }
264 FREE_DUP(dataptr);
265 FREE_DUP(to);
266 if (ret == -1) {
267 return -get_errno();
268 }
269
270 return ret;
271}
272
273ssize_t SysRecv(int socket, void *buffer, size_t length, int flags)
274{
275 int ret;
276
277 SOCKET_U2K(socket);
278 CHECK_ASPACE(buffer, length);
279
280 DUP_FROM_USER_NOCOPY(buffer, length);
281
282 if (buffer == NULL) {
283 set_errno(EFAULT);
284 ret = -1;
285 } else {
286 ret = recv(socket, buffer, length, flags);
287 }
288 if (ret == -1) {
289 FREE_DUP(buffer);
290 return -get_errno();
291 }
292
293 DUP_TO_USER(buffer, ret, FREE_DUP(buffer));
294 FREE_DUP(buffer);
295 return ret;
296}
297
298ssize_t SysRecvFrom(int socket, void *buffer, size_t length,
299 int flags, struct sockaddr *address,
300 socklen_t *addressLen)
301{
302 int ret;
303
304 SOCKET_U2K(socket);
305 CHECK_ASPACE(buffer, length);
306
307 CHECK_ASPACE(addressLen, sizeof(socklen_t));
308 CPY_FROM_USER(addressLen);
309
310 CHECK_ASPACE(address, LEN(addressLen));
311 DUP_FROM_USER_NOCOPY(address, LEN(addressLen));
312
313 DUP_FROM_USER_NOCOPY(buffer, length, FREE_DUP(address));
314
315 if (buffer == NULL || (address != NULL && addressLen == NULL)) {
316 set_errno(EFAULT);
317 ret = -1;
318 } else {
319 ret = recvfrom(socket, buffer, length, flags, address, addressLen);
320 }
321 if (ret == -1) {
322 FREE_DUP(address);
323 FREE_DUP(buffer);
324 return -get_errno();
325 }
326
327 CPY_TO_USER(addressLen, FREE_DUP(address); FREE_DUP(buffer));
328 DUP_TO_USER(address, LEN(addressLen), FREE_DUP(address); FREE_DUP(buffer));
329 DUP_TO_USER(buffer, ret, FREE_DUP(address); FREE_DUP(buffer));
330 FREE_DUP(address);
331 FREE_DUP(buffer);
332 return ret;
333}
334
335int SysShutdown(int socket, int how)
336{
337 int ret;
338
339 SOCKET_U2K(socket);
340 ret = shutdown(socket, how);
341 if (ret == -1) {
342 return -get_errno();
343 }
344
345 return ret;
346}
347
348int SysSetSockOpt(int socket, int level, int optName,
349 const void *optValue, socklen_t optLen)
350{
351 int ret;
352
353 SOCKET_U2K(socket);
354 CHECK_ASPACE(optValue, optLen);
355
356 DUP_FROM_USER(optValue, optLen);
357 ret = setsockopt(socket, level, optName, optValue, optLen);
358 FREE_DUP(optValue);
359 if (ret == -1) {
360 return -get_errno();
361 }
362
363 return ret;
364}
365
366int SysGetSockOpt(int sockfd, int level, int optName,
367 void *optValue, socklen_t *optLen)
368{
369 int ret;
370
371 SOCKET_U2K(sockfd);
372
373 CHECK_ASPACE(optLen, sizeof(socklen_t));
374 CPY_FROM_USER(optLen);
375
376 CHECK_ASPACE(optValue, LEN(optLen));
377 DUP_FROM_USER_NOCOPY(optValue, LEN(optLen));
378
379 if (optLen == NULL) {
380 set_errno(EFAULT);
381 ret = -1;
382 } else {
383 ret = getsockopt(sockfd, level, optName, optValue, optLen);
384 }
385 if (ret == -1) {
386 FREE_DUP(optValue);
387 return -get_errno();
388 }
389
390 CPY_TO_USER(optLen, FREE_DUP(optValue));
391 DUP_TO_USER(optValue, LEN(optLen), FREE_DUP(optValue));
392 FREE_DUP(optValue);
393 return ret;
394}
395
396ssize_t SysSendMsg(int s, const struct msghdr *message, int flags)
397{
398 int ret;
399
400 SOCKET_U2K(s);
401
402 CHECK_ASPACE(message, sizeof(struct msghdr));
403 CPY_FROM_CONST_USER(struct msghdr, message);
404
405 if (message && message->msg_iovlen > IOV_MAX) {
406 set_errno(EMSGSIZE);
407 return -get_errno();
408 }
409
410 CHECK_FIELD_ASPACE(message, msg_name, message->msg_namelen);
411 CHECK_FIELD_ASPACE(message, msg_iov, message->msg_iovlen * sizeof(struct iovec));
412 CHECK_FIELD_ASPACE(message, msg_control, message->msg_controllen);
413
414 DUP_FIELD_FROM_USER(message, msg_iov, message->msg_iovlen * sizeof(struct iovec));
415 CHECK_ARRAY_FIELD_ASPACE(message, msg_iov, message->msg_iovlen, iov_base, iov_len,
416 FREE_DUP_FIELD(message, msg_iov));
417 DUP_FIELD_FROM_USER(message, msg_name, message->msg_namelen,
418 FREE_DUP_FIELD(message, msg_iov));
419 DUP_FIELD_FROM_USER(message, msg_control, message->msg_controllen,
420 FREE_DUP_FIELD(message, msg_iov);
421 FREE_DUP_FIELD(message, msg_name));
422 DUP_ARRAY_FIELD_FROM_USER(message, msg_iov, message->msg_iovlen, iov_base, iov_len,
423 FREE_DUP_FIELD(message, msg_control);
424 FREE_DUP_FIELD(message, msg_iov);
425 FREE_DUP_FIELD(message, msg_name));
426
427 if (message == NULL) {
428 set_errno(EFAULT);
429 ret = -1;
430 } else {
431 ret = sendmsg(s, message, flags);
432 }
433 FREE_DUP_ARRAY_FIELD(message, msg_iov, message->msg_iovlen, iov_base);
434 FREE_DUP_FIELD(message, msg_control);
435 FREE_DUP_FIELD(message, msg_iov);
436 FREE_DUP_FIELD(message, msg_name);
437 if (ret == -1) {
438 return -get_errno();
439 }
440
441 return ret;
442}
443
444ssize_t SysRecvMsg(int s, struct msghdr *message, int flags)
445{
446 int ret;
447
448 SOCKET_U2K(s);
449
450 CHECK_ASPACE(message, sizeof(struct msghdr));
451 CPY_FROM_NONCONST_USER(message);
452
453 if (message && message->msg_iovlen > IOV_MAX) {
454 set_errno(EMSGSIZE);
455 return -get_errno();
456 }
457
458 CHECK_FIELD_ASPACE(message, msg_name, message->msg_namelen);
459 CHECK_FIELD_ASPACE(message, msg_iov, message->msg_iovlen * sizeof(struct iovec));
460 CHECK_FIELD_ASPACE(message, msg_control, message->msg_controllen);
461
462 DUP_FIELD_FROM_USER(message, msg_iov, message->msg_iovlen * sizeof(struct iovec));
463 CHECK_ARRAY_FIELD_ASPACE(message, msg_iov, message->msg_iovlen, iov_base, iov_len,
464 FREE_DUP_FIELD(message, msg_iov));
465 DUP_FIELD_FROM_USER_NOCOPY(message, msg_name, message->msg_namelen,
466 FREE_DUP_FIELD(message, msg_iov));
467 DUP_FIELD_FROM_USER_NOCOPY(message, msg_control, message->msg_controllen,
468 FREE_DUP_FIELD(message, msg_iov);
469 FREE_DUP_FIELD(message, msg_name));
470 DUP_ARRAY_FIELD_FROM_USER_NOCOPY(message, msg_iov, message->msg_iovlen, iov_base, iov_len,
471 FREE_DUP_FIELD(message, msg_control);
472 FREE_DUP_FIELD(message, msg_iov);
473 FREE_DUP_FIELD(message, msg_name));
474
475 if (message == NULL) {
476 set_errno(EFAULT);
477 ret = -1;
478 } else {
479 ret = recvmsg(s, message, flags);
480 }
481 if (ret == -1) {
482 goto OUT;
483 }
484
485 CPY_TO_USER(message, ret = -1; goto OUT);
486 DUP_FIELD_TO_USER(message, msg_control, message->msg_controllen, ret = -1; goto OUT);
487 DUP_FIELD_TO_USER(message, msg_iov, message->msg_iovlen * sizeof(struct iovec), ret = -1; goto OUT);
488 DUP_FIELD_TO_USER(message, msg_name, message->msg_namelen, ret = -1; goto OUT);
489 DUP_ARRAY_FIELD_TO_USER(message, msg_iov, message->msg_iovlen, iov_base, iov_len, ret = -1; goto OUT);
490OUT:
491 FREE_DUP_ARRAY_FIELD(message, msg_iov, message->msg_iovlen, iov_base);
492 FREE_DUP_FIELD(message, msg_control);
493 FREE_DUP_FIELD(message, msg_iov);
494 FREE_DUP_FIELD(message, msg_name);
495 return (ret == -1) ? -get_errno() : ret;
496}
497
498#endif
INT64 ssize_t
Definition: los_typedef.h:79
int SysGetSockName(int s, struct sockaddr *name, socklen_t *namelen)
Definition: net_syscall.c:165
int SysAccept(int socket, struct sockaddr *address, socklen_t *addressLen)
Definition: net_syscall.c:138
int SysBind(int s, const struct sockaddr *name, socklen_t namelen)
Definition: net_syscall.c:79
int SysGetPeerName(int s, struct sockaddr *name, socklen_t *namelen)
Definition: net_syscall.c:194
int SysGetSockOpt(int sockfd, int level, int optName, void *optValue, socklen_t *optLen)
Definition: net_syscall.c:366
ssize_t SysSend(int s, const void *dataptr, size_t size, int flags)
Definition: net_syscall.c:223
ssize_t SysRecvFrom(int socket, void *buffer, size_t length, int flags, struct sockaddr *address, socklen_t *addressLen)
Definition: net_syscall.c:298
int SysSetSockOpt(int socket, int level, int optName, const void *optValue, socklen_t optLen)
Definition: net_syscall.c:348
ssize_t SysSendTo(int s, const void *dataptr, size_t size, int flags, const struct sockaddr *to, socklen_t tolen)
Definition: net_syscall.c:246
ssize_t SysSendMsg(int s, const struct msghdr *message, int flags)
Definition: net_syscall.c:396
ssize_t SysRecvMsg(int s, struct msghdr *message, int flags)
Definition: net_syscall.c:444
ssize_t SysRecv(int socket, void *buffer, size_t length, int flags)
Definition: net_syscall.c:273
int SysShutdown(int socket, int how)
Definition: net_syscall.c:335
int SysConnect(int s, const struct sockaddr *name, socklen_t namelen)
Definition: net_syscall.c:102
int SysListen(int sockfd, int backlog)
Definition: net_syscall.c:125
int SysSocket(int domain, int type, int protocol)
Definition: net_syscall.c:66
int connect(int s, const struct sockaddr *name, socklen_t namelen)
Definition: socket.c:185
int setsockopt(int s, int level, int optname, const void *optval, socklen_t optlen)
设置socket 配置项
Definition: socket.c:148
ssize_t recvmsg(int s, struct msghdr *message, int flags)
只是数据的格式的不同
Definition: socket.c:247
int getpeername(int s, struct sockaddr *name, socklen_t *namelen)
获取对等名称 = getsockname
Definition: socket.c:129
ssize_t recv(int s, void *mem, size_t len, int flags)
Definition: socket.c:234
int getsockname(int s, struct sockaddr *name, socklen_t *namelen)
获取socket名称和长度
Definition: socket.c:136
int shutdown(int s, int how)
Definition: socket.c:124
ssize_t sendto(int s, const void *dataptr, size_t size, int flags, const struct sockaddr *to, socklen_t tolen)
区别是送达地址,意思是这些数据要发给哪个地址的
Definition: socket.c:268
int bind(int s, const struct sockaddr *name, socklen_t namelen)
Definition: socket.c:94
ssize_t sendmsg(int s, const struct msghdr *message, int flags)
只是发送数据的格式的不同
Definition: socket.c:263
int accept(int s, struct sockaddr *addr, socklen_t *addrlen)
Definition: socket.c:70
int getsockopt(int s, int level, int optname, void *optval, socklen_t *optlen)
获取 socket 配置项
Definition: socket.c:143
ssize_t recvfrom(int s, void *mem, size_t len, int flags, struct sockaddr *from, socklen_t *fromlen)
区别是返回源地址,意思是这些数据是从哪个地址过来的
Definition: socket.c:240
int listen(int s, int backlog)
Definition: socket.c:209
ssize_t send(int s, const void *dataptr, size_t size, int flags)
相当于文件操作的 write 功能,区别是第四个参数 同 recv
Definition: socket.c:257
int socket(int domain, int type, int protocol)
Definition: socket.c:314