source: rubycfg_asp/trunk/asp_dcre/tinet/netapp/netapp_subr.c@ 313

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

ソースを追加

  • Property svn:eol-style set to native
  • Property svn:keywords set to Id
  • Property svn:mime-type set to text/x-csrc
File size: 25.9 KB
Line 
1/*
2 * TINET (TCP/IP Protocol Stack)
3 *
4 * Copyright (C) 2001-2017 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 313 2017-07-23 04:50:32Z 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 <syssvc/logtask.h>
59#include <t_syslog.h>
60#include "kernel_cfg.h"
61#include "tinet_cfg.h"
62
63#endif /* of #ifdef TARGET_KERNEL_ASP */
64
65#ifdef TARGET_KERNEL_JSP
66
67#include <s_services.h>
68#include <t_services.h>
69#include "kernel_id.h"
70#include "tinet_id.h"
71
72#endif /* of #ifdef TARGET_KERNEL_JSP */
73
74#include <tinet_defs.h>
75#include <tinet_config.h>
76
77#include <net/net.h>
78#include <net/net_endian.h>
79
80#include <netinet/in.h>
81#include <netinet/in_itron.h>
82
83#include <netapp/netapp.h>
84#include <netapp/netapp_var.h>
85#include <netapp/resolver.h>
86
87#ifdef USE_NETAPP_SUBR
88
89/*
90 * IPv6 と IPv4 で引数が異なる関数のコンパイル
91 */
92
93#if defined(SUPPORT_INET6)
94
95#ifdef USE_TCP_EXTENTIONS
96
97const ID vrid_tcp6_cep[] =
98{
99#if NUM_VRID_TCP6_CEPS >= 1
100 TCP6_RSV_CEPID1,
101#endif
102#if NUM_VRID_TCP6_CEPS >= 2
103 TCP6_RSV_CEPID2,
104#endif
105#if NUM_VRID_TCP6_CEPS >= 3
106 TCP6_RSV_CEPID3,
107#endif
108#if NUM_VRID_TCP6_CEPS >= 4
109 TCP6_RSV_CEPID4,
110#endif
111 };
112
113const ID vrid_tcp6_rep[] =
114{
115#if NUM_VRID_TCP6_REPS >= 1
116 TCP6_RSV_REPID1,
117#endif
118#if NUM_VRID_TCP6_REPS >= 2
119 TCP6_RSV_REPID2,
120#endif
121 };
122
123ID tskid_tcp6_cep[NUM_VRID_TCP6_CEPS];
124ID tskid_tcp6_rep[NUM_VRID_TCP6_REPS];
125
126#endif /* #ifdef USE_TCP_EXTENTIONS */
127
128#ifdef USE_UDP_EXTENTIONS
129
130const ID vrid_udp6_cep[] =
131{
132#if NUM_VRID_UDP6_CEPS >= 1
133 UDP6_RSV_CEPID1,
134#endif
135#if NUM_VRID_UDP6_CEPS >= 2
136 UDP6_RSV_CEPID2,
137#endif
138 };
139
140ID tskid_udp6_cep[NUM_VRID_UDP6_CEPS];
141
142#endif /* #ifdef USE_UDP_EXTENTIONS */
143
144#undef TCP_CRE_REP
145#undef UDP_CRE_CEP
146#undef UDP_DEL_CEP
147#undef TCP_IS_CEPID
148#undef ALLOC_TCP_REP
149#undef ALLOC_TCP_CEP
150#undef ALLOC_UDP_CEP
151#undef FREE_TCP_REP
152#undef FREE_TCP_CEP
153#undef FREE_UDP_CEP
154#undef T_TCPN_CREP
155#undef T_UDPN_CCEP
156#undef NUM_VRID_TCP_CEPS
157#undef NUM_VRID_TCP_REPS
158#undef NUM_VRID_UDP_CEPS
159#undef VRID_TCP_CEP
160#undef VRID_UDP_CEP
161#undef VRID_TCP_REP
162#undef TSKID_TCP_CEP
163#undef TSKID_TCP_REP
164#undef TSKID_UDP_CEP
165#undef API_IPPROTO
166
167#define TCP_CRE_REP tcp6_cre_rep
168#define UDP_CRE_CEP udp6_cre_cep
169#define UDP_DEL_CEP udp6_del_cep
170
171#define TCP_IS_CEPID tcp6_is_cepid
172#define ALLOC_TCP_REP alloc_tcp6_rep
173#define ALLOC_TCP_CEP alloc_tcp6_cep
174#define ALLOC_UDP_CEP alloc_udp6_cep
175#define FREE_TCP_REP free_tcp6_rep
176#define FREE_TCP_CEP free_tcp6_cep
177#define FREE_UDP_CEP free_udp6_cep
178#define T_TCPN_CREP T_TCP6_CREP
179#define T_UDPN_CCEP T_UDP6_CCEP
180#define NUM_VRID_TCP_CEPS NUM_VRID_TCP6_CEPS
181#define NUM_VRID_TCP_REPS NUM_VRID_TCP6_REPS
182#define NUM_VRID_UDP_CEPS NUM_VRID_UDP6_CEPS
183#define VRID_TCP_CEP vrid_tcp6_cep
184#define VRID_TCP_REP vrid_tcp6_rep
185#define VRID_UDP_CEP vrid_udp6_cep
186#define TSKID_TCP_CEP tskid_tcp6_cep
187#define TSKID_TCP_REP tskid_tcp6_rep
188#define TSKID_UDP_CEP tskid_udp6_cep
189#define API_IPPROTO API_PROTO_IPV6
190
191#include <netapp/netappn_subr.c>
192
193#endif /* of #if defined(SUPPORT_INET6) */
194
195#if defined(SUPPORT_INET4)
196
197#ifdef USE_TCP_EXTENTIONS
198
199const ID vrid_tcp4_cep[] =
200{
201#if NUM_VRID_TCP4_CEPS >= 1
202 TCP4_RSV_CEPID1,
203#endif
204#if NUM_VRID_TCP4_CEPS >= 2
205 TCP4_RSV_CEPID2,
206#endif
207#if NUM_VRID_TCP4_CEPS >= 3
208 TCP4_RSV_CEPID3,
209#endif
210#if NUM_VRID_TCP4_CEPS >= 4
211 TCP4_RSV_CEPID4,
212#endif
213 };
214
215const ID vrid_tcp4_rep[] =
216{
217#if NUM_VRID_TCP4_REPS >= 1
218 TCP4_RSV_REPID1,
219#endif
220#if NUM_VRID_TCP4_REPS >= 2
221 TCP4_RSV_REPID2,
222#endif
223 };
224
225ID tskid_tcp4_cep[NUM_VRID_TCP4_CEPS];
226ID tskid_tcp4_rep[NUM_VRID_TCP4_REPS];
227
228#endif /* #ifdef USE_TCP_EXTENTIONS */
229
230#ifdef USE_UDP_EXTENTIONS
231
232const ID vrid_udp4_cep[] =
233{
234#if NUM_VRID_UDP4_CEPS >= 1
235 UDP4_RSV_CEPID1,
236#endif
237#if NUM_VRID_UDP4_CEPS >= 2
238 UDP4_RSV_CEPID2,
239#endif
240 };
241
242ID tskid_udp4_cep[NUM_VRID_UDP4_CEPS];
243
244#endif /* #ifdef USE_UDP_EXTENTIONS */
245
246#undef TCP_CRE_REP
247#undef UDP_CRE_CEP
248#undef UDP_DEL_CEP
249#undef TCP_IS_CEPID
250#undef ALLOC_TCP_REP
251#undef ALLOC_TCP_CEP
252#undef ALLOC_UDP_CEP
253#undef FREE_TCP_REP
254#undef FREE_TCP_CEP
255#undef FREE_UDP_CEP
256#undef T_TCPN_CREP
257#undef T_UDPN_CCEP
258#undef NUM_VRID_TCP_CEPS
259#undef NUM_VRID_TCP_REPS
260#undef NUM_VRID_UDP_CEPS
261#undef VRID_TCP_CEP
262#undef VRID_TCP_REP
263#undef VRID_UDP_CEP
264#undef TSKID_TCP_CEP
265#undef TSKID_TCP_REP
266#undef TSKID_UDP_CEP
267#undef API_IPPROTO
268
269#define TCP_CRE_REP tcp_cre_rep
270#define UDP_CRE_CEP udp_cre_cep
271#define UDP_DEL_CEP udp_del_cep
272#define TCP_IS_CEPID tcp4_is_cepid
273#define ALLOC_TCP_REP alloc_tcp4_rep
274#define ALLOC_TCP_CEP alloc_tcp4_cep
275#define ALLOC_UDP_CEP alloc_udp4_cep
276#define FREE_TCP_REP free_tcp4_rep
277#define FREE_TCP_CEP free_tcp4_cep
278#define FREE_UDP_CEP free_udp4_cep
279#define T_TCPN_CREP T_TCP_CREP
280#define T_UDPN_CCEP T_UDP_CCEP
281#define NUM_VRID_TCP_CEPS NUM_VRID_TCP4_CEPS
282#define NUM_VRID_TCP_REPS NUM_VRID_TCP4_REPS
283#define NUM_VRID_UDP_CEPS NUM_VRID_UDP4_CEPS
284#define VRID_TCP_CEP vrid_tcp4_cep
285#define VRID_TCP_REP vrid_tcp4_rep
286#define VRID_UDP_CEP vrid_udp4_cep
287#define TSKID_TCP_CEP tskid_tcp4_cep
288#define TSKID_TCP_REP tskid_tcp4_rep
289#define TSKID_UDP_CEP tskid_udp4_cep
290#define API_IPPROTO API_PROTO_IPV4
291
292#include <netapp/netappn_subr.c>
293
294#endif /* of #if defined(SUPPORT_INET4) */
295
296#undef TCP_CRE_REP
297#undef ALLOC_TCPN_REP
298#undef ALLOC_TCPN_CEP
299#undef ALLOC_UDPN_CEP
300#undef FREE_TCPN_REP
301#undef FREE_TCPN_CEP
302#undef FREE_UDPN_CEP
303#undef T_TCPN_CREP
304#undef NUM_VRID_TCP_REPS
305#undef NUM_VRID_UDP_CEPS
306#undef VRID_TCP_CEP
307#undef VRID_TCP_REP
308#undef VRID_UDP_CEP
309#undef TSKID_TCP_CEP
310#undef TSKID_TCP_REP
311#undef TSKID_UDP_CEP
312
313/*
314 * 変数
315 */
316
317static uint32_t rand_next = ULONG_C(1);
318
319#if !defined(SUPPORT_INET6) && defined(SUPPORT_INET4)
320
321const T_IN6_ADDR in6_addr_unspecified =
322 IPV6_ADDR_UNSPECIFIED_INIT;
323
324#endif /* of #if !defined(SUPPORT_INET6) && defined(SUPPORT_INET4) */
325
326/*
327 * シリアルポートへの書式付文字列出力ライブラリ
328 */
329
330#define EOF (-1)
331
332/*
333 * 数値変換のための変換表
334 */
335
336const char radhex[] = "0123456789abcdef";
337const char radHEX[] = "0123456789ABCDEF";
338
339/*
340 * netapp_rand -- 乱数を返す。
341 */
342
343uint32_t
344netapp_rand (void)
345{
346 rand_next = (rand_next * 99991 + 12345) & ULONG_C(0x7fffffff);
347 return rand_next;
348 }
349
350/*
351 * srand -- 乱数を初期化する。
352 */
353
354void
355netapp_srand (uint32_t seed)
356{
357 SYSTIM now;
358
359 syscall(get_tim(&now));
360 rand_next += now + seed;
361 }
362
363#ifndef USE_NET_CONS
364
365/*
366 * cons_putchar -- シリアルポートへの文字出力
367 */
368
369void
370cons_putchar (ID portid, char ch)
371{
372 serial_wri_dat(portid, &ch, 1);
373 }
374
375/*
376 * cons_getchar -- シリアルポートからの文字å…
377¥åŠ›
378 */
379
380int_t
381cons_getchar (ID portid)
382{
383 char ch;
384
385 if (serial_rea_dat(portid, &ch, sizeof(ch)) > 0)
386 return ch;
387 else
388 return EOF;
389 }
390
391#endif /* of #ifndef USE_NET_CONS */
392
393/*
394 * cons_putnumber -- cons_printf の数値変換
395 */
396
397int_t
398cons_putnumber(ID portid, ulong_t val, int_t radix,
399 const char *radchar, int_t width, bool_t minus, char padchar)
400{
401 char digits[24];
402 int_t ix, pad, pchars;
403 bool_t left;
404
405 if (width < 0) {
406 width = -width;
407 left = true;
408 }
409 else
410 left = false;
411
412 ix = 0;
413 do {
414 digits[ix ++] = radchar[val % radix];
415 val /= radix;
416 } while (val != 0);
417
418 if (minus)
419 digits[ix ++] = '-';
420
421 if (width > ix)
422 pchars = width;
423 else
424 pchars = ix;
425
426 pad = ix;
427 if (!left) /* 右詰め */
428 for ( ; pad < width; pad ++)
429 cons_putchar(portid, padchar);
430
431 while (ix -- > 0)
432 cons_putchar(portid, digits[ix]);
433
434 if (left) /* 左詰め */
435 for ( ; pad < width; pad ++)
436 cons_putchar(portid, padchar);
437
438 return pchars;
439 }
440
441/*
442 * put_ipv4addr -- IPv4 アドレス出力
443 */
444
445int_t
446put_ipv4addr (ID portid, T_IN4_ADDR *addr, int_t width)
447{
448 int_t len = 3; /* 3 は '.' の文字数 */
449
450 len += cons_putnumber(portid, (*addr >> 24) & 0xff, 10, radhex, 0, false, ' ');
451 cons_putchar(portid, '.');
452 len += cons_putnumber(portid, (*addr >> 16) & 0xff, 10, radhex, 0, false, ' ');
453 cons_putchar(portid, '.');
454 len += cons_putnumber(portid, (*addr >> 8) & 0xff, 10, radhex, 0, false, ' ');
455 cons_putchar(portid, '.');
456 len += cons_putnumber(portid, *addr & 0xff, 10, radhex, 0, false, ' ');
457
458 for ( ; len < width; len ++)
459 cons_putchar(portid, ' ');
460
461 return len;
462 }
463
464/*
465 * ipv6addr -- IPv6 アドレス出力
466 */
467
468int_t
469put_ipv6addr (ID portid, const T_IN6_ADDR *addr, int_t width)
470{
471 int_t len = 0, ix, len6;
472 bool_t omit = false, zero = false;
473
474 if (addr == NULL || IN6_IS_ADDR_UNSPECIFIED(addr)) {
475 cons_putchar(portid, '0');
476 cons_putchar(portid, ':');
477 cons_putchar(portid, ':');
478 cons_putchar(portid, '0');
479 len = 4;
480 }
481 else {
482 if (in6_is_addr_ipv4mapped(addr))
483 len6 = sizeof(T_IN6_ADDR) / 2 - 2;
484 else
485 len6 = sizeof(T_IN6_ADDR) / 2;
486 for (ix = 0; ix < len6; ix ++) {
487 if (omit) {
488 len += cons_putnumber(portid, ntohs(addr->s6_addr16[ix]), 16, radhex, 0, false, ' ');
489 if (ix < 7) {
490 cons_putchar(portid, ':');
491 len ++;
492 }
493 }
494 else if (ix > 0 && ix < 7 && addr->s6_addr16[ix] == 0)
495 zero = true;
496 else {
497 if (zero) {
498 omit = true;
499 cons_putchar(portid, ':');
500 len ++;
501 }
502 len += cons_putnumber(portid, ntohs(addr->s6_addr16[ix]), 16, radhex, 0, false, ' ');
503 if (ix < 7) {
504 cons_putchar(portid, ':');
505 len ++;
506 }
507 }
508 }
509
510 if (len6 == sizeof(T_IN6_ADDR) / 2 - 2) {
511 T_IN4_ADDR ip4addr;
512
513 ip4addr = ntohl(addr->s6_addr32[3]);
514 len += put_ipv4addr(portid, &ip4addr, 0);
515 }
516
517 for ( ; len < width; len ++)
518 cons_putchar(portid, ' ');
519 }
520 return len;
521 }
522
523/*
524 * put_macaddr -- MAC アドレス出力
525 */
526
527int_t
528put_macaddr (ID portid, uint8_t *mac, int_t width)
529{
530 int_t oct, len;
531
532 for (oct = 5; oct -- > 0; ) {
533 cons_putnumber(portid, *mac ++, 16, radhex, 2, false, '0');
534 cons_putchar(portid, ':');
535 }
536 cons_putnumber(portid, *mac, 16, radhex, 2, false, '0');
537
538 for (len = 17; len < width; len ++)
539 cons_putchar(portid, ' ');
540
541 return len;
542 }
543
544/*
545 * cons_printf -- シリアルポートへの書式付文字列出力
546 */
547
548void
549cons_printf (ID portid, const char *fmt, ...)
550{
551 va_list ap;
552 long_t val;
553 char padchar, *str;
554 int_t ch, width, longflag, shortflag, left;
555 T_IN4_ADDR *addr;
556
557 va_start(ap, fmt);
558 while ((ch = *fmt ++) != '\0') {
559 if (ch != '%') { /* 書式指定以外 */
560 cons_putchar(portid, (char)ch);
561 continue;
562 }
563
564 width = longflag = shortflag = 0;
565 padchar = ' ';
566
567 if (*fmt == '-') { /* 左詰め */
568 fmt ++;
569 left = -1;
570 }
571 else
572 left = 1;
573
574 if ((ch = *fmt ++) == '0') { /* 上位桁の 0 */
575 padchar = '0';
576 ch = *fmt ++;
577 }
578
579 while ('0' <= ch && ch <= '9') { /* 出力幅
580 */
581 width = width * 10 + ch - '0';
582 ch = *fmt ++;
583 }
584
585 while (ch == 'l') { /* long (long) の指定 */
586 longflag ++;
587 ch = *fmt ++;
588 }
589
590 while (ch == 'h') { /* short の指定 */
591 shortflag ++;
592 ch = *fmt ++;
593 }
594
595 switch (ch) {
596 case 'd':
597 val = longflag ? (ulong_t)va_arg(ap, long_t)
598 : (ulong_t)va_arg(ap, int_t);
599 if (val >= 0)
600 cons_putnumber(portid, val, 10, radhex, width * left, false, padchar);
601 else
602 cons_putnumber(portid, -val, 10, radhex, width * left, true, padchar);
603 break;
604
605 case 'u':
606 val = longflag ? (ulong_t)va_arg(ap, ulong_t)
607 : (ulong_t)va_arg(ap, uint_t);
608 cons_putnumber(portid, val, 10, radhex, width * left, false, padchar);
609 break;
610
611 case 'x':
612 val = longflag ? (ulong_t)va_arg(ap, ulong_t)
613 : (ulong_t)va_arg(ap, uint_t);
614 cons_putnumber(portid, val, 16, radhex, width * left, false, padchar);
615 break;
616
617 case 'X':
618 val = longflag ? (ulong_t)va_arg(ap, ulong_t)
619 : (ulong_t)va_arg(ap, uint_t);
620 cons_putnumber(portid, val, 16, radHEX, width * left, false, padchar);
621 break;
622
623 case 'c':
624 ch = va_arg(ap, int_t);
625 cons_putchar(portid, (char)ch);
626 break;
627
628 case 's':
629 str = va_arg(ap, char*);
630 while ((ch = *str ++) != '\0') {
631 cons_putchar(portid, (char)ch);
632 width --;
633 }
634 while (width -- > 0)
635 cons_putchar(portid, ' ');
636 break;
637
638 case 'I':
639
640 if (longflag) {
641 str = va_arg(ap, char*);
642 put_ipv6addr(portid, (T_IN6_ADDR *)str, width);
643 }
644 else if (shortflag) {
645 addr = va_arg(ap, T_IN4_ADDR *);
646 put_ipv4addr(portid, addr, width);
647 }
648 else {
649
650#if defined(SUPPORT_INET6)
651
652 str = va_arg(ap, char*);
653 put_ipv6addr(portid, (T_IN6_ADDR *)str, width);
654
655#else /* of #if defined(SUPPORT_INET6) */
656
657#if defined(SUPPORT_INET4)
658
659 addr = va_arg(ap, T_IN4_ADDR *);
660 put_ipv4addr(portid, addr, width);
661
662#endif /* of #if defined(SUPPORT_INET4) */
663
664#endif /* of #if defined(SUPPORT_INET6) */
665
666 }
667 break;
668
669 case 'M':
670 str = va_arg(ap, char*);
671 put_macaddr(portid, (uint8_t *)str, width);
672 break;
673
674 case '%':
675 cons_putchar(portid, '%');
676 break;
677
678 case '0':
679 fmt --;
680 break;
681
682 default:
683 break;
684 }
685
686 }
687 va_end(ap);
688 }
689
690/*
691 * host2msg16 -- 16ビットの値を、バイトオーダーを調整してメッセージに書き込む。
692 */
693
694void
695host2msg16 (void *msg, uint16_t host_data)
696{
697 uint16_t msg_data;
698
699 msg_data = htons(host_data);
700 memcpy(msg, &msg_data, sizeof(msg_data));
701 }
702
703/*
704 * host2msg32 -- 32ビットの値を、バイトオーダーを調整してメッセージに書き込む。
705 */
706
707void
708host2msg32 (void *msg, uint32_t host_data)
709{
710 uint32_t msg_data;
711
712 msg_data = htonl(host_data);
713 memcpy(msg, &msg_data, sizeof(msg_data));
714 }
715
716/*
717 * msg2host16 -- 16ビットの値を、バイトオーダーを調整してメッセージから読み出す。
718 */
719
720uint16_t
721msg2host16 (void *msg)
722{
723 uint16_t host_data;
724
725 memcpy(&host_data, msg, sizeof(host_data));
726 return htons(host_data);
727 }
728
729/*
730 * msg2host32 -- 32ビットの値を、バイトオーダーを調整してメッセージから読み出す。
731 */
732
733uint32_t
734msg2host32 (void *msg)
735{
736 uint32_t host_data;
737
738 memcpy(&host_data, msg, sizeof(host_data));
739 return htonl(host_data);
740 }
741
742/*
743 * skip_blanks -- 空白と TAB をスキップする。
744 */
745
746char *
747skip_blanks (char *line)
748{
749 while (*line == ' ' || *line == '\t')
750 line ++;
751 return line;
752 }
753
754/*
755 * get_ipv4addr -- 文字列の IPv4 アドレスを T_IN4_ADDR 値に変換する。
756 */
757
758char *
759get_ipv4addr (T_IN4_ADDR *addr, char *line)
760{
761 int_t oct;
762
763 *addr = IPV4_ADDRANY;
764 while ('0' <= *line && *line <= '9') {
765 oct = 0;
766 while ('0' <= *line && *line <= '9')
767 oct = oct * 10 + (*line ++) - '0';
768 *addr = (*addr << 8) | (oct & 0xff);
769 if (*line == '.')
770 line ++;
771 }
772#if 1
773 return *addr == IPV4_ADDRANY ? NULL : line;
774#else
775 return line;
776#endif
777 }
778
779#if defined(SUPPORT_INET6) || defined(USE_RESOLVER)
780
781/*
782 * get_ipv6addr -- 文字列の IPv6 アドレスを T_IN6_ADDR 値に変換する。
783 */
784
785char *
786get_ipv6addr (T_IN6_ADDR *addr, char *line)
787{
788 int_t word, ix = 0, omit = 0, six;
789 char *ipv4line;
790
791 memset(addr, 0, sizeof(T_IN6_ADDR));
792
793 /*
794 * IPv4 アドレス(数字.)を検出したら IPv4 アドレスとしてå…
795¥åŠ›ã—、
796 * IPv4 射影アドレスに変換する。
797 */
798 for (ipv4line = line; '0' <= *ipv4line && *ipv4line <= '9'; ipv4line ++)
799 ;
800 if (*ipv4line == '.') {
801 T_IN4_ADDR ipv4addr;
802
803 line = get_ipv4addr(&ipv4addr, line);
804 in6_make_ipv4mapped (addr, ipv4addr);
805 }
806 else {
807 while (ix < 8 &&
808 (('0' <= *line && *line <= '9') ||
809 ('a' <= *line && *line <= 'f') ||
810 ('A' <= *line && *line <= 'F'))) {
811 word = 0;
812 while (('0' <= *line && *line <= '9') ||
813 ('a' <= *line && *line <= 'f') ||
814 ('A' <= *line && *line <= 'F')) {
815 if ('0' <= *line && *line <= '9')
816 word = (word << 4) + (*line ++) - '0';
817 else if ('a' <= *line && *line <= 'f')
818 word = (word << 4) + (*line ++) - 'a' + 10;
819 else if ('A' <= *line && *line <= 'F')
820 word = (word << 4) + (*line ++) - 'A' + 10;
821 }
822 addr->s6_addr16[ix ++] = htons(word);
823 if (*line == ':') {
824 line ++;
825 if (*line == ':') {
826 omit = ix;
827 line ++;
828 }
829 }
830 }
831 if (omit > 0) {
832 six = 7;
833 while (ix > omit) {
834 addr->s6_addr16[six --] = addr->s6_addr16[-- ix];
835 addr->s6_addr16[ ix ] = 0;
836 }
837 }
838 }
839 return line;
840 }
841
842#endif /* of #if defined(SUPPORT_INET6) || defined(USE_RESOLVER) */
843
844/*
845 * デバッグ行å…
846¥åŠ›
847 */
848
849int_t
850cons_getline (ID portid, char *line, int_t size)
851{
852 int_t ch, len;
853
854 len = size;
855 while (size > 0) {
856 if ((ch = cons_getchar(portid)) != EOF) {
857 if (ch == '\r') {
858 cons_putchar(portid, '\n');
859 break;
860 }
861 else if (ch == '\b') {
862 if (size < len) {
863 line --;
864 size ++;
865 }
866 }
867 else {
868 *line ++ = ch;
869 size --;
870 }
871 }
872 }
873 *line = '\0';
874 return len - size;
875 }
876
877/*
878 * get_int -- 整数変換
879 */
880
881char *
882get_int (int_t *val, char *line)
883{
884 int_t sign = 1;
885
886 line = skip_blanks(line);
887 if (*line == '-') {
888 sign = -1;
889 line ++;
890 }
891 else if (*line == '+')
892 line ++;
893
894 line = skip_blanks(line);
895 *val = 0;
896 while ('0' <= *line && *line <= '9') {
897 *val = *val * 10 + *line - '0';
898 line ++;
899 }
900
901 *val = *val * sign;
902 return line;
903 }
904
905/*
906 * get_xuint -- 符号なし整数 (16進) 変換
907 */
908
909char *
910get_xuint (uint_t *val, char *line)
911{
912 line = skip_blanks(line);
913 *val = 0;
914 while (1) {
915 if ('0' <= *line && *line <= '9')
916 *val = (*val << 4) + *line - '0';
917 else if ('a' <= *line && *line <= 'f')
918 *val = (*val << 4) + *line - 'a' + 10;
919 else if ('A' <= *line && *line <= 'F')
920 *val = (*val << 4) + *line - 'A' + 10;
921 else
922 break;
923 line ++;
924 }
925 return line;
926 }
927
928#ifdef USE_RESOLVER
929
930/*
931 * dns_strtype -- DNS の type の文字列を返す。
932 */
933
934const char *
935dns_strtype (uint_t type)
936{
937 switch (type) {
938 case DNS_TYPE_A:
939 return "A";
940 break;
941 case DNS_TYPE_NS:
942 return "NS";
943 break;
944 case DNS_TYPE_CNAME:
945 return "CNAME";
946 break;
947 case DNS_TYPE_SOA:
948 return "SOA";
949 break;
950 case DNS_TYPE_PTR:
951 return "PTR";
952 break;
953 case DNS_TYPE_AAAA:
954 return "AAAA";
955 break;
956 default:
957 return "unknown type";
958 break;
959 }
960 }
961
962/*
963 * dns_strclass -- DNS の class を表示する。
964 */
965
966const char *
967dns_strclass (uint_t class)
968{
969 switch (class) {
970 case DNS_CLASS_IN:
971 return "IN";
972 break;
973 default:
974 return "unknown class";
975 break;
976 }
977 }
978
979/*
980 * resolv_hoststr -- 文字列のFQDN・ホスト名・IPv6/IPv4 アドレスを解析する。
981 */
982
983#define IS_HOSTCH_DIGIT(c) (('0'<=(c)&&(c)<='9'))
984#define IS_HOSTCH_XDIGIT(c) (IS_HOSTCH_DIGIT(c)||('a'<=(c)&&(c)<='f')||('A'<=(c)&&(c)<='F'))
985#define IS_HOSTCH_ALPHA(c) (('a'<=(c)&&(c)<='z')||('A'<=(c)&&(c)<='z'))
986#define IS_HOSTCH_ALNUM(c) (IS_HOSTCH_ALPHA(c)||IS_HOSTCH_DIGIT(c))
987#define IS_HOSTCH_IPV6ADDR(c) (IS_HOSTCH_XDIGIT(c)||(c)==':')
988#define IS_HOSTCH_IPV4ADDR(c) (IS_HOSTCH_DIGIT(c)||(c)=='.')
989#define IS_HOSTCH_IPADDR(c) (IS_HOSTCH_XDIGIT(c)||(c)==':'||(c)=='.')
990#define IS_HOSTCH_NAME_FIRST(c) (IS_HOSTCH_ALPHA(c))
991#define IS_HOSTCH_NAME(c) (IS_HOSTCH_ALNUM(c)||(c)=='-'||(c)=='.')
992#define IS_HOSTCH_BLANK(c) ((c)=='\0'||(c)==' '||(c)=='\t')
993
994char *
995resolv_hoststr (uint_t *flags, char *hostname, uint_t name_size, char *line)
996{
997 char *h, *p;
998
999 h = hostname;
1000 p = line = skip_blanks(line);
1001
1002 if (IS_HOSTCH_IPADDR(*p)) {
1003 while (IS_HOSTCH_DIGIT(*p)) {
1004 if (h - hostname > name_size)
1005 return NULL;
1006 *h ++ = *p ++;
1007 }
1008 if (p > line && *p == '.') {
1009 while (IS_HOSTCH_IPV4ADDR(*p)) {
1010 if (h - hostname > name_size)
1011 return NULL;
1012 *h ++ = *p ++;
1013 }
1014 if (IS_HOSTCH_BLANK(*p)) {
1015 *flags |= HOSTSTR_IPV4;
1016 *h = '\0';
1017 return p;
1018 }
1019 }
1020 else if (IS_HOSTCH_IPADDR(*p)) {
1021 while (IS_HOSTCH_IPADDR(*p)) {
1022 if (h - hostname > name_size)
1023 return NULL;
1024 *h ++ = *p ++;
1025 }
1026 if (IS_HOSTCH_BLANK(*p)) {
1027 *flags |= HOSTSTR_IPV6;
1028 *h = '\0';
1029 return p;
1030 }
1031 }
1032 h = hostname;
1033 p = line;
1034 }
1035
1036 if (IS_HOSTCH_NAME_FIRST(*p)) {
1037 *flags |= HOSTSTR_HOSTNAME;
1038 while (IS_HOSTCH_NAME(*p)) {
1039 if (h - hostname > name_size)
1040 return NULL;
1041 if (*p == '.')
1042 *flags |= HOSTSTR_FQDN;
1043 *h ++ = *p ++;
1044 }
1045 }
1046 else
1047 *flags |= HOSTSTR_OTHER;
1048
1049 *h = '\0';
1050 return p;
1051 }
1052
1053/*
1054 * show_dns_domain_name -- DNS のドメイン名を表示する。
1055 */
1056
1057uint_t
1058show_dns_domain_name (ID portid, uint8_t *hdr, uint_t offset)
1059{
1060 uint8_t *ptr;
1061 uint_t c;
1062
1063 ptr = hdr + offset;
1064 while (*ptr) {
1065 if ((*ptr & DNS_MSG_COMP_MARK) == DNS_MSG_COMP_MARK) {
1066 show_dns_domain_name(portid, hdr, (*ptr & ~DNS_MSG_COMP_MARK) << 8 | *(ptr + 1));
1067 ptr += 2;
1068 break;
1069 }
1070 else {
1071 for (c = 1; c <= *ptr; c++)
1072 cons_printf(portid, "%c", *(ptr + c));
1073 ptr += *ptr + 1;
1074 if (*ptr)
1075 cons_printf(portid, ".");
1076 }
1077 }
1078 return ptr - hdr;
1079 }
1080
1081/*
1082 * resolv_options -- アドレス解決のオプション解析
1083 */
1084
1085char *
1086resolv_options (uint_t *flags, char *line, char apip)
1087{
1088#if defined(SUPPORT_INET6)
1089 T_IN6_ADDR in6_addr;
1090#endif
1091
1092#if defined(SUPPORT_INET4)
1093 T_IN4_ADDR in4_addr;
1094#endif
1095
1096 line = skip_blanks(line);
1097
1098#if defined(SUPPORT_INET6)
1099
1100#if defined(SUPPORT_INET4)
1101
1102 *flags |= DNS_LUP_FLAGS_PROTO_IPV6 | DNS_LUP_FLAGS_PROTO_IPV4;
1103 if (apip == API_PROTO_IPV4)
1104 *flags |= DNS_LUP_FLAGS_QTYPE_A;
1105 else
1106 *flags |= DNS_LUP_FLAGS_QTYPE_AAAA;
1107
1108 if (*line == '-') {
1109 line ++;
1110 if (*line == '6') {
1111 line ++;
1112 *flags &= ~DNS_LUP_FLAGS_PROTO_IPV4;
1113 }
1114 else if (*line == '4') {
1115 line ++;
1116 *flags &= ~DNS_LUP_FLAGS_PROTO_IPV6;
1117 }
1118 if (*line == 'Q' || *line == 'q') {
1119 *flags &= ~DNS_LUP_FLAGS_QTYPE_A;
1120 line ++;
1121 }
1122 else if (*line == 'A' || *line == 'a') {
1123 *flags &= ~DNS_LUP_FLAGS_QTYPE_AAAA;
1124 line ++;
1125 }
1126 while (*line && !(*line == ' ' || *line == '\t'))
1127 line ++;
1128 }
1129
1130#else /* of #if defined(SUPPORT_INET4) */
1131
1132 *flags = DNS_LUP_FLAGS_PROTO_IPV6 | DNS_LUP_FLAGS_QTYPE_AAAA;
1133 if (*line == '-') {
1134 line ++;
1135 while (*line && !(*line == ' ' || *line == '\t'))
1136 line ++;
1137 }
1138
1139#endif /* of #if defined(SUPPORT_INET4) */
1140
1141#else /* of #if defined(SUPPORT_INET6) */
1142
1143#if defined(SUPPORT_INET4)
1144
1145 *flags = DNS_LUP_FLAGS_PROTO_IPV4 | DNS_LUP_FLAGS_QTYPE_A;
1146 if (*line == '-') {
1147 line ++;
1148 while (*line && !(*line == ' ' || *line == '\t'))
1149 line ++;
1150 }
1151
1152#endif /* of #if defined(SUPPORT_INET4) */
1153
1154#endif /* of #if defined(SUPPORT_INET6) */
1155
1156#if defined(SUPPORT_INET6)
1157
1158 if (*flags | DNS_LUP_FLAGS_PROTO_IPV6) {
1159 /*
1160 * IPv6 で DNS サーバにç…
1161§ä¼šã™ã‚‹ã“とが指定されても、
1162 * サーバの IPv6 アドレスが未定義の時は、指定を外す。
1163 */
1164 dns_in6_get_addr(&in6_addr);
1165 if (IN6_IS_ADDR_UNSPECIFIED(&in6_addr))
1166 *flags &= ~DNS_LUP_FLAGS_PROTO_IPV6;
1167 }
1168
1169#endif /* of #if defined(SUPPORT_INET6) */
1170
1171#if defined(SUPPORT_INET4)
1172
1173 if (*flags | DNS_LUP_FLAGS_PROTO_IPV4) {
1174 /*
1175 * IPv4 で DNS サーバにç…
1176§ä¼šã™ã‚‹ã“とが指定されても、
1177 * サーバの IPv4 アドレスが未定義の時は、指定を外す。
1178 */
1179 dns_in4_get_addr(&in4_addr);
1180 if (in4_addr == IPV4_ADDRANY)
1181 *flags &= ~DNS_LUP_FLAGS_PROTO_IPV4;
1182 }
1183
1184#endif /* of #if defined(SUPPORT_INET4) */
1185
1186 return line;
1187 }
1188
1189#endif /* of #ifdef USE_RESOLVER */
1190
1191/*
1192 * lookup_ipaddr -- ホスト名・リテラルのIPアドレスをIP アドレスに変換する。
1193 */
1194
1195char *
1196lookup_ipaddr (T_IN_ADDR *addr, char *line, char apip)
1197{
1198
1199#ifdef USE_RESOLVER
1200
1201 static char hostname[DBG_LINE_SIZE + 1];
1202
1203 ER_UINT error;
1204 uint_t flags = 0;
1205 char *last;
1206
1207 line = skip_blanks(resolv_options(&flags, line, apip));
1208 if ((last = resolv_hoststr(&flags, hostname, sizeof(hostname), line)) == NULL) {
1209 cons_printf(CONSOLE_PORTID, "unknown host: %s.\n", hostname);
1210 return NULL;
1211 }
1212
1213 switch (flags & DNS_LUP_FLAGS_NAME_MASK) {
1214 case DNS_LUP_FLAGS_NAME_IPV4:
1215 case DNS_LUP_FLAGS_NAME_IPV6:
1216 line = GET_IPADDR(addr, line); /* IP Address by Literal */
1217 break;
1218
1219 case DNS_LUP_FLAGS_NAME_HOST:
1220 case DNS_LUP_FLAGS_NAME_FQDN:
1221 line = last;
1222 if ((flags & (DNS_LUP_FLAGS_PROTO_IPV6 | DNS_LUP_FLAGS_PROTO_IPV4)) == 0) {
1223 cons_printf(CONSOLE_PORTID, "DNS server not available.\n");
1224 return NULL;
1225 }
1226
1227 flags |= DNS_LUP_OPCODE_FORWARD;
1228 if ((error = dns_host_addr(flags, hostname, addr)) != E_OK) {
1229 cons_printf(CONSOLE_PORTID, "error: %s.\n", itron_strerror(error));
1230 return NULL;
1231 }
1232 break;
1233
1234 }
1235
1236 return line;
1237
1238#else /* of #ifdef USE_RESOLVER */
1239
1240 return GET_IPADDR(addr, skip_blanks(line)); /* IP Address by Literal */
1241
1242#endif /* of #ifdef USE_RESOLVER */
1243
1244 }
1245
1246#endif /* of #ifdef USE_NETAPP_SUBR */
Note: See TracBrowser for help on using the repository browser.