You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

778 lines
27 KiB

  1. /* udns.h
  2. header file for the UDNS library.
  3. Copyright (C) 2005 Michael Tokarev <mjt@corpit.ru>
  4. This file is part of UDNS library, an async DNS stub resolver.
  5. This library is free software; you can redistribute it and/or
  6. modify it under the terms of the GNU Lesser General Public
  7. License as published by the Free Software Foundation; either
  8. version 2.1 of the License, or (at your option) any later version.
  9. This library is distributed in the hope that it will be useful,
  10. but WITHOUT ANY WARRANTY; without even the implied warranty of
  11. MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
  12. Lesser General Public License for more details.
  13. You should have received a copy of the GNU Lesser General Public
  14. License along with this library, in file named COPYING.LGPL; if not,
  15. write to the Free Software Foundation, Inc., 59 Temple Place,
  16. Suite 330, Boston, MA 02111-1307 USA
  17. */
  18. #ifndef UDNS_VERSION /* include guard */
  19. #define UDNS_VERSION "0.4"
  20. #ifdef WINDOWS
  21. # ifdef UDNS_DYNAMIC_LIBRARY
  22. # ifdef DNS_LIBRARY_BUILD
  23. # define UDNS_API __declspec(dllexport)
  24. # define UDNS_DATA_API __declspec(dllexport)
  25. # else
  26. # define UDNS_API __declspec(dllimport)
  27. # define UDNS_DATA_API __declspec(dllimport)
  28. # endif
  29. # endif
  30. #endif
  31. #ifndef UDNS_API
  32. # define UDNS_API
  33. #endif
  34. #ifndef UDNS_DATA_API
  35. # define UDNS_DATA_API
  36. #endif
  37. #include <sys/types.h> /* for time_t */
  38. #ifdef __cplusplus
  39. extern "C" {
  40. #endif
  41. /* forward declarations if sockets stuff isn't #include'd */
  42. struct in_addr;
  43. struct in6_addr;
  44. struct sockaddr;
  45. /**************************************************************************/
  46. /**************** Common definitions **************************************/
  47. UDNS_API const char *
  48. dns_version(void);
  49. struct dns_ctx;
  50. struct dns_query;
  51. /* shorthand for [const] unsigned char */
  52. typedef unsigned char dnsc_t;
  53. typedef const unsigned char dnscc_t;
  54. #define DNS_MAXDN 255 /* max DN length */
  55. #define DNS_DNPAD 1 /* padding for DN buffers */
  56. #define DNS_MAXLABEL 63 /* max DN label length */
  57. #define DNS_MAXNAME 1024 /* max asciiz domain name length */
  58. #define DNS_HSIZE 12 /* DNS packet header size */
  59. #define DNS_PORT 53 /* default domain port */
  60. #define DNS_MAXSERV 6 /* max servers to consult */
  61. #define DNS_MAXPACKET 512 /* max traditional-DNS UDP packet size */
  62. #define DNS_EDNS0PACKET 4096 /* EDNS0 packet size to use */
  63. enum dns_class { /* DNS RR Classes */
  64. DNS_C_INVALID = 0, /* invalid class */
  65. DNS_C_IN = 1, /* Internet */
  66. DNS_C_CH = 3, /* CHAOS */
  67. DNS_C_HS = 4, /* HESIOD */
  68. DNS_C_ANY = 255 /* wildcard */
  69. };
  70. enum dns_type { /* DNS RR Types */
  71. DNS_T_INVALID = 0, /* Cookie. */
  72. DNS_T_A = 1, /* Host address. */
  73. DNS_T_NS = 2, /* Authoritative server. */
  74. DNS_T_MD = 3, /* Mail destination. */
  75. DNS_T_MF = 4, /* Mail forwarder. */
  76. DNS_T_CNAME = 5, /* Canonical name. */
  77. DNS_T_SOA = 6, /* Start of authority zone. */
  78. DNS_T_MB = 7, /* Mailbox domain name. */
  79. DNS_T_MG = 8, /* Mail group member. */
  80. DNS_T_MR = 9, /* Mail rename name. */
  81. DNS_T_NULL = 10, /* Null resource record. */
  82. DNS_T_WKS = 11, /* Well known service. */
  83. DNS_T_PTR = 12, /* Domain name pointer. */
  84. DNS_T_HINFO = 13, /* Host information. */
  85. DNS_T_MINFO = 14, /* Mailbox information. */
  86. DNS_T_MX = 15, /* Mail routing information. */
  87. DNS_T_TXT = 16, /* Text strings. */
  88. DNS_T_RP = 17, /* Responsible person. */
  89. DNS_T_AFSDB = 18, /* AFS cell database. */
  90. DNS_T_X25 = 19, /* X_25 calling address. */
  91. DNS_T_ISDN = 20, /* ISDN calling address. */
  92. DNS_T_RT = 21, /* Router. */
  93. DNS_T_NSAP = 22, /* NSAP address. */
  94. DNS_T_NSAP_PTR = 23, /* Reverse NSAP lookup (deprecated). */
  95. DNS_T_SIG = 24, /* Security signature. */
  96. DNS_T_KEY = 25, /* Security key. */
  97. DNS_T_PX = 26, /* X.400 mail mapping. */
  98. DNS_T_GPOS = 27, /* Geographical position (withdrawn). */
  99. DNS_T_AAAA = 28, /* Ip6 Address. */
  100. DNS_T_LOC = 29, /* Location Information. */
  101. DNS_T_NXT = 30, /* Next domain (security). */
  102. DNS_T_EID = 31, /* Endpoint identifier. */
  103. DNS_T_NIMLOC = 32, /* Nimrod Locator. */
  104. DNS_T_SRV = 33, /* Server Selection. */
  105. DNS_T_ATMA = 34, /* ATM Address */
  106. DNS_T_NAPTR = 35, /* Naming Authority PoinTeR */
  107. DNS_T_KX = 36, /* Key Exchange */
  108. DNS_T_CERT = 37, /* Certification record */
  109. DNS_T_A6 = 38, /* IPv6 address (deprecates AAAA) */
  110. DNS_T_DNAME = 39, /* Non-terminal DNAME (for IPv6) */
  111. DNS_T_SINK = 40, /* Kitchen sink (experimentatl) */
  112. DNS_T_OPT = 41, /* EDNS0 option (meta-RR) */
  113. DNS_T_DS = 43, /* DNSSEC */
  114. DNS_T_SSHFP = 44,
  115. DNS_T_IPSECKEY = 45,
  116. DNS_T_RRSIG = 46, /* DNSSEC */
  117. DNS_T_NSEC = 47, /* DNSSEC */
  118. DNS_T_DNSKEY = 48,
  119. DNS_T_DHCID = 49,
  120. DNS_T_NSEC3 = 50,
  121. DNS_T_NSEC3PARAMS = 51,
  122. DNS_T_TALINK = 58, /* draft-ietf-dnsop-trust-history */
  123. DNS_T_SPF = 99,
  124. DNS_T_UINFO = 100,
  125. DNS_T_UID = 101,
  126. DNS_T_GID = 102,
  127. DNS_T_UNSPEC = 103,
  128. DNS_T_TSIG = 250, /* Transaction signature. */
  129. DNS_T_IXFR = 251, /* Incremental zone transfer. */
  130. DNS_T_AXFR = 252, /* Transfer zone of authority. */
  131. DNS_T_MAILB = 253, /* Transfer mailbox records. */
  132. DNS_T_MAILA = 254, /* Transfer mail agent records. */
  133. DNS_T_ANY = 255, /* Wildcard match. */
  134. DNS_T_ZXFR = 256, /* BIND-specific, nonstandard. */
  135. DNS_T_DLV = 32769, /* RFC 4431, 5074, DNSSEC Lookaside Validation */
  136. DNS_T_MAX = 65536
  137. };
  138. /**************************************************************************/
  139. /**************** Domain Names (DNs) **************************************/
  140. /* return length of the DN */
  141. UDNS_API unsigned
  142. dns_dnlen(dnscc_t *dn);
  143. /* return #of labels in a DN */
  144. UDNS_API unsigned
  145. dns_dnlabels(dnscc_t *dn);
  146. /* lower- and uppercase single DN char */
  147. #define DNS_DNLC(c) ((c) >= 'A' && (c) <= 'Z' ? (c) - 'A' + 'a' : (c))
  148. #define DNS_DNUC(c) ((c) >= 'a' && (c) <= 'z' ? (c) - 'a' + 'A' : (c))
  149. /* compare the DNs, return dnlen of equal or 0 if not */
  150. UDNS_API unsigned
  151. dns_dnequal(dnscc_t *dn1, dnscc_t *dn2);
  152. /* copy one DN to another, size checking */
  153. UDNS_API unsigned
  154. dns_dntodn(dnscc_t *sdn, dnsc_t *ddn, unsigned ddnsiz);
  155. /* convert asciiz string of length namelen (0 to use strlen) to DN */
  156. UDNS_API int
  157. dns_ptodn(const char *name, unsigned namelen,
  158. dnsc_t *dn, unsigned dnsiz, int *isabs);
  159. /* simpler form of dns_ptodn() */
  160. #define dns_sptodn(name,dn,dnsiz) dns_ptodn((name),0,(dn),(dnsiz),0)
  161. UDNS_DATA_API extern dnscc_t dns_inaddr_arpa_dn[14];
  162. #define DNS_A4RSIZE 30
  163. UDNS_API int
  164. dns_a4todn(const struct in_addr *addr, dnscc_t *tdn,
  165. dnsc_t *dn, unsigned dnsiz);
  166. UDNS_API int
  167. dns_a4ptodn(const struct in_addr *addr, const char *tname,
  168. dnsc_t *dn, unsigned dnsiz);
  169. UDNS_API dnsc_t *
  170. dns_a4todn_(const struct in_addr *addr, dnsc_t *dn, dnsc_t *dne);
  171. UDNS_DATA_API extern dnscc_t dns_ip6_arpa_dn[10];
  172. #define DNS_A6RSIZE 74
  173. UDNS_API int
  174. dns_a6todn(const struct in6_addr *addr, dnscc_t *tdn,
  175. dnsc_t *dn, unsigned dnsiz);
  176. UDNS_API int
  177. dns_a6ptodn(const struct in6_addr *addr, const char *tname,
  178. dnsc_t *dn, unsigned dnsiz);
  179. UDNS_API dnsc_t *
  180. dns_a6todn_(const struct in6_addr *addr, dnsc_t *dn, dnsc_t *dne);
  181. /* convert DN into asciiz string */
  182. UDNS_API int
  183. dns_dntop(dnscc_t *dn, char *name, unsigned namesiz);
  184. /* convert DN into asciiz string, using static buffer (NOT thread-safe!) */
  185. UDNS_API const char *
  186. dns_dntosp(dnscc_t *dn);
  187. /* return buffer size (incl. null byte) required for asciiz form of a DN */
  188. UDNS_API unsigned
  189. dns_dntop_size(dnscc_t *dn);
  190. /* either wrappers or reimplementations for inet_ntop() and inet_pton() */
  191. UDNS_API const char *dns_ntop(int af, const void *src, char *dst, int size);
  192. UDNS_API int dns_pton(int af, const char *src, void *dst);
  193. /**************************************************************************/
  194. /**************** DNS raw packet layout ***********************************/
  195. enum dns_rcode { /* reply codes */
  196. DNS_R_NOERROR = 0, /* ok, no error */
  197. DNS_R_FORMERR = 1, /* format error */
  198. DNS_R_SERVFAIL = 2, /* server failed */
  199. DNS_R_NXDOMAIN = 3, /* domain does not exists */
  200. DNS_R_NOTIMPL = 4, /* not implemented */
  201. DNS_R_REFUSED = 5, /* query refused */
  202. /* these are for BIND_UPDATE */
  203. DNS_R_YXDOMAIN = 6, /* Name exists */
  204. DNS_R_YXRRSET = 7, /* RRset exists */
  205. DNS_R_NXRRSET = 8, /* RRset does not exist */
  206. DNS_R_NOTAUTH = 9, /* Not authoritative for zone */
  207. DNS_R_NOTZONE = 10, /* Zone of record different from zone section */
  208. /*ns_r_max = 11,*/
  209. /* The following are TSIG extended errors */
  210. DNS_R_BADSIG = 16,
  211. DNS_R_BADKEY = 17,
  212. DNS_R_BADTIME = 18
  213. };
  214. static __inline unsigned dns_get16(dnscc_t *s) {
  215. return ((unsigned)s[0]<<8) | s[1];
  216. }
  217. static __inline unsigned dns_get32(dnscc_t *s) {
  218. return ((unsigned)s[0]<<24) | ((unsigned)s[1]<<16)
  219. | ((unsigned)s[2]<<8) | s[3];
  220. }
  221. static __inline dnsc_t *dns_put16(dnsc_t *d, unsigned n) {
  222. *d++ = (dnsc_t)((n >> 8) & 255); *d++ = (dnsc_t)(n & 255); return d;
  223. }
  224. static __inline dnsc_t *dns_put32(dnsc_t *d, unsigned n) {
  225. *d++ = (dnsc_t)((n >> 24) & 255); *d++ = (dnsc_t)((n >> 16) & 255);
  226. *d++ = (dnsc_t)((n >> 8) & 255); *d++ = (dnsc_t)(n & 255);
  227. return d;
  228. }
  229. /* DNS Header layout */
  230. enum {
  231. /* bytes 0:1 - query ID */
  232. DNS_H_QID1 = 0,
  233. DNS_H_QID2 = 1,
  234. DNS_H_QID = DNS_H_QID1,
  235. #define dns_qid(pkt) dns_get16((pkt)+DNS_H_QID)
  236. /* byte 2: flags1 */
  237. DNS_H_F1 = 2,
  238. DNS_HF1_QR = 0x80, /* query response flag */
  239. #define dns_qr(pkt) ((pkt)[DNS_H_F1]&DNS_HF1_QR)
  240. DNS_HF1_OPCODE = 0x78, /* opcode, 0 = query */
  241. #define dns_opcode(pkt) (((pkt)[DNS_H_F1]&DNS_HF1_OPCODE)>>3)
  242. DNS_HF1_AA = 0x04, /* auth answer */
  243. #define dns_aa(pkt) ((pkt)[DNS_H_F1]&DNS_HF1_AA)
  244. DNS_HF1_TC = 0x02, /* truncation flag */
  245. #define dns_tc(pkt) ((pkt)[DNS_H_F1]&DNS_HF1_TC)
  246. DNS_HF1_RD = 0x01, /* recursion desired (may be set in query) */
  247. #define dns_rd(pkt) ((pkt)[DNS_H_F1]&DNS_HF1_RD)
  248. /* byte 3: flags2 */
  249. DNS_H_F2 = 3,
  250. DNS_HF2_RA = 0x80, /* recursion available */
  251. #define dns_ra(pkt) ((pkt)[DNS_H_F2]&DNS_HF2_RA)
  252. DNS_HF2_Z = 0x40, /* reserved */
  253. DNS_HF2_AD = 0x20, /* DNSSEC: authentic data */
  254. #define dns_ad(pkt) ((pkt)[DNS_H_F2]&DNS_HF2_AD)
  255. DNS_HF2_CD = 0x10, /* DNSSEC: checking disabled */
  256. #define dns_cd(pkt) ((pkt)[DNS_H_F2]&DNS_HF2_CD)
  257. DNS_HF2_RCODE = 0x0f, /* response code, DNS_R_XXX above */
  258. #define dns_rcode(pkt) ((pkt)[DNS_H_F2]&DNS_HF2_RCODE)
  259. /* bytes 4:5: qdcount, numqueries */
  260. DNS_H_QDCNT1 = 4,
  261. DNS_H_QDCNT2 = 5,
  262. DNS_H_QDCNT = DNS_H_QDCNT1,
  263. #define dns_numqd(pkt) dns_get16((pkt)+4)
  264. /* bytes 6:7: ancount, numanswers */
  265. DNS_H_ANCNT1 = 6,
  266. DNS_H_ANCNT2 = 7,
  267. DNS_H_ANCNT = DNS_H_ANCNT1,
  268. #define dns_numan(pkt) dns_get16((pkt)+6)
  269. /* bytes 8:9: nscount, numauthority */
  270. DNS_H_NSCNT1 = 8,
  271. DNS_H_NSCNT2 = 9,
  272. DNS_H_NSCNT = DNS_H_NSCNT1,
  273. #define dns_numns(pkt) dns_get16((pkt)+8)
  274. /* bytes 10:11: arcount, numadditional */
  275. DNS_H_ARCNT1 = 10,
  276. DNS_H_ARCNT2 = 11,
  277. DNS_H_ARCNT = DNS_H_ARCNT1,
  278. #define dns_numar(pkt) dns_get16((pkt)+10)
  279. #define dns_payload(pkt) ((pkt)+DNS_HSIZE)
  280. /* EDNS0 (OPT RR) flags (Ext. Flags) */
  281. DNS_EF1_DO = 0x80, /* DNSSEC OK */
  282. };
  283. /* packet buffer: start at pkt, end before pkte, current pos *curp.
  284. * extract a DN and set *curp to the next byte after DN in packet.
  285. * return -1 on error, 0 if dnsiz is too small, or dnlen on ok.
  286. */
  287. UDNS_API int
  288. dns_getdn(dnscc_t *pkt, dnscc_t **curp, dnscc_t *end,
  289. dnsc_t *dn, unsigned dnsiz);
  290. /* skip the DN at position cur in packet ending before pkte,
  291. * return pointer to the next byte after the DN or NULL on error */
  292. UDNS_API dnscc_t *
  293. dns_skipdn(dnscc_t *end, dnscc_t *cur);
  294. struct dns_rr { /* DNS Resource Record */
  295. dnsc_t dnsrr_dn[DNS_MAXDN]; /* the DN of the RR */
  296. enum dns_class dnsrr_cls; /* Class */
  297. enum dns_type dnsrr_typ; /* Type */
  298. unsigned dnsrr_ttl; /* Time-To-Live (TTL) */
  299. unsigned dnsrr_dsz; /* data size */
  300. dnscc_t *dnsrr_dptr; /* pointer to start of data */
  301. dnscc_t *dnsrr_dend; /* past end of data */
  302. };
  303. struct dns_parse { /* RR/packet parsing state */
  304. dnscc_t *dnsp_pkt; /* start of the packet */
  305. dnscc_t *dnsp_end; /* end of the packet */
  306. dnscc_t *dnsp_cur; /* current packet position */
  307. dnscc_t *dnsp_ans; /* start of answer section */
  308. int dnsp_rrl; /* number of RRs left to go */
  309. int dnsp_nrr; /* RR count so far */
  310. unsigned dnsp_ttl; /* TTL value so far */
  311. dnscc_t *dnsp_qdn; /* the RR DN we're looking for */
  312. enum dns_class dnsp_qcls; /* RR class we're looking for or 0 */
  313. enum dns_type dnsp_qtyp; /* RR type we're looking for or 0 */
  314. dnsc_t dnsp_dnbuf[DNS_MAXDN]; /* domain buffer */
  315. };
  316. /* initialize the parse structure */
  317. UDNS_API void
  318. dns_initparse(struct dns_parse *p, dnscc_t *qdn,
  319. dnscc_t *pkt, dnscc_t *cur, dnscc_t *end);
  320. /* search next RR, <0=error, 0=no more RRs, >0 = found. */
  321. UDNS_API int
  322. dns_nextrr(struct dns_parse *p, struct dns_rr *rr);
  323. UDNS_API void
  324. dns_rewind(struct dns_parse *p, dnscc_t *qdn);
  325. /**************************************************************************/
  326. /**************** Resolver Context ****************************************/
  327. /* default resolver context */
  328. UDNS_DATA_API extern struct dns_ctx dns_defctx;
  329. /* reset resolver context to default state, close it if open, drop queries */
  330. UDNS_API void
  331. dns_reset(struct dns_ctx *ctx);
  332. /* reset resolver context and read in system configuration */
  333. UDNS_API int
  334. dns_init(struct dns_ctx *ctx, int do_open);
  335. /* return new resolver context with the same settings as copy */
  336. UDNS_API struct dns_ctx *
  337. dns_new(const struct dns_ctx *copy);
  338. /* free resolver context returned by dns_new(); all queries are dropped */
  339. UDNS_API void
  340. dns_free(struct dns_ctx *ctx);
  341. /* add nameserver for a resolver context (or reset nslist if serv==NULL) */
  342. UDNS_API int
  343. dns_add_serv(struct dns_ctx *ctx, const char *serv);
  344. /* add nameserver using struct sockaddr structure (with ports) */
  345. UDNS_API int
  346. dns_add_serv_s(struct dns_ctx *ctx, const struct sockaddr *sa);
  347. /* add search list element for a resolver context (or reset it if srch==NULL) */
  348. UDNS_API int
  349. dns_add_srch(struct dns_ctx *ctx, const char *srch);
  350. /* set options for a resolver context */
  351. UDNS_API int
  352. dns_set_opts(struct dns_ctx *ctx, const char *opts);
  353. enum dns_opt { /* options */
  354. DNS_OPT_FLAGS, /* flags, DNS_F_XXX */
  355. DNS_OPT_TIMEOUT, /* timeout in secounds */
  356. DNS_OPT_NTRIES, /* number of retries */
  357. DNS_OPT_NDOTS, /* ndots */
  358. DNS_OPT_UDPSIZE, /* EDNS0 UDP size */
  359. DNS_OPT_PORT, /* port to use */
  360. };
  361. /* set or get (if val<0) an option */
  362. UDNS_API int
  363. dns_set_opt(struct dns_ctx *ctx, enum dns_opt opt, int val);
  364. enum dns_flags {
  365. DNS_NOSRCH = 0x00010000, /* do not perform search */
  366. DNS_NORD = 0x00020000, /* request no recursion */
  367. DNS_AAONLY = 0x00040000, /* set AA flag in queries */
  368. DNS_SET_DO = 0x00080000, /* set EDNS0 "DO" bit (DNSSEC OK) */
  369. DNS_SET_CD = 0x00100000, /* set CD bit (DNSSEC: checking disabled) */
  370. };
  371. /* set the debug function pointer */
  372. typedef void
  373. (dns_dbgfn)(int code, const struct sockaddr *sa, unsigned salen,
  374. dnscc_t *pkt, int plen,
  375. const struct dns_query *q, void *data);
  376. UDNS_API void
  377. dns_set_dbgfn(struct dns_ctx *ctx, dns_dbgfn *dbgfn);
  378. /* open and return UDP socket */
  379. UDNS_API int
  380. dns_open(struct dns_ctx *ctx);
  381. /* return UDP socket or -1 if not open */
  382. UDNS_API int
  383. dns_sock(const struct dns_ctx *ctx);
  384. /* close the UDP socket */
  385. UDNS_API void
  386. dns_close(struct dns_ctx *ctx);
  387. /* return number of requests queued */
  388. UDNS_API int
  389. dns_active(const struct dns_ctx *ctx);
  390. /* return status of the last operation */
  391. UDNS_API int
  392. dns_status(const struct dns_ctx *ctx);
  393. UDNS_API void
  394. dns_setstatus(struct dns_ctx *ctx, int status);
  395. /* handle I/O event on UDP socket */
  396. UDNS_API void
  397. dns_ioevent(struct dns_ctx *ctx, time_t now);
  398. /* process any timeouts, return time in secounds to the
  399. * next timeout (or -1 if none) but not greather than maxwait */
  400. UDNS_API int
  401. dns_timeouts(struct dns_ctx *ctx, int maxwait, time_t now);
  402. /* define timer requesting routine to use */
  403. typedef void dns_utm_fn(struct dns_ctx *ctx, int timeout, void *data);
  404. UDNS_API void
  405. dns_set_tmcbck(struct dns_ctx *ctx, dns_utm_fn *fn, void *data);
  406. /**************************************************************************/
  407. /**************** Making Queries ******************************************/
  408. /* query callback routine */
  409. typedef void dns_query_fn(struct dns_ctx *ctx, void *result, void *data);
  410. /* query parse routine: raw DNS => application structure */
  411. typedef int
  412. dns_parse_fn(dnscc_t *qdn, dnscc_t *pkt, dnscc_t *cur, dnscc_t *end,
  413. void **res);
  414. enum dns_status {
  415. DNS_E_NOERROR = 0, /* ok, not an error */
  416. DNS_E_TEMPFAIL = -1, /* timeout, SERVFAIL or similar */
  417. DNS_E_PROTOCOL = -2, /* got garbled reply */
  418. DNS_E_NXDOMAIN = -3, /* domain does not exists */
  419. DNS_E_NODATA = -4, /* domain exists but no data of reqd type */
  420. DNS_E_NOMEM = -5, /* out of memory while processing */
  421. DNS_E_BADQUERY = -6 /* the query is malformed */
  422. };
  423. /* submit generic DN query */
  424. UDNS_API struct dns_query *
  425. dns_submit_dn(struct dns_ctx *ctx,
  426. dnscc_t *dn, int qcls, int qtyp, int flags,
  427. dns_parse_fn *parse, dns_query_fn *cbck, void *data);
  428. /* submit generic name query */
  429. UDNS_API struct dns_query *
  430. dns_submit_p(struct dns_ctx *ctx,
  431. const char *name, int qcls, int qtyp, int flags,
  432. dns_parse_fn *parse, dns_query_fn *cbck, void *data);
  433. /* cancel the given async query in progress */
  434. UDNS_API int
  435. dns_cancel(struct dns_ctx *ctx, struct dns_query *q);
  436. /* resolve a generic query, return the answer */
  437. UDNS_API void *
  438. dns_resolve_dn(struct dns_ctx *ctx,
  439. dnscc_t *qdn, int qcls, int qtyp, int flags,
  440. dns_parse_fn *parse);
  441. UDNS_API void *
  442. dns_resolve_p(struct dns_ctx *ctx,
  443. const char *qname, int qcls, int qtyp, int flags,
  444. dns_parse_fn *parse);
  445. UDNS_API void *
  446. dns_resolve(struct dns_ctx *ctx, struct dns_query *q);
  447. /* Specific RR handlers */
  448. #define dns_rr_common(prefix) \
  449. char *prefix##_cname; /* canonical name */ \
  450. char *prefix##_qname; /* original query name */ \
  451. unsigned prefix##_ttl; /* TTL value */ \
  452. int prefix##_nrr /* number of records */
  453. struct dns_rr_null { /* NULL RRset, aka RRset template */
  454. dns_rr_common(dnsn);
  455. };
  456. UDNS_API int
  457. dns_stdrr_size(const struct dns_parse *p);
  458. UDNS_API void *
  459. dns_stdrr_finish(struct dns_rr_null *ret, char *cp, const struct dns_parse *p);
  460. struct dns_rr_a4 { /* the A RRset */
  461. dns_rr_common(dnsa4);
  462. struct in_addr *dnsa4_addr; /* array of addresses, naddr elements */
  463. };
  464. UDNS_API dns_parse_fn dns_parse_a4; /* A RR parsing routine */
  465. typedef void /* A query callback routine */
  466. dns_query_a4_fn(struct dns_ctx *ctx, struct dns_rr_a4 *result, void *data);
  467. /* submit A IN query */
  468. UDNS_API struct dns_query *
  469. dns_submit_a4(struct dns_ctx *ctx, const char *name, int flags,
  470. dns_query_a4_fn *cbck, void *data);
  471. /* resolve A IN query */
  472. UDNS_API struct dns_rr_a4 *
  473. dns_resolve_a4(struct dns_ctx *ctx, const char *name, int flags);
  474. struct dns_rr_a6 { /* the AAAA RRset */
  475. dns_rr_common(dnsa6);
  476. struct in6_addr *dnsa6_addr; /* array of addresses, naddr elements */
  477. };
  478. UDNS_API dns_parse_fn dns_parse_a6; /* A RR parsing routine */
  479. typedef void /* A query callback routine */
  480. dns_query_a6_fn(struct dns_ctx *ctx, struct dns_rr_a6 *result, void *data);
  481. /* submit AAAA IN query */
  482. UDNS_API struct dns_query *
  483. dns_submit_a6(struct dns_ctx *ctx, const char *name, int flags,
  484. dns_query_a6_fn *cbck, void *data);
  485. /* resolve AAAA IN query */
  486. UDNS_API struct dns_rr_a6 *
  487. dns_resolve_a6(struct dns_ctx *ctx, const char *name, int flags);
  488. struct dns_rr_ptr { /* the PTR RRset */
  489. dns_rr_common(dnsptr);
  490. char **dnsptr_ptr; /* array of PTRs */
  491. };
  492. UDNS_API dns_parse_fn dns_parse_ptr; /* PTR RR parsing routine */
  493. typedef void /* PTR query callback */
  494. dns_query_ptr_fn(struct dns_ctx *ctx, struct dns_rr_ptr *result, void *data);
  495. /* submit PTR IN in-addr.arpa query */
  496. UDNS_API struct dns_query *
  497. dns_submit_a4ptr(struct dns_ctx *ctx, const struct in_addr *addr,
  498. dns_query_ptr_fn *cbck, void *data);
  499. /* resolve PTR IN in-addr.arpa query */
  500. UDNS_API struct dns_rr_ptr *
  501. dns_resolve_a4ptr(struct dns_ctx *ctx, const struct in_addr *addr);
  502. /* the same as above, but for ip6.arpa */
  503. UDNS_API struct dns_query *
  504. dns_submit_a6ptr(struct dns_ctx *ctx, const struct in6_addr *addr,
  505. dns_query_ptr_fn *cbck, void *data);
  506. UDNS_API struct dns_rr_ptr *
  507. dns_resolve_a6ptr(struct dns_ctx *ctx, const struct in6_addr *addr);
  508. struct dns_mx { /* single MX RR */
  509. int priority; /* MX priority */
  510. char *name; /* MX name */
  511. };
  512. struct dns_rr_mx { /* the MX RRset */
  513. dns_rr_common(dnsmx);
  514. struct dns_mx *dnsmx_mx; /* array of MXes */
  515. };
  516. UDNS_API dns_parse_fn dns_parse_mx; /* MX RR parsing routine */
  517. typedef void /* MX RR callback */
  518. dns_query_mx_fn(struct dns_ctx *ctx, struct dns_rr_mx *result, void *data);
  519. /* submit MX IN query */
  520. UDNS_API struct dns_query *
  521. dns_submit_mx(struct dns_ctx *ctx, const char *name, int flags,
  522. dns_query_mx_fn *cbck, void *data);
  523. /* resolve MX IN query */
  524. UDNS_API struct dns_rr_mx *
  525. dns_resolve_mx(struct dns_ctx *ctx, const char *name, int flags);
  526. struct dns_txt { /* single TXT record */
  527. int len; /* length of the text */
  528. dnsc_t *txt; /* pointer to text buffer. May contain nulls. */
  529. };
  530. struct dns_rr_txt { /* the TXT RRset */
  531. dns_rr_common(dnstxt);
  532. struct dns_txt *dnstxt_txt; /* array of TXT records */
  533. };
  534. UDNS_API dns_parse_fn dns_parse_txt; /* TXT RR parsing routine */
  535. typedef void /* TXT RR callback */
  536. dns_query_txt_fn(struct dns_ctx *ctx, struct dns_rr_txt *result, void *data);
  537. /* submit TXT query */
  538. UDNS_API struct dns_query *
  539. dns_submit_txt(struct dns_ctx *ctx, const char *name, int qcls, int flags,
  540. dns_query_txt_fn *cbck, void *data);
  541. /* resolve TXT query */
  542. UDNS_API struct dns_rr_txt *
  543. dns_resolve_txt(struct dns_ctx *ctx, const char *name, int qcls, int flags);
  544. struct dns_srv { /* single SRV RR */
  545. int priority; /* SRV priority */
  546. int weight; /* SRV weight */
  547. int port; /* SRV port */
  548. char *name; /* SRV name */
  549. };
  550. struct dns_rr_srv { /* the SRV RRset */
  551. dns_rr_common(dnssrv);
  552. struct dns_srv *dnssrv_srv; /* array of SRVes */
  553. };
  554. UDNS_API dns_parse_fn dns_parse_srv; /* SRV RR parsing routine */
  555. typedef void /* SRV RR callback */
  556. dns_query_srv_fn(struct dns_ctx *ctx, struct dns_rr_srv *result, void *data);
  557. /* submit SRV IN query */
  558. UDNS_API struct dns_query *
  559. dns_submit_srv(struct dns_ctx *ctx,
  560. const char *name, const char *srv, const char *proto,
  561. int flags, dns_query_srv_fn *cbck, void *data);
  562. /* resolve SRV IN query */
  563. UDNS_API struct dns_rr_srv *
  564. dns_resolve_srv(struct dns_ctx *ctx,
  565. const char *name, const char *srv, const char *proto,
  566. int flags);
  567. /* NAPTR (RFC3403) RR type */
  568. struct dns_naptr { /* single NAPTR RR */
  569. int order; /* NAPTR order */
  570. int preference; /* NAPTR preference */
  571. char *flags; /* NAPTR flags */
  572. char *service; /* NAPTR service */
  573. char *regexp; /* NAPTR regexp */
  574. char *replacement; /* NAPTR replacement */
  575. };
  576. struct dns_rr_naptr { /* the NAPTR RRset */
  577. dns_rr_common(dnsnaptr);
  578. struct dns_naptr *dnsnaptr_naptr; /* array of NAPTRes */
  579. };
  580. UDNS_API dns_parse_fn dns_parse_naptr; /* NAPTR RR parsing routine */
  581. typedef void /* NAPTR RR callback */
  582. dns_query_naptr_fn(struct dns_ctx *ctx,
  583. struct dns_rr_naptr *result, void *data);
  584. /* submit NAPTR IN query */
  585. UDNS_API struct dns_query *
  586. dns_submit_naptr(struct dns_ctx *ctx, const char *name, int flags,
  587. dns_query_naptr_fn *cbck, void *data);
  588. /* resolve NAPTR IN query */
  589. UDNS_API struct dns_rr_naptr *
  590. dns_resolve_naptr(struct dns_ctx *ctx, const char *name, int flags);
  591. UDNS_API struct dns_query *
  592. dns_submit_a4dnsbl(struct dns_ctx *ctx,
  593. const struct in_addr *addr, const char *dnsbl,
  594. dns_query_a4_fn *cbck, void *data);
  595. UDNS_API struct dns_query *
  596. dns_submit_a4dnsbl_txt(struct dns_ctx *ctx,
  597. const struct in_addr *addr, const char *dnsbl,
  598. dns_query_txt_fn *cbck, void *data);
  599. UDNS_API struct dns_rr_a4 *
  600. dns_resolve_a4dnsbl(struct dns_ctx *ctx,
  601. const struct in_addr *addr, const char *dnsbl);
  602. UDNS_API struct dns_rr_txt *
  603. dns_resolve_a4dnsbl_txt(struct dns_ctx *ctx,
  604. const struct in_addr *addr, const char *dnsbl);
  605. UDNS_API struct dns_query *
  606. dns_submit_a6dnsbl(struct dns_ctx *ctx,
  607. const struct in6_addr *addr, const char *dnsbl,
  608. dns_query_a4_fn *cbck, void *data);
  609. UDNS_API struct dns_query *
  610. dns_submit_a6dnsbl_txt(struct dns_ctx *ctx,
  611. const struct in6_addr *addr, const char *dnsbl,
  612. dns_query_txt_fn *cbck, void *data);
  613. UDNS_API struct dns_rr_a4 *
  614. dns_resolve_a6dnsbl(struct dns_ctx *ctx,
  615. const struct in6_addr *addr, const char *dnsbl);
  616. UDNS_API struct dns_rr_txt *
  617. dns_resolve_a6dnsbl_txt(struct dns_ctx *ctx,
  618. const struct in6_addr *addr, const char *dnsbl);
  619. UDNS_API struct dns_query *
  620. dns_submit_rhsbl(struct dns_ctx *ctx,
  621. const char *name, const char *rhsbl,
  622. dns_query_a4_fn *cbck, void *data);
  623. UDNS_API struct dns_query *
  624. dns_submit_rhsbl_txt(struct dns_ctx *ctx,
  625. const char *name, const char *rhsbl,
  626. dns_query_txt_fn *cbck, void *data);
  627. UDNS_API struct dns_rr_a4 *
  628. dns_resolve_rhsbl(struct dns_ctx *ctx, const char *name, const char *rhsbl);
  629. UDNS_API struct dns_rr_txt *
  630. dns_resolve_rhsbl_txt(struct dns_ctx *ctx, const char *name, const char *rhsbl);
  631. /**************************************************************************/
  632. /**************** Names, Names ********************************************/
  633. struct dns_nameval {
  634. int val;
  635. const char *name;
  636. };
  637. UDNS_DATA_API extern const struct dns_nameval dns_classtab[];
  638. UDNS_DATA_API extern const struct dns_nameval dns_typetab[];
  639. UDNS_DATA_API extern const struct dns_nameval dns_rcodetab[];
  640. UDNS_API int
  641. dns_findname(const struct dns_nameval *nv, const char *name);
  642. #define dns_findclassname(cls) dns_findname(dns_classtab, (cls))
  643. #define dns_findtypename(type) dns_findname(dns_typetab, (type))
  644. #define dns_findrcodename(rcode) dns_findname(dns_rcodetab, (rcode))
  645. UDNS_API const char *dns_classname(enum dns_class cls);
  646. UDNS_API const char *dns_typename(enum dns_type type);
  647. UDNS_API const char *dns_rcodename(enum dns_rcode rcode);
  648. const char *_dns_format_code(char *buf, const char *prefix, int code);
  649. UDNS_API const char *dns_strerror(int errnum);
  650. /* simple pseudo-random number generator, code by Bob Jenkins */
  651. struct udns_jranctx { /* the context */
  652. unsigned a, b, c, d;
  653. };
  654. /* initialize the RNG with a given seed */
  655. UDNS_API void
  656. udns_jraninit(struct udns_jranctx *x, unsigned seed);
  657. /* return next random number. 32bits on most platforms so far. */
  658. UDNS_API unsigned
  659. udns_jranval(struct udns_jranctx *x);
  660. #ifdef __cplusplus
  661. } /* extern "C" */
  662. #endif
  663. #endif /* include guard */