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