source: azure_iot_hub/trunk/ntshell/src/socket_stub.c@ 388

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

Azure IoT Hub Device C SDK を使ったサンプルの追加

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