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

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

NTShellタスクを更新

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