source: asp3_tinet_ecnl_arm/trunk/asp3_dcre/tinet/netapp/netapp_subr.c@ 352

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

arm向けASP3版ECNLを追加

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