source: asp3_tinet_ecnl_rx/trunk/ntshell/src/socket_stub.c@ 387

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

ファイルディスクリプタ処理を更新

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