source: EcnlProtoTool/trunk/ntshell/src/socket_stub.c

Last change on this file was 442, checked in by coas-nagasima, 4 years ago

ntshellアプリはnewlibを使うよう変更し、syscallの実装部分と区別がつくよう更新。

  • Property svn:eol-style set to native
  • Property svn:mime-type set to text/x-csrc;charset=UTF-8
File size: 53.5 KB
RevLine 
[286]1/*
[439]2 * TOPPERS PROJECT Home Network Working Group Software
[286]3 *
[439]4 * Copyright (C) 2017-2019 Cores Co., Ltd. Japan
[286]5 *
6 * 上記著作権者は,以下の(1)~(4)の条件を満たす場合に限り,本ソフトウェ
7 * ア(本ソフトウェアを改変したものを含む.以下同じ)を使用・複製・改
8 * 変・再配布(以下,利用と呼ぶ)することを無償で許諾する.
9 * (1) 本ソフトウェアをソースコードの形で利用する場合には,上記の著作
10 * 権表示,この利用条件および下記の無保証規定が,そのままの形でソー
11 * スコード中に含まれていること.
12 * (2) 本ソフトウェアを,ライブラリ形式など,他のソフトウェア開発に使
13 * 用できる形で再配布する場合には,再配布に伴うドキュメント(利用
14 * 者マニュアルなど)に,上記の著作権表示,この利用条件および下記
15 * の無保証規定を掲載すること.
16 * (3) 本ソフトウェアを,機器に組み込むなど,他のソフトウェア開発に使
17 * 用できない形で再配布する場合には,次のいずれかの条件を満たすこ
18 * と.
19 * (a) 再配布に伴うドキュメント(利用者マニュアルなど)に,上記の著
20 * 作権表示,この利用条件および下記の無保証規定を掲載すること.
21 * (b) 再配布の形態を,別に定める方法によって,TOPPERSプロジェクトに
22 * 報告すること.
23 * (4) 本ソフトウェアの利用により直接的または間接的に生じるいかなる損
24 * 害からも,上記著作権者およびTOPPERSプロジェクトを免責すること.
25 * また,本ソフトウェアのユーザまたはエンドユーザからのいかなる理
26 * 由に基づく請求からも,上記著作権者およびTOPPERSプロジェクトを
27 * 免責すること.
28 *
29 * 本ソフトウェアは,無保証で提供されているものである.上記著作権者お
30 * よびTOPPERSプロジェクトは,本ソフトウェアに関して,特定の使用目的
31 * に対する適合性も含めて,いかなる保証も行わない.また,本ソフトウェ
32 * アの利用により直接的または間接的に生じたいかなる損害に関しても,そ
33 * の責任を負わない.
34 *
35 * @(#) $Id$
36 */
[331]37#include "shellif.h"
[279]38#include <kernel.h>
39#include <t_syslog.h>
40#include <t_stdlib.h>
41#include <sil.h>
42#include "syssvc/syslog.h"
[441]43#include <tinet_defs.h>
[279]44#include <tinet_config.h>
[441]45#include <net/net.h>
46#include <net/net_endian.h>
[279]47#include <netinet/in.h>
48#include <netinet/in_itron.h>
49#include <tinet_nic_defs.h>
50#include <tinet_cfg.h>
51#include <netinet/in_var.h>
52#include <net/ethernet.h>
53#include <net/if6_var.h>
54#include <net/net.h>
55#include <net/if_var.h>
56#include <netinet/udp_var.h>
[441]57#include <net/net_buf.h>
58#include <netinet/udp.h>
59#include <netinet/udp_var.h>
60#include <netinet/tcp.h>
61#include <netinet/tcp_var.h>
62#include <netapp/resolver.h>
[433]63#include "fdtable.h"
[441]64#include "kernel_cfg.h"
[279]65
[441]66#ifdef _DEBUG
67static const char THIS_FILE[] = __FILE__;
68#endif
69
[331]70#define SOCKET_TIMEOUT 2000000
[441]71#define TCP_SOCKET_BUF_SIZE 512
[331]72
[441]73struct addrinfo {
74 int ai_flags;
75 int ai_family;
76 int ai_socktype;
77 int ai_protocol;
78 socklen_t ai_addrlen;
79 struct sockaddr *ai_addr;
80 char *ai_canonname;
81 struct addrinfo *ai_next;
82};
83
84typedef uint16_t in_port_t;
85typedef uint32_t in_addr_t;
86struct in_addr { in_addr_t s_addr; };
87
88struct sockaddr_in {
89 sa_family_t sin_family;
90 in_port_t sin_port;
91 struct in_addr sin_addr;
92 uint8_t sin_zero[8];
93};
94
95struct in6_addr
96{
97 union {
98 uint8_t __s6_addr[16];
99 uint16_t __s6_addr16[8];
100 uint32_t __s6_addr32[4];
101 } __in6_union;
102};
103//#define s6_addr __in6_union.__s6_addr
104//#define s6_addr16 __in6_union.__s6_addr16
105//#define s6_addr32 __in6_union.__s6_addr32
106
107struct sockaddr_in6
108{
109 sa_family_t sin6_family;
110 in_port_t sin6_port;
111 uint32_t sin6_flowinfo;
112 struct in6_addr sin6_addr;
113 uint32_t sin6_scope_id;
114};
115
116typedef struct socket_t {
117 int family;
118 int type;
119 int protocol;
120 int cepid;
121 int repid;
122 int backlog;
123 unsigned int flags;
124 union {
125 struct sockaddr_in laddr4;
126 struct sockaddr_in6 laddr6;
127 };
128 union {
129 struct sockaddr_in raddr4;
130 struct sockaddr_in6 raddr6;
131 };
132 int buf_size;
133 unsigned char *buf;
134 void *input;
135 int len;
136} socket_t;
137
138#define tcp6_cre_cep tcp_cre_cep
139#define tcp6_del_cep tcp_del_cep
140#define tcp6_del_rep tcp_del_rep
141#define tcp6_can_cep tcp_can_cep
142#define tcp6_sht_cep tcp_sht_cep
143#define tcp6_cls_cep tcp_cls_cep
144#define tcp6_snd_oob tcp_snd_oob
145#define tcp6_snd_dat tcp_snd_dat
146#define tcp6_rcv_oob tcp_rcv_oob
147#define tcp6_rcv_buf tcp_rcv_buf
148#define tcp6_rel_buf tcp_rel_buf
149#define tcp6_get_opt tcp_get_opt
150#define tcp6_set_opt tcp_set_opt
151
152#define udp6_can_cep udp_can_cep
153
154#ifndef SUPPORT_INET6
155
156ER tcp6_cre_rep (ID repid, T_TCP6_CREP *pk_crep) { return E_SYS; }
157ER tcp6_acp_cep (ID cepid, ID repid, T_IPV6EP *p_dstaddr, TMO tmout) { return E_SYS; }
158ER tcp6_con_cep (ID cepid, T_IPV6EP *p_myaddr, T_IPV6EP *p_dstaddr, TMO tmout) { return E_SYS; }
159
160ER udp6_cre_cep (ID cepid, T_UDP6_CCEP *pk_ccep) { return E_SYS; }
161ER udp6_del_cep (ID cepid) { return E_SYS; }
162ER_UINT udp6_snd_dat (ID cepid, T_IPV6EP *p_dstaddr, void *data, int_t len, TMO tmout) { return E_SYS; }
163ER_UINT udp6_rcv_dat (ID cepid, T_IPV6EP *p_dstaddr, void *data, int_t len, TMO tmout) { return E_SYS; }
164ER udp6_set_opt (ID cepid, int_t optname, void *optval, int_t optlen) { return E_SYS; }
165ER udp6_get_opt (ID cepid, int_t optname, void *optval, int_t optlen) { return E_SYS; }
166
167const T_IN6_ADDR *in6_get_ifaddr (int_t index) { return NULL; }
168
169#endif
170
171ER socket_tcp_callback(ID cepid, FN fncd, void *p_parblk);
172ER socket_tcp6_callback(ID cepid, FN fncd, void *p_parblk);
173ER socket_udp_callback(ID cepid, FN fncd, void *p_parblk);
174ER socket_udp6_callback(ID cepid, FN fncd, void *p_parblk);
175
176static int tcp_fd_close(struct SHELL_FILE *fp);
177static size_t tcp_fd_read(struct SHELL_FILE *fp, unsigned char *data, size_t len);
178static size_t tcp_fd_write(struct SHELL_FILE *fp, const unsigned char *data, size_t len);
179static off_t tcp_fd_seek(struct SHELL_FILE *fp, off_t ofs, int org);
180static int tcp_fd_ioctl(struct SHELL_FILE *fp, int req, void *arg);
181static bool_t tcp_fd_readable(struct SHELL_FILE *fp);
182static bool_t tcp_fd_writable(struct SHELL_FILE *fp);
183static void tcp_fd_delete(struct SHELL_FILE *fp);
184
185static int udp_fd_close(struct SHELL_FILE *fp);
186static size_t udp_fd_read(struct SHELL_FILE *fp, unsigned char *data, size_t len);
187static size_t udp_fd_write(struct SHELL_FILE *fp, const unsigned char *data, size_t len);
188static off_t udp_fd_seek(struct SHELL_FILE *fp, off_t ofs, int org);
189static int udp_fd_ioctl(struct SHELL_FILE *fp, int req, void *arg);
190static bool_t udp_fd_readable(struct SHELL_FILE *fp);
191static bool_t udp_fd_writable(struct SHELL_FILE *fp);
192static void udp_fd_delete(struct SHELL_FILE *fp);
193
194IO_TYPE IO_TYPE_TCP = { tcp_fd_close, tcp_fd_read, tcp_fd_write, tcp_fd_seek, tcp_fd_ioctl, tcp_fd_readable, tcp_fd_writable, tcp_fd_delete };
195IO_TYPE IO_TYPE_UDP = { udp_fd_close, udp_fd_read, udp_fd_write, udp_fd_seek, udp_fd_ioctl, udp_fd_readable, udp_fd_writable, udp_fd_delete };
196
[279]197typedef struct id_table_t {
198 int used;
199 ID id;
200} id_table_t;
201
202id_table_t tcp_repid_table[] = {
203 {0, USR_TCP_REP1}, {0, USR_TCP_REP2}, {0, USR_TCP_REP3}, {0, USR_TCP_REP4}
204};
205#define tcp_repid_table_count (sizeof(tcp_repid_table) / sizeof(tcp_repid_table[0]))
206
207id_table_t tcp_cepid_table[] = {
[441]208 {0, USR_TCP_CEP1}, {0, USR_TCP_CEP2}, {0, USR_TCP_CEP3}, {0, USR_TCP_CEP4},
209#ifndef TOPPERS_GRSAKURA
210 {0, USR_TCP_CEP5}, {0, USR_TCP_CEP6}, {0, USR_TCP_CEP7}, {0, USR_TCP_CEP8}
211#endif
[279]212};
213#define tcp_cepid_table_count (sizeof(tcp_cepid_table) / sizeof(tcp_cepid_table[0]))
214
[441]215#ifdef SUPPORT_INET6
216
217id_table_t tcp6_repid_table[] = {
218 {0, USR_TCP6_REP1}, {0, USR_TCP6_REP2}, {0, USR_TCP6_REP3}, {0, USR_TCP6_REP4}
219};
220#define tcp6_repid_table_count (sizeof(tcp6_repid_table) / sizeof(tcp6_repid_table[0]))
221
222id_table_t tcp6_cepid_table[] = {
223 {0, USR_TCP6_CEP1}, {0, USR_TCP6_CEP2}, {0, USR_TCP6_CEP3}, {0, USR_TCP6_CEP4},
224#ifndef TOPPERS_GRSAKURA
225 {0, USR_TCP6_CEP5}, {0, USR_TCP6_CEP6}, {0, USR_TCP6_CEP7}, {0, USR_TCP6_CEP8}
226#endif
227};
228#define tcp6_cepid_table_count (sizeof(tcp6_cepid_table) / sizeof(tcp6_cepid_table[0]))
229
230#else
231
232#define tcp6_repid_table NULL
233#define tcp6_repid_table_count 0
234
235#define tcp6_cepid_table NULL
236#define tcp6_cepid_table_count 0
237
238#endif
239
[279]240id_table_t udp_cepid_table[] = {
241 {0, USR_UDP_CEP1}, {0, USR_UDP_CEP2}, {0, USR_UDP_CEP3}, {0, USR_UDP_CEP4}
242};
243#define udp_cepid_table_count (sizeof(udp_cepid_table) / sizeof(udp_cepid_table[0]))
244
[441]245#ifdef SUPPORT_INET6
246
247id_table_t udp6_cepid_table[] = {
248 {0, USR_UDP6_CEP1}, {0, USR_UDP6_CEP2}, {0, USR_UDP6_CEP3}, {0, USR_UDP6_CEP4}
249};
250#define udp6_cepid_table_count (sizeof(udp6_cepid_table) / sizeof(udp6_cepid_table[0]))
251
252#else
253
254#define udp6_cepid_table NULL
255#define udp6_cepid_table_count 0
256
257#endif
258
259void addrcpy(void *_dst, const void *_src, int len)
260{
261#if _NET_CFG_BYTE_ORDER == _NET_CFG_BIG_ENDIAN
262 memcpy(_dst, _src, len);
263#else
264 uint8_t *dst = (uint8_t *)_dst, *src = &((uint8_t *)_src)[len];
265 while (src != _src)
266 *dst++ = *--src;
267#endif
268}
269
[279]270ID new_id(id_table_t *table, int count)
271{
272 for (int i = 0; i < count; i++) {
273 id_table_t *item = &table[i];
274 if (item->used != 0)
275 continue;
276
277 item->used = 1;
278 return item->id;
279}
280
[331]281 return -ENOMEM;
[279]282}
283
284int delete_id(id_table_t *table, int count, ID id)
285{
286 for (int i = 0; i < count; i++) {
287 id_table_t *item = &table[i];
288 if ((item->used == 0) || (item->id != id))
289 continue;
290
291 item->used = 0;
292 return 0;
293 }
[331]294 return -EINVAL;
[279]295}
296
[441]297typedef struct SHELL_FILE SOCKET;
[279]298
[331]299int shell_socket(int family, int type, int protocol)
[279]300{
301 SOCKET *fp;
[331]302 unsigned int flags;
[279]303
304 switch (family) {
305 case AF_INET:
306 case AF_INET6:
307 break;
308 default:
[331]309 return -EAFNOSUPPORT;
[279]310 }
311
[331]312 flags = type & (SOCK_CLOEXEC|SOCK_NONBLOCK);
313 type &= ~flags;
314
[279]315 switch (type) {
316 case SOCK_STREAM:
[441]317 fp = new_fp(&IO_TYPE_TCP, 0, 0);
318 if (fp == NULL)
319 return -ENOMEM;
320
321 fp->exinf = malloc(sizeof(socket_t));
322 memset(fp->exinf, 0, sizeof(socket_t));
[279]323 break;
324 case SOCK_DGRAM:
[441]325 fp = new_fp(&IO_TYPE_UDP, 0, 1);
326 if (fp == NULL)
327 return -ENOMEM;
328
329 fp->exinf = malloc(sizeof(socket_t));
330 memset(fp->exinf, 0, sizeof(socket_t));
[279]331 break;
332 default:
[331]333 return -ENOPROTOOPT;
[279]334 }
335
[441]336 socket_t *socket = (socket_t *)fp->exinf;
337 socket->family = family;
338 socket->type = type;
339 socket->protocol = protocol;
340 socket->flags = flags;
[279]341
342 return fp->fd;
343}
344
[331]345int shell_bind(int fd, const struct sockaddr *addr, socklen_t len)
[279]346{
347 SOCKET *fp = fd_to_fp(fd);
[331]348 if (fp == NULL)
349 return -EBADF;
[441]350 socket_t *socket = (socket_t *)fp->exinf;
351 if (socket->family != addr->sa_family)
[331]352 return -EINVAL;
[279]353
354 ER ret;
355 switch (addr->sa_family) {
356 case AF_INET: {
357 if (len < 8) {
[331]358 return -EINVAL;
[279]359 }
360 struct sockaddr_in *addr_in = (struct sockaddr_in *)addr;
[441]361 memcpy(&socket->laddr4, addr, len);
362 switch (socket->type) {
[279]363 case SOCK_STREAM: {
364 ID cepid = new_id(tcp_cepid_table, tcp_cepid_table_count);
365 if (cepid < 0)
[331]366 return -ENOMEM;
[279]367
[441]368 socket->buf_size = TCP_SOCKET_BUF_SIZE + TCP_SOCKET_BUF_SIZE;
369 socket->buf = malloc(socket->buf_size);
370#ifdef _DEBUG
371 memset(socket->buf, 0, socket->buf_size);
372#endif
373 T_TCP_CCEP ccep = { 0, socket->buf, TCP_SOCKET_BUF_SIZE, &socket->buf[TCP_SOCKET_BUF_SIZE], TCP_SOCKET_BUF_SIZE, (FP)socket_tcp_callback };
[279]374 ret = tcp_cre_cep(cepid, &ccep);
375 if (ret != E_OK) {
[441]376 free(socket->buf);
377 socket->buf = NULL;
378 socket->buf_size = 0;
[279]379 delete_id(tcp_cepid_table, tcp_cepid_table_count, cepid);
[331]380 return -ENOMEM;
[279]381 }
382 fp->handle = cepid;
[441]383 socket->cepid = cepid;
[279]384 break;
385 }
386 case SOCK_DGRAM: {
387 ID cepid = new_id(udp_cepid_table, udp_cepid_table_count);
388 if (cepid < 0)
[331]389 return -ENOMEM;
[279]390
[331]391 T_UDP_CCEP ccep = { 0, {ntohl(addr_in->sin_addr.s_addr), ntohs(addr_in->sin_port)}, (FP)socket_udp_callback };
[279]392 ret = udp_cre_cep(cepid, &ccep);
393 if (ret != E_OK) {
394 delete_id(udp_cepid_table, udp_cepid_table_count, cepid);
[331]395 return -ENOMEM;
[279]396 }
397 fp->handle = cepid;
[441]398 socket->cepid = cepid;
[279]399 break;
400 }
401 default:
[331]402 return -ENOPROTOOPT;
[279]403 }
404 break;
405 }
406 case AF_INET6: {
407 if (len < 20) {
[331]408 return -EINVAL;
[279]409 }
[441]410 struct sockaddr_in6 *addr_in6 = (struct sockaddr_in6 *)addr;
411 memcpy(&socket->laddr6, addr, len);
412 switch (socket->type) {
413 case SOCK_STREAM: {
414 ID cepid = new_id(tcp6_cepid_table, tcp6_cepid_table_count);
415 if (cepid < 0)
416 return -ENOMEM;
417
418 socket->buf_size = TCP_SOCKET_BUF_SIZE + TCP_SOCKET_BUF_SIZE;
419 socket->buf = malloc(socket->buf_size);
420#ifdef _DEBUG
421 memset(socket->buf, 0, socket->buf_size);
422#endif
423 T_TCP6_CCEP ccep = { 0, socket->buf, TCP_SOCKET_BUF_SIZE, &socket->buf[TCP_SOCKET_BUF_SIZE], TCP_SOCKET_BUF_SIZE, (FP)socket_tcp6_callback };
424 ret = tcp6_cre_cep(cepid, &ccep);
425 if (ret != E_OK) {
426 free(socket->buf);
427 socket->buf = NULL;
428 socket->buf_size = 0;
429 delete_id(tcp6_cepid_table, tcp6_cepid_table_count, cepid);
430 return -ENOMEM;
431 }
432 fp->handle = cepid;
433 socket->cepid = cepid;
434 break;
435 }
436 case SOCK_DGRAM: {
437 ID cepid = new_id(udp6_cepid_table, udp6_cepid_table_count);
438 if (cepid < 0)
439 return -ENOMEM;
440
441 T_UDP6_CCEP ccep = { 0, { { ntohl(addr_in6->sin6_addr.__in6_union.__s6_addr) }, ntohs(addr_in6->sin6_port)}, (FP)socket_udp6_callback };
442 ret = udp6_cre_cep(cepid, &ccep);
443 if (ret != E_OK) {
444 delete_id(udp6_cepid_table, udp6_cepid_table_count, cepid);
445 return -ENOMEM;
446 }
447 fp->handle = cepid;
448 socket->cepid = cepid;
449 break;
450 }
451 default:
452 return -ENOPROTOOPT;
453 }
[279]454 break;
455 }
[441]456 default:
457 return -ENOPROTOOPT;
[279]458 }
459
460 return 0;
461}
462
[331]463int shell_listen(int fd, int backlog)
[279]464{
465 SOCKET *fp = fd_to_fp(fd);
[331]466 if (fp == NULL)
467 return -EBADF;
[441]468 socket_t *socket = (socket_t *)fp->exinf;
469 if (socket->type != SOCK_STREAM)
[331]470 return -EINVAL;
[279]471
[441]472 socket->backlog = backlog;
[279]473
474 ER ret;
[441]475 switch (socket->family) {
[279]476 case AF_INET: {
477 ID repid = new_id(tcp_repid_table, tcp_repid_table_count);
478 if (repid < 0)
[331]479 return -ENOMEM;
[279]480
[441]481 struct sockaddr_in *laddr = &socket->laddr4;
[279]482 T_TCP_CREP crep = { 0, {ntohl(laddr->sin_addr.s_addr), ntohs(laddr->sin_port)} };
483 ret = tcp_cre_rep(repid, &crep);
484 if (ret != E_OK) {
485 delete_id(tcp_repid_table, tcp_repid_table_count, repid);
[331]486 return -ENOMEM;
[279]487 }
[441]488 socket->repid = repid;
[279]489 break;
490 }
491 case AF_INET6: {
[441]492 ID repid = new_id(tcp6_repid_table, tcp6_repid_table_count);
493 if (repid < 0)
494 return -ENOMEM;
495
496 struct sockaddr_in6 *laddr = &socket->laddr6;
497 T_TCP6_CREP crep = { 0, { { ntohl(laddr->sin6_addr.__in6_union.__s6_addr) }, ntohs(laddr->sin6_port)} };
498 ret = tcp6_cre_rep(repid, &crep);
499 if (ret != E_OK) {
500 delete_id(tcp6_repid_table, tcp6_repid_table_count, repid);
501 return -ENOMEM;
502 }
503 socket->repid = repid;
[279]504 break;
505 }
[441]506 default:
507 return -ENOPROTOOPT;
[279]508 }
509
510 return 0;
511}
512
[441]513int shell_connect(int fd, const struct sockaddr *addr, socklen_t alen)
[279]514{
515 SOCKET *fp = fd_to_fp(fd);
[331]516 if (fp == NULL)
517 return -EBADF;
[441]518 socket_t *socket = (socket_t *)fp->exinf;
519 if (socket->type != SOCK_STREAM)
[331]520 return -EINVAL;
[279]521
522 ER ret;
[441]523 switch (socket->family) {
[279]524 case AF_INET: {
[441]525 if (alen < sizeof(struct sockaddr_in)) {
[331]526 return -EINVAL;
[279]527 }
[441]528 if (socket->cepid == 0) {
[279]529 ID cepid = new_id(tcp_cepid_table, tcp_cepid_table_count);
530 if (cepid < 0)
[331]531 return -ENOMEM;
[279]532
[441]533 socket->buf_size = TCP_SOCKET_BUF_SIZE + TCP_SOCKET_BUF_SIZE;
534 socket->buf = malloc(socket->buf_size);
535#ifdef _DEBUG
536 memset(socket->buf, 0, socket->buf_size);
537#endif
538 T_TCP_CCEP ccep = { 0, socket->buf, TCP_SOCKET_BUF_SIZE, &socket->buf[TCP_SOCKET_BUF_SIZE], TCP_SOCKET_BUF_SIZE, (FP)socket_tcp_callback };
[279]539 ret = tcp_cre_cep(cepid, &ccep);
540 if (ret != E_OK) {
[441]541 free(socket->buf);
542 socket->buf = NULL;
543 socket->buf_size = 0;
[279]544 delete_id(tcp_cepid_table, tcp_cepid_table_count, cepid);
[331]545 return -ENOMEM;
[279]546 }
547 fp->handle = cepid;
[441]548 fp->writable = 1;
549 socket->cepid = cepid;
[279]550 }
[441]551 struct sockaddr_in *laddr = &socket->laddr4;
552 struct sockaddr_in *raddr = &socket->raddr4;
553 memcpy(raddr, addr, sizeof(struct sockaddr_in));
[279]554 T_IPV4EP lep = { ntohl(laddr->sin_addr.s_addr), ntohs(laddr->sin_port) };
555 T_IPV4EP rep = { ntohl(raddr->sin_addr.s_addr), ntohs(raddr->sin_port) };
[441]556 ret = tcp_con_cep(socket->cepid, &lep, &rep, SOCKET_TIMEOUT);
557 if (ret == E_TMOUT) {
558 return -ETIMEDOUT;
559 }
560 else if (ret < 0) {
[331]561 return -EHOSTUNREACH;
[279]562 }
563 break;
564 }
565 case AF_INET6: {
[441]566 if (alen < sizeof(struct sockaddr_in6)) {
567 return -EINVAL;
568 }
569 if (socket->cepid == 0) {
570 ID cepid = new_id(tcp6_cepid_table, tcp6_cepid_table_count);
571 if (cepid < 0)
572 return -ENOMEM;
573
574 socket->buf_size = TCP_SOCKET_BUF_SIZE + TCP_SOCKET_BUF_SIZE;
575 socket->buf = malloc(socket->buf_size);
576#ifdef _DEBUG
577 memset(socket->buf, 0, socket->buf_size);
578#endif
579 T_TCP6_CCEP ccep = { 0, socket->buf, TCP_SOCKET_BUF_SIZE, &socket->buf[TCP_SOCKET_BUF_SIZE], TCP_SOCKET_BUF_SIZE, (FP)socket_tcp6_callback };
580 ret = tcp6_cre_cep(cepid, &ccep);
581 if (ret != E_OK) {
582 free(socket->buf);
583 socket->buf = NULL;
584 socket->buf_size = 0;
585 delete_id(tcp6_cepid_table, tcp6_cepid_table_count, cepid);
586 return -ENOMEM;
587 }
588 fp->handle = cepid;
589 fp->writable = 1;
590 socket->cepid = cepid;
591 }
592 struct sockaddr_in6 *laddr = &socket->laddr6;
593 struct sockaddr_in6 *raddr = &socket->raddr6;
594 memcpy(raddr, addr, sizeof(struct sockaddr_in6));
595 T_IPV6EP lep;
596 addrcpy(&lep.ipaddr, &laddr->sin6_addr, 16);
597 lep.portno = ntohs(laddr->sin6_port);
598 T_IPV6EP rep;
599 addrcpy(&rep.ipaddr, &raddr->sin6_addr, 16);
600 rep.portno = ntohs(raddr->sin6_port);
601 ret = tcp6_con_cep(socket->cepid, &lep, &rep, SOCKET_TIMEOUT);
602 if (ret == E_TMOUT) {
603 return -ETIMEDOUT;
604 }
605 else if (ret < 0) {
606 return -EHOSTUNREACH;
607 }
[279]608 break;
609 }
[441]610 default:
611 return -ENOPROTOOPT;
[279]612 }
613
[441]614 if (fp->writeevt_w != fp->writeevt_r) fp->writeevt_r++;
615
[279]616 return 0;
617}
618
[441]619int shell_accept(int fd, struct sockaddr *restrict addr, socklen_t *restrict alen)
[279]620{
621 SOCKET *lfp = fd_to_fp(fd);
[331]622 if (lfp == NULL)
623 return -EBADF;
[441]624 if (((socket_t *)lfp->exinf)->type != SOCK_STREAM)
[331]625 return -EINVAL;
[279]626
[441]627 SOCKET *fp = new_fp(&IO_TYPE_TCP, 0, 0);
628 if (fp == NULL)
[331]629 return -ENOMEM;
[279]630
[441]631 fp->exinf = malloc(sizeof(socket_t));
632 memset(fp->exinf, 0, sizeof(socket_t));
[279]633
[441]634 memcpy(fp->exinf, lfp->exinf, offsetof(socket_t, buf_size));
635
[279]636 ER ret;
[441]637 socket_t *socket = (socket_t *)fp->exinf;
638 switch (socket->family) {
[279]639 case AF_INET: {
640 ID cepid;
[441]641 if (socket->cepid == 0) {
[279]642 cepid = new_id(tcp_cepid_table, tcp_cepid_table_count);
643 if (cepid < 0)
[331]644 return -ENOMEM;
[279]645
[441]646 socket->buf_size = TCP_SOCKET_BUF_SIZE + TCP_SOCKET_BUF_SIZE;
647 socket->buf = malloc(socket->buf_size);
648#ifdef _DEBUG
649 memset(socket->buf, 0, socket->buf_size);
650#endif
651 T_TCP_CCEP ccep = { 0, socket->buf, TCP_SOCKET_BUF_SIZE, &socket->buf[TCP_SOCKET_BUF_SIZE], TCP_SOCKET_BUF_SIZE, (FP)socket_tcp_callback };
[279]652 ret = tcp_cre_cep(cepid, &ccep);
653 if (ret != E_OK) {
[441]654 free(socket->buf);
655 socket->buf = NULL;
656 socket->buf_size = 0;
[279]657 delete_id(tcp_cepid_table, tcp_cepid_table_count, cepid);
[331]658 return -ENOMEM;
[279]659 }
660 fp->handle = cepid;
[441]661 fp->writable = 1;
662 socket->cepid = cepid;
[279]663 }
664 else {
[441]665 cepid = ((socket_t *)lfp->exinf)->cepid;
666 fp->handle = cepid;
667 fp->writable = 1;
668 lfp->handle = tmax_tcp_cepid + ((socket_t *)lfp->exinf)->repid;
669 ((socket_t *)lfp->exinf)->cepid = 0;
670 ((socket_t *)lfp->exinf)->buf_size = 0;
671 ((socket_t *)lfp->exinf)->buf = 0;
[279]672 }
673 T_IPV4EP rep = { 0, 0 };
[441]674 ret = tcp_acp_cep(socket->cepid, socket->repid, &rep, TMO_FEVR);
[279]675 if (ret < 0) {
[331]676 return -ENOMEM;
[279]677 }
[441]678 struct sockaddr_in *raddr = &socket->raddr4;
679 memset(raddr, 0, sizeof(struct sockaddr_in));
[279]680 raddr->sin_family = AF_INET;
681 raddr->sin_port = htons(rep.portno);
682 raddr->sin_addr.s_addr = htonl(rep.ipaddr);
[441]683
684 if (addr != NULL && alen != NULL) {
685 int sz = *alen;
686 if (sz < sizeof(struct sockaddr_in)) {
687 return -EINVAL;
688 }
689 if (sz > sizeof(struct sockaddr_in))
690 sz = sizeof(struct sockaddr_in);
691 memcpy(addr, raddr, sz);
692 *alen = sz;
693 }
[279]694 break;
695 }
696 case AF_INET6: {
[441]697 ID cepid;
698 if (socket->cepid == 0) {
699 cepid = new_id(tcp6_cepid_table, tcp6_cepid_table_count);
700 if (cepid < 0)
701 return -ENOMEM;
[279]702
[441]703 socket->buf_size = TCP_SOCKET_BUF_SIZE + TCP_SOCKET_BUF_SIZE;
704 socket->buf = malloc(socket->buf_size);
705#ifdef _DEBUG
706 memset(socket->buf, 0, socket->buf_size);
707#endif
708 T_TCP6_CCEP ccep = { 0, socket->buf, TCP_SOCKET_BUF_SIZE, &socket->buf[TCP_SOCKET_BUF_SIZE], TCP_SOCKET_BUF_SIZE, (FP)socket_tcp6_callback };
709 ret = tcp6_cre_cep(cepid, &ccep);
710 if (ret != E_OK) {
711 free(socket->buf);
712 socket->buf = NULL;
713 socket->buf_size = 0;
714 delete_id(tcp6_cepid_table, tcp6_cepid_table_count, cepid);
715 return -ENOMEM;
716 }
717 fp->handle = cepid;
718 fp->writable = 1;
719 socket->cepid = cepid;
[279]720 }
[441]721 else {
722 cepid = ((socket_t *)lfp->exinf)->cepid;
723 fp->handle = cepid;
724 fp->writable = 1;
725 lfp->handle = tmax_tcp6_cepid + ((socket_t *)lfp->exinf)->repid;
726 ((socket_t *)lfp->exinf)->cepid = 0;
727 ((socket_t *)lfp->exinf)->buf_size = 0;
728 ((socket_t *)lfp->exinf)->buf = 0;
729 }
730 T_IPV6EP rep = { { 0 }, 0 };
731 ret = tcp6_acp_cep(socket->cepid, socket->repid, &rep, TMO_FEVR);
732 if (ret < 0) {
733 return -ENOMEM;
734 }
735 struct sockaddr_in6 *raddr = &socket->raddr6;
736 memset(raddr, 0, sizeof(struct sockaddr_in6));
737 raddr->sin6_family = AF_INET;
738 raddr->sin6_port = htons(rep.portno);
739 addrcpy(&raddr->sin6_addr, &rep.ipaddr, 16);
740
741 if (addr != NULL && alen != NULL) {
742 int sz = *alen;
743 if (sz < sizeof(struct sockaddr_in6)) {
744 return -EINVAL;
745 }
746 if (sz > sizeof(struct sockaddr_in6))
747 sz = sizeof(struct sockaddr_in6);
748 memcpy(addr, raddr, sz);
749 *alen = sz;
750 }
751 break;
[279]752 }
[441]753 default:
754 return -ENOPROTOOPT;
755 }
[279]756
[441]757 if (fp->writeevt_w != fp->writeevt_r) fp->writeevt_r++;
758
[279]759 return fp->fd;
760}
761
[441]762ssize_t shell_sendto(int fd, const void *buf, size_t len, int flags, const struct sockaddr *addr, socklen_t alen)
[279]763{
764 SOCKET *fp = fd_to_fp(fd);
765 if (fp == NULL) {
[331]766 return -EBADF;
[279]767 }
768
769 int ret = 0;
[441]770 socket_t *socket = (socket_t *)fp->exinf;
771 switch (socket->family) {
[279]772 case AF_INET: {
[441]773 switch (socket->type) {
[279]774 case SOCK_STREAM: {
[441]775 if ((addr != NULL) || (alen != 0)) {
776 return -EISCONN;
777 }
778
[279]779 if (flags & MSG_OOB) {
[441]780 ret = tcp_snd_oob(socket->cepid, (void *)buf, len, SOCKET_TIMEOUT);
[279]781 if (ret < 0) {
[331]782 return -ECOMM;
[279]783 }
784 }
785 else {
[441]786 int temp = len;
787 for (;;) {
788 ret = tcp_snd_dat(socket->cepid, (void *)buf, len, SOCKET_TIMEOUT);
789 if (ret < 0) {
790 return (ret == E_TMOUT) ? -EAGAIN : -ECOMM;
791 }
792 len -= ret;
793 if (len <= 0)
794 break;
795 buf = (const void *)&((uint8_t *)buf)[ret];
796 }
797 ret = temp;
[279]798 }
799 break;
800 }
801 case SOCK_DGRAM: {
[441]802 if ((addr == NULL) || (alen < sizeof(struct sockaddr_in))) {
803 return -EINVAL;
804 }
805 struct sockaddr_in *raddr = &socket->raddr4;
806 memcpy(raddr, addr, sizeof(struct sockaddr_in));
807 T_IPV4EP rep = { ntohl(raddr->sin_addr.s_addr), ntohs(raddr->sin_port) };
808 ret = udp_snd_dat(socket->cepid, &rep, (void *)buf, len,
809 (socket->flags & O_NONBLOCK) ? TMO_POL : SOCKET_TIMEOUT);
810 if (ret < 0) {
811 return (ret == E_TMOUT) ? -EAGAIN : -ECOMM;
812 }
813 break;
[279]814 }
815 }
816 break;
817 }
818 case AF_INET6: {
[441]819 switch (socket->type) {
[279]820 case SOCK_STREAM: {
[441]821 if ((addr != NULL) || (alen != 0)) {
822 return -EISCONN;
[279]823 }
824
825 if (flags & MSG_OOB) {
[441]826 ret = tcp6_snd_oob(socket->cepid, (void *)buf, len, SOCKET_TIMEOUT);
[279]827 if (ret < 0) {
[331]828 return -ECOMM;
[279]829 }
830 }
831 else {
[441]832 int temp = len;
833 for (;;) {
834 ret = tcp6_snd_dat(socket->cepid, (void *)buf, len, SOCKET_TIMEOUT);
835 if (ret < 0) {
836 return (ret == E_TMOUT) ? -EAGAIN : -ECOMM;
837 }
838 len -= ret;
839 if (len <= 0)
840 break;
841 buf = (const void *)&((uint8_t *)buf)[ret];
[279]842 }
[441]843 ret = temp;
[279]844 }
845 break;
846 }
847 case SOCK_DGRAM: {
[441]848 if ((addr == NULL) || (alen < sizeof(struct sockaddr_in6))) {
[331]849 return -EINVAL;
[279]850 }
[441]851 struct sockaddr_in6 *raddr = &socket->raddr6;
852 memcpy(raddr, addr, sizeof(struct sockaddr_in6));
853 T_IPV6EP rep;
854 addrcpy(&rep.ipaddr, &raddr->sin6_addr, 16);
855 rep.portno = ntohs(raddr->sin6_port);
856 ret = udp6_snd_dat(socket->cepid, &rep, (void *)buf, len,
857 (socket->flags & O_NONBLOCK) ? TMO_POL : SOCKET_TIMEOUT);
[279]858 if (ret < 0) {
[441]859 return (ret == E_TMOUT) ? -EAGAIN : -ECOMM;
[279]860 }
861 break;
862 }
863 }
864 break;
865 }
[441]866 default:
867 return -ENOPROTOOPT;
[279]868 }
869
[441]870 if (fp->writeevt_w != fp->writeevt_r) fp->writeevt_r++;
871
[279]872 return ret;
873}
874
[331]875ssize_t shell_sendmsg(int fd, const struct msghdr *msg, int flags)
[279]876{
[331]877 no_implement("sendmsg\n");
878 return -ENOSYS;
879}
880
[441]881ssize_t shell_recvfrom(int fd, void *restrict buf, size_t len, int flags, struct sockaddr *restrict addr, socklen_t *restrict alen)
[331]882{
[279]883 SOCKET *fp = fd_to_fp(fd);
884 if (fp == NULL) {
[331]885 return -EBADF;
[279]886 }
887
888 int ret = 0;
[441]889 socket_t *socket = (socket_t *)fp->exinf;
890 switch (socket->family) {
[279]891 case AF_INET: {
[441]892 switch (socket->type) {
[279]893 case SOCK_STREAM: {
894 if (flags & MSG_OOB) {
[441]895 ret = tcp_rcv_oob(socket->cepid, buf, len);
[279]896 if (ret < 0) {
[441]897 syslog(LOG_ERROR, "tcp_rcv_oob => %d", ret);
[331]898 return -ECOMM;
[279]899 }
900 }
901 else {
[441]902 int rsz, tmp;
903 if (socket->input == NULL) {
904 ret = wai_sem(SEM_FILEDESC);
905 if (ret < 0) {
906 syslog(LOG_ERROR, "wai_sem => %d", ret);
907 }
908 socket->len = 0;
909 ret = sig_sem(SEM_FILEDESC);
910 if (ret < 0) {
911 syslog(LOG_ERROR, "sig_sem => %d", ret);
912 }
913 ret = tcp_rcv_buf(socket->cepid, &socket->input,
914 (socket->flags & O_NONBLOCK) ? TMO_POL : SOCKET_TIMEOUT);
915 if (ret < 0) {
916 if ((socket->flags & O_NONBLOCK) == 0)
917 syslog(LOG_ERROR, "tcp_rcv_buf => %d", ret);
918 return (ret == E_TMOUT) ? -EAGAIN : -ECOMM;
919 }
920 rsz = ret;
[279]921 }
[441]922 else
923 rsz = socket->len;
924 tmp = rsz;
925 if (rsz > len)
926 rsz = len;
927 if (rsz > 0) {
928 memcpy(buf, socket->input, rsz);
929 ret = wai_sem(SEM_FILEDESC);
930 if (ret < 0) {
931 syslog(LOG_ERROR, "wai_sem => %d", ret);
932 }
933 socket->len = tmp - rsz;
934 ret = sig_sem(SEM_FILEDESC);
935 if (ret < 0) {
936 syslog(LOG_ERROR, "sig_sem => %d", ret);
937 }
938 if (tmp - rsz == 0) {
939 socket->input = NULL;
940 }
941 else
942 socket->input = (void *)&((uint8_t *)socket->input)[rsz];
943 ret = tcp_rel_buf(socket->cepid, rsz);
944 if ((ret != E_OBJ) && (ret < 0)) {
945 syslog(LOG_ERROR, "tcp_rel_buf => %d", ret);
946 //return -ECOMM;
947 }
948 }
949 else {
950 syslog(LOG_ERROR, "shell_recvfrom => %d", rsz);
951 }
952 ret = rsz;
[279]953 }
954 break;
955 }
956 case SOCK_DGRAM: {
[441]957 struct sockaddr_in *raddr = &socket->raddr4;
958 int rsz;
959 ret = wai_sem(SEM_FILEDESC);
[279]960 if (ret < 0) {
[441]961 syslog(LOG_ERROR, "wai_sem => %d", ret);
[279]962 }
[441]963 T_NET_BUF *input = socket->input;
964 if (input == NULL) {
965 ret = sig_sem(SEM_FILEDESC);
966 if (ret < 0) {
967 syslog(LOG_ERROR, "sig_sem => %d", ret);
968 }
969
970 T_IPV4EP rep = { 0, 0 };
971 ret = udp_rcv_dat(socket->cepid, &rep, buf, len,
972 (socket->flags & O_NONBLOCK) ? TMO_POL : SOCKET_TIMEOUT);
973 if (ret < 0) {
974 if ((socket->flags & O_NONBLOCK) == 0)
975 syslog(LOG_ERROR, "udp_rcv_buf => %d", ret);
976 return (ret == E_TMOUT) ? -EAGAIN : -ECOMM;
977 }
978 rsz = ret;
979 if ((addr != NULL) && (alen != NULL)) {
980 ret = wai_sem(SEM_FILEDESC);
981 if (ret < 0) {
982 syslog(LOG_ERROR, "wai_sem => %d", ret);
983 }
984 int sz = *alen;
985 memset(raddr, 0, sizeof(struct sockaddr_in));
986 raddr->sin_family = AF_INET;
987 raddr->sin_port = htons(rep.portno);
988 raddr->sin_addr.s_addr = htonl(rep.ipaddr);
989 if (sz > sizeof(struct sockaddr_in))
990 sz = sizeof(struct sockaddr_in);
991 memcpy(addr, raddr, sz);
992 *alen = sz;
993 ret = sig_sem(SEM_FILEDESC);
994 if (ret < 0) {
995 syslog(LOG_ERROR, "sig_sem => %d", ret);
996 }
997 }
998 }
999 else {
1000 rsz = socket->len;
1001 void *pbuf = socket->buf;
1002 socket->input = NULL;
1003 socket->len = 0;
1004 socket->buf = NULL;
1005 if ((addr != NULL) && (alen != NULL)) {
1006 int sz = *alen;
1007 if (sz > sizeof(struct sockaddr_in))
1008 sz = sizeof(struct sockaddr_in);
1009 memcpy(addr, raddr, sz);
1010 *alen = sz;
1011 }
1012 ret = sig_sem(SEM_FILEDESC);
1013 if (ret < 0) {
1014 syslog(LOG_ERROR, "sig_sem => %d", ret);
1015 }
1016 if (rsz > len)
1017 rsz = len;
1018 memcpy(buf, pbuf, rsz);
1019 ret = rel_net_buf(input);
1020 if (ret < 0) {
1021 syslog(LOG_ERROR, "rel_net_buf => %d", ret);
1022 //return -ECOMM;
1023 }
1024 }
1025 ret = rsz;
[279]1026 }
1027 }
1028 break;
1029 }
1030 case AF_INET6: {
[441]1031 switch (socket->type) {
[279]1032 case SOCK_STREAM: {
1033 if (flags & MSG_OOB) {
[441]1034 ret = tcp6_rcv_oob(socket->cepid, buf, len);
[279]1035 if (ret < 0) {
[441]1036 syslog(LOG_ERROR, "tcp6_rcv_oob => %d", ret);
[331]1037 return -ECOMM;
[279]1038 }
1039 }
1040 else {
[441]1041 int rsz, tmp;
1042 if (socket->input == NULL) {
1043 ret = wai_sem(SEM_FILEDESC);
1044 if (ret < 0) {
1045 syslog(LOG_ERROR, "wai_sem => %d", ret);
1046 }
1047 socket->len = 0;
1048 ret = sig_sem(SEM_FILEDESC);
1049 if (ret < 0) {
1050 syslog(LOG_ERROR, "sig_sem => %d", ret);
1051 }
1052 ret = tcp6_rcv_buf(socket->cepid, &socket->input,
1053 (socket->flags & O_NONBLOCK) ? TMO_POL : SOCKET_TIMEOUT);
1054 if (ret < 0) {
1055 if ((socket->flags & O_NONBLOCK) == 0)
1056 syslog(LOG_ERROR, "tcp6_rcv_buf => %d", ret);
1057 return (ret == E_TMOUT) ? -EAGAIN : -ECOMM;
1058 }
1059 rsz = ret;
[279]1060 }
[441]1061 else
1062 rsz = socket->len;
1063 tmp = rsz;
1064 if (rsz > len)
1065 rsz = len;
1066 if (rsz >= 0) {
1067 memcpy(buf, socket->input, rsz);
1068 ret = wai_sem(SEM_FILEDESC);
1069 if (ret < 0) {
1070 syslog(LOG_ERROR, "wai_sem => %d", ret);
1071 }
1072 socket->len = tmp - rsz;
1073 ret = sig_sem(SEM_FILEDESC);
1074 if (ret < 0) {
1075 syslog(LOG_ERROR, "sig_sem => %d", ret);
1076 }
1077 if (tmp - rsz == 0) {
1078 socket->input = NULL;
1079 }
1080 else
1081 socket->input = (void *)&((uint8_t *)socket->input)[rsz];
1082 ret = tcp6_rel_buf(socket->cepid, rsz);
1083 if ((ret != E_OBJ) && (ret < 0)) {
1084 syslog(LOG_ERROR, "tcp6_rel_buf => %d", ret);
1085 //return -ECOMM;
1086 }
1087 }
1088 ret = rsz;
[279]1089 }
1090 break;
1091 }
1092 case SOCK_DGRAM: {
[441]1093 struct sockaddr_in6 *raddr = &socket->raddr6;
1094 int rsz;
1095 ret = wai_sem(SEM_FILEDESC);
[279]1096 if (ret < 0) {
[441]1097 syslog(LOG_ERROR, "wai_sem => %d", ret);
[279]1098 }
[441]1099 T_NET_BUF *input = socket->input;
1100 if (input == NULL) {
1101 ret = sig_sem(SEM_FILEDESC);
1102 if (ret < 0) {
1103 syslog(LOG_ERROR, "sig_sem => %d", ret);
1104 }
1105
1106 T_IPV6EP rep = { { 0 }, 0 };
1107 ret = udp6_rcv_dat(socket->cepid, &rep, buf, len,
1108 (socket->flags & O_NONBLOCK) ? TMO_POL : SOCKET_TIMEOUT);
1109 if (ret < 0) {
1110 if ((socket->flags & O_NONBLOCK) == 0)
1111 syslog(LOG_ERROR, "udp6_rcv_buf => %d", ret);
1112 return (ret == E_TMOUT) ? -EAGAIN : -ECOMM;
1113 }
1114 rsz = ret;
1115 if ((addr != NULL) && (alen != NULL)) {
1116 ret = wai_sem(SEM_FILEDESC);
1117 if (ret < 0) {
1118 syslog(LOG_ERROR, "wai_sem => %d", ret);
1119 }
1120 int sz = *alen;
1121 memset(raddr, 0, sizeof(struct sockaddr_in6));
1122 raddr->sin6_family = AF_INET;
1123 raddr->sin6_port = htons(rep.portno);
1124 addrcpy(&raddr->sin6_addr, &rep.ipaddr, 16);
1125 if (sz > sizeof(struct sockaddr_in6))
1126 sz = sizeof(struct sockaddr_in6);
1127 memcpy(addr, raddr, sz);
1128 *alen = sz;
1129 ret = sig_sem(SEM_FILEDESC);
1130 if (ret < 0) {
1131 syslog(LOG_ERROR, "sig_sem => %d", ret);
1132 }
1133 }
1134 }
1135 else {
1136 rsz = socket->len;
1137 void *pbuf = socket->buf;
1138 socket->input = NULL;
1139 socket->len = 0;
1140 socket->buf = NULL;
1141 if ((addr != NULL) && (alen != NULL)) {
1142 int sz = *alen;
1143 if (sz > sizeof(struct sockaddr_in6))
1144 sz = sizeof(struct sockaddr_in6);
1145 memcpy(addr, raddr, sz);
1146 *alen = sz;
1147 }
1148 ret = sig_sem(SEM_FILEDESC);
1149 if (ret < 0) {
1150 syslog(LOG_ERROR, "sig_sem => %d", ret);
1151 }
1152 if (rsz > len)
1153 rsz = len;
1154 memcpy(buf, pbuf, rsz);
1155 ret = rel_net_buf(input);
1156 if (ret < 0) {
1157 syslog(LOG_ERROR, "rel_net_buf => %d", ret);
1158 //return -ECOMM;
1159 }
1160 }
1161 ret = rsz;
[279]1162 }
1163 }
1164 break;
1165 }
[441]1166 default:
1167 return -ENOPROTOOPT;
[279]1168 }
1169
[441]1170 if (fp->readevt_w != fp->readevt_r) fp->readevt_r++;
1171
[279]1172 return ret;
1173}
1174
[331]1175ssize_t shell_recvmsg(int fd, struct msghdr *msg, int flags)
[279]1176{
[331]1177 no_implement("recvmsg\n");
1178 return -ENOSYS;
1179}
1180
1181int shell_shutdown(int fd, int how)
1182{
[279]1183 SOCKET *fp = fd_to_fp(fd);
1184 if (fp == NULL) {
[331]1185 return -EBADF;
[279]1186 }
1187
1188 ER ret;
[441]1189 socket_t *socket = (socket_t *)fp->exinf;
1190 switch (socket->family) {
[279]1191 case AF_INET: {
[441]1192 switch (socket->type) {
[279]1193 case SOCK_STREAM: {
[441]1194 ret = tcp_sht_cep(socket->cepid);
[279]1195 if (ret < 0) {
[331]1196 return -ECOMM;
[279]1197 }
1198 break;
1199 }
1200 }
1201 break;
1202 }
1203 case AF_INET6: {
[441]1204 switch (socket->type) {
1205 case SOCK_STREAM: {
1206 ret = tcp6_sht_cep(socket->cepid);
1207 if (ret < 0) {
1208 return -ECOMM;
1209 }
1210 break;
1211 }
1212 }
1213 break;
[279]1214 }
[441]1215 default:
1216 return -ENOPROTOOPT;
[279]1217 }
1218
1219 return 0;
1220}
1221
[441]1222int shell_getsockopt(int fd, int level, int optname, void *optval, socklen_t *restrict optlen)
[279]1223{
1224 SOCKET *fp = fd_to_fp(fd);
1225 if (fp == NULL) {
[331]1226 return -EBADF;
[279]1227 }
1228
1229 ER ret;
[441]1230 socket_t *socket = (socket_t *)fp->exinf;
1231 switch (socket->family) {
[279]1232 case AF_INET: {
[441]1233 switch (socket->type) {
[279]1234 case SOCK_STREAM: {
[441]1235 switch (level) {
1236 case SOL_SOCKET:
1237 switch (optname) {
1238 case SO_REUSEADDR:
1239 if (socket->flags & SO_REUSEADDR) {
1240 *(bool *)optval = true;
1241 }
1242 else {
1243 *(bool *)optval = false;
1244 }
1245 break;
1246 case SO_KEEPALIVE:
1247 if (socket->flags & SO_KEEPALIVE) {
1248 *(bool *)optval = true;
1249 }
1250 else {
1251 *(bool *)optval = false;
1252 }
1253 break;
1254 case SO_ERROR:
1255 *(int *)optval = 0;
1256 break;
1257 default:
1258 return -EINVAL;
[279]1259 }
[441]1260 break;
1261 case IPPROTO_TCP:
1262 ret = tcp_get_opt(socket->cepid, optname, (void *)optval, *optlen);
1263 if (ret < 0) {
1264 return -EINVAL;
[279]1265 }
[441]1266 *optlen = ret;
[279]1267 break;
1268 default:
[441]1269 return -EINVAL;
1270 }
1271 break;
1272 }
1273 case SOCK_DGRAM: {
1274 switch (level) {
1275 case IPPROTO_UDP:
1276 ret = udp_get_opt(socket->cepid, optname, (void *)optval, *optlen);
[279]1277 if (ret < 0) {
[331]1278 return -EINVAL;
[279]1279 }
1280 *optlen = ret;
1281 break;
[441]1282 default:
1283 return -EINVAL;
[279]1284 }
1285 break;
1286 }
[441]1287 }
1288 break;
1289 }
1290 case AF_INET6: {
1291 switch (socket->type) {
1292 case SOCK_STREAM: {
1293 switch (level) {
1294 case SOL_SOCKET:
1295 switch (optname) {
1296 case SO_REUSEADDR:
1297 if (socket->flags & SO_REUSEADDR) {
1298 *(bool *)optval = true;
1299 }
1300 else {
1301 *(bool *)optval = false;
1302 }
1303 break;
1304 case SO_KEEPALIVE:
1305 if (socket->flags & SO_KEEPALIVE) {
1306 *(bool *)optval = true;
1307 }
1308 else {
1309 *(bool *)optval = false;
1310 }
1311 break;
1312 case SO_ERROR:
1313 *(int *)optval = 0;
1314 break;
1315 default:
1316 return -EINVAL;
1317 }
1318 break;
1319 case IPPROTO_TCP:
1320 ret = tcp6_get_opt(socket->cepid, optname, (void *)optval, *optlen);
1321 if (ret < 0) {
1322 return -EINVAL;
1323 }
1324 *optlen = ret;
1325 break;
1326 default:
1327 return -EINVAL;
1328 }
1329 break;
1330 }
[279]1331 case SOCK_DGRAM: {
[441]1332 switch (level) {
1333 case IPPROTO_UDP:
1334 ret = udp6_get_opt(socket->cepid, optname, (void *)optval, *optlen);
1335 if (ret < 0) {
1336 return -EINVAL;
1337 }
1338 *optlen = ret;
1339 break;
1340 default:
[331]1341 return -EINVAL;
[279]1342 }
1343 break;
1344 }
1345 }
1346 break;
1347 }
[441]1348 default:
1349 return -ENOPROTOOPT;
[279]1350 }
1351
1352 return 0;
1353}
1354
[331]1355int shell_setsockopt(int fd, int level, int optname, const void *optval, socklen_t optlen)
[279]1356{
1357 SOCKET *fp = fd_to_fp(fd);
1358 if (fp == NULL) {
[331]1359 return -EBADF;
[279]1360 }
1361
1362 ER ret;
[441]1363 socket_t *socket = (socket_t *)fp->exinf;
1364 switch (socket->family) {
[279]1365 case AF_INET: {
[441]1366 switch (socket->type) {
[279]1367 case SOCK_STREAM: {
[441]1368 switch (level){
1369 case SOL_SOCKET:
1370 switch (optname) {
1371 case SO_REUSEADDR:
1372 if (*(bool *)optval) {
1373 socket->flags |= SO_REUSEADDR;
1374 }
1375 else {
1376 socket->flags &= ~SO_REUSEADDR;
1377 }
1378 break;
1379 case SO_KEEPALIVE:
1380 if (*(bool *)optval) {
1381 socket->flags |= SO_KEEPALIVE;
1382 }
1383 else {
1384 socket->flags &= ~SO_KEEPALIVE;
1385 }
1386 break;
1387 default:
1388 return -EINVAL;
[279]1389 }
[441]1390 break;
1391 case IPPROTO_TCP:
1392 ret = tcp_set_opt(socket->cepid, optname, (void *)optval, optlen);
1393 if (ret < 0) {
1394 return -EINVAL;
[279]1395 }
1396 break;
1397 default:
[441]1398 return -EINVAL;
1399 }
1400 break;
1401 }
1402 case SOCK_DGRAM: {
1403 switch (level){
1404 case IPPROTO_UDP:
1405 ret = udp_set_opt(socket->cepid, optname, (void *)optval, optlen);
[279]1406 if (ret < 0) {
[331]1407 return -EINVAL;
[279]1408 }
1409 break;
[441]1410 default:
1411 return -EINVAL;
[279]1412 }
1413 break;
1414 }
[441]1415 }
1416 break;
1417 }
1418 case AF_INET6: {
1419 switch (socket->type) {
1420 case SOCK_STREAM: {
1421 switch (level){
1422 case SOL_SOCKET:
1423 switch (optname) {
1424 case SO_REUSEADDR:
1425 if (*(bool *)optval) {
1426 socket->flags |= SO_REUSEADDR;
1427 }
1428 else {
1429 socket->flags &= ~SO_REUSEADDR;
1430 }
1431 break;
1432 case SO_KEEPALIVE:
1433 if (*(bool *)optval) {
1434 socket->flags |= SO_KEEPALIVE;
1435 }
1436 else {
1437 socket->flags &= ~SO_KEEPALIVE;
1438 }
1439 break;
1440 default:
1441 return -EINVAL;
1442 }
1443 break;
1444 case IPPROTO_TCP:
1445 ret = tcp6_set_opt(socket->cepid, optname, (void *)optval, optlen);
1446 if (ret < 0) {
1447 return -EINVAL;
1448 }
1449 break;
1450 default:
1451 return -EINVAL;
1452 }
1453 break;
1454 }
[279]1455 case SOCK_DGRAM: {
[441]1456 switch (level){
1457 case IPPROTO_UDP:
1458 ret = udp6_set_opt(socket->cepid, optname, (void *)optval, optlen);
1459 if (ret < 0) {
1460 return -EINVAL;
1461 }
1462 break;
1463 default:
[331]1464 return -EINVAL;
[279]1465 }
1466 break;
1467 }
1468 }
1469 break;
1470 }
[441]1471 default:
1472 return -ENOPROTOOPT;
1473 }
1474
1475 return 0;
1476}
1477
1478int shell_getpeername(int fd, struct sockaddr *restrict addr, socklen_t *restrict len)
1479{
1480 SOCKET *fp = fd_to_fp(fd);
1481 if (fp == NULL) {
1482 return -EBADF;
1483 }
1484 if (len == NULL) {
1485 return -EINVAL;
1486 }
1487
1488 socklen_t size = *len;
1489 socket_t *socket = (socket_t *)fp->exinf;
1490 switch (socket->family) {
1491 case AF_INET: {
1492 struct sockaddr_in *raddr = &socket->raddr4;
1493 *len = sizeof(struct sockaddr_in);
1494 if (size > sizeof(struct sockaddr_in))
1495 size = sizeof(struct sockaddr_in);
1496 memcpy(addr, raddr, size);
1497 break;
1498 }
[279]1499 case AF_INET6: {
[441]1500 struct sockaddr_in6 *raddr = &socket->raddr6;
1501 *len = sizeof(struct sockaddr_in6);
1502 if (size > sizeof(struct sockaddr_in6))
1503 size = sizeof(struct sockaddr_in6);
1504 memcpy(addr, raddr, size);
1505 break;
[279]1506 }
[441]1507 default:
1508 return -ENOPROTOOPT;
[279]1509 }
1510
1511 return 0;
1512}
1513
[441]1514int shell_getsockname(int fd, struct sockaddr *restrict addr, socklen_t *restrict len)
[279]1515{
[441]1516 SOCKET *fp = fd_to_fp(fd);
1517 if (fp == NULL) {
1518 return -EBADF;
1519 }
1520 if (len == NULL) {
1521 return -EINVAL;
1522 }
1523
1524 socklen_t size = *len;
1525 socket_t *socket = (socket_t *)fp->exinf;
1526 switch (socket->family) {
[279]1527 case AF_INET: {
[441]1528 const T_IN4_ADDR *laddr4 = in4_get_ifaddr(0);
1529 struct sockaddr_in laddr;
1530 laddr.sin_family = AF_INET;
1531 laddr.sin_addr.s_addr = htonl(*laddr4);
1532 laddr.sin_port = socket->laddr4.sin_port;
1533 memset(&laddr.sin_zero, 0, sizeof(laddr.sin_zero));
1534 *len = sizeof(struct sockaddr_in);
1535 if (size > sizeof(struct sockaddr_in))
1536 size = sizeof(struct sockaddr_in);
1537 memcpy(addr, &laddr, size);
1538 break;
1539 }
1540 case AF_INET6: {
1541 const T_IN6_ADDR *laddr6 = in6_get_ifaddr(0);
1542 struct sockaddr_in6 laddr;
1543 laddr.sin6_family = AF_INET;
1544 addrcpy(&laddr.sin6_addr, laddr6, 16);
1545 laddr.sin6_port = socket->laddr6.sin6_port;
1546 *len = sizeof(struct sockaddr_in6);
1547 if (size > sizeof(struct sockaddr_in6))
1548 size = sizeof(struct sockaddr_in6);
1549 memcpy(addr, &laddr, size);
1550 break;
1551 }
1552 default:
1553 return -ENOPROTOOPT;
1554 }
1555
1556 return 0;
1557}
1558
1559int tcp_fd_close(struct SHELL_FILE *fp)
1560{
1561 ER ret, ret2;
1562
1563 socket_t *socket = (socket_t *)fp->exinf;
1564 switch (socket->family) {
1565 case AF_INET: {
1566 if (socket->cepid != 0) {
1567 ID cepid = socket->cepid;
1568 ret = tcp_can_cep(cepid, TFN_TCP_ALL);
1569 if ((ret < 0) && (ret != E_OBJ)) {
1570 syslog(LOG_ERROR, "tcp_can_cep => %d", ret);
1571 }
[279]1572 ret = tcp_sht_cep(cepid);
[441]1573 if ((ret < 0) && (ret != E_OBJ)) {
1574 syslog(LOG_ERROR, "tcp_sht_cep => %d", ret);
[279]1575 }
[441]1576 ret = tcp_cls_cep(cepid, (socket->repid != 0) ? 0 : SOCKET_TIMEOUT);
1577 ret2 = tcp_del_cep(cepid);
1578 if (ret2 < 0) {
1579 syslog(LOG_ERROR, "tcp_del_cep => %d", ret2);
[279]1580 }
[441]1581 //delete_fd_by_id(&IO_TYPE_TCP, cepid);
[279]1582 delete_id(tcp_cepid_table, tcp_cepid_table_count, cepid);
[441]1583 if ((ret < 0) || (ret2 < 0)) {
1584 return (ret == E_TMOUT) ? -ETIMEDOUT : -EIO;
[279]1585 }
1586 }
[441]1587 else if (socket->repid != 0) {
1588 ID repid = socket->repid;
[279]1589 ret = tcp_del_rep(repid);
[441]1590 //delete_fd_by_id(&IO_TYPE_TCP, tmax_tcp_cepid + repid);
[279]1591 delete_id(tcp_repid_table, tcp_repid_table_count, repid);
1592 if (ret < 0) {
[331]1593 return -EINVAL;
[279]1594 }
1595 }
1596 else {
[331]1597 return -EINVAL;
[279]1598 }
1599 break;
1600 }
1601 case AF_INET6: {
[441]1602 if (socket->cepid != 0) {
1603 ID cepid = socket->cepid;
1604 ret = tcp6_can_cep(cepid, TFN_TCP_ALL);
1605 if ((ret < 0) && (ret != E_OBJ)) {
1606 syslog(LOG_ERROR, "tcp_can_cep => %d", ret);
1607 }
1608 ret = tcp6_sht_cep(cepid);
1609 if ((ret < 0) && (ret != E_OBJ)) {
1610 syslog(LOG_ERROR, "tcp6_sht_cep => %d", ret);
1611 }
1612 ret = tcp6_cls_cep(cepid, (socket->repid != 0) ? 0 : SOCKET_TIMEOUT);
1613 ret2 = tcp6_del_cep(cepid);
1614 if (ret2 < 0) {
1615 syslog(LOG_ERROR, "tcp6_del_cep => %d", ret2);
1616 }
1617 //delete_fd_by_id(&IO_TYPE_TCP, cepid);
1618 delete_id(tcp6_cepid_table, tcp6_cepid_table_count, cepid);
1619 if ((ret < 0) || (ret2 < 0)) {
1620 return (ret == E_TMOUT) ? -ETIMEDOUT : -EIO;
1621 }
1622 }
1623 else if (socket->repid != 0) {
1624 ID repid = socket->repid;
1625 ret = tcp6_del_rep(repid);
1626 //delete_fd_by_id(&IO_TYPE_TCP, tmax_tcp6_cepid + repid);
1627 delete_id(tcp6_repid_table, tcp6_repid_table_count, repid);
1628 if (ret < 0) {
1629 return -EINVAL;
1630 }
1631 }
1632 else {
1633 return -EINVAL;
1634 }
1635 break;
[279]1636 }
[441]1637 default:
1638 return -ENOPROTOOPT;
[279]1639 }
1640
1641 return 0;
1642}
1643
[441]1644size_t tcp_fd_read(struct SHELL_FILE *fp, unsigned char *dst, size_t dstsz)
[279]1645{
[441]1646 return shell_recvfrom(fp->fd, dst, dstsz, 0, NULL, NULL);
[279]1647}
1648
[441]1649size_t tcp_fd_write(struct SHELL_FILE *fp, const unsigned char *src, size_t srcsz)
[279]1650{
[441]1651 return shell_sendto(fp->fd, src, srcsz, 0, NULL, 0);
[279]1652}
1653
[441]1654off_t tcp_fd_seek(struct SHELL_FILE *fp, off_t ofs, int org)
[279]1655{
[331]1656 return -EPERM;
[279]1657}
1658
[441]1659int tcp_fd_ioctl(struct SHELL_FILE *fp, int req, void *arg)
[331]1660{
[441]1661 socket_t *socket = (socket_t *)fp->exinf;
1662
1663 switch (req) {
1664 case F_GETFL:
1665 return socket->flags;
1666 case F_SETFL:
1667 socket->flags = (unsigned int)arg;
1668 return 0;
1669 }
1670
[331]1671 return -EINVAL;
1672}
1673
[441]1674bool_t tcp_fd_readable(struct SHELL_FILE *fp)
[279]1675{
1676 ER ret;
[441]1677
1678 socket_t *socket = (socket_t *)fp->exinf;
1679 if (socket->cepid != 0) {
1680 if (socket->len == 0) {
1681 ret = tcp_rcv_buf(socket->cepid, &socket->input, TMO_NBLK);
1682 if ((ret != E_WBLK) && (ret != E_OBJ) && (ret < 0)) {
1683 syslog(LOG_ERROR, "tcp_rcv_buf => %d", ret);
1684 //return ret;
1685 }
1686 if (ret > 0) {
1687 ret = wai_sem(SEM_FILEDESC);
1688 if (ret < 0) {
1689 syslog(LOG_ERROR, "wai_sem => %d", ret);
1690 }
1691 socket->len += ret;
1692 ret = sig_sem(SEM_FILEDESC);
1693 if (ret < 0) {
1694 syslog(LOG_ERROR, "sig_sem => %d", ret);
1695 }
1696 }
1697 }
1698 else ret = 1;
1699 if (ret > 0) {
1700 return true;
1701 }
1702 }
1703
1704 return false;
1705}
1706
1707bool_t tcp_fd_writable(struct SHELL_FILE *fp)
1708{
1709 //socket_t *socket = (socket_t *)fp->exinf;
1710
1711 return /*fp->writable &&*/ (fp->writeevt_w == fp->writeevt_r);
1712}
1713
1714void tcp_fd_delete(struct SHELL_FILE *fp)
1715{
1716 socket_t *socket = (socket_t *)fp->exinf;
1717 free(socket->buf);
1718 socket->buf = NULL;
1719 free(fp->exinf);
1720 fp->exinf = NULL;
1721}
1722
1723ER socket_tcp_callback(ID cepid, FN fncd, void *p_parblk)
1724{
1725 struct SHELL_FILE *fp = id_to_fd(&IO_TYPE_TCP, cepid);
1726 FLGPTN flgptn = 0;
1727 ER ret;
1728 int len;
1729
1730 if (fp == NULL)
1731 return E_PAR;
1732
1733 socket_t *socket = (socket_t *)fp->exinf;
1734 int fd = fp->fd;
1735 FD_SET(fd, (fd_set *)&flgptn);
1736
1737 switch (fncd) {
1738 case TFN_TCP_RCV_BUF:
1739 len = *(int *)p_parblk;
1740 if ((len <= 0) || (fp->exinf == NULL))
1741 return E_OK;
1742
1743 ret = wai_sem(SEM_FILEDESC);
1744 if (ret < 0) {
1745 syslog(LOG_ERROR, "wai_sem => %d", ret);
1746 }
1747 socket->len += len;
1748 ret = sig_sem(SEM_FILEDESC);
1749 if (ret < 0) {
1750 syslog(LOG_ERROR, "sig_sem => %d", ret);
1751 }
1752
1753 if (fp->readevt_w == fp->readevt_r) fp->readevt_w++;
1754
1755 set_flg(FLG_SELECT_WAIT, flgptn);
1756 return E_OK;
1757
1758 case TFN_TCP_RCV_DAT:
1759 len = *(int *)p_parblk;
1760 if ((len <= 0) || (fp->exinf == NULL))
1761 return E_OK;
1762
1763 ret = wai_sem(SEM_FILEDESC);
1764 if (ret < 0) {
1765 syslog(LOG_ERROR, "wai_sem => %d", ret);
1766 }
1767 socket->len += len;
1768 ret = sig_sem(SEM_FILEDESC);
1769 if (ret < 0) {
1770 syslog(LOG_ERROR, "sig_sem => %d", ret);
1771 }
1772
1773 if (fp->readevt_w == fp->readevt_r) fp->readevt_w++;
1774
1775 set_flg(FLG_SELECT_WAIT, flgptn);
1776 return E_OK;
1777
1778 case TFN_TCP_SND_DAT:
1779 if (fp->writeevt_w == fp->writeevt_r) fp->writeevt_w++;
1780
1781 set_flg(FLG_SELECT_WAIT, flgptn);
1782 return E_OK;
1783
1784 case TFN_TCP_CAN_CEP:
1785 if (fp->errorevt_w == fp->errorevt_r) fp->errorevt_w++;
1786
1787 set_flg(FLG_SELECT_WAIT, flgptn);
1788 return E_OK;
1789
1790 case TFN_TCP_DEL_REP:
1791 delete_fd_by_id(&IO_TYPE_TCP, tmax_tcp_cepid + cepid);
1792 return E_OK;
1793
1794 case TFN_TCP_DEL_CEP:
1795 delete_fd_by_id(&IO_TYPE_TCP, cepid);
1796 return E_OK;
1797
1798 default:
1799 return E_OK;
1800 }
1801}
1802
1803ER socket_tcp6_callback(ID cepid, FN fncd, void *p_parblk)
1804{
1805 struct SHELL_FILE *fp = id_to_fd(&IO_TYPE_TCP, cepid);
1806 FLGPTN flgptn = 0;
1807 ER ret;
1808 int len;
1809
1810 if (fp == NULL)
1811 return E_PAR;
1812
1813 socket_t *socket = (socket_t *)fp->exinf;
1814 int fd = fp->fd;
1815 FD_SET(fd, (fd_set *)&flgptn);
1816
1817 switch (fncd) {
1818 case TFN_TCP_RCV_BUF:
1819 len = *(int *)p_parblk;
1820 if ((len <= 0) || (fp->exinf == NULL))
1821 return E_OK;
1822
1823 ret = wai_sem(SEM_FILEDESC);
1824 if (ret < 0) {
1825 syslog(LOG_ERROR, "wai_sem => %d", ret);
1826 }
1827 socket->len += len;
1828 ret = sig_sem(SEM_FILEDESC);
1829 if (ret < 0) {
1830 syslog(LOG_ERROR, "sig_sem => %d", ret);
1831 }
1832
1833 if (fp->readevt_w == fp->readevt_r) fp->readevt_w++;
1834
1835 set_flg(FLG_SELECT_WAIT, flgptn);
1836 return E_OK;
1837
1838 case TFN_TCP_RCV_DAT:
1839 len = *(int *)p_parblk;
1840 if ((len <= 0) || (fp->exinf == NULL))
1841 return E_OK;
1842
1843 ret = wai_sem(SEM_FILEDESC);
1844 if (ret < 0) {
1845 syslog(LOG_ERROR, "wai_sem => %d", ret);
1846 }
1847 socket->len += len;
1848 ret = sig_sem(SEM_FILEDESC);
1849 if (ret < 0) {
1850 syslog(LOG_ERROR, "sig_sem => %d", ret);
1851 }
1852
1853 if (fp->readevt_w == fp->readevt_r) fp->readevt_w++;
1854
1855 set_flg(FLG_SELECT_WAIT, flgptn);
1856 return E_OK;
1857
1858 case TFN_TCP_SND_DAT:
1859 if (fp->writeevt_w == fp->writeevt_r) fp->writeevt_w++;
1860
1861 set_flg(FLG_SELECT_WAIT, flgptn);
1862 return E_OK;
1863
1864 case TFN_TCP_CAN_CEP:
1865 if (fp->errorevt_w == fp->errorevt_r) fp->errorevt_w++;
1866
1867 set_flg(FLG_SELECT_WAIT, flgptn);
1868 return E_OK;
1869
1870 case TFN_TCP_DEL_REP:
1871 delete_fd_by_id(&IO_TYPE_TCP, tmax_tcp_cepid + cepid);
1872 return E_OK;
1873
1874 case TFN_TCP_DEL_CEP:
1875 delete_fd_by_id(&IO_TYPE_TCP, cepid);
1876 return E_OK;
1877
1878 default:
1879 return E_OK;
1880 }
1881}
1882
1883int udp_fd_close(struct SHELL_FILE *fp)
1884{
1885 ER ret;
[279]1886 ID cepid;
[441]1887
1888 socket_t *socket = (socket_t *)fp->exinf;
1889 switch (socket->family) {
[279]1890 case AF_INET: {
[441]1891 cepid = socket->cepid;
1892 ret = udp_can_cep(cepid, TFN_UDP_ALL);
1893 if ((ret < 0) && (ret != E_OBJ)) {
1894 syslog(LOG_ERROR, "udp_can_cep => %d", ret);
1895 }
[279]1896 ret = udp_del_cep(cepid);
[441]1897 if (ret < 0) {
1898 syslog(LOG_ERROR, "udp_del_cep => %d", ret);
1899 }
1900 //delete_fd_by_id(&IO_TYPE_UDP, cepid);
[279]1901 delete_id(udp_cepid_table, udp_cepid_table_count, cepid);
1902 if (ret < 0) {
[331]1903 return -EINVAL;
[279]1904 }
1905 break;
1906 }
1907 case AF_INET6: {
[441]1908 cepid = socket->cepid;
1909 ret = udp6_can_cep(cepid, TFN_UDP_ALL);
1910 if ((ret < 0) && (ret != E_OBJ)) {
1911 syslog(LOG_ERROR, "udp6_can_cep => %d", ret);
1912 }
1913 ret = udp6_del_cep(cepid);
1914 if (ret < 0) {
1915 syslog(LOG_ERROR, "udp6_del_cep => %d", ret);
1916 }
1917 //delete_fd_by_id(&IO_TYPE_UDP, cepid);
1918 delete_id(udp6_cepid_table, udp6_cepid_table_count, cepid);
1919 if (ret < 0) {
1920 return -EINVAL;
1921 }
1922 break;
[279]1923 }
[441]1924 default:
1925 return -ENOPROTOOPT;
[279]1926 }
1927
1928 return 0;
1929}
1930
[441]1931size_t udp_fd_read(struct SHELL_FILE *fp, unsigned char *dst, size_t dstsz)
[279]1932{
[441]1933 return shell_recvfrom(fp->fd, dst, dstsz, 0, NULL, NULL);
[279]1934}
1935
[441]1936size_t udp_fd_write(struct SHELL_FILE *fp, const unsigned char *src, size_t srcsz)
[279]1937{
[441]1938 return shell_sendto(fp->fd, src, srcsz, 0, NULL, 0);
[279]1939}
1940
[441]1941off_t udp_fd_seek(struct SHELL_FILE *fp, off_t ofs, int org)
[279]1942{
[331]1943 return -EPERM;
[279]1944}
1945
[441]1946int udp_fd_ioctl(struct SHELL_FILE *fp, int req, void *arg)
[331]1947{
1948 return -EINVAL;
1949}
1950
[441]1951bool_t udp_fd_readable(struct SHELL_FILE *fp)
1952{
1953 socket_t *socket = (socket_t *)fp->exinf;
1954 if (socket->cepid != 0) {
1955 if (socket->input != NULL) {
1956 return true;
1957 }
1958 }
1959
1960 return false;
1961}
1962
1963bool_t udp_fd_writable(struct SHELL_FILE *fp)
1964{
1965 //socket_t *socket = (socket_t *)fp->exinf;
1966
1967 return fp->writable && (fp->writeevt_w == fp->writeevt_r);
1968}
1969
1970void udp_fd_delete(struct SHELL_FILE *fp)
1971{
1972 //socket_t *socket = (socket_t *)fp->exinf;
1973 //free(socket->buf);
1974 //socket->buf = NULL;
1975 free(fp->exinf);
1976 fp->exinf = NULL;
1977}
1978
1979ER socket_udp_callback(ID cepid, FN fncd, void *p_parblk)
1980{
1981 struct SHELL_FILE *fp = id_to_fd(&IO_TYPE_UDP, cepid);
1982 FLGPTN flgptn = 0;
1983 int len;
1984
1985 if (fp == NULL)
1986 return E_PAR;
1987
1988 int fd = fp->fd;
1989 FD_SET(fd, (fd_set *)&flgptn);
1990
1991 switch (fncd) {
1992 case TEV_UDP_RCV_DAT:
1993 {
1994 T_UDP_RCV_DAT_PARA *udppara = (T_UDP_RCV_DAT_PARA *)p_parblk;
1995 len = udppara->len;
1996 if ((len <= 0) || (fp->exinf == NULL))
1997 return E_OK;
1998
1999 ER ret = wai_sem(SEM_FILEDESC);
2000 if (ret < 0) {
2001 syslog(LOG_ERROR, "wai_sem => %d", ret);
2002 }
2003 socket_t *socket = (socket_t *)fp->exinf;
2004 socket->len = len;
2005 if (socket->input != NULL) {
2006 ret = rel_net_buf(socket->input);
2007 if (ret < 0) {
2008 syslog(LOG_ERROR, "rel_net_buf => %d", ret);
2009 }
2010 }
2011 socket->input = udppara->input;
2012 socket->buf = GET_UDP_SDU(udppara->input, udppara->off);
2013 memset(&socket->raddr4, 0, sizeof(struct sockaddr_in));
2014 socket->raddr4.sin_family = AF_INET;
2015 socket->raddr4.sin_port = htons(udppara->rep4.portno);
2016 socket->raddr4.sin_addr.s_addr = htonl(udppara->rep4.ipaddr);
2017 udppara->input->flags |= NB_FLG_NOREL_IFOUT;
2018 ret = sig_sem(SEM_FILEDESC);
2019 if (ret < 0) {
2020 syslog(LOG_ERROR, "sig_sem => %d", ret);
2021 }
2022
2023 if (fp->readevt_w == fp->readevt_r) fp->readevt_w++;
2024
2025 set_flg(FLG_SELECT_WAIT, flgptn);
2026 return E_OK;
2027 }
2028 case TFN_UDP_CRE_CEP:
2029 return E_OK;
2030
2031 case TFN_UDP_RCV_DAT:
2032 len = *(int *)p_parblk;
2033 if ((len <= 0) || (fp->exinf == NULL))
2034 return E_OK;
2035
2036 if (fp->readevt_w == fp->readevt_r) fp->readevt_w++;
2037
2038 set_flg(FLG_SELECT_WAIT, flgptn);
2039 return E_OK;
2040
2041 case TFN_UDP_SND_DAT:
2042 if (fp->writeevt_w == fp->writeevt_r) fp->writeevt_w++;
2043
2044 set_flg(FLG_SELECT_WAIT, flgptn);
2045 return E_OK;
2046
2047 case TFN_UDP_CAN_CEP:
2048 if (fp->errorevt_w == fp->errorevt_r) fp->errorevt_w++;
2049
2050 set_flg(FLG_SELECT_WAIT, flgptn);
2051 return E_OK;
2052
2053 case TFN_UDP_DEL_CEP:
2054 delete_fd_by_id(&IO_TYPE_UDP, cepid);
2055 return E_OK;
2056
2057 default:
2058 return E_OK;
2059 }
2060}
2061
2062ER socket_udp6_callback(ID cepid, FN fncd, void *p_parblk)
2063{
2064 struct SHELL_FILE *fp = id_to_fd(&IO_TYPE_UDP, cepid);
2065 FLGPTN flgptn = 0;
2066 int len;
2067
2068 if (fp == NULL)
2069 return E_PAR;
2070
2071 int fd = fp->fd;
2072 FD_SET(fd, (fd_set *)&flgptn);
2073
2074 switch (fncd) {
2075 case TEV_UDP_RCV_DAT:
2076 {
2077 T_UDP_RCV_DAT_PARA *udppara = (T_UDP_RCV_DAT_PARA *)p_parblk;
2078 len = udppara->len;
2079 if ((len <= 0) || (fp->exinf == NULL))
2080 return E_OK;
2081
2082 ER ret = wai_sem(SEM_FILEDESC);
2083 if (ret < 0) {
2084 syslog(LOG_ERROR, "wai_sem => %d", ret);
2085 }
2086 socket_t *socket = (socket_t *)fp->exinf;
2087 socket->len = len;
2088 if (socket->input != NULL) {
2089 ret = rel_net_buf(socket->input);
2090 if (ret < 0) {
2091 syslog(LOG_ERROR, "rel_net_buf => %d", ret);
2092 }
2093 }
2094 socket->input = udppara->input;
2095 socket->buf = GET_UDP_SDU(udppara->input, udppara->off);
2096 memset(&socket->raddr6, 0, sizeof(struct sockaddr_in6));
2097 socket->raddr6.sin6_family = AF_INET;
2098 socket->raddr6.sin6_port = htons(udppara->rep6.portno);
2099 addrcpy(&socket->raddr6.sin6_addr, &udppara->rep6.ipaddr, 16);
2100 udppara->input->flags |= NB_FLG_NOREL_IFOUT;
2101 ret = sig_sem(SEM_FILEDESC);
2102 if (ret < 0) {
2103 syslog(LOG_ERROR, "sig_sem => %d", ret);
2104 }
2105
2106 if (fp->readevt_w == fp->readevt_r) fp->readevt_w++;
2107
2108 set_flg(FLG_SELECT_WAIT, flgptn);
2109 return E_OK;
2110 }
2111 case TFN_UDP_CRE_CEP:
2112 return E_OK;
2113
2114 case TFN_UDP_RCV_DAT:
2115 len = *(int *)p_parblk;
2116 if ((len <= 0) || (fp->exinf == NULL))
2117 return E_OK;
2118
2119 if (fp->readevt_w == fp->readevt_r) fp->readevt_w++;
2120
2121 set_flg(FLG_SELECT_WAIT, flgptn);
2122 return E_OK;
2123
2124 case TFN_UDP_SND_DAT:
2125 if (fp->writeevt_w == fp->writeevt_r) fp->writeevt_w++;
2126
2127 set_flg(FLG_SELECT_WAIT, flgptn);
2128 return E_OK;
2129
2130 case TFN_UDP_CAN_CEP:
2131 if (fp->errorevt_w == fp->errorevt_r) fp->errorevt_w++;
2132
2133 set_flg(FLG_SELECT_WAIT, flgptn);
2134 return E_OK;
2135
2136 case TFN_UDP_DEL_CEP:
2137 delete_fd_by_id(&IO_TYPE_UDP, cepid);
2138 return E_OK;
2139
2140 default:
2141 return E_OK;
2142 }
2143}
2144
[279]2145#ifndef TCP_CFG_EXTENTIONS
2146ER tcp_cre_rep(ID repid, T_TCP_CREP *pk_crep)
2147{
2148 syslog(LOG_ERROR, "tcp_cre_rep not implement");
2149 shell_abort();
2150 return E_SYS;
2151}
2152
2153ER tcp_cre_cep(ID cepid, T_TCP_CCEP *pk_ccep)
2154{
2155 syslog(LOG_ERROR, "tcp_cre_cep not implement");
2156 shell_abort();
2157 return E_SYS;
2158}
2159#endif
2160
2161#ifndef UDP_CFG_EXTENTIONS
2162ER udp_cre_cep(ID cepid, T_UDP_CCEP *pk_ccep)
2163{
2164 syslog(LOG_ERROR, "udp_cre_cep not implement");
2165 shell_abort();
2166 return E_SYS;
2167}
2168#endif
2169
2170#ifndef TCP_CFG_EXTENTIONS
2171ER_UINT tcp_snd_oob(ID cepid, void *data, int_t len, TMO tmout)
2172{
2173 syslog(LOG_ERROR, "tcp_snd_oob not implement");
2174 shell_abort();
2175 return E_SYS;
2176}
2177
2178ER_UINT tcp_rcv_oob(ID cepid, void *data, int_t len)
2179{
2180 syslog(LOG_ERROR, "tcp_rcv_oob not implement");
2181 shell_abort();
2182 return E_SYS;
2183}
2184
2185ER tcp_set_opt(ID cepid, int_t optname, void *optval, int_t optlen)
2186{
2187 syslog(LOG_ERROR, "tcp_set_opt not implement");
2188 shell_abort();
2189 return E_SYS;
2190}
2191
2192ER tcp_get_opt(ID cepid, int_t optname, void *optval, int_t optlen)
2193{
2194 syslog(LOG_ERROR, "tcp_get_opt not implement");
2195 shell_abort();
2196 return E_SYS;
2197}
2198#endif
2199
2200#ifndef UDP_CFG_EXTENTIONS
2201ER udp_get_opt(ID cepid, int_t optname, void *optval, int_t optlen)
2202{
2203 syslog(LOG_ERROR, "udp_get_opt not implement");
2204 shell_abort();
2205 return E_SYS;
2206}
2207
2208ER udp_set_opt(ID cepid, int_t optname, void *optval, int_t optlen)
2209{
2210 syslog(LOG_ERROR, "udp_set_opt not implement");
2211 shell_abort();
2212 return E_SYS;
2213}
2214#endif
[441]2215
2216// musl-1.1.18/network/lookup.h
2217struct address {
2218 int family;
2219 unsigned scopeid;
2220 uint8_t addr[16];
2221 int sortkey;
2222};
2223
2224#define MAXNS 3
2225
2226struct resolvconf {
2227 struct address ns[MAXNS];
2228 unsigned nns, attempts, ndots;
2229 unsigned timeout;
2230};
2231
2232// musl-1.1.18/network/resolvconf.c
2233int __get_resolv_conf(struct resolvconf *conf, char *search, size_t search_sz)
2234{
2235 int nns = 0;
2236
2237 conf->ndots = 1;
2238 conf->timeout = 5;
2239 conf->attempts = 2;
2240 if (search) *search = 0;
2241
2242#if defined(SUPPORT_INET4)
2243 T_IN4_ADDR in4_addr;
2244 conf->ns[nns].family = AF_INET;
2245 conf->ns[nns].scopeid = 0;
2246 dns_in4_get_addr(&in4_addr);
2247 *(uint32_t *)conf->ns[nns].addr = ntohl(in4_addr);
2248 nns++;
2249#endif
2250
2251#if defined(SUPPORT_INET6)
2252 conf->ns[nns].family = AF_INET6;
2253 conf->ns[nns].scopeid = 0;
2254 dns_in6_get_addr((T_IN6_ADDR *)conf->ns[nns].addr);
2255 nns++;
2256#endif
2257 conf->nns = nns;
2258
2259 return 0;
2260}
Note: See TracBrowser for help on using the repository browser.