source: azure_iot_hub/trunk/asp3_dcre/tinet/netapp/netapp_subr.c@ 388

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

Azure IoT Hub Device C SDK を使ったサンプルの追加

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