source: EcnlProtoTool/trunk/asp3_dcre/tinet/netapp/netapp_subr.c@ 270

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

mruby版ECNLプロトタイピング・ツールを追加

  • Property svn:eol-style set to native
  • Property svn:keywords set to Id
  • Property svn:mime-type set to text/x-csrc
File size: 15.4 KB
Line 
1/*
2 * TINET (TCP/IP Protocol Stack)
3 *
4 * Copyright (C) 2001-2009 by Dep. of Computer Science and Engineering
5 * Tomakomai National College of Technology, JAPAN
6 *
7 * 上記著作権者
8は,以下の (1)~(4) の条件か,Free Software Foundation
9 * によってå…
10¬è¡¨ã•ã‚Œã¦ã„ã‚‹ GNU General Public License の Version 2 に記
11 * 述されている条件を満たす場合に限り,本ソフトウェア(本ソフトウェア
12 * を改変したものを含む.以下同じ)を使用・複製・改変・再é…
13å¸ƒï¼ˆä»¥ä¸‹ï¼Œ
14 * 利用と呼ぶ)することを無償で許諾する.
15 * (1) 本ソフトウェアをソースコードの形で利用する場合には,上記の著作
16 * 権表示,この利用条件および下記の無保証規定が,そのままの形でソー
17 * スコード中に含まれていること.
18 * (2) 本ソフトウェアを,ライブラリ形式など,他のソフトウェア開発に使
19 * 用できる形で再é…
20å¸ƒã™ã‚‹å ´åˆã«ã¯ï¼Œå†é…
21å¸ƒã«ä¼´ã†ãƒ‰ã‚­ãƒ¥ãƒ¡ãƒ³ãƒˆï¼ˆåˆ©ç”¨
22 * 者
23マニュアルなど)に,上記の著作権表示,この利用条件および下記
24 * の無保証規定を掲載すること.
25 * (3) 本ソフトウェアを,機器に組み込むなど,他のソフトウェア開発に使
26 * 用できない形で再é…
27å¸ƒã™ã‚‹å ´åˆã«ã¯ï¼Œæ¬¡ã®æ¡ä»¶ã‚’満たすこと.
28 * (a) 再é…
29å¸ƒã«ä¼´ã†ãƒ‰ã‚­ãƒ¥ãƒ¡ãƒ³ãƒˆï¼ˆåˆ©ç”¨è€…
30マニュアルなど)に,上記の著
31 * 作権表示,この利用条件および下記の無保証規定を掲載すること.
32 * (4) 本ソフトウェアの利用により直接的または間接的に生じるいかなる損
33 * 害からも,上記著作権者
34およびTOPPERSプロジェクトをå…
35è²¬ã™ã‚‹ã“と.
36 *
37 * 本ソフトウェアは,無保証で提供されているものである.上記著作権者
38お
39 * よびTOPPERSプロジェクトは,本ソフトウェアに関して,その適用可能性も
40 * 含めて,いかなる保証も行わない.また,本ソフトウェアの利用により直
41 * 接的または間接的に生じたいかなる損害に関しても,その責任を負わない.
42 *
43 * @(#) $Id: netapp_subr.c 270 2017-02-09 04:03:47Z coas-nagasima $
44 */
45
46/*
47 * ネットワーク応用プログラムサポートルーチン
48 */
49
50#include <stdarg.h>
51#include <string.h>
52
53#ifdef TARGET_KERNEL_ASP
54
55#include <kernel.h>
56#include <sil.h>
57#include <syssvc/serial.h>
58#include "kernel_cfg.h"
59#include "tinet_cfg.h"
60
61#endif /* of #ifdef TARGET_KERNEL_ASP */
62
63#ifdef TARGET_KERNEL_JSP
64
65#include <s_services.h>
66#include <t_services.h>
67#include "kernel_id.h"
68#include "tinet_id.h"
69
70#endif /* of #ifdef TARGET_KERNEL_JSP */
71
72#include <tinet_defs.h>
73#include <tinet_config.h>
74
75#include <net/net.h>
76
77#include <netinet/in.h>
78#include <netinet/in_itron.h>
79
80#include <netapp/netapp.h>
81#include <netapp/netapp_var.h>
82
83#ifdef USE_NETAPP_SUBR
84
85/*
86 * シリアルポートへの書式付文字列出力ライブラリ
87 */
88
89#define EOF (-1)
90
91/*
92 * 数値変換のための変換表
93 */
94
95const char radhex[] = "0123456789abcdef";
96const char radHEX[] = "0123456789ABCDEF";
97
98#ifndef USE_NET_CONS
99
100/*
101 * cons_putchar -- シリアルポートへの文字出力
102 */
103
104void
105cons_putchar (ID portid, char ch)
106{
107 serial_wri_dat(portid, &ch, 1);
108 }
109
110/*
111 * cons_getchar -- シリアルポートからの文字å…
112¥åŠ›
113 */
114
115int_t
116cons_getchar (ID portid)
117{
118 char ch;
119
120 if (serial_rea_dat(portid, &ch, sizeof(ch)) > 0)
121 return ch;
122 else
123 return EOF;
124 }
125
126#endif /* of #ifndef USE_NET_CONS */
127
128/*
129 * cons_putnumber -- cons_printf の数値変換
130 */
131
132int_t
133cons_putnumber(ID portid, ulong_t val, int_t radix,
134 const char *radchar, int_t width, bool_t minus, char padchar)
135{
136 char digits[24];
137 int_t ix, pad, pchars;
138 bool_t left;
139
140 if (width < 0) {
141 width = -width;
142 left = true;
143 }
144 else
145 left = false;
146
147 ix = 0;
148 do {
149 digits[ix ++] = radchar[val % radix];
150 val /= radix;
151 } while (val != 0);
152
153 if (minus)
154 digits[ix ++] = '-';
155
156 if (width > ix)
157 pchars = width;
158 else
159 pchars = ix;
160
161 pad = ix;
162 if (!left) /* 右詰め */
163 for ( ; pad < width; pad ++)
164 cons_putchar(portid, padchar);
165
166 while (ix -- > 0)
167 cons_putchar(portid, digits[ix]);
168
169 if (left) /* 左詰め */
170 for ( ; pad < width; pad ++)
171 cons_putchar(portid, padchar);
172
173 return pchars;
174 }
175
176#if defined(SUPPORT_INET4)
177
178/*
179 * put_ipv4addr -- IPv4 アドレス出力
180 */
181
182int_t
183put_ipv4addr (ID portid, T_IN4_ADDR *addr, int_t width)
184{
185 int_t len = 3; /* 3 は '.' の文字数 */
186
187 len += cons_putnumber(portid, (*addr >> 24) & 0xff, 10, radhex, 0, false, ' ');
188 cons_putchar(portid, '.');
189 len += cons_putnumber(portid, (*addr >> 16) & 0xff, 10, radhex, 0, false, ' ');
190 cons_putchar(portid, '.');
191 len += cons_putnumber(portid, (*addr >> 8) & 0xff, 10, radhex, 0, false, ' ');
192 cons_putchar(portid, '.');
193 len += cons_putnumber(portid, *addr & 0xff, 10, radhex, 0, false, ' ');
194
195 for ( ; len < width; len ++)
196 cons_putchar(portid, ' ');
197
198 return len;
199 }
200
201#define PUT_IPADDR(p,a,w) put_ipv4addr(p,a,w)
202
203#endif /* of #if defined(SUPPORT_INET4) */
204
205#if defined(SUPPORT_INET6)
206
207/*
208 * ipv6addr -- IPv6 アドレス出力
209 */
210
211int_t
212put_ipv6addr (ID portid, const T_IN6_ADDR *addr, int_t width)
213{
214 int_t len = 0, ix;
215 bool_t omit = false, zero = false;
216
217 if (addr == NULL) {
218 cons_putchar(portid, '0');
219 cons_putchar(portid, ':');
220 cons_putchar(portid, ':');
221 cons_putchar(portid, '0');
222 len = 4;
223 }
224 else {
225 for (ix = 0; ix < sizeof(T_IN6_ADDR) / 2; ix ++) {
226 if (omit) {
227 len += cons_putnumber(portid, ntohs(addr->s6_addr16[ix]), 16, radhex, 0, false, ' ');
228 if (ix < 7) {
229 cons_putchar(portid, ':');
230 len ++;
231 }
232 }
233 else if (ix > 0 && ix < 7 && addr->s6_addr16[ix] == 0)
234 zero = true;
235 else {
236 if (zero) {
237 omit = true;
238 cons_putchar(portid, ':');
239 len ++;
240 }
241 len += cons_putnumber(portid, ntohs(addr->s6_addr16[ix]), 16, radhex, 0, false, ' ');
242 if (ix < 7) {
243 cons_putchar(portid, ':');
244 len ++;
245 }
246 }
247 }
248
249 for ( ; len < width; len ++)
250 cons_putchar(portid, ' ');
251 }
252 return len;
253 }
254
255#define PUT_IPADDR(p,a,w) put_ipv6addr(p,a,w)
256
257#endif /* of #if defined(SUPPORT_INET6) */
258
259/*
260 * put_macaddr -- MAC アドレス出力
261 */
262
263int_t
264put_macaddr (ID portid, uint8_t *mac, int_t width)
265{
266 int_t oct, len;
267
268 for (oct = 5; oct -- > 0; ) {
269 cons_putnumber(portid, *mac ++, 16, radhex, 2, false, '0');
270 cons_putchar(portid, ':');
271 }
272 cons_putnumber(portid, *mac, 16, radhex, 2, false, '0');
273
274 for (len = 17; len < width; len ++)
275 cons_putchar(portid, ' ');
276
277 return len;
278 }
279
280/*
281 * cons_printf -- シリアルポートへの書式付文字列出力
282 */
283
284void
285cons_printf (ID portid, const char *fmt, ...)
286{
287 va_list ap;
288 long_t val;
289 char padchar, *str;
290 int_t ch, width, longflag, left;
291
292#if defined(SUPPORT_INET4)
293 T_IN4_ADDR *addr;
294#endif /* of #if defined(SUPPORT_INET4) */
295
296 va_start(ap, fmt);
297 while ((ch = *fmt ++) != '\0') {
298 if (ch != '%') { /* 書式指定以外 */
299 cons_putchar(portid, (char)ch);
300 continue;
301 }
302
303 width = longflag = 0;
304 padchar = ' ';
305
306 if (ch == '-') { /* 左詰め */
307 fmt ++;
308 left = -1;
309 }
310 else
311 left = 1;
312
313 if ((ch = *fmt ++) == '0') { /* 上位桁の 0 */
314 padchar = '0';
315 ch = *fmt ++;
316 }
317
318 while ('0' <= ch && ch <= '9') { /* 出力幅
319 */
320 width = width * 10 + ch - '0';
321 ch = *fmt ++;
322 }
323
324 while (ch == 'l') { /* long (long) の指定 */
325 longflag ++;
326 ch = *fmt ++;
327 }
328
329 switch (ch) {
330 case 'd':
331 val = longflag ? (ulong_t)va_arg(ap, long_t)
332 : (ulong_t)va_arg(ap, int_t);
333 if (val >= 0)
334 cons_putnumber(portid, val, 10, radhex, width * left, false, padchar);
335 else
336 cons_putnumber(portid, -val, 10, radhex, width * left, true, padchar);
337 break;
338
339 case 'u':
340 val = longflag ? (ulong_t)va_arg(ap, ulong_t)
341 : (ulong_t)va_arg(ap, uint_t);
342 cons_putnumber(portid, val, 10, radhex, width * left, false, padchar);
343 break;
344
345 case 'x':
346 val = longflag ? (ulong_t)va_arg(ap, ulong_t)
347 : (ulong_t)va_arg(ap, uint_t);
348 cons_putnumber(portid, val, 16, radhex, width * left, false, padchar);
349 break;
350
351 case 'X':
352 val = longflag ? (ulong_t)va_arg(ap, ulong_t)
353 : (ulong_t)va_arg(ap, uint_t);
354 cons_putnumber(portid, val, 16, radHEX, width * left, false, padchar);
355 break;
356
357 case 'c':
358 ch = va_arg(ap, int_t);
359 cons_putchar(portid, (char)ch);
360 break;
361
362 case 's':
363 str = va_arg(ap, char*);
364 while ((ch = *str ++) != '\0') {
365 cons_putchar(portid, (char)ch);
366 width --;
367 }
368 while (width -- > 0)
369 cons_putchar(portid, ' ');
370 break;
371
372 case 'I':
373
374#if defined(SUPPORT_INET4)
375
376 addr = va_arg(ap, T_IN4_ADDR *);
377 put_ipv4addr(portid, addr, width);
378
379#endif /* of #if defined(SUPPORT_INET4) */
380
381#if defined(SUPPORT_INET6)
382
383 str = va_arg(ap, char*);
384 put_ipv6addr(portid, (T_IN6_ADDR *)str, width);
385
386#endif /* of #if defined(SUPPORT_INET6) */
387
388 break;
389
390 case 'M':
391 str = va_arg(ap, char*);
392 put_macaddr(portid, str, width);
393 break;
394
395 case '%':
396 cons_putchar(portid, '%');
397 break;
398
399 case '0':
400 fmt --;
401 break;
402
403 default:
404 break;
405 }
406
407 }
408 va_end(ap);
409 }
410
411/*
412 * skip_blanks -- 空白と TAB をスキップする。
413 */
414
415char *
416skip_blanks (char *line)
417{
418 while (*line == ' ' || *line == '\t')
419 line ++;
420 return line;
421 }
422
423/*
424 * get_ipv4addr -- 文字列の IPv4 アドレスを T_IN4_ADDR 値に変換する。
425 */
426
427char *
428get_ipv4addr (T_IN4_ADDR *addr, char *line)
429{
430 int_t oct;
431
432 *addr = 0;
433 while ('0' <= *line && *line <= '9') {
434 oct = 0;
435 while ('0' <= *line && *line <= '9')
436 oct = oct * 10 + (*line ++) - '0';
437 *addr = (*addr << 8) | (oct & 0xff);
438 if (*line == '.')
439 line ++;
440 }
441 return line;
442 }
443
444#if defined(SUPPORT_INET6)
445
446/*
447 * get_ipv6addr -- 文字列の IPv6 アドレスを T_IN6_ADDR 値に変換する。
448 */
449
450char *
451get_ipv6addr (T_IN6_ADDR *addr, char *line)
452{
453 int_t word, ix = 0, omit = 0, six;
454
455 memset(addr, 0, sizeof(T_IN6_ADDR));
456 while (ix < 8 &&
457 (('0' <= *line && *line <= '9') ||
458 ('a' <= *line && *line <= 'f') ||
459 ('A' <= *line && *line <= 'F'))) {
460 word = 0;
461 while (('0' <= *line && *line <= '9') ||
462 ('a' <= *line && *line <= 'f') ||
463 ('A' <= *line && *line <= 'F')) {
464 if ('0' <= *line && *line <= '9')
465 word = (word << 4) + (*line ++) - '0';
466 else if ('a' <= *line && *line <= 'f')
467 word = (word << 4) + (*line ++) - 'a' + 10;
468 else if ('A' <= *line && *line <= 'F')
469 word = (word << 4) + (*line ++) - 'A' + 10;
470 }
471 addr->s6_addr16[ix ++] = htons(word);
472 if (*line == ':') {
473 line ++;
474 if (*line == ':') {
475 omit = ix;
476 line ++;
477 }
478 }
479 }
480 if (omit > 0) {
481 six = 7;
482 while (ix > omit) {
483 addr->s6_addr16[six --] = addr->s6_addr16[-- ix];
484 addr->s6_addr16[ ix ] = 0;
485 }
486 }
487 return line;
488 }
489
490#endif /* of #if defined(SUPPORT_INET6) */
491
492/*
493 * デバッグ行å…
494¥åŠ›
495 */
496
497int_t
498cons_getline (ID portid, char *line, int_t size)
499{
500 int_t ch, len;
501
502 len = size;
503 while (size > 0) {
504 if ((ch = cons_getchar(portid)) != EOF) {
505 if (ch == '\r') {
506 cons_putchar(portid, '\n');
507 break;
508 }
509 else if (ch == '\b') {
510 if (size < len) {
511 line --;
512 size ++;
513 }
514 }
515 else {
516 *line ++ = ch;
517 size --;
518 }
519 }
520 }
521 *line = '\0';
522 return len - size;
523 }
524
525/*
526 * get_int -- 整数変換
527 */
528
529char *
530get_int (int_t *val, char *line)
531{
532 int_t sign = 1;
533
534 line = skip_blanks(line);
535 if (*line == '-') {
536 sign = -1;
537 line ++;
538 }
539 else if (*line == '+')
540 line ++;
541
542 line = skip_blanks(line);
543 *val = 0;
544 while ('0' <= *line && *line <= '9') {
545 *val = *val * 10 + *line - '0';
546 line ++;
547 }
548
549 *val = *val * sign;
550 return line;
551 }
552
553/*
554 * get_xuint -- 符号なし整数 (16進) 変換
555 */
556
557char *
558get_xuint (uint_t *val, char *line)
559{
560 line = skip_blanks(line);
561 *val = 0;
562 while (1) {
563 if ('0' <= *line && *line <= '9')
564 *val = (*val << 4) + *line - '0';
565 else if ('a' <= *line && *line <= 'f')
566 *val = (*val << 4) + *line - 'a' + 10;
567 else if ('A' <= *line && *line <= 'F')
568 *val = (*val << 4) + *line - 'A' + 10;
569 else
570 break;
571 line ++;
572 }
573 return line;
574 }
575
576#ifdef USE_TCP_EXTENTIONS
577
578const ID vrid_tcp_rep[] =
579{
580#if NUM_VRID_TCP_REPS >= 1
581 TCP_RSV_REPID1,
582#endif
583#if NUM_VRID_TCP_REPS >= 2
584 TCP_RSV_REPID2,
585#endif
586 };
587
588const ID vrid_tcp_cep[] =
589{
590#if NUM_VRID_TCP_CEPS >= 1
591 TCP_RSV_CEPID1,
592#endif
593#if NUM_VRID_TCP_CEPS >= 2
594 TCP_RSV_CEPID2,
595#endif
596#if NUM_VRID_TCP_CEPS >= 3
597 TCP_RSV_CEPID3,
598#endif
599#if NUM_VRID_TCP_CEPS >= 4
600 TCP_RSV_CEPID4,
601#endif
602 };
603
604ID tskid_tcp_rep[NUM_VRID_TCP_REPS];
605ID tskid_tcp_cep[NUM_VRID_TCP_CEPS];
606
607/*
608 * alloc_tcp_rep -- TCP 受付口を獲得する。
609 */
610
611ER
612alloc_tcp_rep (ID *repid, ID tskid, T_TCP_CREP *crep)
613{
614 int_t ix;
615
616 *repid = TCP_REP_NONE;
617 syscall(wai_sem(SEM_ALLOC_TCP_REP_LOCK));
618 for (ix = NUM_VRID_TCP_REPS; ix -- > 0; ) {
619 if (tskid_tcp_rep[ix] == TSK_NONE) {
620 *repid = vrid_tcp_rep[ix];
621 tskid_tcp_rep[ix] = tskid;
622 break;
623 }
624 }
625 syscall(sig_sem(SEM_ALLOC_TCP_REP_LOCK));
626
627 if (*repid == TCP_REP_NONE)
628 return E_NOEXS;
629 else
630 return TCP_CRE_REP(*repid, crep);
631 }
632
633/*
634 * free_tcp_rep -- TCP 受付口を解放する。
635 */
636
637ER
638free_tcp_rep (ID repid, bool_t call_tcp_del_rep)
639{
640 int_t ix;
641
642 syscall(wai_sem(SEM_ALLOC_TCP_REP_LOCK));
643 for (ix = NUM_VRID_TCP_REPS; ix -- > 0; ) {
644 if (repid == vrid_tcp_rep[ix]) {
645 tskid_tcp_rep[ix] = TSK_NONE;
646 break;
647 }
648 }
649 syscall(sig_sem(SEM_ALLOC_TCP_REP_LOCK));
650
651 if (call_tcp_del_rep)
652 return tcp_del_rep(repid);
653 else
654 return E_OK;
655 }
656
657/*
658 * alloc_tcp_cep -- TCP 通信端点を獲得する。
659 */
660
661ER
662alloc_tcp_cep (ID *cepid, ID tskid, T_TCP_CCEP *ccep)
663{
664 int_t ix;
665
666 *cepid = TCP_CEP_NONE;
667 syscall(wai_sem(SEM_ALLOC_TCP_CEP_LOCK));
668 for (ix = NUM_VRID_TCP_CEPS; ix -- > 0; ) {
669 if (tskid_tcp_cep[ix] == TSK_NONE) {
670 *cepid = vrid_tcp_cep[ix];
671 tskid_tcp_cep[ix] = tskid;
672 break;
673 }
674 }
675 syscall(sig_sem(SEM_ALLOC_TCP_CEP_LOCK));
676
677 if (*cepid == TCP_CEP_NONE)
678 return E_NOEXS;
679 else
680 return tcp_cre_cep(*cepid, ccep);
681 }
682
683/*
684 * free_tcp_cep -- TCP 通信端点を解放する。
685 */
686
687ER
688free_tcp_cep (ID cepid)
689{
690 int_t ix;
691
692 syscall(wai_sem(SEM_ALLOC_TCP_CEP_LOCK));
693 for (ix = NUM_VRID_TCP_CEPS; ix -- > 0; ) {
694 if (cepid == vrid_tcp_cep[ix]) {
695 tskid_tcp_cep[ix] = TSK_NONE;
696 break;
697 }
698 }
699 syscall(sig_sem(SEM_ALLOC_TCP_CEP_LOCK));
700
701 return tcp_del_cep(cepid);
702 }
703
704#endif /* of #ifdef USE_TCP_EXTENTIONS */
705
706#ifdef USE_UDP_EXTENTIONS
707
708const ID vrid_udp_cep[] =
709{
710#if NUM_VRID_UDP_CEPS >= 1
711 UDP_RSV_CEPID1,
712#endif
713#if NUM_VRID_UDP_CEPS >= 2
714 UDP_RSV_CEPID2,
715#endif
716 };
717
718ID tskid_udp_cep[NUM_VRID_UDP_CEPS];
719
720/*
721 * alloc_udp_cep -- UDP 通信端点を獲得する。
722 */
723
724ER
725alloc_udp_cep (ID *cepid, ID tskid, T_UDP_CCEP *ccep)
726{
727 int_t ix;
728
729 *cepid = UDP_CEP_NONE;
730 syscall(wai_sem(SEM_ALLOC_UDP_CEP_LOCK));
731 for (ix = NUM_VRID_UDP_CEPS; ix -- > 0; ) {
732 if (tskid_udp_cep[ix] == TSK_NONE) {
733 *cepid = vrid_udp_cep[ix];
734 tskid_udp_cep[ix] = tskid;
735 break;
736 }
737 }
738 syscall(sig_sem(SEM_ALLOC_UDP_CEP_LOCK));
739
740 if (*cepid == UDP_CEP_NONE)
741 return E_NOEXS;
742 else
743 return UDP_CRE_CEP(*cepid, ccep);
744 }
745
746/*
747 * free_udp_cep -- UDP 通信端点を解放する。
748 */
749
750ER
751free_udp_cep (ID cepid, bool_t call_udp_del_cep)
752{
753 int_t ix;
754
755 syscall(wai_sem(SEM_ALLOC_UDP_CEP_LOCK));
756 for (ix = NUM_VRID_UDP_CEPS; ix -- > 0; ) {
757 if (cepid == vrid_udp_cep[ix]) {
758 tskid_udp_cep[ix] = TSK_NONE;
759 break;
760 }
761 }
762 syscall(sig_sem(SEM_ALLOC_UDP_CEP_LOCK));
763
764 if (call_udp_del_cep)
765 return udp_del_cep(cepid);
766 else
767 return E_OK;
768 }
769
770#endif /* of #ifdef USE_UDP_EXTENTIONS */
771
772#endif /* of #ifdef USE_NETAPP_SUBR */
Note: See TracBrowser for help on using the repository browser.