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