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

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

prototoolに関連するプロジェクトをnewlibからmuslを使うよう変更・更新
ntshellをnewlibの下位の実装から、muslのsyscallの実装に変更・更新
以下のOSSをアップデート
・mruby-1.3.0
・musl-1.1.18
・onigmo-6.1.3
・tcc-0.9.27
以下のOSSを追加
・openssl-1.1.0e
・curl-7.57.0
・zlib-1.2.11
以下のmrbgemsを追加
・iij/mruby-digest
・iij/mruby-env
・iij/mruby-errno
・iij/mruby-iijson
・iij/mruby-ipaddr
・iij/mruby-mock
・iij/mruby-require
・iij/mruby-tls-openssl

  • Property svn:eol-style set to native
  • Property svn:mime-type set to text/x-csrc;charset=UTF-8
File size: 19.6 KB
RevLine 
[286]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 */
[331]37#include "shellif.h"
[279]38#include <kernel.h>
39#include <t_syslog.h>
40#include <t_stdlib.h>
[331]41#include <string.h>
[279]42#include <sil.h>
43#include <setjmp.h>
44#include "syssvc/syslog.h"
45#include <tinet_config.h>
46#include <netinet/in.h>
47#include <netinet/in_itron.h>
48#include <tinet_nic_defs.h>
49#include <tinet_cfg.h>
50#include <netinet/in_var.h>
51#include <net/ethernet.h>
52#include <net/if6_var.h>
53#include <net/net.h>
54#include <net/if_var.h>
55#include <netinet/udp_var.h>
56//#include <netinet/tcp_var.h>
57extern const ID tmax_tcp_cepid;
58#include "ff.h"
59#include "socket_stub.h"
60
[331]61#define SOCKET_TIMEOUT 2000000
62
[279]63typedef struct id_table_t {
64 int used;
65 ID id;
66} id_table_t;
67
68id_table_t tcp_repid_table[] = {
69 {0, USR_TCP_REP1}, {0, USR_TCP_REP2}, {0, USR_TCP_REP3}, {0, USR_TCP_REP4}
70};
71#define tcp_repid_table_count (sizeof(tcp_repid_table) / sizeof(tcp_repid_table[0]))
72
73id_table_t tcp_cepid_table[] = {
74 {0, USR_TCP_CEP1}, {0, USR_TCP_CEP2}, {0, USR_TCP_CEP3}, {0, USR_TCP_CEP4}, {0, USR_TCP_CEP5}, {0, USR_TCP_CEP6}, {0, USR_TCP_CEP7}, {0, USR_TCP_CEP8}
75};
76#define tcp_cepid_table_count (sizeof(tcp_cepid_table) / sizeof(tcp_cepid_table[0]))
77
78id_table_t udp_cepid_table[] = {
79 {0, USR_UDP_CEP1}, {0, USR_UDP_CEP2}, {0, USR_UDP_CEP3}, {0, USR_UDP_CEP4}
80};
81#define udp_cepid_table_count (sizeof(udp_cepid_table) / sizeof(udp_cepid_table[0]))
82
83ID new_id(id_table_t *table, int count)
84{
85 for (int i = 0; i < count; i++) {
86 id_table_t *item = &table[i];
87 if (item->used != 0)
88 continue;
89
90 item->used = 1;
91 return item->id;
92}
93
[331]94 return -ENOMEM;
[279]95}
96
97int delete_id(id_table_t *table, int count, ID id)
98{
99 for (int i = 0; i < count; i++) {
100 id_table_t *item = &table[i];
101 if ((item->used == 0) || (item->id != id))
102 continue;
103
104 item->used = 0;
105 return 0;
106 }
[331]107 return -EINVAL;
[279]108}
109
110int delete_tcp_rep(int repid)
111{
[331]112 return delete_tcp_fd(tmax_tcp_cepid + repid);
[279]113}
114
115unsigned char tcp_buf[tcp_cepid_table_count][2 * 512];
116
117unsigned char *id_to_buff(ID id)
118{
119 for (int i = 0; i < tcp_cepid_table_count; i++) {
120 id_table_t *item = &tcp_cepid_table[i];
121 if ((item->used == 0) || (item->id != id))
122 continue;
123
124 return tcp_buf[i];
125 }
126
127 return NULL;
128}
129
130typedef struct _IO_FILE SOCKET;
131
[331]132int shell_socket(int family, int type, int protocol)
[279]133{
134 SOCKET *fp;
[331]135 unsigned int flags;
[279]136
137 switch (family) {
138 case AF_INET:
139 case AF_INET6:
140 break;
141 default:
[331]142 return -EAFNOSUPPORT;
[279]143 }
144
[331]145 flags = type & (SOCK_CLOEXEC|SOCK_NONBLOCK);
146 type &= ~flags;
147
[279]148 switch (type) {
149 case SOCK_STREAM:
150 fp = new_tcp_fd(0);
151 break;
152 case SOCK_DGRAM:
153 fp = new_udp_fd(0);
154 break;
155 default:
[331]156 return -ENOPROTOOPT;
[279]157 }
158
159 if (fp == NULL) {
[331]160 return -ENOMEM;
[279]161 }
162
163 fp->socket.family = family;
164 fp->socket.type = type;
165 fp->socket.protocol = protocol;
[331]166 fp->socket.flags = flags;
[279]167
168 return fp->fd;
169}
170
[331]171int shell_bind(int fd, const struct sockaddr *addr, socklen_t len)
[279]172{
173 SOCKET *fp = fd_to_fp(fd);
[331]174 if (fp == NULL)
175 return -EBADF;
176 if (fp->socket.family != addr->sa_family)
177 return -EINVAL;
[279]178
179 ER ret;
180 switch (addr->sa_family) {
181 case AF_INET: {
182 if (len < 8) {
[331]183 return -EINVAL;
[279]184 }
185 struct sockaddr_in *addr_in = (struct sockaddr_in *)addr;
186 memcpy(&fp->socket.laddr4, addr, len);
187 switch (fp->socket.type) {
188 case SOCK_STREAM: {
189 ID cepid = new_id(tcp_cepid_table, tcp_cepid_table_count);
190 if (cepid < 0)
[331]191 return -ENOMEM;
[279]192
193 fp->socket.buf_size = 512 + 512;
194 fp->socket.buf = id_to_buff(cepid);
[331]195 T_TCP_CCEP ccep = { 0, fp->socket.buf, 512, &fp->socket.buf[512], 512, (FP)socket_tcp_callback };
[279]196 ret = tcp_cre_cep(cepid, &ccep);
197 if (ret != E_OK) {
198 delete_id(tcp_cepid_table, tcp_cepid_table_count, cepid);
[331]199 return -ENOMEM;
[279]200 }
201 fp->handle = cepid;
202 fp->socket.cepid = cepid;
203 break;
204 }
205 case SOCK_DGRAM: {
206 ID cepid = new_id(udp_cepid_table, udp_cepid_table_count);
207 if (cepid < 0)
[331]208 return -ENOMEM;
[279]209
[331]210 T_UDP_CCEP ccep = { 0, {ntohl(addr_in->sin_addr.s_addr), ntohs(addr_in->sin_port)}, (FP)socket_udp_callback };
[279]211 ret = udp_cre_cep(cepid, &ccep);
212 if (ret != E_OK) {
213 delete_id(udp_cepid_table, udp_cepid_table_count, cepid);
[331]214 return -ENOMEM;
[279]215 }
216 fp->handle = cepid;
217 fp->socket.cepid = cepid;
218 break;
219 }
220 default:
[331]221 return -ENOPROTOOPT;
[279]222 }
223 break;
224 }
225 case AF_INET6: {
226 if (len < 20) {
[331]227 return -EINVAL;
[279]228 }
229 memcpy(&fp->socket.laddr4, addr, len);
230 break;
231 }
232 }
233
234 return 0;
235}
236
[331]237int shell_listen(int fd, int backlog)
[279]238{
239 SOCKET *fp = fd_to_fp(fd);
[331]240 if (fp == NULL)
241 return -EBADF;
242 if (fp->socket.type != SOCK_STREAM)
243 return -EINVAL;
[279]244
245 fp->socket.backlog = backlog;
246
247 ER ret;
248 switch (fp->socket.family) {
249 case AF_INET: {
250 ID repid = new_id(tcp_repid_table, tcp_repid_table_count);
251 if (repid < 0)
[331]252 return -ENOMEM;
[279]253
254 struct sockaddr_in *laddr = &fp->socket.laddr4;
255 T_TCP_CREP crep = { 0, {ntohl(laddr->sin_addr.s_addr), ntohs(laddr->sin_port)} };
256 ret = tcp_cre_rep(repid, &crep);
257 if (ret != E_OK) {
258 delete_id(tcp_repid_table, tcp_repid_table_count, repid);
[331]259 return -ENOMEM;
[279]260 }
261 fp->socket.repid = repid;
262 break;
263 }
264 case AF_INET6: {
265 break;
266 }
267 }
268
269 return 0;
270}
271
[331]272int shell_connect(int fd, const struct sockaddr *addr, socklen_t len)
[279]273{
274 SOCKET *fp = fd_to_fp(fd);
[331]275 if (fp == NULL)
276 return -EBADF;
277 if (fp->socket.type != SOCK_STREAM)
278 return -EINVAL;
[279]279
280 ER ret;
281 switch (fp->socket.family) {
282 case AF_INET: {
283 if (len < 8) {
[331]284 return -EINVAL;
[279]285 }
286 if (fp->socket.cepid == 0) {
287 ID cepid = new_id(tcp_cepid_table, tcp_cepid_table_count);
288 if (cepid < 0)
[331]289 return -ENOMEM;
[279]290
291 fp->socket.buf_size = 512 + 512;
292 fp->socket.buf = id_to_buff(cepid);
[331]293 T_TCP_CCEP ccep = { 0, fp->socket.buf, 512, &fp->socket.buf[512], 512, (FP)socket_tcp_callback };
[279]294 ret = tcp_cre_cep(cepid, &ccep);
295 if (ret != E_OK) {
296 delete_id(tcp_cepid_table, tcp_cepid_table_count, cepid);
[331]297 return -ENOMEM;
[279]298 }
299 fp->handle = cepid;
300 fp->socket.cepid = cepid;
301 }
302 struct sockaddr_in *laddr = &fp->socket.laddr4;
303 struct sockaddr_in *raddr = &fp->socket.raddr4;
304 memset(raddr, 0, sizeof(*raddr));
305 memcpy(raddr, addr, len);
306 T_IPV4EP lep = { ntohl(laddr->sin_addr.s_addr), ntohs(laddr->sin_port) };
307 T_IPV4EP rep = { ntohl(raddr->sin_addr.s_addr), ntohs(raddr->sin_port) };
[331]308 ret = tcp_con_cep(fp->socket.cepid, &lep, &rep, SOCKET_TIMEOUT);
[279]309 if (ret < 0) {
[331]310 return -EHOSTUNREACH;
[279]311 }
312 break;
313 }
314 case AF_INET6: {
315 break;
316 }
317 }
318
319 return 0;
320}
321
[331]322int shell_accept(int fd, struct sockaddr *__restrict addr, socklen_t *__restrict len)
[279]323{
324 SOCKET *lfp = fd_to_fp(fd);
[331]325 if (lfp == NULL)
326 return -EBADF;
327 if (lfp->socket.type != SOCK_STREAM)
328 return -EINVAL;
[279]329
330 SOCKET *fp = new_tcp_fd(0);
331 if (fp == NULL) {
[331]332 return -ENOMEM;
[279]333 }
334
335 memcpy(&fp->socket, &lfp->socket, sizeof(fp->socket));
336
337 ER ret;
338 switch (fp->socket.family) {
339 case AF_INET: {
340 ID cepid;
341 if (fp->socket.cepid == 0) {
342 cepid = new_id(tcp_cepid_table, tcp_cepid_table_count);
343 if (cepid < 0)
[331]344 return -ENOMEM;
[279]345
346 fp->socket.buf_size = 512 + 512;
347 fp->socket.buf = id_to_buff(cepid);
[331]348 T_TCP_CCEP ccep = { 0, fp->socket.buf, 512, &fp->socket.buf[512], 512, (FP)socket_tcp_callback };
[279]349 ret = tcp_cre_cep(cepid, &ccep);
350 if (ret != E_OK) {
351 delete_id(tcp_cepid_table, tcp_cepid_table_count, cepid);
[331]352 return -ENOMEM;
[279]353 }
354 fp->handle = cepid;
355 fp->socket.cepid = cepid;
356 }
357 else {
358 cepid = lfp->socket.cepid;
359 lfp->handle = tmax_tcp_cepid + lfp->socket.repid;
360 lfp->socket.cepid = 0;
361 lfp->socket.buf_size = 0;
362 lfp->socket.buf = 0;
363 }
364 T_IPV4EP rep = { 0, 0 };
365 ret = tcp_acp_cep(fp->socket.cepid, fp->socket.repid, &rep, TMO_FEVR);
366 if (ret < 0) {
[331]367 return -ENOMEM;
[279]368 }
369 struct sockaddr_in *raddr = &fp->socket.raddr4;
370 memset(raddr, 0, sizeof(*raddr));
371 raddr->sin_family = AF_INET;
372 raddr->sin_port = htons(rep.portno);
373 raddr->sin_addr.s_addr = htonl(rep.ipaddr);
374 break;
375 }
376 case AF_INET6: {
[331]377 return -EAFNOSUPPORT;
[279]378 }
379 }
380
381 if (addr != NULL && len != NULL) {
382 int sz = *len;
383 if (sz < 8) {
[331]384 return -EINVAL;
[279]385 }
386 struct sockaddr_in *raddr = &fp->socket.raddr4;
387 if (sz > sizeof(*raddr))
388 sz = sizeof(*raddr);
389 memcpy(addr, raddr, sz);
390 *len = sizeof(*raddr);
391 }
392
393 return fp->fd;
394}
395
[331]396ssize_t shell_send(int fd, const void *buf, size_t len, int flags)
[279]397{
398 SOCKET *fp = fd_to_fp(fd);
399 if (fp == NULL) {
[331]400 return -EBADF;
[279]401 }
402
403 int ret = 0;
404 switch (fp->socket.family) {
405 case AF_INET: {
406 switch (fp->socket.type) {
407 case SOCK_STREAM: {
408 if (flags & MSG_OOB) {
[331]409 ret = tcp_snd_oob(fp->socket.cepid, (void *)buf, len, SOCKET_TIMEOUT);
[279]410 if (ret < 0) {
[331]411 return -ECOMM;
[279]412 }
413 }
414 else {
[331]415 ret = tcp_snd_dat(fp->socket.cepid, (void *)buf, len, SOCKET_TIMEOUT);
[279]416 if (ret < 0) {
[331]417 return -ECOMM;
[279]418 }
419 }
420 break;
421 }
422 case SOCK_DGRAM: {
[331]423 return -EINVAL;
[279]424 }
425 }
426 break;
427 }
428 case AF_INET6: {
[331]429 return -EAFNOSUPPORT;
[279]430 }
431 }
432
433 return ret;
434}
435
[331]436ssize_t shell_sendto(int fd, const void *buf, size_t len, int flags, const struct sockaddr *addr, socklen_t alen)
[279]437{
438 SOCKET *fp = fd_to_fp(fd);
439 if (fp == NULL) {
[331]440 return -EBADF;
[279]441 }
442
443 int ret = 0;
444 switch (fp->socket.family) {
445 case AF_INET: {
446 switch (fp->socket.type) {
447 case SOCK_STREAM: {
448 if ((addr != NULL) && (alen != 0)) {
[331]449 return -EINVAL;
[279]450 }
451
452 if (flags & MSG_OOB) {
[331]453 ret = tcp_snd_oob(fp->socket.cepid, (void *)buf, len, SOCKET_TIMEOUT);
[279]454 if (ret < 0) {
[331]455 return -ECOMM;
[279]456 }
457 }
458 else {
[331]459 ret = tcp_snd_dat(fp->socket.cepid, (void *)buf, len, SOCKET_TIMEOUT);
[279]460 if (ret < 0) {
[331]461 return -ECOMM;
[279]462 }
463 }
464 break;
465 }
466 case SOCK_DGRAM: {
467 int sz = alen;
468 if (sz < 8) {
[331]469 return -EINVAL;
[279]470 }
471 struct sockaddr_in *raddr = &fp->socket.raddr4;
472 memset(raddr, 0, sizeof(*raddr));
473 memcpy(raddr, addr, sz);
474 T_IPV4EP rep = { ntohl(raddr->sin_addr.s_addr), ntohs(raddr->sin_port) };
[331]475 ret = udp_snd_dat(fp->socket.cepid, &rep, (void *)buf, len,
476 (fp->socket.flags & O_NONBLOCK) ? 0 : SOCKET_TIMEOUT);
[279]477 if (ret < 0) {
[331]478 return -ECOMM;
[279]479 }
480 break;
481 }
482 }
483 break;
484 }
485 case AF_INET6: {
[331]486 return -EAFNOSUPPORT;
[279]487 }
488 }
489
490 return ret;
491}
492
[331]493ssize_t shell_sendmsg(int fd, const struct msghdr *msg, int flags)
[279]494{
[331]495 no_implement("sendmsg\n");
496 return -ENOSYS;
497}
498
499ssize_t shell_recv(int fd, void *buf, size_t len, int flags)
500{
[279]501 SOCKET *fp = fd_to_fp(fd);
502 if (fp == NULL) {
[331]503 return -EBADF;
[279]504 }
505
506 int ret = 0;
507 switch (fp->socket.family) {
508 case AF_INET: {
509 switch (fp->socket.type) {
510 case SOCK_STREAM: {
511 if (flags & MSG_OOB) {
512 ret = tcp_rcv_oob(fp->socket.cepid, buf, len);
513 if (ret < 0) {
[331]514 return -ECOMM;
[279]515 }
516 }
517 else {
518 ret = tcp_rcv_dat(fp->socket.cepid, buf, len, TMO_FEVR);
519 if (ret < 0) {
[331]520 return -ECOMM;
[279]521 }
522 }
523 break;
524 }
525 case SOCK_DGRAM: {
526 T_IPV4EP rep = { 0, 0 };
[331]527 ret = udp_rcv_dat(fp->socket.cepid, &rep, buf, len, (fp->socket.flags & O_NONBLOCK) ? 0 : TMO_FEVR);
[279]528 if (ret < 0) {
[331]529 return -ECOMM;
[279]530 }
531 }
532 }
533 break;
534 }
535 case AF_INET6: {
[331]536 return -EAFNOSUPPORT;
[279]537 }
538 }
539
540 return ret;
541}
542
[331]543ssize_t shell_recvfrom(int fd, void *buf, size_t len, int flags, struct sockaddr *__restrict addr, socklen_t *__restrict alen)
[279]544{
545 SOCKET *fp = fd_to_fp(fd);
546 if (fp == NULL) {
[331]547 return -EBADF;
[279]548 }
549
550 int ret = 0;
551 switch (fp->socket.family) {
552 case AF_INET: {
553 switch (fp->socket.type) {
554 case SOCK_STREAM: {
555 if (flags & MSG_OOB) {
556 ret = tcp_rcv_oob(fp->socket.cepid, buf, len);
557 if (ret < 0) {
[331]558 return -ECOMM;
[279]559 }
560 }
561 else {
562 ret = tcp_rcv_dat(fp->socket.cepid, buf, len, TMO_FEVR);
563 if (ret < 0) {
[331]564 return -ECOMM;
[279]565 }
566 }
567 break;
568 }
569 case SOCK_DGRAM: {
570 T_IPV4EP rep = { 0, 0 };
571 ret = udp_rcv_dat(fp->socket.cepid, &rep, buf, len, TMO_FEVR);
572 if (ret < 0) {
[331]573 return -ECOMM;
[279]574 }
575 int sz = *alen;
576 struct sockaddr_in raddr;
577 memset(&raddr, 0, sizeof(raddr));
578 raddr.sin_family = AF_INET;
579 raddr.sin_port = htons(rep.portno);
580 raddr.sin_addr.s_addr = htonl(rep.ipaddr);
581 if (sz > sizeof(raddr))
582 sz = sizeof(raddr);
583 memcpy(addr, &raddr, sz);
584 }
585 }
586 break;
587 }
588 case AF_INET6: {
[331]589 return -EAFNOSUPPORT;
[279]590 }
591 }
592
593 return ret;
594}
595
[331]596ssize_t shell_recvmsg(int fd, struct msghdr *msg, int flags)
[279]597{
[331]598 no_implement("recvmsg\n");
599 return -ENOSYS;
600}
601
602int shell_shutdown(int fd, int how)
603{
[279]604 SOCKET *fp = fd_to_fp(fd);
605 if (fp == NULL) {
[331]606 return -EBADF;
[279]607 }
608
609 ER ret;
610 switch (fp->socket.family) {
611 case AF_INET: {
612 switch (fp->socket.type) {
613 case SOCK_STREAM: {
614 ret = tcp_sht_cep(fp->socket.cepid);
615 if (ret < 0) {
[331]616 return -ECOMM;
[279]617 }
618 break;
619 }
620 }
621 break;
622 }
623 case AF_INET6: {
[331]624 return -EAFNOSUPPORT;
[279]625 }
626 }
627
628 return 0;
629}
630
[331]631int shell_getsockopt(int fd, int level, int optname, void *optval, socklen_t *__restrict optlen)
[279]632{
633 SOCKET *fp = fd_to_fp(fd);
634 if (fp == NULL) {
[331]635 return -EBADF;
[279]636 }
637
638 ER ret;
639 switch (fp->socket.family) {
640 case AF_INET: {
641 switch (fp->socket.type) {
642 case SOCK_STREAM: {
643 switch (optname) {
644 case SO_REUSEADDR:
645 if (fp->socket.flags & SO_REUSEADDR) {
646 *(bool *)optval = true;
647 }
648 else {
649 *(bool *)optval = false;
650 }
651 break;
652 default:
653 ret = tcp_get_opt(fp->socket.cepid, optname, (void *)optval, *optlen);
654 if (ret < 0) {
[331]655 return -EINVAL;
[279]656 }
657 *optlen = ret;
658 break;
659 }
660 break;
661 }
662 case SOCK_DGRAM: {
663 ret = udp_get_opt(fp->socket.cepid, optname, (void *)optval, *optlen);
664 if (ret < 0) {
[331]665 return -EINVAL;
[279]666 }
667 *optlen = ret;
668 break;
669 }
670 }
671 break;
672 }
673 case AF_INET6: {
[331]674 return -EAFNOSUPPORT;
[279]675 }
676 }
677
678 return 0;
679}
680
[331]681int shell_setsockopt(int fd, int level, int optname, const void *optval, socklen_t optlen)
[279]682{
683 SOCKET *fp = fd_to_fp(fd);
684 if (fp == NULL) {
[331]685 return -EBADF;
[279]686 }
687
688 ER ret;
689 switch (fp->socket.family) {
690 case AF_INET: {
691 switch (fp->socket.type) {
692 case SOCK_STREAM: {
693 switch (optname) {
694 case SO_REUSEADDR:
695 if (*(bool *)optval) {
696 fp->socket.flags |= SO_REUSEADDR;
697 }
698 else {
699 fp->socket.flags &= ~SO_REUSEADDR;
700 }
701 break;
702 default:
703 ret = tcp_set_opt(fp->socket.cepid, optname, (void *)optval, optlen);
704 if (ret < 0) {
[331]705 return -EINVAL;
[279]706 }
707 break;
708 }
709 break;
710 }
711 case SOCK_DGRAM: {
712 ret = udp_set_opt(fp->socket.cepid, optname, (void *)optval, optlen);
713 if (ret < 0) {
[331]714 return -EINVAL;
[279]715 }
716 break;
717 }
718 }
719 break;
720 }
721 case AF_INET6: {
[331]722 return -EAFNOSUPPORT;
[279]723 }
724 }
725
726 return 0;
727}
728
729int tcp_fd_close(struct _IO_FILE *fp)
730{
731 ER ret;
732 switch (fp->socket.family) {
733 case AF_INET: {
734 if (fp->socket.cepid != 0) {
735 ID cepid = fp->socket.cepid;
736 ret = tcp_sht_cep(cepid);
737 if (ret < 0) {
738 //return -1;
739 }
[331]740 ret = tcp_cls_cep(cepid, (fp->socket.repid != 0) ? 0 : SOCKET_TIMEOUT);
[279]741 if (ret < 0) {
742 //return -1;
743 }
744 ret = tcp_del_cep(cepid);
745 delete_tcp_fd(cepid);
746 delete_id(tcp_cepid_table, tcp_cepid_table_count, cepid);
747 if (ret < 0) {
[331]748 return -EINVAL;
[279]749 }
750 }
751 else if (fp->socket.repid != 0) {
752 ID repid = fp->socket.repid;
753 ret = tcp_del_rep(repid);
754 delete_tcp_fd(tmax_tcp_cepid + repid);
755 delete_id(tcp_repid_table, tcp_repid_table_count, repid);
756 if (ret < 0) {
[331]757 return -EINVAL;
[279]758 }
759 }
760 else {
[331]761 return -EINVAL;
[279]762 }
763 break;
764 }
765 case AF_INET6: {
[331]766 return -EAFNOSUPPORT;
[279]767 }
768 }
769
770 return 0;
771}
772
773size_t tcp_fd_read(struct _IO_FILE *fp, unsigned char *dst, size_t dstsz)
774{
[331]775 return shell_recv(fp->fd, dst, dstsz, 0);
[279]776}
777
778size_t tcp_fd_write(struct _IO_FILE *fp, const unsigned char *src, size_t srcsz)
779{
[331]780 return shell_send(fp->fd, src, srcsz, 0);
[279]781}
782
783off_t tcp_fd_seek(struct _IO_FILE *fp, off_t ofs, int org)
784{
[331]785 return -EPERM;
[279]786}
787
[331]788int tcp_fd_ioctl(struct _IO_FILE *fp, int req, void *arg)
789{
790 return -EINVAL;
791}
792
[279]793int udp_fd_close(struct _IO_FILE *fp)
794{
795 ER ret;
796 ID cepid;
797 switch (fp->socket.family) {
798 case AF_INET: {
799 cepid = fp->socket.cepid;
800 ret = udp_del_cep(cepid);
801 delete_udp_fd(cepid);
802 delete_id(udp_cepid_table, udp_cepid_table_count, cepid);
803 if (ret < 0) {
[331]804 return -EINVAL;
[279]805 }
806 break;
807 }
808 case AF_INET6: {
[331]809 return -EAFNOSUPPORT;
[279]810 }
811 }
812
813 return 0;
814}
815
816size_t udp_fd_read(struct _IO_FILE *fp, unsigned char *dst, size_t dstsz)
817{
[331]818 return shell_recv(fp->fd, dst, dstsz, 0);
[279]819}
820
821size_t udp_fd_write(struct _IO_FILE *fp, const unsigned char *src, size_t srcsz)
822{
[331]823 return shell_send(fp->fd, src, srcsz, 0);
[279]824}
825
826off_t udp_fd_seek(struct _IO_FILE *fp, off_t ofs, int org)
827{
[331]828 return -EPERM;
[279]829}
830
[331]831int udp_fd_ioctl(struct _IO_FILE *fp, int req, void *arg)
832{
833 return -EINVAL;
834}
835
[279]836#ifndef TCP_CFG_EXTENTIONS
837ER tcp_cre_rep(ID repid, T_TCP_CREP *pk_crep)
838{
839 syslog(LOG_ERROR, "tcp_cre_rep not implement");
840 shell_abort();
841 return E_SYS;
842}
843
844ER tcp_cre_cep(ID cepid, T_TCP_CCEP *pk_ccep)
845{
846 syslog(LOG_ERROR, "tcp_cre_cep not implement");
847 shell_abort();
848 return E_SYS;
849}
850#endif
851
852#ifndef UDP_CFG_EXTENTIONS
853ER udp_cre_cep(ID cepid, T_UDP_CCEP *pk_ccep)
854{
855 syslog(LOG_ERROR, "udp_cre_cep not implement");
856 shell_abort();
857 return E_SYS;
858}
859#endif
860
861#ifndef TCP_CFG_EXTENTIONS
862ER_UINT tcp_snd_oob(ID cepid, void *data, int_t len, TMO tmout)
863{
864 syslog(LOG_ERROR, "tcp_snd_oob not implement");
865 shell_abort();
866 return E_SYS;
867}
868
869ER_UINT tcp_rcv_oob(ID cepid, void *data, int_t len)
870{
871 syslog(LOG_ERROR, "tcp_rcv_oob not implement");
872 shell_abort();
873 return E_SYS;
874}
875
876ER tcp_set_opt(ID cepid, int_t optname, void *optval, int_t optlen)
877{
878 syslog(LOG_ERROR, "tcp_set_opt not implement");
879 shell_abort();
880 return E_SYS;
881}
882
883ER tcp_get_opt(ID cepid, int_t optname, void *optval, int_t optlen)
884{
885 syslog(LOG_ERROR, "tcp_get_opt not implement");
886 shell_abort();
887 return E_SYS;
888}
889#endif
890
891#ifndef UDP_CFG_EXTENTIONS
892ER udp_get_opt(ID cepid, int_t optname, void *optval, int_t optlen)
893{
894 syslog(LOG_ERROR, "udp_get_opt not implement");
895 shell_abort();
896 return E_SYS;
897}
898
899ER udp_set_opt(ID cepid, int_t optname, void *optval, int_t optlen)
900{
901 syslog(LOG_ERROR, "udp_set_opt not implement");
902 shell_abort();
903 return E_SYS;
904}
905#endif
Note: See TracBrowser for help on using the repository browser.