source: asp3_tinet_ecnl_arm/trunk/ntshell/src/socket_stub.c@ 400

Last change on this file since 400 was 400, checked in by coas-nagasima, 3 years ago

ファイルヘッダーの更新

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