1 module jmap.resolv; 2 3 /+ 4 5 ******************************************************************* 6 * Test DNS SRV lookups 7 * copyright Gerald Carter <jerry@samba.org> 2006 8 * 9 * For some bizarre reason the ns_initparse(), et. al. routines 10 * are not available in the shared version of libresolv.so. 11 * 12 * To compile, run 13 * dmd dnstest -L-lresolv 14 * 15 *******************************************************************/ 16 17 /* standard system headers */ 18 19 import std.stdio; 20 import std.string; 21 import core.sys.posix.netinet.in_; 22 import std.exception : enforce; 23 import std.experimental.logger : tracef; 24 import core.stdc.string : strerror; 25 import core.stdc.errno : errno; 26 27 enum ns_s_max = 4; 28 extern(C) struct dst_key; 29 30 /* resolver headers */ 31 #include <sys/types.h> 32 #include <netinet/in.h> 33 #include <arpa/nameser.h> 34 #include <resolv.h> 35 36 #include <netdb.h> 37 alias fromCString = fromStringz; 38 39 struct RecordSRV 40 { 41 string name; 42 string address; 43 } 44 45 46 void main(string[] args) 47 { 48 auto records = getRecordsSRV(args[1]); 49 foreach(record;records) 50 writeln(record); 51 } 52 53 RecordSRV[] getRecordsSRV(string hostname) 54 { 55 ns_msg h; 56 ns_rr rr; 57 58 RecordSRV[] records; 59 60 char[NS_PACKETSZ] buffer; 61 // send the request 62 63 int resp_len = res_query(cast(char*) hostname.toStringz, NSClass.in_, NSType.srv, buffer.ptr, buffer.sizeof); 64 enforce(resp_len >=0, format!"Query for %s failed"(hostname)); 65 writefln("resp = %s",buffer); 66 // now do the parsing 67 auto result = ns_initparse( cast(const(char)*) buffer.ptr, resp_len, &h ); 68 enforce (!result, "Failed to parse response buffer"); 69 70 int numAnswerRecords = ns_msg_count(h, NSSect.an); 71 writefln("num an Records = %s",numAnswerRecords); 72 73 foreach(recordNum; 0 .. numAnswerRecords) 74 { 75 result = ns_parserr( &h, NSSect.an, recordNum, &rr ); 76 if(result) 77 { 78 stderr.writefln("ns_parserr: %s, %s" ,result,strerror(errno).fromStringz); 79 continue; 80 } 81 82 if ( ns_rr_type(rr) == NSType.srv ) { 83 char[4096] name; 84 in_addr ip; 85 86 //int ret = dn_expand( cast(const(char)*) ns_msg_base(h), cast(const(char)*) ns_msg_end(h), cast(const(char)*) ns_rr_rdata(rr)+6, name.ptr, name.sizeof); 87 int ret = dn_expand( cast(char*) ns_msg_base(h), cast(char*) ns_msg_end(h), cast(char*) ns_rr_rdata(rr)+6, name.ptr, name.sizeof); 88 enforce(ret >=0, format!"Failed to uncompress name (%s)"(ret)); 89 tracef("%s",name); 90 records ~= RecordSRV(name.ptr.fromStringz.idup,""); 91 } 92 } 93 94 numAnswerRecords = ns_msg_count(h, NSSect.ar); 95 writefln("num ar Records = %s",numAnswerRecords); 96 97 foreach(recordNum; 0 .. numAnswerRecords) 98 { 99 writefln("%s",ns_rr_type(rr)); 100 result = ns_parserr( &h, NSSect.ar, recordNum, &rr ); 101 if(result) 102 { 103 stderr.writefln("ns_parserr: %s" ,strerror(errno).fromStringz); 104 continue; 105 } 106 107 if ( ns_rr_type(rr) == NSType.a ) { 108 import std.conv : to; 109 char*[1024] name; 110 in_addr ip; 111 //const(char)** p = ns_rr_rdata(rr); 112 auto p = ns_rr_rdata(rr); 113 writeln("%s",p); 114 ip.s_addr = (p[3].to!int << 24) | (p[2].to!int << 16) | (p[1].to!int << 8) | p[0].to!int; 115 records ~= RecordSRV(ns_rr_name(rr).idup, inet_ntoa(ip).fromStringz.idup); 116 } 117 } 118 119 return records; 120 } 121 122 extern(C) @system: 123 124 /* 125 * Copyright (c) 1983, 1987, 1989 126 * The Regents of the University of California. All rights reserved. 127 * 128 * Redistribution and use in source and binary forms, with or without 129 * modification, are permitted provided that the following conditions 130 * are met: 131 * 1. Redistributions of source code must retain the above copyright 132 * notice, this list of conditions and the following disclaimer. 133 * 2. Redistributions in binary form must reproduce the above copyright 134 * notice, this list of conditions and the following disclaimer in the 135 * documentation and/or other materials provided with the distribution. 136 * 4. Neither the name of the University nor the names of its contributors 137 * may be used to endorse or promote products derived from this software 138 * without specific prior written permission. 139 * 140 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND 141 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 142 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 143 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE 144 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 145 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 146 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 147 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 148 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 149 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 150 * SUCH DAMAGE. 151 */ 152 153 /* 154 * Portions Copyright (c) 1996-1999 by Internet Software Consortium. 155 * 156 * Permission to use, copy, modify, and distribute this software for any 157 * purpose with or without fee is hereby granted, provided that the above 158 * copyright notice and this permission notice appear in all copies. 159 * 160 * THE SOFTWARE IS PROVIDED "AS IS" AND INTERNET SOFTWARE CONSORTIUM DISCLAIMS 161 * ALL WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES 162 * OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL INTERNET SOFTWARE 163 * CONSORTIUM BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL 164 * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR 165 * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS 166 * ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS 167 * SOFTWARE. 168 */ 169 170 /* 171 * @(#)resolv.h 8.1 (Berkeley) 6/2/93 172 * $BINDId: resolv.h,v 8.31 2000/03/30 20:16:50 vixie Exp $ 173 */ 174 175 /+ 176 #include <sys/cdefs.h> 177 #include <sys/param.h> 178 #include <sys/types.h> 179 #include <stdio.h> 180 #include <netinet/in.h> 181 #include <arpa/nameser.h> 182 #include <bits/types/res_state.h> 183 +/ 184 /* 185 * Global defines and variables for resolver stub. 186 */ 187 enum LOCALDOMAINPARTS = 2; /* min levels in name that is "local" */ 188 189 enum ResolverCode 190 { 191 timeout = 5, // min. seconds between retries 192 maxNDots = 15, // should reflect bit field size 193 maxRetrans = 30, // only for resolv.conf/RES_OPTIONS 194 maxRetry = 5, // only for resolv.conf/RES_OPTIONS 195 defaultTries = 2, // Default tries 196 maxTime = 65535, // Infinity, in milliseconds 197 } 198 199 200 //alias nsaddr = nsaddr_list[0]; /* for backward compatibility */ 201 202 /* 203 * Revision information. This is the release date in YYYYMMDD format. 204 * It can change every day so the right thing to do with it is use it 205 * in preprocessor commands such as "#if (__RES > 19931104)". Do not 206 * compare for equality; rather, use it to determine whether your resolver 207 * is new enough to contain a certain feature. 208 */ 209 210 enum __RES = 19991006; 211 212 /* 213 * Resolver configuration file. 214 * Normally not present, but may contain the address of the 215 * inital name server(s) to query and the domain search list. 216 */ 217 218 enum _PATH_RESCONF = "/etc/resolv.conf"; 219 220 struct res_sym 221 { 222 int number; /* Identifying number, like T_MX */ 223 char** name; /* Its symbolic name, like "MX" */ 224 char** humanname; /* Its fun name, like "mail exchanger" */ 225 } 226 227 /* 228 * Resolver options (keep these in synch with res_debug.c, please) 229 */ 230 enum ResolverOption 231 { 232 init = 0x00000001, // address initialized 233 debugMessages = 0x00000002, // print debug messages 234 aaOnly = 0x00000004, 235 useVirtualCircuit = 0x00000008, // use virtual circuit 236 primary = 0x00000010, 237 ignoreTruncationErrors = 0x00000020, // ignore trucation errors 238 recurse = 0x00000040, // recursion desired 239 defaultDomainName = 0x00000080, // use default domain name 240 keepTCPSocketOPen = 0x00000100, // Keep TCP socket open 241 searchUpLocalDomainTree = 0x00000200, // search up local domain tree 242 shutOffHostAliases = 0x00001000, // shuts off HOSTALIASES feature 243 rotateNSListAfterEachQuery = 0x00004000, // rotate ns list after each query 244 noCheckName = 0x00008000, 245 keepTSig = 0x00010000, 246 blast = 0x00020000, 247 useEDNS0 = 0x00100000, // Use EDNS0. 248 singleKUp = 0x00200000, // one outstanding request at a time 249 singleKUpReop = 0x00400000, // -"-, but open new socket for each request 250 useDNSSEC = 0x00800000, // use DNSSEC using OK bit in OPT 251 notLDQuery = 0x01000000, // Do not look up unqualified name as a TLD 252 noReload = 0x02000000, // No automatic configuration reload 253 trustAD = 0x04000000, // Request AD bit, keep it in responses 254 default_ = ResolverOption.recurse | ResolverOption.defaultDomainName | ResolverOption.searchUpLocalDomainTree, 255 } 256 257 /* 258 * Resolver "pfcode" values. Used by dig. 259 */ 260 enum PfCode 261 { 262 stats = 0x00000001, 263 update = 0x00000002, 264 class_ = 0x00000004, 265 cmd = 0x00000008, 266 ques = 0x00000010, 267 ans = 0x00000020, 268 auth = 0x00000040, 269 add = 0x00000080, 270 head1 = 0x00000100, 271 head2 = 0x00000200, 272 ttlID = 0x00000400, 273 headx = 0x00000800, 274 query = 0x00001000, 275 reply = 0x00002000, 276 init = 0x00004000, 277 /* 0x00008000 */ 278 } 279 280 /* Things involving an internal (static) resolver context. */ 281 //__res_state* __res_state(); // 282 283 void fp_nquery (const(char)* *, int, FILE *); 284 void fp_query (const(char)* *, FILE *); 285 const(char* )* hostalias (const(char* )* ); 286 void p_query (const(char)* *); 287 void res_close(); 288 int res_init(); 289 int res_isourserver (const sockaddr_in *); 290 int res_mkquery (int, const(char* )* , int, int, const(char)* *, int, const(char)* *, char* *, int); 291 //int res_query(char*, int, int, char*, int); 292 int __res_query(char*, int, int, char*, int); 293 alias res_query = __res_query; 294 //extern(C) int res_query (const(char)* , int, int, char*, int) ; 295 int res_querydomain (const(char* )* , const(char* )* , int, int, char* *, int); 296 int res_search (const(char* )* , int, int, char* *, int) ; 297 int res_send (const(char)* *, int, char* *, int) ; 298 299 300 int res_hnok (const(char* )* ); 301 int res_ownok (const(char* )* ); 302 int res_mailok (const(char* )* ); 303 int res_dnok (const(char* )* ); 304 int sym_ston (const res_sym *, const(char* )* , int *); 305 const(char* )* sym_ntos (const res_sym *, int, int *); 306 const(char* )* sym_ntop (const res_sym *, int, int *); 307 int b64_ntop (const(char)* *, size_t, char* *, size_t); 308 int b64_pton (char**, char**, size_t); 309 int loc_aton (const(char* )* __ascii, char** __binary); 310 const(char* )* loc_ntoa (const(char)* *__binary, char* *__ascii); 311 int dn_skipname (const(char)* *, const(char)* *) ; 312 void putlong(uint, char**); 313 void putshort (ushort, char* *); 314 const(char* )* p_class (int); 315 const(char* )* p_time (ushort); 316 const(char* )* p_type (int); 317 const(char* )* p_rcode (int); 318 const(char)** p_cdnname (const(char)* *, const(char)* *, int, FILE *); 319 const(char)** p_cdname (const(char)* *, const(char)* *, FILE *); 320 const(char)** p_fqnname (const(char)* *__cp, const(char)* *__msg, int, char* *, int); 321 const(char)** p_fqname (const(char)* *, const(char)* *, FILE *); 322 const(char)** p_option (ulong __option); 323 int dn_count_labels (const(char* )* ); 324 int dn_comp (const(char* )* , char* *, int, char* **, char* **); 325 // int dn_expand(const(char)* msg, const(char)* eomorig, const(char)* comp_dn, char* exp_dn, int length); 326 //int dn_expand(char* msg, char* eomorig, char* comp_dn, char* exp_dn, int length); 327 int __dn_expand(char* msg, char* eomorig, char* comp_dn, char* exp_dn, int length); 328 alias dn_expand = __dn_expand; 329 uint res_randomid(); 330 int res_nameinquery (const(char* )* , int, int, const(char)* *, const(char)* *); 331 int res_queriesmatch (const(char)* *, const(char)* *, const(char)* *, const(char)* *); 332 /* Things involving a resolver context. */ 333 int res_ninit (res_state); 334 void fp_resstat (const res_state, FILE *); 335 const(char* )* res_hostalias (const res_state, const(char* )* , char* *, size_t); 336 int res_nquery (res_state, const(char* )* , int, int, char* *, int); 337 int res_nsearch (res_state, const(char* )* , int, int, char* *, int); 338 int res_nquerydomain (res_state, const(char* )* , const(char* )* , int, int, char* *, int); 339 int res_nmkquery (res_state, int, const(char* )* , int, int, const(char)* *, int, const(char)* *, char* *, int); 340 int res_nsend (res_state, const(char)* *, int, char* *, int); 341 void res_nclose (res_state); 342 343 // #include <sys/types.h> 344 // #include <netinet/in.h> 345 346 /* res_state: the global state used by the resolver stub. */ 347 enum MAXNS =3; /* max # name servers we'll track */ 348 enum MAXDFLSRCH =3; /* # default domain levels to try */ 349 enum MAXDNSRCH = 6; /* max # domains in search path */ 350 enum MAXRESOLVSORT= 10; /* number of net to sort on */ 351 352 struct res_state 353 { 354 import std.bitmanip : bitfields; 355 int retrans; /* retransmition time interval */ 356 int retry; /* number of times to retransmit */ 357 ulong options; /* option flags - see below. */ 358 int nscount; /* number of name servers */ 359 sockaddr_in[MAXNS] nsaddr_list; /* address of name server */ 360 ushort id; /* current message id */ 361 /* 2 byte hole here. */ 362 char*[MAXDNSRCH+1] dnsrch; /* components of domain to search */ 363 char[256] defdname; /* default domain (deprecated) */ 364 ulong pfcode; /* RES_PRF_ flags - see below. */ 365 366 mixin(bitfields!( 367 uint, "ndots", 4, // threshold for initial abs. query 368 uint, "nsort", 4, // number of elements in sort_list[] 369 uint,"ipv6_unavail",1, // connecting to IPv6 server failed 370 uint, "unused",23, 371 )); 372 struct SortListEntry 373 { 374 in_addr addr; 375 uint mask; 376 } 377 SortListEntry [MAXRESOLVSORT] sort_list; 378 /* 4 byte hole here on 64-bit architectures. */ 379 void * __glibc_unused_qhook; 380 void * __glibc_unused_rhook; 381 int res_h_errno; /* last one set for this context */ 382 int _vcsock; /* PRIVATE: for res_send VC i/o */ 383 uint _flags; /* PRIVATE: see below */ 384 /* 4 byte hole here on 64-bit architectures. */ 385 union U 386 { 387 char[52] pad; /* On an i386 this means 512b total. */ 388 struct Ext 389 { 390 ushort nscount; 391 ushort[MAXNS] nsmap; 392 int[MAXNS] nssocks; 393 ushort nscount6; 394 ushort nsinit; 395 sockaddr_in6*[MAXNS] nsaddrs; 396 uint[2] __glibc_reserved; 397 } 398 Ext _ext; 399 } 400 U _u; 401 }; 402 403 /* 404 * Copyright (c) 1983, 1989, 1993 405 * The Regents of the University of California. All rights reserved. 406 * 407 * Redistribution and use in source and binary forms, with or without 408 * modification, are permitted provided that the following conditions 409 * are met: 410 * 1. Redistributions of source code must retain the above copyright 411 * notice, this list of conditions and the following disclaimer. 412 * 2. Redistributions in binary form must reproduce the above copyright 413 * notice, this list of conditions and the following disclaimer in the 414 * documentation and/or other materials provided with the distribution. 415 * 4. Neither the name of the University nor the names of its contributors 416 * may be used to endorse or promote products derived from this software 417 * without specific prior written permission. 418 * 419 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND 420 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 421 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 422 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE 423 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 424 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 425 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 426 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 427 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 428 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 429 * SUCH DAMAGE. 430 */ 431 432 /* 433 * Copyright (c) 2004 by Internet Systems Consortium, Inc. ("ISC") 434 * Copyright (c) 1996-1999 by Internet Software Consortium. 435 * 436 * Permission to use, copy, modify, and distribute this software for any 437 * purpose with or without fee is hereby granted, provided that the above 438 * copyright notice and this permission notice appear in all copies. 439 * 440 * THE SOFTWARE IS PROVIDED "AS IS" AND INTERNET SOFTWARE CONSORTIUM DISCLAIMS 441 * ALL WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES 442 * OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL INTERNET SOFTWARE 443 * CONSORTIUM BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL 444 * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR 445 * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS 446 * ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS 447 * SOFTWARE. 448 */ 449 450 /+ 451 #include <sys/param.h> 452 #include <sys/types.h> 453 #include <stdint.h> 454 +/ 455 /* 456 * Define constants based on RFC 883, RFC 1034, RFC 1035 457 */ 458 enum NS_PACKETSZ =512; /*%< default UDP packet size */ 459 enum NS_MAXDNAME =1025; /*%< maximum domain name */ 460 enum NS_MAXMSG =65535; // %< maximum message size 461 enum NS_MAXCDNAME =255; // %< maximum compressed domain name */ 462 enum NS_MAXLABEL =63; // %< maximum length of domain label */ 463 enum NS_HFIXEDSZ =12; // /*%< #/bytes of fixed data in header */ 464 enum NS_QFIXEDSZ =4; // /*%< #/bytes of fixed data in query */ 465 enum NS_RRFIXEDSZ =10; /*%< #/bytes of fixed data in r record */ 466 enum NS_INT32SZ =4; /*%< #/bytes of data in a uint32_t */ 467 enum NS_INT16SZ =2; /*%< #/bytes of data in a uint16_t */ 468 enum NS_INT8SZ =1; /*%< #/bytes of data in a uint8_t */ 469 enum NS_INADDRSZ =4; /*%< IPv4 T_A */ 470 enum NS_IN6ADDRSZ =16; /*%< IPv6 T_AAAA */ 471 enum NS_CMPRSFLGS =0xc0; /*%< Flag bits indicating name compression. */ 472 enum NS_DEFAULTPORT =53; /*%< For both TCP and UDP. */ 473 /* 474 * These can be expanded with synonyms, just keep ns_parse.c:ns_parserecord() 475 * in synch with it. 476 */ 477 enum NSSect 478 { 479 qd = 0, /*%< Query: Question. */ 480 zn = 0, /*%< Update: Zone. */ 481 an = 1, /*%< Query: Answer. */ 482 pr = 1, /*%< Update: Prerequisites. */ 483 ns = 2, /*%< Query: Name servers. */ 484 ud = 2, /*%< Update: Update. */ 485 ar = 3, /*%< Query|Update: Additional records. */ 486 max = 4, 487 } 488 489 alias ns_sect = NSSect; 490 /*% 491 * This is a message handle. It is caller allocated and has no dynamic data. 492 * This structure is intended to be opaque to all but ns_parse.c, thus the 493 * leading _'s on the member names. Use the accessor functions, not the _'s. 494 */ 495 struct ns_msg 496 { 497 const(char)* _msg; 498 const(char)* _eom; 499 ushort _id; 500 ushort _flags; 501 ushort[ns_s_max] _counts; 502 const(char)[ns_s_max]* _sections; 503 ns_sect _sect; 504 int _rrnum; 505 const(char) *_msg_ptr; 506 } 507 508 /* Private data structure - do not use from outside library. */ 509 //struct _ns_flagdata { int mask, shift; }; 510 //extern const struct _ns_flagdata _ns_flagdata[]; 511 512 /* Accessor macros - this is part of the public interface. */ 513 auto ns_msg_id(ns_msg handle) 514 { 515 return handle._id; 516 } 517 518 auto ns_msg_base(ns_msg handle) 519 { 520 return handle._msg; 521 } 522 523 auto ns_msg_end(ns_msg handle) 524 { 525 return handle._eom; 526 } 527 528 auto ns_msg_size(ns_msg handle) 529 { 530 return handle._eom - handle._msg; 531 } 532 533 auto ns_msg_count(Section)(ns_msg handle, Section section) 534 { 535 return handle._counts[section]; 536 } 537 538 /*% 539 * This is a parsed record. It is caller allocated and has no dynamic data. 540 */ 541 struct ns_rr 542 { 543 char[NS_MAXDNAME] name; 544 ushort type; 545 ushort rr_class; 546 uint ttl; 547 ushort rdlength; 548 const(char) * rdata; 549 } 550 551 /* Accessor macros - this is part of the public interface. */ 552 string ns_rr_name(ns_rr rr) 553 { 554 return (rr.name[0] != '\0') ? rr.name.ptr.fromStringz.idup: "."; 555 } 556 557 auto ns_rr_type(ns_rr rr) 558 { 559 return cast(NSType)rr.type; 560 } 561 562 auto ns_rr_class(ns_rr rr) 563 { 564 return cast(NSClass) rr.rr_class; 565 } 566 567 auto ns_rr_ttl(ns_rr rr) 568 { 569 return rr.ttl; 570 } 571 572 auto ns_rr_rdlen(ns_rr rr) 573 { 574 return rr.rdlength; 575 } 576 577 char[] ns_rr_rdata(ns_rr rr) 578 { 579 return rr.rdata[0.. rr.rdlength].dup; 580 } 581 582 /*% 583 * These don't have to be in the same order as in the packet flags word, 584 * and they can even overlap in some cases, but they will need to be kept 585 * in synch with ns_parse.c:ns_flagdata[]. 586 */ 587 enum FlagCode 588 { 589 qr, /*%< Question/Response. */ 590 opcode, /*%< Operation code. */ 591 aa, /*%< Authoritative Answer. */ 592 tc, /*%< Truncation occurred. */ 593 rd, /*%< Recursion Desired. */ 594 ra, /*%< Recursion Available. */ 595 z, /*%< MBZ. */ 596 ad, /*%< Authentic Data (DNSSEC). */ 597 cd, /*%< Checking Disabled (DNSSEC). */ 598 rcode, /*%< Response code. */ 599 max 600 } 601 602 /*% 603 * Currently defined opcodes. 604 */ 605 enum OpCode 606 { 607 query = 0, /*%< Standard query. */ 608 iquery = 1, /*%< Inverse query (deprecated/unsupported). */ 609 status = 2, /*%< Name server status query (unsupported). */ 610 /* Opcode 3 is undefined/reserved. */ 611 notify = 4, /*%< Zone change notification. */ 612 update = 5, /*%< Zone update message. */ 613 max = 6 614 } 615 616 /*% 617 * Currently defined response codes. 618 */ 619 enum ResponseCode 620 { 621 noerror = 0, /*%< No error occurred. */ 622 formerr = 1, /*%< Format error. */ 623 servfail = 2, /*%< Server failure. */ 624 nxdomain = 3, /*%< Name error. */ 625 notimpl = 4, /*%< Unimplemented. */ 626 refused = 5, /*%< Operation refused. */ 627 /* these are for BIND_UPDATE */ 628 yxdomain = 6, /*%< Name exists */ 629 yxrrset = 7, /*%< RRset exists */ 630 nxrrset = 8, /*%< RRset does not exist */ 631 notauth = 9, /*%< Not authoritative for zone */ 632 notzone = 10, /*%< Zone of record different from zone section */ 633 _max = 11, 634 /* The following are EDNS extended rcodes */ 635 badvers = 16, 636 /* The following are TSIG errors */ 637 badsig = 16, 638 badkey = 17, 639 badtime = 18 640 } 641 642 /* BIND_UPDATE */ 643 enum BindUpdateOperation 644 { 645 delete_ = 0, 646 add = 1, 647 max = 2 648 } 649 650 /*% 651 * This structure is used for TSIG authenticated messages 652 */ 653 struct ns_tsig_key 654 { 655 char[NS_MAXDNAME] name; 656 char[NS_MAXDNAME] alg; 657 char *data; 658 int len; 659 } 660 661 /*% 662 * This structure is used for TSIG authenticated TCP messages 663 */ 664 struct ns_tcp_tsig_state 665 { 666 int counter; 667 dst_key *key; 668 void *ctx; 669 char[NS_PACKETSZ] sig; 670 int siglen; 671 } 672 673 enum NS_TSIG_FUDGE = 300; 674 enum NS_TSIG_TCP_COUNT = 100; 675 enum NS_TSIG_ALG_HMAC_MD5 = "HMAC-MD5.SIG-ALG.REG.INT"; 676 677 enum NS_TSIG_ERROR_NO_TSIG = -10; 678 enum NS_TSIG_ERROR_NO_SPACE = -11; 679 enum NS_TSIG_ERROR_FORMERR = -12; 680 681 /*% 682 * Currently defined type values for resources and queries. 683 */ 684 enum NSType 685 { 686 invalid = 0, 687 a = 1, 688 ns = 2, 689 md = 3, 690 mf = 4, 691 cname = 5, 692 soa = 6, 693 mb = 7, 694 mg = 8, 695 mr = 9, 696 null_ = 10, 697 wks = 11, 698 ptr = 12, 699 hinfo = 13, 700 minfo = 14, 701 mx = 15, 702 txt = 16, 703 rp = 17, 704 afsdb = 18, 705 x25 = 19, 706 isdn = 20, 707 rt = 21, 708 nsap = 22, 709 nsap_ptr = 23, 710 sig = 24, 711 key = 25, 712 px = 26, 713 gpos = 27, 714 aaaa = 28, 715 loc = 29, 716 nxt = 30, 717 eid = 31, 718 nimloc = 32, 719 srv = 33, 720 atma = 34, 721 naptr = 35, 722 kx = 36, 723 cert = 37, 724 a6 = 38, 725 dname = 39, 726 sink = 40, 727 opt = 41, 728 apl = 42, 729 ds = 43, 730 sshfp = 44, 731 ipseckey = 45, 732 rrsig = 46, 733 nsec = 47, 734 dnskey = 48, 735 dhcid = 49, 736 nsec3 = 50, 737 nsec3param = 51, 738 tlsa = 52, 739 smimea = 53, 740 hip = 55, 741 ninfo = 56, 742 rkey = 57, 743 talink = 58, 744 cds = 59, 745 cdnskey = 60, 746 openpgpkey = 61, 747 csync = 62, 748 spf = 99, 749 uinfo = 100, 750 uid = 101, 751 gid = 102, 752 unspec = 103, 753 nid = 104, 754 l32 = 105, 755 l64 = 106, 756 lp = 107, 757 eui48 = 108, 758 eui64 = 109, 759 tkey = 249, 760 tsig = 250, 761 ixfr = 251, 762 axfr = 252, 763 mailb = 253, 764 maila = 254, 765 any = 255, 766 uri = 256, 767 caa = 257, 768 avc = 258, 769 ta = 32768, 770 dlv = 32769, 771 772 max = 65536 773 } 774 775 /*% 776 * Values for class field 777 */ 778 enum NSClass 779 { 780 invalid = 0, /*%< Cookie. */ 781 in_ = 1, /*%< Internet. */ 782 ns_c_2 = 2, /*%< unallocated/unsupported. */ 783 chaos = 3, /*%< MIT Chaos-net. */ 784 hesiod = 4, /*%< MIT Hesiod. */ 785 /* Query class values which do not appear in resource records */ 786 none = 254, /*%< for prereq. sections in update requests */ 787 any = 255, /*%< Wildcard match. */ 788 max = 65536 789 } 790 791 /* Certificate type values in CERT resource records. */ 792 enum NSCertType 793 { 794 pkix = 1, /*%< PKIX (X.509v3) */ 795 spki = 2, /*%< SPKI */ 796 pgp = 3, /*%< PGP */ 797 url = 253, /*%< URL private type */ 798 oid = 254 /*%< OID private type */ 799 } 800 801 /*% 802 * EDNS0 extended flags and option codes, host order. 803 */ 804 enum NS_OPT_DNSSEC_OK =0x8000U; 805 enum NS_OPT_NSID =3; 806 /+ 807 808 /*% 809 * Inline versions of get/put short/long. Pointer is advanced. 810 */ 811 enum NS_GET16(s, cp) do { \ 812 const(char) *t_cp = (const(char) *)(cp); \ 813 (s) = ((uint16_t)t_cp[0] << 8) \ 814 | ((uint16_t)t_cp[1]) \ 815 ; \ 816 (cp) += NS_INT16SZ; \ 817 } while (0) 818 819 enum NS_GET32(l, cp) do { \ 820 const(char) *t_cp = (const(char) *)(cp); \ 821 (l) = ((uint32_t)t_cp[0] << 24) \ 822 | ((uint32_t)t_cp[1] << 16) \ 823 | ((uint32_t)t_cp[2] << 8) \ 824 | ((uint32_t)t_cp[3]) \ 825 ; \ 826 (cp) += NS_INT32SZ; \ 827 } while (0) 828 829 enum NS_PUT16(s, cp) do { \ 830 uint16_t t_s = (uint16_t)(s); \ 831 char *t_cp = (char *)(cp); \ 832 *t_cp++ = t_s >> 8; \ 833 *t_cp = t_s; \ 834 (cp) += NS_INT16SZ; \ 835 } while (0) 836 837 enum NS_PUT32(l, cp) do { \ 838 uint32_t t_l = (uint32_t)(l); \ 839 char *t_cp = (char *)(cp); \ 840 *t_cp++ = t_l >> 24; \ 841 *t_cp++ = t_l >> 16; \ 842 *t_cp++ = t_l >> 8; \ 843 *t_cp = t_l; \ 844 (cp) += NS_INT32SZ; \ 845 } while (0) 846 +/ 847 int ns_msg_getflag (ns_msg, int); 848 uint ns_get16 (const(char) *); 849 ulong ns_get32 (const(char) *); 850 void ns_put16 (uint, char *); 851 void ns_put32 (ulong, char *); 852 int ns_initparse (const(char) *, int, ns_msg *); 853 int ns_skiprr (const(char) *, const(char) *, ns_sect, int); 854 int ns_parserr (ns_msg*, ns_sect, int, ns_rr *); 855 int ns_sprintrr (const ns_msg *, const ns_rr *, const(char) *, const(char) *, char *, size_t) 856 ; 857 int ns_sprintrrf (const(char) *, size_t, const(char) *, NSClass, NSType, ulong, const(char) *, size_t, const(char) *, const(char) *, char *, size_t); 858 int ns_format_ttl (ulong, char *, size_t); 859 int ns_parse_ttl (const(char) *, ulong *); 860 uint32_t ns_datetosecs (const(char) *, int *); 861 int ns_name_ntol (const(char) *, char *, size_t) 862 ; 863 int ns_name_ntop (const(char) *, char *, size_t); 864 int ns_name_pton (const(char) *, char *, size_t); 865 int ns_name_unpack (const(char) *, const(char) *, 866 const(char) *, char *, size_t) 867 ; 868 int ns_name_pack (const(char) *, char *, int, 869 const(char) **, const(char) **) 870 ; 871 int ns_name_uncompress (const(char) *, 872 const(char) *, 873 const(char) *, 874 char *, size_t); 875 int ns_name_compress (const(char) *, char *, size_t, 876 const(char) **, 877 const(char) **); 878 int ns_name_skip (const(char) **, const(char) *) 879 ; 880 void ns_name_rollback (const(char) *, 881 const(char) **, 882 const(char) **); 883 int ns_samedomain (const(char) *, const(char) *); 884 int ns_subdomain (const(char) *, const(char) *); 885 int ns_makecanon (const(char) *, char *, size_t); 886 int ns_samename (const(char) *, const(char) *); 887 //__END_DECLS 888 889 // #include <arpa/nameser_compat.h> 890 +/