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

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

文字コードを設定

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