source: EcnlProtoTool/trunk/asp3_dcre/tinet/netapp/resolver.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
File size: 30.3 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 * と.
29 * (a) 再é…
30å¸ƒã«ä¼´ã†ãƒ‰ã‚­ãƒ¥ãƒ¡ãƒ³ãƒˆï¼ˆåˆ©ç”¨è€…
31マニュアルなど)に,上記の著
32 * 作権表示,この利用条件および下記の無保証規定を掲載すること.
33 * (b) 再é…
34å¸ƒã®å½¢æ…
35‹ã‚’,別に定める方法によって,TOPPERSプロジェクトに
36 * 報告すること.
37 * (4) 本ソフトウェアの利用により直接的または間接的に生じるいかなる損
38 * 害からも,上記著作権者
39およびTOPPERSプロジェクトをå…
40è²¬ã™ã‚‹ã“と.
41 *
42 * 本ソフトウェアは,無保証で提供されているものである.上記著作権者
43お
44 * よびTOPPERSプロジェクトは,本ソフトウェアに関して,その適用可能性も
45 * 含めて,いかなる保証も行わない.また,本ソフトウェアの利用により直
46 * 接的または間接的に生じたいかなる損害に関しても,その責任を負わない.
47 *
48 * @(#) $Id$
49 */
50
51/*
52 * ホスト名←→IP アドレス変換
53 */
54
55#include <string.h>
56
57#ifdef TARGET_KERNEL_ASP
58
59#include <kernel.h>
60#include <t_syslog.h>
61#include <syssvc/logtask.h>
62#include "kernel_cfg.h"
63#include "tinet_cfg.h"
64
65#endif /* of #ifdef TARGET_KERNEL_ASP */
66
67#ifdef TARGET_KERNEL_JSP
68
69#include <s_services.h>
70#include <t_services.h>
71#include "kernel_id.h"
72#include "tinet_id.h"
73
74#endif /* of #ifdef TARGET_KERNEL_JSP */
75
76#include <tinet_config.h>
77
78#include <netinet/in.h>
79#include <netinet/in_itron.h>
80
81#include <netapp/netapp.h>
82#include <netapp/netapp_var.h>
83#include <netapp/resolver.h>
84
85#if defined(USE_RESOLVER)
86
87/*
88 * 局所変数
89 */
90
91static uint8_t dns_domain_name[DNS_NAME_LENGTH + 1] = RSLV_CFG_DNS_DOMAIN_NAME_STR;
92
93#if defined(SUPPORT_INET6)
94static T_IN6_ADDR in6_addr_dns = IPV6_ADDR_DNS_INIT;
95static T_IN6_ADDR in6_addr_dns_init = IPV6_ADDR_DNS_INIT;
96#endif
97
98#if defined(SUPPORT_INET4)
99static T_IN4_ADDR in4_addr_dns = IPV4_ADDR_DNS;
100#endif
101
102static uint16_t dns_msg_id = 0;
103
104/*
105 * get_dns_header -- DNS メッセージから DNS ヘッダを取り出す。
106 */
107
108static ER_UINT
109get_dns_header (uint8_t *msg, uint_t length, T_RSLV_DNS_MSG *rslv)
110{
111 T_DNS_HDR *dns_hdr;
112
113 /* DNS ヘッダを取り出す。*/
114 if (length < sizeof(rslv->dns_hdr))
115 return EV_RSLV_ESIZE;
116 dns_hdr = (T_DNS_HDR*)msg;
117 rslv->dns_hdr.id = MSG2HOST16(dns_hdr->id);
118 rslv->dns_hdr.code = MSG2HOST16(dns_hdr->code);
119 rslv->dns_hdr.qdcount = MSG2HOST16(dns_hdr->qdcount);
120 rslv->dns_hdr.ancount = MSG2HOST16(dns_hdr->ancount);
121 rslv->dns_hdr.nscount = MSG2HOST16(dns_hdr->nscount);
122 rslv->dns_hdr.arcount = MSG2HOST16(dns_hdr->arcount);
123 return sizeof(rslv->dns_hdr);
124 }
125
126/*
127 * dns_strtype -- DNS の type の文字列を返す。
128 */
129
130static const char *
131dns_flag_qtype (uint16_t flags)
132{
133 if (flags & DNS_LUP_FLAGS_QTYPE_AAAA)
134 return "AAAA";
135 else if (flags & DNS_LUP_FLAGS_QTYPE_A)
136 return " A";
137 else if (flags & DNS_LUP_FLAGS_QTYPE_PTR)
138 return " PTR";
139 else
140 return "unknown type";
141 }
142
143#if defined(SUPPORT_INET6)
144
145/*
146 * udp6_dns -- UDP/IPv6 により DNS サーバからメッセージを受信する。
147 */
148
149static ER
150udp6_dns (uint16_t flags, T_IN6_ADDR *addr, uint8_t *msg, uint_t msg_size, uint_t length)
151{
152 T_IPV6EP ep_dns;
153 ER_UINT len = E_OK;
154 int retry;
155
156 /* DNS サーバの IPv6 アドレスが未定義の時はパラメータエラー */
157 if (IN6_IS_ADDR_UNSPECIFIED(addr) || (in6_is_addr_ipv4mapped(addr) && addr->s6_addr32[3] == IPV4_ADDRANY)) {
158 syslog(LOG_NOTICE, "[RSLV] undefined IPv6 DNS server address.");
159 return E_PAR;
160 }
161
162 memcpy(&ep_dns.ipaddr, addr, sizeof(*addr));
163 ep_dns.portno = RSLV_CFG_DNS_PORTNO;
164 for (retry = NUM_DNS_UDP_RETRY + 1; retry -- > 0; ) {
165 if ((len = udp6_snd_dat(UDP6_RESOLVER_CEPID, &ep_dns, msg, length, TMO_DNS_UDP_SND)) >= 0) {
166 if ((len = udp6_rcv_dat(UDP6_RESOLVER_CEPID, &ep_dns, msg, msg_size, TMO_DNS_UDP_RCV)) >= 0)
167 return len;
168 }
169 if (flags & DNS_LUP_FLAGS_MSG) {
170 if (len == E_TMOUT)
171 syslog(LOG_NOTICE, "[RSLV] TMOUT: %d, type: %s, server: %s.%d.",
172 NUM_DNS_UDP_RETRY + 1 - retry,
173 dns_flag_qtype(flags),
174 ipv62str(NULL, &ep_dns.ipaddr), ep_dns.portno);
175 else {
176 syslog(LOG_NOTICE, "[RSLV] error: %s, type: %s,\n server: %s.%d.",
177 itron_strerror(len),
178 dns_flag_qtype(flags),
179 ipv62str(NULL, &ep_dns.ipaddr), ep_dns.portno);
180 return len;
181 }
182 }
183 }
184 return E_TMOUT;
185 }
186
187#endif /* of #if defined(SUPPORT_INET6) */
188
189#if defined(SUPPORT_INET4)
190
191/*
192 * udp4_dns -- UDP/IPv4 により DNS サーバからメッセージを受信する。
193 */
194
195static ER
196udp4_dns (uint16_t flags, T_IN4_ADDR *addr, uint8_t *msg, uint_t msg_size, uint_t length)
197{
198 T_IPV4EP ep_dns;
199 ER_UINT len = E_OK;
200 int retry;
201
202 /* DNS サーバの IPv4 アドレスが未定義の時はパラメータエラー */
203 if (*addr == IPV4_ADDRANY) {
204 syslog(LOG_NOTICE, "[RSLV] undefined IPv4 DNS server address.");
205 return E_PAR;
206 }
207
208 memcpy(&ep_dns.ipaddr, addr, sizeof(*addr));
209 ep_dns.portno = RSLV_CFG_DNS_PORTNO;
210 for (retry = NUM_DNS_UDP_RETRY + 1; retry -- > 0; ) {
211 if ((len = udp_snd_dat(UDP4_RESOLVER_CEPID, &ep_dns, msg, length, TMO_DNS_UDP_SND)) >= 0) {
212 if ((len = udp_rcv_dat(UDP4_RESOLVER_CEPID, &ep_dns, msg, msg_size, TMO_DNS_UDP_RCV)) >= 0)
213 return len;
214 }
215 if (flags & DNS_LUP_FLAGS_MSG) {
216 if (len == E_TMOUT)
217 syslog(LOG_NOTICE, "[RSLV] TMOUT: %d, type: %s, server: %s.%d.",
218 NUM_DNS_UDP_RETRY + 1 - retry,
219 dns_flag_qtype(flags),
220 ip2str(NULL, &ep_dns.ipaddr), ep_dns.portno);
221 else {
222 syslog(LOG_NOTICE, "[RSLV] error: %s, type: %s, server: %s.%d.",
223 itron_strerror(len),
224 dns_flag_qtype(flags),
225 ip2str(NULL, &ep_dns.ipaddr), ep_dns.portno);
226 return len;
227 }
228 }
229 }
230 return E_TMOUT;
231 }
232
233#endif /* of #if defined(SUPPORT_INET4) */
234
235/*
236 * skip_label -- ラベルを読み飛ばす。
237 */
238
239static char *
240skip_label (char *name)
241{
242 while (!(*name == '\0' || *name == '.'))
243 name ++;
244 return name;
245 }
246
247/*
248 * add_name -- メッセージに名前を追加する。
249 */
250
251static ER_UINT
252add_name (uint8_t *msg, uint_t size, uint_t offset, char *name)
253{
254 uint_t label_len;
255 uint8_t *tail;
256
257 while (*name != '\0') {
258
259 /* メッセージサイズに達していたらエラー */
260 if (offset + 1 > size)
261 return E_BOVR;
262
263 /* ラベルの終わりを見つける。*/
264 tail = skip_label(name);
265
266 /* ラベル長を設定する。*/
267 label_len = tail - (uint8_t*)name;
268 if (label_len > DNS_LABEL_LENGTH) { /* 63 オクテットを超
269えるとエラー */
270 syslog(LOG_NOTICE, "[RSLV] label length(%d) too long > %d.",
271 label_len, DNS_LABEL_LENGTH);
272 return E_PAR;
273 }
274
275 *(msg + offset) = (uint8_t)label_len;
276 offset ++;
277
278 /* ラベル名を設定する。*/
279 if (offset + label_len > size) { /* メッセージサイズを超
280えるとエラー */
281 syslog(LOG_NOTICE, "[RSLV] message length(%d) too long > %d.",
282 offset + label_len, size);
283 return E_BOVR;
284 }
285
286 memcpy((void*)(msg + offset), (void*)name, label_len);
287 offset += label_len;
288
289 /* 次のラベルに移動する。*/
290 if (*tail == '\0')
291 name = tail;
292 else
293 name = tail + 1; /* '.' をスキップする。*/
294 }
295
296 return offset;
297 }
298
299/*
300 * add_ipv6addr -- メッセージに IPv6 アドレスを追加する。
301 */
302
303static ER_UINT
304add_ipv6addr (uint8_t *msg, uint_t size, uint_t offset, char *name)
305{
306 T_IN6_ADDR addr;
307 ER_UINT error;
308 uint_t len;
309 int col;
310 char digit[2];
311
312 len = strlen(name);
313 if (len == 0)
314 return E_PAR;
315
316 digit[1] = '\0';
317 get_ipv6addr(&addr, name);
318 for (col = sizeof(T_IN6_ADDR) * 2; -- col >= 0; ) {
319
320 /* 16進数 1桁の値を、名前として追加する。*/
321 digit[0] = (addr.s6_addr8[col / 2] >> ((1 - (col % 2)) << 2)) & 0x0f;
322 if (digit[0] >= 10)
323 digit[0] += 'a' - 10;
324 else
325 digit[0] += '0';
326 if ((error = add_name(msg, size, offset, digit)) < 0)
327 return error;
328 offset = error;
329 }
330
331 /* "ip6" を追加する。*/
332 if ((error = add_name(msg, size, offset, "ip6")) < 0)
333 return error;
334
335 /* "arpa" を追加する。*/
336 return add_name(msg, size, error, "arpa");
337 }
338
339/*
340 * add_ipv4addr -- メッセージに IPv4 アドレスを追加する。
341 */
342
343static ER_UINT
344add_ipv4addr (uint8_t *msg, uint_t size, uint_t offset, char *name)
345{
346 T_IN4_ADDR addr;
347 ER_UINT error;
348 uint_t len, octet;
349 int col;
350 char *op, ostr[4];
351
352 len = strlen(name);
353 if (len == 0)
354 return E_PAR;
355
356 ostr[3] = '\0';
357 get_ipv4addr(&addr, name);
358 for (col = 0; col < sizeof(T_IN4_ADDR); col ++) {
359
360 /* 1オクテットの値を、整数値からリテラルに変換する。*/
361 octet = (addr >> (col << 3)) & 0xff;
362 op = &ostr[3];
363 while (octet > 0) {
364 *(-- op) = octet % 10 + '0';
365 octet /= 10;
366 }
367
368 /* 1オクテットの値を、名前として追加する。*/
369 if ((error = add_name(msg, size, offset, op)) < 0)
370 return error;
371 offset = error;
372 }
373
374 /* "in-addr" を追加する。*/
375 if ((error = add_name(msg, size, offset, "in-addr")) < 0)
376 return error;
377
378 /* "arpa" を追加する。*/
379 return add_name(msg, size, error, "arpa");
380 }
381
382/*
383 * setup_dns_msg -- DNS メッセージを作成する。
384 */
385
386static ER
387setup_dns_msg (uint16_t flags, char *name, uint8_t *msg, uint_t msg_size)
388{
389 T_DNS_HDR dns_hdr;
390 ER_UINT offset;
391
392 memset((void*)&dns_hdr, 0, sizeof(dns_hdr));
393
394 dns_msg_id++;
395 HOST2MSG16(dns_hdr.id, dns_msg_id);
396 HOST2MSG16(dns_hdr.code, (flags & DNS_OPCODE_MASK) | DNS_RECURSION_DESIRED);
397 HOST2MSG16(dns_hdr.qdcount, 1);
398
399 memcpy((void*)msg, (void*)&dns_hdr, sizeof(dns_hdr));
400 offset = sizeof(dns_hdr);
401
402 switch (flags & DNS_LUP_FLAGS_NAME_MASK) {
403
404 case DNS_LUP_FLAGS_NAME_HOST:
405 case DNS_LUP_FLAGS_NAME_FQDN:
406
407 /* ホスト名、または FQDN の時の処理。*/
408 /* ホスト名を追加する。*/
409 if ((offset = add_name(msg, msg_size, offset, name)) < 0)
410 return offset;
411
412 if (offset - sizeof(dns_hdr) > DNS_NAME_LENGTH) { /* 名前が 255 オクテットを超
413えるとエラー */
414 syslog(LOG_NOTICE, "[RSLV] name length(%d) too long > %d.",
415 offset - sizeof(dns_hdr), DNS_NAME_LENGTH);
416 return E_PAR;
417 }
418
419 /* ホスト名だけの時は、ドメイン名を追加する。*/
420 if ((flags & DNS_LUP_FLAGS_NAME_MASK) == DNS_LUP_FLAGS_NAME_HOST) {
421
422 /* ドメイン名を追加する。*/
423 if ((offset = add_name(msg, msg_size, offset, dns_domain_name)) < 0)
424 return offset;
425
426 if (offset - sizeof(dns_hdr) > DNS_NAME_LENGTH) { /* 名前が 255 オクテットを超
427えるとエラー */
428 syslog(LOG_NOTICE, "[RSLV] name length(%d) too long > %d.",
429 offset - sizeof(dns_hdr), DNS_NAME_LENGTH);
430 return E_PAR;
431 }
432 }
433 break;
434
435 case DNS_LUP_FLAGS_NAME_IPV4:
436 if ((offset = add_ipv4addr(msg, msg_size, offset, name)) < 0)
437 return offset;
438 break;
439
440 case DNS_LUP_FLAGS_NAME_IPV6:
441 if ((offset = add_ipv6addr(msg, msg_size, offset, name)) < 0)
442 return offset;
443 break;
444
445 default:
446 syslog(LOG_NOTICE, "[RSLV] unknown name type: %04x.", flags & DNS_LUP_FLAGS_NAME_MASK);
447 return E_PAR;
448 break;
449
450 }
451
452 /* 名前の終了コード、TYPE、CLASS を追加してもメッセージ長を超
453えないことを確認する。*/
454 if (offset + sizeof(uint16_t) * 2 + 1 > msg_size) {
455 syslog(LOG_NOTICE, "[RSLV] message length(%d) too long > %d.",
456 offset + sizeof(uint16_t) * 2 + 1, msg_size);
457 return E_BOVR;
458 }
459
460 /* 名前の終了コードを設定する。*/
461 *(msg + offset) = '\0';
462 offset ++;
463
464 /* DNS の TYPE を設定する。*/
465 if (flags & DNS_LUP_FLAGS_QTYPE_PTR)
466 host2msg16(msg + offset, DNS_TYPE_PTR);
467 else if (flags & DNS_LUP_FLAGS_QTYPE_AAAA)
468 host2msg16(msg + offset, DNS_TYPE_AAAA);
469 else if (flags & DNS_LUP_FLAGS_QTYPE_A)
470 host2msg16(msg + offset, DNS_TYPE_A);
471 else {
472 syslog(LOG_NOTICE, "[RSLV] unknown query type: %04x.", flags & DNS_LUP_FLAGS_QTYPE_MASK);
473 return E_PAR;
474 }
475 offset += sizeof(uint16_t);
476
477 /* DNS の CLASS を設定する。*/
478 host2msg16(msg + offset, DNS_CLASS_IN);
479
480 return offset + sizeof(uint16_t);
481 }
482
483/*
484 * skip_dns_name -- DNS メッセージの名前を読み飛ばす。
485 *
486 * 注意: 圧縮形式を考æ…
487®ã™ã‚‹ã€‚上位 2ビットが 11なら圧縮形式。
488 */
489
490static ER_UINT
491skip_dns_name (uint8_t *name, uint_t offset, uint_t length)
492{
493 while (*(name + offset)) {
494 if ((*(name + offset) & 0xc0) == 0xc0) {
495 if (offset + 2 > length)
496 return EV_RSLV_ESIZE;
497 else
498 return offset + 2;
499 }
500 else if (offset + *name + 1 > length)
501 return EV_RSLV_ESIZE;
502 else
503 offset += *name + 1;
504 }
505 return offset + 1;
506 }
507
508/*
509 * skip_dns_qd -- DNS Question section を読み飛ばす。
510 */
511
512static ER_UINT
513skip_dns_qd (uint8_t *msg, uint_t offset, uint_t length, uint_t count)
514{
515 ER_UINT next;
516
517 while (count != 0) {
518 /* name を読み飛ばす。*/
519 if ((next = skip_dns_name(msg, offset, length)) < 0)
520 return next;
521 offset = next;
522
523 /* type、class を読み飛ばす。*/
524 if ((offset + sizeof(uint16_t) + sizeof(uint16_t)) > length)
525 return EV_RSLV_ESIZE;
526 offset += sizeof(uint16_t) + sizeof(uint16_t);
527
528 count --;
529 }
530
531 return offset;
532 }
533
534/*
535 * skip_dns_rr -- DNS RR を読み飛ばす。
536 */
537
538static ER_UINT
539skip_dns_rr (uint8_t *msg, uint_t offset, uint_t length, uint_t count)
540{
541 ER_UINT next;
542 uint16_t len = 0;
543
544 while (count != 0) {
545 /* name を読み飛ばす。*/
546 if ((next = skip_dns_name(msg, offset, length)) < 0)
547 return next;
548 offset = next;
549
550 /* type、class、TTL を読み飛ばす。*/
551 if (offset + sizeof(uint16_t) + sizeof(uint16_t) + sizeof(uint32_t) > length)
552 return EV_RSLV_ESIZE;
553 offset += sizeof(uint16_t) + sizeof(uint16_t) + sizeof(uint32_t);
554
555 /* RD length と RDATA を読み飛ばす。*/
556 if (offset + sizeof(uint16_t) > length)
557 return EV_RSLV_ESIZE;
558 len = msg2host16(msg + offset);
559
560 if (offset + sizeof(uint16_t) + len > length)
561 return EV_RSLV_ESIZE;
562 offset += sizeof(uint16_t) + len;
563
564 count --;
565 }
566
567 return offset;
568 }
569
570/*
571 * dns_analyze_qd -- DNS メッセージの question section を解析する。
572 */
573
574ER_UINT
575dns_analyze_qd (T_RSLV_QD *qd, uint_t offset, uint8_t *msg, uint_t length)
576{
577 ER_UINT error;
578 T_DNS_QD *dns_qd;
579
580 if ((error = skip_dns_name(msg, offset, length)) < 0)
581 return error;
582 offset = error;
583
584 /* DNS メッセージ内
585の形式のサイズでチェックする。*/
586 if (offset + T_DNS_QD_SIZE > length)
587 return EV_RSLV_ESIZE;
588
589 /*
590 * DNS メッセージ内
591の SOA RDATA をバイトオーダーを調整して
592 * 内
593部構造体にコピーする。
594 */
595 dns_qd = (T_DNS_QD*)(msg + offset);
596 qd->type = MSG2HOST16(dns_qd->type);
597 qd->class = MSG2HOST16(dns_qd->class);
598
599 return offset + T_DNS_QD_SIZE;
600 }
601
602/*
603 * dns_analyze_soa -- DNS メッセージの SOA RDATA を解析する。
604 */
605
606ER_UINT
607dns_analyze_soa (T_RSLV_SOA *soa, uint_t offset, uint8_t *msg, uint_t length)
608{
609 ER_UINT error;
610 T_DNS_SOA *dns_soa;
611
612 /* MNAME をスキップする。*/
613 if ((error = skip_dns_name(msg, offset, length)) < 0)
614 return error;
615 offset = error;
616
617 /* RNAME をスキップする。*/
618 if ((error = skip_dns_name(msg, offset, length)) < 0)
619 return error;
620 offset = error;
621
622 /* DNS メッセージ内
623の形式のサイズでチェックする。*/
624 if (offset + T_DNS_SOA_SIZE > length)
625 return EV_RSLV_ESIZE;
626
627 /*
628 * DNS メッセージ内
629の SOA RDATA をバイトオーダーを調整して
630 * 内
631部構造体にコピーする。
632 */
633 dns_soa = (T_DNS_SOA*)(msg + offset);
634 soa->serial = MSG2HOST32(dns_soa->serial);
635 soa->refresh = MSG2HOST32(dns_soa->refresh);
636 soa->retry = MSG2HOST32(dns_soa->retry);
637 soa->expire = MSG2HOST32(dns_soa->expire);
638 soa->minimum = MSG2HOST32(dns_soa->minimum);
639
640 return offset + T_DNS_SOA_SIZE;
641 }
642
643/*
644 * dns_analyze_rr -- DNS メッセージの AN/NS/AR section を解析する。
645 */
646
647ER_UINT
648dns_analyze_rr (T_RSLV_RR *rr, uint_t offset, uint8_t *msg, uint_t length)
649{
650 ER_UINT error;
651 T_DNS_RR *dns_rr;
652
653 if ((error = skip_dns_name(msg, offset, length)) < 0)
654 return error;
655 offset = error;
656
657 /* DNS メッセージ内
658の形式のサイズでチェックする。*/
659 if (offset + T_DNS_RR_SIZE > length)
660 return EV_RSLV_ESIZE;
661
662 /*
663 * DNS メッセージ内
664の SOA RDATA をバイトオーダーを調整して
665 * 内
666部構造体にコピーする。
667 */
668 dns_rr = (T_DNS_RR*)(msg + offset);
669 rr->type = MSG2HOST16(dns_rr->type);
670 rr->class = MSG2HOST16(dns_rr->class);
671 rr->ttl = MSG2HOST32(dns_rr->ttl);
672 rr->rdlength = MSG2HOST16(dns_rr->rdlength);
673 rr->rdata_offset= offset + sizeof(rr->type) + sizeof(rr->class)
674 + sizeof(rr->ttl) + sizeof(rr->rdlength);
675
676 return offset + T_DNS_RR_SIZE + rr->rdlength;
677 }
678
679/*
680 * analyze_dns_msg -- DNS メッセージを解析する。
681 */
682
683static ER_UINT
684analyze_dns_msg (uint8_t *msg, uint_t length, T_RSLV_DNS_MSG *rslv)
685{
686 ER_UINT offset;
687
688 /* DNS ヘッダを取り出す。*/
689 if ((offset = get_dns_header(msg, length, rslv)) < 0)
690 return offset;
691
692 /* question section を読み飛ばす。*/
693 rslv->qd_offset = offset;
694 if ((offset = skip_dns_qd(msg, offset, length, rslv->dns_hdr.qdcount)) < 0)
695 return offset;
696
697 /* answer section を読み飛ばす。*/
698 rslv->an_offset = offset;
699 if ((offset = skip_dns_rr(msg, offset, length, rslv->dns_hdr.ancount)) < 0)
700 return offset;
701
702 /* authority records section を読み飛ばす。*/
703 rslv->ns_offset = offset;
704 if ((offset = skip_dns_rr(msg, offset, length, rslv->dns_hdr.nscount)) < 0)
705 return offset;
706
707 /* additional records section を読み飛ばす。*/
708 rslv->ar_offset = offset;
709 if ((offset = skip_dns_rr(msg, offset, length, rslv->dns_hdr.arcount)) < 0)
710 return offset;
711
712 return E_OK;
713 }
714
715/*
716 * dns_lookup_host_sub -- DNS によりホストの情
717報を取得する(補助関数)。
718 */
719
720static ER_UINT
721dns_lookup_host_sub (uint16_t flags, char *hostname, uint8_t *msg,
722 uint_t msg_size, T_RSLV_DNS_MSG *rslv)
723{
724#if defined(SUPPORT_INET6) && defined(SUPPORT_INET4)
725 uint16_t proto;
726#endif
727 ER_UINT length;
728 ER error;
729
730 if ((length = setup_dns_msg(flags, hostname, msg, msg_size)) < 0)
731 return length;
732
733#if defined(SUPPORT_INET6)
734
735#if defined(SUPPORT_INET4)
736
737 if (flags & DNS_LUP_FLAGS_PROTO_IPV6) {
738 proto = DNS_LUP_FLAGS_PROTO_IPV6;
739 if ((length = udp6_dns(flags, &in6_addr_dns, msg, msg_size, length)) < 0)
740 return length;
741 }
742 else if (flags & DNS_LUP_FLAGS_PROTO_IPV4) {
743 proto = DNS_LUP_FLAGS_PROTO_IPV4;
744 if ((length = udp4_dns(flags, &in4_addr_dns, msg, msg_size, length)) < 0)
745 return length;
746 }
747 else {
748 syslog(LOG_NOTICE, "[RSLV] unknown lookup protocol: %04x.", flags & DNS_LUP_FLAGS_PROTO_MASK);
749 return E_PAR;
750 }
751
752#else /* of #if defined(SUPPORT_INET4) */
753
754 if (flags & DNS_LUP_FLAGS_PROTO_IPV6) {
755 if ((length = udp6_dns(flags, &in6_addr_dns, msg, msg_size, length)) < 0)
756 return length;
757 }
758 else {
759 syslog(LOG_NOTICE, "[RSLV] unknown lookup protocol: %04x.", flags & DNS_LUP_FLAGS_PROTO_MASK);
760 return E_PAR;
761 }
762
763#endif /* of #if defined(SUPPORT_INET4) */
764
765#else /* of #if defined(SUPPORT_INET6) */
766
767#if defined(SUPPORT_INET4)
768
769 if (flags & DNS_LUP_FLAGS_PROTO_IPV4) {
770 if ((length = udp4_dns(flags, &in4_addr_dns, msg, msg_size, length)) < 0)
771 return length;
772 }
773 else {
774 syslog(LOG_NOTICE, "[RSLV] unknown lookup protocol: %04x.", flags & DNS_LUP_FLAGS_PROTO_MASK);
775 return E_PAR;
776 }
777
778#endif /* of #if defined(SUPPORT_INET4) */
779
780#endif /* of #if defined(SUPPORT_INET6) */
781
782 if ((error = analyze_dns_msg(msg, length, rslv)) != E_OK)
783 return error;
784 else {
785 if ((rslv->dns_hdr.ancount > 0) && (flags & DNS_LUP_FLAGS_MSG)) {
786
787#if defined(SUPPORT_INET6)
788
789#if defined(SUPPORT_INET4)
790
791 if (proto & DNS_LUP_FLAGS_PROTO_IPV6) {
792 syslog(LOG_NOTICE, "[RSLV] reslv: type: %s, server: %s.%d.",
793 dns_flag_qtype(flags),
794 ipv62str(NULL, &in6_addr_dns),
795 RSLV_CFG_DNS_PORTNO);
796 }
797 else {
798 syslog(LOG_NOTICE, "[RSLV] reslv: type: %s, server: %s.%d.",
799 dns_flag_qtype(flags),
800 ip2str(NULL, &in4_addr_dns),
801 RSLV_CFG_DNS_PORTNO);
802 }
803
804#else /* of #if defined(SUPPORT_INET4) */
805
806 syslog(LOG_NOTICE, "[RSLV] reslv: type: %s, server: %s.%d.",
807 dns_flag_qtype(flags),
808 ipv62str(NULL, &in6_addr_dns),
809 RSLV_CFG_DNS_PORTNO);
810
811#endif /* of #if defined(SUPPORT_INET4) */
812
813#else /* of #if defined(SUPPORT_INET6) */
814
815#if defined(SUPPORT_INET4)
816
817 syslog(LOG_NOTICE, "[RSLV] reslv: type: %s, server: %s.%d.",
818 dns_flag_qtype(flags),
819 ip2str(NULL, &in4_addr_dns),
820 RSLV_CFG_DNS_PORTNO);
821
822#endif /* of #if defined(SUPPORT_INET4) */
823
824#endif /* of #if defined(SUPPORT_INET6) */
825
826 }
827 return length;
828 }
829 }
830
831#if defined(SUPPORT_INET6) && defined(SUPPORT_INET4)
832
833/*
834 * udp64_dns -- DNS/IPv6、DNS/IPv4 により DNS サーバからメッセージを受信する。
835 */
836
837static ER_UINT
838udp64_dns (uint16_t flags, char *hostname, uint8_t *msg,
839 uint_t msg_size, T_RSLV_DNS_MSG *rslv)
840{
841 ER_UINT length;
842 ER error;
843 uint16_t proto;
844
845 /* DNS メッセージを作成する。*/
846 if ((length = setup_dns_msg(flags, hostname, msg, msg_size)) < 0)
847 return length;
848
849 /* UDP/IPv6 の DNS サーバにç…
850§ä¼šã™ã‚‹ã€‚*/
851 proto = DNS_LUP_FLAGS_PROTO_IPV6;
852 if ((length = udp6_dns(flags, &in6_addr_dns, msg, msg_size, length)) < 0) {
853 /* UDP/IPv6 の DNS サーバへのç…
854§ä¼šãŒã‚¨ãƒ©ãƒ¼ã«ãªã£ãŸæ™‚は、UDP/IPv4 の DNS サーバにç…
855§ä¼šã™ã‚‹ã€‚*/
856 if ((length = setup_dns_msg(flags, hostname, msg, msg_size)) < 0)
857 return length;
858
859 /* UDP/IPv4 の DNS サーバにç…
860§ä¼šã™ã‚‹ã€‚*/
861 proto = DNS_LUP_FLAGS_PROTO_IPV4;
862 if ((length = udp4_dns(flags, &in4_addr_dns, msg, msg_size, length)) < 0)
863 return length;
864 }
865
866 /* DNS メッセージを解析する。*/
867 if ((error = analyze_dns_msg(msg, length, rslv)) != E_OK)
868 return error;
869 else {
870 if ((rslv->dns_hdr.ancount > 0) && (flags & DNS_LUP_FLAGS_MSG)) {
871 if (proto & DNS_LUP_FLAGS_PROTO_IPV6) {
872 syslog(LOG_NOTICE, "[RSLV] reslv: type: %s, server: %s.%d.",
873 dns_flag_qtype(flags),
874 ipv62str(NULL, &in6_addr_dns),
875 RSLV_CFG_DNS_PORTNO);
876 }
877 else {
878 syslog(LOG_NOTICE, "[RSLV] reslv: type: %s, server: %s.%d.",
879 dns_flag_qtype(flags),
880 ip2str(NULL, &in4_addr_dns),
881 RSLV_CFG_DNS_PORTNO);
882 }
883 }
884 return length;
885 }
886 }
887
888#endif /* of #if defined(SUPPORT_INET6) && defined(SUPPORT_INET4) */
889
890/*
891 * dns_lookup_host -- DNS によりホストの情
892報を取得する。
893 */
894
895ER_UINT
896dns_lookup_host (uint16_t flags, char *hostname, uint8_t *msg,
897 uint_t msg_size, T_RSLV_DNS_MSG *rslv)
898{
899 ER error;
900
901#if defined(SUPPORT_INET6) && defined(SUPPORT_INET4)
902
903 if ((flags & DNS_LUP_FLAGS_PROTO_MASK) == (DNS_LUP_FLAGS_PROTO_IPV6 | DNS_LUP_FLAGS_PROTO_IPV4)) {
904
905 /*
906 * IPv6/IPv4 の両方が指定された時の処理
907 * まず type == AAAA で DNS サーバにç…
908§ä¼šã™ã‚‹ã€‚
909 */
910 if (flags & DNS_LUP_FLAGS_QTYPE_PTR) {
911 if ((error = udp64_dns(flags, hostname, msg, msg_size, rslv)) < 0)
912 return error;
913 }
914 else if (flags & DNS_LUP_FLAGS_QTYPE_AAAA) {
915 if ((error = udp64_dns(flags & ~DNS_LUP_FLAGS_QTYPE_A, hostname, msg, msg_size, rslv)) < 0)
916 return error;
917 }
918 else {
919 HOST2MSG16(rslv->dns_hdr.ancount, 0);
920 error = E_OK;
921 }
922
923 if (rslv->dns_hdr.ancount == 0) {
924
925 /*
926 * type == AAAA でアドレス解決ができなかった時の処理
927 * type == A で DNS サーバにç…
928§ä¼šã™ã‚‹ã€‚
929 */
930 if (flags & DNS_LUP_FLAGS_QTYPE_A)
931 return udp64_dns(flags & ~DNS_LUP_FLAGS_QTYPE_AAAA, hostname, msg, msg_size, rslv);
932 else {
933 syslog(LOG_NOTICE, "[RSLV] unknown query type: %04x.", flags & DNS_LUP_FLAGS_QTYPE_MASK);
934 return E_PAR;
935 }
936 }
937 else
938 return error;
939 }
940
941 if ((flags & DNS_LUP_FLAGS_QTYPE_MASK) == (DNS_LUP_FLAGS_QTYPE_AAAA | DNS_LUP_FLAGS_QTYPE_A)) {
942
943 /*
944 * type == AAAA と A の両方が指定された時の処理
945 * まず type == AAAA で DNS サーバにç…
946§ä¼šã™ã‚‹ã€‚
947 */
948 if ((error = dns_lookup_host_sub(flags & ~DNS_LUP_FLAGS_QTYPE_A, hostname, msg, msg_size, rslv)) < 0)
949 return error;
950
951 if (rslv->dns_hdr.ancount == 0) {
952
953 /*
954 * type == AAAA でアドレス解決ができなかった時の処理
955 * type == A で DNS サーバにç…
956§ä¼šã™ã‚‹ã€‚
957 */
958 return dns_lookup_host_sub(flags & ~DNS_LUP_FLAGS_QTYPE_AAAA, hostname, msg, msg_size, rslv);
959 }
960#if 0
961 else {
962 syslog(LOG_NOTICE, "[RSLV] unknown query type: %04x.", flags & DNS_LUP_FLAGS_QTYPE_MASK);
963 return E_PAR;
964 }
965#endif
966 }
967
968 else {
969 /* IPv6/IPv4 のどちらか一方が指定された時の処理 */
970 error = dns_lookup_host_sub(flags, hostname, msg, msg_size, rslv);
971 }
972
973#else /* of #if defined(SUPPORT_INET6) && defined(SUPPORT_INET4) */
974
975 error = dns_lookup_host_sub(flags, hostname, msg, msg_size, rslv);
976
977#endif /* of #if defined(SUPPORT_INET6) && defined(SUPPORT_INET4) */
978
979 return error;
980 }
981
982#if defined(SUPPORT_INET6)
983
984/*
985 * dns_in6_set_dname -- DNS の ドメイン名を設定する(DHCPv6用)。
986 *
987 * 注意: new に NULL を指定すると、初期値に戻す。
988 */
989
990const uint8_t *
991dns_in6_set_dname (const uint8_t *new, uint_t len)
992{
993 uint8_t *dst;
994 int label_len, name_len = DNS_NAME_LENGTH;
995
996 if (new == NULL)
997 strcpy(dns_domain_name, RSLV_CFG_DNS_DOMAIN_NAME_STR);
998 else {
999 dst = dns_domain_name;
1000 while ((*new != 0) && (name_len > 0) && (len > 0)) {
1001 label_len = *new ++;
1002 len --;
1003 while ((name_len > 0) && (len > 0) && (label_len > 0)) {
1004 *dst ++ = *new ++;
1005 name_len --;
1006 len --;
1007 label_len --;
1008 }
1009 if ((*new != 0) && (name_len > 0)) {
1010 *dst ++ = '.';
1011 name_len --;
1012 }
1013 }
1014 *dst = '\0';
1015 }
1016 return dns_domain_name;
1017 }
1018
1019/*
1020 * dns_in6_get_dname -- DNS の ドメイン名を得る。
1021 */
1022
1023const uint8_t *
1024dns_in6_get_dname (void)
1025{
1026 return dns_domain_name;
1027 }
1028
1029/*
1030 * dns_in6_set_addr -- DNS サーバの IPv6 アドレスを設定する(DHCPv6用)。
1031 *
1032 * 注意: new に NULL を指定すると、初期値に戻す。
1033 */
1034
1035T_IN6_ADDR *
1036dns_in6_set_addr (T_IN6_ADDR *new)
1037{
1038 if (new == NULL)
1039 in6_addr_dns = in6_addr_dns_init;
1040 else
1041 in6_addr_dns = *new;
1042 return &in6_addr_dns;
1043 }
1044
1045/*
1046 * dns_in6_get_addr -- DNS サーバの IPv6 アドレスを得る。
1047 */
1048
1049T_IN6_ADDR *
1050dns_in6_get_addr (T_IN6_ADDR *dst)
1051{
1052 if (dst == NULL)
1053 return NULL;
1054 else {
1055 *dst = in6_addr_dns;
1056 return dst;
1057 }
1058 }
1059
1060#endif /* of #if defined(SUPPORT_INET6) */
1061
1062#if defined(SUPPORT_INET4)
1063
1064/*
1065 * dns_in4_set_dname -- DNS の ドメイン名を設定する(DHCPv4用)。
1066 *
1067 * 注意: new に NULL を指定すると、初期値に戻す。
1068 */
1069
1070const uint8_t *
1071dns_in4_set_dname (const uint8_t *new, uint_t len)
1072{
1073 uint8_t *dst;
1074 int name_len = DNS_NAME_LENGTH;
1075
1076 if (new == NULL)
1077 strcpy(dns_domain_name, RSLV_CFG_DNS_DOMAIN_NAME_STR);
1078 else {
1079 dst = dns_domain_name;
1080 while ((name_len -- > 0) && (len -- > 0) && *new)
1081 *dst ++ = *new ++;
1082 *dst = '\0';
1083 }
1084 return dns_domain_name;
1085 }
1086
1087/*
1088 * dns_in4_get_dname -- DNS の ドメイン名を得る。
1089 */
1090
1091const uint8_t *
1092dns_in4_get_dname (void)
1093{
1094 return dns_domain_name;
1095 }
1096
1097/*
1098 * dns_in4_set_addr -- DNS サーバの IPv4 アドレスを設定する(DHCPv4用)。
1099 *
1100 * 注意: new に NULL を指定すると、初期値に戻す。
1101 */
1102
1103T_IN4_ADDR *
1104dns_in4_set_addr (T_IN4_ADDR *new)
1105{
1106 if (new == NULL)
1107 in4_addr_dns = IPV4_ADDR_DNS;
1108 else
1109 in4_addr_dns = *new;
1110 return &in4_addr_dns;
1111 }
1112
1113/*
1114 * dns_in4_get_addr -- DNS サーバの IPv4 アドレスを得る。
1115 */
1116
1117T_IN4_ADDR *
1118dns_in4_get_addr (T_IN4_ADDR *dst)
1119{
1120 if (dst == NULL)
1121 return NULL;
1122 else {
1123 *dst = in4_addr_dns;
1124 return dst;
1125 }
1126 }
1127
1128#endif /* of #if defined(SUPPORT_INET4) */
1129
1130/*
1131 * dns_host_addr -- ホスト名を IP アドレスに変換する。
1132 */
1133
1134ER
1135dns_host_addr (uint16_t flags, char *hostname, T_IN_ADDR *addr)
1136{
1137 T_RSLV_DNS_MSG rslv;
1138 T_RSLV_RR rr;
1139 ER_UINT length, offset;
1140 ER error = E_OK;
1141 int scount;
1142 uint8_t *msg;
1143
1144#if defined(SUPPORT_INET6) && defined(SUPPORT_INET4)
1145
1146 T_IN4_ADDR addr4;
1147
1148#endif /* of #if defined(SUPPORT_INET6) && defined(SUPPORT_INET4) */
1149
1150 if ((error = tget_mpf(MPF_RSLV_SRBUF, (void*)&msg, TMO_FEVR)) != E_OK)
1151 return error;
1152
1153 if ((length = dns_lookup_host(flags, hostname, msg, DNS_UDP_MSG_LENGTH, &rslv)) < 0) {
1154 error = length;
1155 goto err_ret;
1156 }
1157
1158 offset = rslv.an_offset;
1159 for (scount = 1; scount <= rslv.dns_hdr.ancount; scount ++) {
1160 if ((offset = dns_analyze_rr(&rr, offset, msg, length)) < 0) {
1161 error = offset;
1162 goto err_ret;
1163 }
1164
1165#if defined(SUPPORT_INET6)
1166
1167 if (rr.type == DNS_TYPE_AAAA && rr.class == DNS_CLASS_IN && rr.rdlength == sizeof(*addr)) {
1168 memcpy((void*)addr, (void*)(msg + rr.rdata_offset), sizeof(*addr));
1169 break;
1170 }
1171
1172#if defined(SUPPORT_INET4)
1173
1174 if (rr.type == DNS_TYPE_A && rr.class == DNS_CLASS_IN && rr.rdlength == sizeof(addr4)) {
1175 addr4 = msg2host32(msg + rr.rdata_offset);
1176 in6_make_ipv4mapped(addr, addr4);
1177 break;
1178 }
1179
1180#endif /* of #if defined(SUPPORT_INET4) */
1181
1182#else /* of #if defined(SUPPORT_INET6) */
1183
1184#if defined(SUPPORT_INET4)
1185
1186 if (rr.type == DNS_TYPE_A && rr.class == DNS_CLASS_IN && rr.rdlength == sizeof(*addr)) {
1187 *addr = msg2host32((msg + rr.rdata_offset));
1188 break;
1189 }
1190
1191#endif /* of #if defined(SUPPORT_INET4) */
1192
1193#endif /* of #if defined(SUPPORT_INET6) */
1194
1195 }
1196 if (scount > rslv.dns_hdr.ancount)
1197 error = EV_RSLV_UNEXPCT;
1198
1199err_ret:
1200 rel_mpf(MPF_RSLV_SRBUF, (void*)msg);
1201 return error;
1202 }
1203
1204#endif /* of #if defined(USE_RESOLVER) */
Note: See TracBrowser for help on using the repository browser.