1
2udns(3) Library Functions Manual udns(3)
3
4
5
7 udns - stub DNS resolver library
8
9
11 #include <udns.h>
12 struct dns_ctx;
13 struct dns_query;
14 extern struct dns_ctx dns_defctx;
15 struct dns_ctx *ctx;
16 typedef void dns_query_fn(ctx, void *result, void *data);
17 typedef int
18 dns_parse_fn(const unsigned char *qnd,
19 const unsigned char *pkt,
20 const unsigned char *cur,
21 const unsigned char *end,
22 void **resultp);
23
24 cc ... -ludns
25
26
28 The DNS library, udns, implements thread-safe stub DNS resolver func‐
29 tionality, which may be used both traditional, syncronous way and asyn‐
30 cronously, with application-supplied event loop.
31
32
33 While DNS works with both TCP and UDP, performing UDP query first and
34 if the result does not fit in UDP buffer (512 bytes max for original
35 DNS protocol), retrying the query over TCP, the library uses UDP only,
36 but uses EDNS0 (RFC2671) extensions which allows larger UDP buffers.
37
38
39 The library uses single UDP socket to perform all operations even when
40 asking multiple nameservers. This way, it is very simple to use the
41 library in asyncronous event-loop applications: an application should
42 add only single socket to the set of filedescriptors it monitors for
43 I/O.
44
45
46 The library uses two main objects, resolver context of type
47 struct dns_ctx, and query structure of type struct dns_query, both are
48 opaque for an application. Resolver context holds global information
49 about the resolver, such as list of nameservers to use, list of active
50 requests and the like. Query objects holds information about a single
51 DNS query in progress and are allocated/processed/freed by the library.
52 Pointer to query structure may be treated as an identifier of an in-
53 progress query and may be used to cancel the asyncronous query or to
54 wait for it to complete.
55
56
57 Asyncronous interface works as follows. An application initializes
58 resolver context, submits any number of queries for it using one of
59 supplied dns_submit_XXX() routines (each return the query identifier as
60 pointer to query structure), waits for input on the UDP socket used by
61 the library, and gives some control to the library by calling
62 dns_ioevent() and dns_timeouts() routines when appropriate. The
63 library performs all necessary processing and executes application sup‐
64 plied callback routine when a query completes (either successefully or
65 not), giving it the result if any, pointer to the resolver context
66 (from which completion status may be obtained), and the data pointer
67 supplied by an application when the query has been submitted. When
68 submitting a query, an application requests how to handle the reply --
69 to either return raw DNS reply packet for its own low-level processing,
70 or it may provide an address of parsing routine of type dns_parse_fn to
71 perform conversion of on-wire format into easy to use data structure
72 (the library provides parsing routines for several commonly used
73 resource record types, as well as type-safe higher-level inteface that
74 requests parsing automatically). The I/O monitoring and timeout han‐
75 dling may be either traditional select() or poll() based, or any call‐
76 back-driven technique may be used.
77
78
79 Additionally, the library provides traditional syncronous interface,
80 which may be intermixed with asyncronous calls (during syncronous query
81 processing, other asyncronous queries for the same resolver context
82 continued to be processed as usual). An application uses one of numer‐
83 ous dns_resolve_XXX() routines provided by the library to perform a
84 query. As with asyncronous interface, an application may either
85 request to return raw DNS packet or type-specific data structure by
86 providing the parsing routine to handle the reply. Every routine from
87 dns_resolve_XXX() series return pointer to result or NULL in case of
88 any error. Query completion status (or length of the raw DNS packet)
89 is available from the resolver context using dns_status() routine, the
90 same way as for the asyncronous interface.
91
92
93 Internally, library uses on-wire format of domain names, referred to as
94 DN format in this manual page. This is a series of domain labels whith
95 preceeding length byte, terminated by zero-length label wich is inte‐
96 gral part of the DN format. There are several routines provided to
97 convert from traditional asciiz string to DN and back. Higher-level
98 type-specific query interface hides the DN format from an application.
99
100
102 Every DNS Resource Record (RR) has a type and a class. The library
103 defines several integer constants, DNS_C_XXX and DNS_T_XXX, to use as
104 symbolic names for RR classes and types, such as DNS_C_IN for Internet
105 class, DNS_T_A for IPv4 address record type and so on. See udns.h
106 header file for complete list of all such constants.
107
108
109 The following constants are defined in udns.h header file:
110
111 DNS_MAXDN (255 bytes)
112 Maximum length of the domain name in internal (on-wire) DN for‐
113 mat.
114
115 DNS_MAXLABEL (63 bytes)
116 Maximum length of a single label in DN format.
117
118 DNS_MAXNAME (1024 bytes)
119 Maximum length of asciiz format of a domain name.
120
121 DNS_HSIZE (12 bytes)
122 Size of header in DNS packet.
123
124 DNS_PORT (53)
125 Default port to use when contacting a DNS server.
126
127 DNS_MAXSERV (6 servers)
128 Maximum number of DNS servers to use.
129
130 DNS_MAXPACKET (512 bytes)
131 Maximum length of DNS UDP packet as specified by original DNS
132 protocol
133
134 DNS_EDNS0PACKET (4096 bytes)
135 Default length of DNS UDP packet (with EDNS0 extensions) the
136 library uses. Note that recursive nameservers usually resides
137 near the client asking them to resolve names, e.g. on the same
138 LAN segment or even on the same host, so UDP packet fragmenta‐
139 tion isn't a problem in most cases. Note also that the size of
140 actual packets will be as many bytes as actual reply size
141 requires, which is smaller than this value in almost all cases.
142
143
144 Additionally, several constants are defined to simplify work with raw
145 DNS packets, such as DNS response codes (DNS_R_XXX), DNS header layout
146 (DNS_H_XXX) and others. Again, see udns.h for complete list. Library
147 error codes (DNS_E_XXX) are described later in this manual page.
148
149
151 Resolver context, of type struct dns_ctx, is an object which is opaque
152 to an application. Several routines provided by the library to ini‐
153 tialize, copy and free resolver contexts. Most other high-level rou‐
154 tines in this library expects a pointer to resolver context, ctx, as
155 the first argument. There is a default resolver context available,
156 named dns_defctx. When the context pointer ctx passed to a routine is
157 NULL, dns_defctx is used. Several resolver contexts may be active at
158 the same time, for example, when an application is multi-threaded and
159 each thread uses resolver.
160
161 In order to use the library, an application should initialize and open
162 one or more resolver context objects. These are two separate actions,
163 performed by dns_init() (or dns_reset()), and dns_open(). Between the
164 two calls, an application is free to pefrorm additional initialisation,
165 such as setting custom nameservers, options or domain search lists.
166 Optionally, in case no additional custom initialisation is required,
167 dns_init() may open the context if do_open argument (see below) is non-
168 zero.
169
170 When initializing resolver context, the library uses information from
171 system file /etc/resolv.conf (see resolv.conf(5)), consults environment
172 variables $LOCALDOMAIN, $NSCACHEIP, $NAMESERVERS and $RES_OPTIONS, and
173 local host name to obtain list of local nameservers, domain name search
174 list and various resolver options.
175
176 The following routines to initialize resolver context are available:
177
178 void dns_reset(ctx)
179 int dns_init(ctx, int do_open)
180 dns_reset() resets a given resolver context to default values,
181 preparing it to be opened by dns_open(). It is ok to call this
182 routine against opened and active context - all active queries
183 will be dropped, sockets will be closed and so on. This routine
184 does not initialize any parameters from system configuration
185 files, use dns_init() for this. There's no error return - oper‐
186 ation always succeeds. dns_init() does everything dns_reset()
187 does, plus initializes various parameters of the context accord‐
188 ing to system configuration and process environment variables.
189 If do_open is non-zero, dns_init() calls dns_open(), so that the
190 whole library initialisation is performed in a single step.
191
192 struct dns_ctx *dns_new(struct dns_ctx *copy)
193 void dns_free(ctx)
194 dns_new() allocates new resolver context and copies all parame‐
195 ters for a given resolver context copy, or default context if
196 copy is NULL, and returns pointer to the newly allocated con‐
197 text. The context being copied should be initialized.
198 dns_new() may fail if there's no memory available to make a copy
199 of copy, in which case the routine will return NULL pointer.
200 dns_free() is used to close assotiated socket and free resolver
201 context resources and cancelling (abandoming) all active queries
202 assotiated with it. It's an error to free dns_defctx, only
203 dynamically allocated contexts returned by dns_new() are allowed
204 to be freed by dns_free().
205
206 int dns_add_serv(ctx, const char *servaddr)
207 int dns_add_serv_s(ctx, const struct sockaddr *sa)
208 int dns_add_srch(ctx, const char *srch)
209 Add an element to list of nameservers (dns_add_serv(), as
210 asciiz-string servaddr with an IP address of the nameserver, and
211 dns_add_serv_s(), as initialized socket address sa), or search
212 list (dns_add_srch(), as a pointer to domain name) for the given
213 context ctx. If the last argument is a NULL pointer, the corre‐
214 sponding list (search or nameserver) is reset instead. Upon
215 successeful completion, each routine returns new number of ele‐
216 ments in the list in question. On error, negative value is
217 returned and global variable errno is set appropriately. It is
218 an error to call any of this functions if the context is opened
219 (after dns_open() or dns_init() with non-zero argument).
220
221 int dns_set_opts(ctx, const char *opts)
222 set resolver context options from opts string, in the same way
223 as processing options statement in resolv.conf and $RES_OPTIONS
224 environment variable. Return number of unrecognized/invalid
225 options found (all recognized and valid options gets processed).
226
227 void dns_set_opt(ctx, int opt, val)
228 TODO The flags argument is a bitmask with the following bits
229 defined:
230
231 DNS_NOSRCH
232 do not perform domain name search in search list.
233
234 DNS_NORD
235 do not request recursion when performing queries (i.e.
236 don't set RD flag in querues).
237
238 DNS_AAONLY
239 request authoritative answers only (i.e. set AA flag in
240 queries).
241
242
243 int dns_open(ctx)
244 int dns_sock(const ctx)
245 void dns_close(ctx)
246 dns_open() opens the UDP socket used for queries if not already
247 open, and return assotiated filedescriptor (or negative value in
248 case of error). Before any query can be submitted, the context
249 should be opened using this routine. And before opening, the
250 context should be initialized. dns_sock() return the UDP socket
251 if open, or -1 if not. dns_close() closes the UDP socket if it
252 was open, and drops all active queries if any.
253
254
255 int dns_active(const ctx)
256 return number of active queries queued for the given context
257 ctx, or zero if none.
258
259
260 int dns_status(const ctx)
261 return status code from last operation. When using syncronous
262 interface, this is the query completion status of the last
263 query. With asyncronous interface, from within the callback
264 routine, this is the query completion status of the query for
265 which the callback is being called. When query submission
266 fails, this is the error code indicating failure reason. All
267 error codes are negative and are represented by DNS_E_XXX con‐
268 stants described below.
269
270
271 void dns_ioevent(ctx, time_t now)
272 this routine may be called by an application to process I/O
273 events on the UDP socket used by the library, as returned by
274 dns_sock(). The routine tries to receive incoming UDP datagram
275 from the socket and process it. The socket is set up to be non-
276 blocking, so it is safe to call the routine even if there's no
277 data to read. The routine will process as many datagrams as are
278 queued for the socket, so it is safe to use it with either
279 level-triggered or edge-triggered I/O monitoring model. The now
280 argument is either a current time as returned by time(), or 0,
281 in which case the routine will obtain current time by it's own.
282
283
284 int dns_timeouts(ctx, int maxwait, time_t now)
285 process any pending timeouts and return number of secounds from
286 current time (now if it is not 0) to the time when the library
287 wants the application to pass it control to process more queued
288 requests. In case when there are no requests pending, this time
289 is -1. The routine will not request a time larger than maxwait
290 secounds if it is greather or equal to zero. If now is 0, the
291 routine will obtain current time by it's own; when it is not 0,
292 it should contain current time as returned by time().
293
294
295 typedef void dns_utm_fn(ctx, int timeout, void *data)
296 void dns_set_tmcbck(ctx, dns_utm_fn *utmfn, void *data)
297 An application may use custom callback-based I/O multiplexing
298 mechanism. Usually such a mechanism have concept of a timer,
299 and an ability to register a timer event in a form of a callback
300 routine which will be executed after certain amount of time. In
301 order to use such an event mechanism, udns provides an ability
302 to register and de-register timer events necessary for internal
303 processing using whatever event mechanism an application uses.
304 For this to work, it is possible to assotiate a pointer to a
305 routine that will perform necessary work for (de)registering
306 timer events with a given resolver context, and udns will call
307 that routine at appropriate times. Prototype of such a routine
308 is shown by dns_utm_fn typedef above. Libudns assotiates single
309 timer with resolver context. User-supplied utmfn routine will
310 be called by the library with the following arguments:
311
312 ctx == NULL
313 delete user timer, at context free time or when an appli‐
314 cation changes user timer request routine using
315 dns_set_tmcbck();
316
317 ctx != NULL, timeout < 0
318 don't fire timer anymore, when there are no active
319 requests;
320
321 ctx != NULL, timeout == 0
322 fire timer at the next possibility, but not immediately;
323
324 ctx != NULL, timeout > 0
325 fire timer after timeout seconds after now.
326
327 The data argument passed to the routine will be the same as
328 passed to dns_set_tmcbck().
329
330 When a timer expires, an application should call dns_timeouts()
331 routine (see below). Non-callback timer usage is provided too.
332
333
334 XXXX TODO: some more resolver context routines, like dns_set_dbgfn()
335 etc.
336
337
339 There are two ways to perform DNS queries: traditional syncronous way,
340 when udns performs all the necessary processing and return control to
341 the application only when the query completes, and asyncronous way,
342 when an application submits one or more queries to the library using
343 given resolver context, and waits for completion by monitoring
344 filedescriptor used by library and calling library routines to process
345 input on that filedescriptor. Asyncronous mode works with callback
346 routines: an application supplies an address of a routine to execute
347 when the query completes, and a data pointer, which is passed to the
348 callback routine.
349
350
351 Queries are submitted to the library in a form of struct dns_query. To
352 perform asyncronous query, an application calls one of the dns_sub‐
353 mit_XXX() rounines, and provides necessary information for a callback,
354 together with all the query parameters. When the query completes,
355 library will call application-supplied callback routine, giving it the
356 resolver context (wich holds query completion status), dynamically
357 allocated result (which will be either raw DNS packet or, if applicatin
358 requested parsing the result by specifying non-NULL parse routine,
359 ready-to-use type-specific structure), and a data pointer provided by
360 an application when it submitted the query. It is the application
361 who's responsible for freeing the result memory.
362
363 Generic query callback routine looks like this:
364 typedef void
365 dns_query_fn(ctx, void *result, void *data)
366 Type-specific query interface expects similar form of callback routine
367 with the only difference in type of result argument, which will be
368 pointer to specific data structure (decoded reply) instead of this void
369 pointer to raw DNS packet data.
370
371
372 Result parsing routine looks like this:
373 typedef int
374 dns_parse_fn(const unsigned char *qdn,
375 const unsigned char *pkt,
376 const unsigned char *cur,
377 const unsigned char *end,
378 void **resultp);
379 When called by the library, the arguments are as follows: pkt points to
380 the start of the packet received; end points past the end of the packet
381 received; cur points past the query DN in the query section of the
382 packet; qdn points to the original query DN. The routine should allo‐
383 cate a single buffer to hold the result, parse the reply filling in the
384 buffer, and return the buffer using resultp argument. It returns 0 in
385 case of error, or udns error code (DNS_E_XXX constants) in case of
386 error. Note that by the time when the parse routine is called by the
387 library, packet is already verified to be a reply to the original
388 query, by matching query DN, query class and query type.
389
390
391 Type-specific query inteface supplies necessary parsing routines auto‐
392 matically.
393
394
395 In case of error, query completion status as returned by dns_sta‐
396 tus(ctx), will contain one of the following values:
397
398 positive value
399 length of raw DNS packet if parsing is not requested.
400
401 0 the query was successeful and the reply points to type-specific
402 data structure.
403
404 DNS_E_TEMPFAIL
405 temporary error, the resolver nameserver was not able to process
406 our query or timed out.
407
408 DNS_E_PROTOCOL
409 protocol error, a nameserver returned malformed reply.
410
411 DNS_E_NXDOMAIN
412 the domain name does not exist.
413
414 DNS_E_NODATA
415 there is no data of requested type found.
416
417 DNS_E_NOMEM
418 out of memory while processing request.
419
420 DNS_E_BADQUERY
421 some aspect of the query (most common is the domain name in
422 question) is invalid, and the library can't even start a query.
423
424
425 Library provides two series of routines which uses similar interface --
426 one for asyncronous queries and another for syncronous queries. There
427 are two general low-level routines in each series to submit (asyn‐
428 cronous interface) and resolve (syncronous interface) queries, as well
429 as several type-specific routines with more easy-to-use interfaces. To
430 submit an asyncronous query, use one of dns_submit_XXX() routine, each
431 of which accepts query parameters, pointers to callback routine and to
432 callback data, and optional current time hint. Note type-specific
433 dns_submit_XXX() routines expects specific type of the callback routine
434 as well, which accepts reply as a pointer to corresponding structure,
435 not a void pointer). Every dns_submit_XXX() routine return pointer to
436 internal query structure of type struct dns_query, used as an identi‐
437 fier for the given query.
438
439
440 To resolve a query syncronously, use one of dns_resolve_XXX() routines,
441 which accepts the same query parameters (but not the callback pointers)
442 as corresponding dns_submit_XXX(), and return the query result, which
443 is the same as passed to the callback routine in case of asyncronous
444 interface.
445
446
447 In either case, the result memory (if the query completed successe‐
448 fully) is dynamically allocated and should be freed by an application.
449 If the query failed for any reason, the result will be NULL, and error
450 status will be available from dns_status(ctx) routine as shown above.
451
452
453 struct dns_query *
454 dns_submit_dn(ctx,
455 const unsigned char *dn, qcls, qtyp, flags,
456 parse, cbck, data)
457 struct dns_query *
458 dns_submit_p(ctx,
459 const char *name, qcls, qtyp, flags,
460 parse, cbck, data)
461 enum dns_class qcls;
462 enum dns_type qtyp;
463 int flags;
464 dns_parse_fn *parse;
465 dns_query_fn *cbck;
466 void *data;
467 submit a query for processing for the given resolver context
468 ctx. Two routines differs only in 3rd argument, which is domain
469 name in DN format (dn) or asciiz string (name). The query will
470 be performed for the given domain name, with type qtyp in class
471 qcls, using option bits in flags, using RR parsing routine
472 pointed by parse if not-NULL, and upon completion, cbck function
473 will be called with the data argument. In case of successeful
474 query submission, the routine return pointer to internal query
475 structure which may be treated as an identifier of the query as
476 used by the library, and may be used as an argument for dns_can‐
477 cel() routine. In case of error, NULL will be returned, and
478 context error status (available using dns_status() routine) will
479 be set to corresponding error code, which in this case may be
480 DNS_E_BADQUERY if the name of dn is invalid, DNS_E_NOMEM if
481 there's no memory available to allocate query structure, or
482 DNS_E_TEMPFAIL if an internal error occured.
483
484
485 void *dns_resolve_dn(ctx,
486 const unsigned char *dn, qcls, qtyp, flags, parse);
487 void *dns_resolve_p(ctx,
488 const char *name, qcls, qtyp, flags, parse)
489 enum dns_class qcls;
490 enum dns_type qtyp;
491 int flags;
492 dns_parse_fn *parse;
493 syncronous interface. The routines perform all the steps neces‐
494 sary to resolve the given query and return the result. If
495 there's no positive result for any reason, all the routines
496 return NULL, and set context error status (available using
497 dns_status() routine) to indicate the error code. If the query
498 was successeful, context status code will contain either the
499 length of the raw DNS reply packet if parse argument was NULL
500 (in which case the return value is pointer to the reply DNS
501 packet), or 0 (in which case the return value is the result of
502 parse routine). If the query successeful (return value is not
503 NULL), the memory returned was dynamically allocated by the
504 library and should be free()d by application after use.
505
506
507 void *dns_resolve(ctx, struct dns_query *q)
508 wait for the given query q, as returned by one of dns_sub‐
509 mit_XXX() routines, for completion, and return the result. The
510 callback routine will not be called for this query. After com‐
511 pletion, the query identifier q is not valid. Both
512 dns_resolve_dn() and dns_resolve_p() are just wrappers around
513 corresponding submit routines and this dns_resolve() routine.
514
515
516 void dns_cancel(ctx, struct dns_query *q)
517 cancel an active query q, without calling a callback routine.
518 After completion, the query identifier q is not valid.
519
520
522 In addition to the generic low-level query interface, the library pro‐
523 vides a set of routines to perform specific queries in a type-safe man‐
524 ner, as well as parsers for several well-known resource record types.
525 The library implements high-level interface for A, AAAA, PTR, MX and
526 TXT records and DNSBL and RHSBL functionality. These routines returns
527 specific types as result of a query, instead of raw DNS packets. The
528 following types and routines are available.
529
530
531 struct dns_rr_null {
532 char *dnsn_qname; /* original query name */
533 char *dnsn_cname; /* canonical name */
534 unsigned dnsn_ttl; /* Time-To-Live (TTL) value */
535 int dnsn_nrr; /* number of records in the set */
536 };
537
538 NULL RR set, used as a base for all other RR type structures. Every RR
539 structure as used by the library have four standard fields as in
540 struct dns_rr_null.
541
542
543 IN A Queries
544 struct dns_rr_a4 { /* IN A RRset */
545 char *dnsa4_qname; /* original query name */
546 char *dnsa4_cname; /* canonical name */
547 unsigned dnsa4_ttl; /* Time-To-Live (TTL) value */
548 int dnsa4_nrr; /* number of addresses in the set */
549 struct in_addr dnsa4_addr[]; /* array of addresses */
550 };
551 typedef void
552 dns_query_a4_fn(ctx, struct dns_rr_a4 *result, data)
553 dns_parse_fn dns_parse_a4;
554 struct dns_query *
555 dns_submit_a4(ctx, const char *name, int flags,
556 dns_query_a4_fn *cbck, data);
557 struct dns_rr_a4 *
558 dns_resolve_a4(ctx, const char *name, int flags);
559
560 The dns_rr_a4 structure holds a result of an IN A query, which is an
561 array of IPv4 addresses. Callback routine for IN A queries expected to
562 be of type dns_query_a4_fn, which expects pointer to dns_rr_a4 struc‐
563 ture as query result instead of raw DNS packet. The dns_parse_a4() is
564 used to convert raw DNS reply packet into dns_rr_a4 structure (it is
565 used internally and may be used directly too with generic query inter‐
566 face). Routines dns_submit_a4() and dns_resolve_a4() are used to per‐
567 form A IN queries in a type-safe manner. The name parameter is the
568 domain name in question, and flags is query flags bitmask, with one
569 bit, DNS_NOSRCH, of practical interest (if the name is absolute, that
570 is, it ends up with a dot, DNS_NOSRCH flag will be set automatically).
571
572
573 IN AAAA Queries
574 struct dns_rr_a6 { /* IN AAAA RRset */
575 char *dnsa6_qname; /* original query name */
576 char *dnsa6_cname; /* canonical name */
577 unsigned dnsa6_ttl; /* Time-To-Live (TTL) value */
578 int dnsa6_nrr; /* number of addresses in the set */
579 struct in6_addr dnsa6_addr[]; /* array of addresses */
580 };
581 typedef void
582 dns_query_a6_fn(ctx, struct dns_rr_a6 *result, data)
583 dns_parse_fn dns_parse_a6;
584 struct dns_query *
585 dns_submit_a6(ctx, const char *name, int flags,
586 dns_query_a6_fn *cbck, data);
587 struct dns_rr_a6 *
588 dns_resolve_a6(ctx, const char *name, int flags);
589
590 The dns_rr_a6 structure holds a result of an IN AAAA query, which is an
591 array of IPv6 addresses. Callback routine for IN AAAA queries expected
592 to be of type dns_query_a6_fn, which expects pointer to dns_rr_a6
593 structure as query result instead of raw DNS packet. The
594 dns_parse_a6() is used to convert raw DNS reply packet into dns_rr_a6
595 structure (it is used internally and may be used directly too with
596 generic query interface). Routines dns_submit_a6() and
597 dns_resolve_a6() are used to perform AAAA IN queries in a type-safe
598 manner. The name parameter is the domain name in question, and flags
599 is query flags bitmask, with one bit, DNS_NOSRCH, of practical interest
600 (if the name is absolute, that is, it ends up with a dot, DNS_NOSRCH
601 flag will be set automatically).
602
603
604 IN PTR Queries
605 struct dns_rr_ptr { /* IN PTR RRset */
606 char *dnsptr_qname; /* original query name */
607 char *dnsptr_cname; /* canonical name */
608 unsigned dnsptr_ttl; /* Time-To-Live (TTL) value */
609 int dnsptr_nrr; /* number of domain name pointers */
610 char *dnsptr_ptr[]; /* array of domain name pointers */
611 };
612 typedef void
613 dns_query_ptr_fn(ctx, struct dns_rr_ptr *result, data)
614 dns_parse_fn dns_parse_ptr;
615 struct dns_query *
616 dns_submit_a4ptr(ctx, const struct in_addr *addr,
617 dns_query_ptr_fn *cbck, data);
618 struct dns_rr_ptr *
619 dns_resolve_a4ptr(ctx, const struct in_addr *addr);
620 struct dns_query *
621 dns_submit_a6ptr(ctx, const struct in6_addr *addr,
622 dns_query_ptr_fn *cbck, data);
623 struct dns_rr_ptr *
624 dns_resolve_a6ptr(ctx, const struct in6_addr *addr);
625
626 The dns_rr_ptr structure holds a result of an IN PTR query, which is an
627 array of domain name pointers for a given IPv4 or IPv6 address. Call‐
628 back routine for IN PTR queries expected to be of type
629 dns_query_ptr_fn, which expects pointer to dns_rr_ptr structure as
630 query result instead of raw DNS packet. The dns_parse_ptr() is used to
631 convert raw DNS reply packet into dns_rr_ptr structure (it is used
632 internally and may be used directly too with generic query interface).
633 Routines dns_submit_a4ptr() and dns_resolve_a4ptr() are used to perform
634 IN PTR queries for IPv4 addresses in a type-safe manner. Routines
635 dns_submit_a6ptr() and dns_resolve_a6ptr() are used to perform IN PTR
636 queries for IPv6 addresses.
637
638
639 IN MX Queries
640 struct dns_mx { /* single MX record */
641 int priority; /* priority value of this MX */
642 char *name; /* domain name of this MX */
643 };
644 struct dns_rr_mx { /* IN MX RRset */
645 char *dnsmx_qname; /* original query name */
646 char *dnsmx_cname; /* canonical name */
647 unsigned dnsmx_ttl; /* Time-To-Live (TTL) value */
648 int dnsmx_nrr; /* number of mail exchangers in the set */
649 struct dns_mx dnsmx_mx[]; /* array of mail exchangers */
650 };
651 typedef void
652 dns_query_mx_fn(ctx, struct dns_rr_mx *result, data)
653 dns_parse_fn dns_parse_mx;
654 struct dns_query *
655 dns_submit_mx(ctx, const char *name, int flags,
656 dns_query_mx_fn *cbck, data);
657 struct dns_rr_mx *
658 dns_resolve_mx(ctx, const char *name, int flags);
659
660 The dns_rr_mx structure holds a result of an IN MX query, which is an
661 array of mail exchangers for a given domain. Callback routine for IN
662 MX queries expected to be of type dns_query_mx_fn, which expects
663 pointer to dns_rr_mx structure as query result instead of raw DNS
664 packet. The dns_parse_mx() is used to convert raw DNS reply packet
665 into dns_rr_mx structure (it is used internally and may be used
666 directly too with generic query interface). Routines dns_submit_mx()
667 and dns_resolve_mx() are used to perform IN MX queries in a type-safe
668 manner. The name parameter is the domain name in question, and flags
669 is query flags bitmask, with one bit, DNS_NOSRCH, of practical interest
670 (if the name is absolute, that is, it ends up with a dot, DNS_NOSRCH
671 flag will be set automatically).
672
673
674 TXT Queries
675 struct dns_txt { /* single TXT record */
676 int len; /* length of the text */
677 unsigned char *txt; /* pointer to the text */
678 };
679 struct dns_rr_txt { /* TXT RRset */
680 char *dnstxt_qname; /* original query name */
681 char *dnstxt_cname; /* canonical name */
682 unsigned dnstxt_ttl; /* Time-To-Live (TTL) value */
683 int dnstxt_nrr; /* number of text records in the set */
684 struct dns_txt dnstxt_txt[]; /* array of TXT records */
685 };
686 typedef void
687 dns_query_txt_fn(ctx, struct dns_rr_txt *result, data)
688 dns_parse_fn dns_parse_txt;
689 struct dns_query *
690 dns_submit_txt(ctx, const char *name, enum dns_class qcls,
691 int flags, dns_query_txt_fn *cbck, data);
692 struct dns_rr_txt *
693 dns_resolve_txt(ctx, const char *name,
694 enum dns_class qcls, int flags);
695
696 The dns_rr_txt structure holds a result of a TXT query, which is an
697 array of text records for a given domain name. Callback routine for
698 TXT queries expected to be of type dns_query_txt_fn, which expects
699 pointer to dns_rr_txt structure as query result instead of raw DNS
700 packet. The dns_parse_txt() is used to convert raw DNS reply packet
701 into dns_rr_txt structure (it is used internally and may be used
702 directly too with generic query interface). Routines dns_submit_txt()
703 and dns_resolve_txt() are used to perform IN MX queries in a type-safe
704 manner. The name parameter is the domain name in question, and flags
705 is query flags bitmask, with one bit, DNS_NOSRCH, of practical interest
706 (if the name is absolute, that is, it ends up with a dot, DNS_NOSRCH
707 flag will be set automatically). Note that each TXT string is repre‐
708 sented by struct dns_txt, while zero-terminated (and the len field of
709 the structure does not include the terminator), may contain embedded
710 null characters -- content of TXT records is not interpreted by the
711 library in any way.
712
713
714 SRV Queries
715 struct dns_srv { /* single SRV record */
716 int priority; /* priority of the record */
717 int weight; /* weight of the record */
718 int port; /* the port number to connect to */
719 char *name; /* target host name */
720 };
721 struct dns_rr_srv { /* SRV RRset */
722 char *dnssrv_qname; /* original query name */
723 char *dnssrv_cname; /* canonical name */
724 unsigned dnssrv_ttl; /* Time-To-Live (TTL) value */
725 int dnssrv_nrr; /* number of text records in the set */
726 struct dns_srv dnssrv_srv[]; /* array of SRV records */
727 };
728 typedef void
729 dns_query_srv_fn(ctx, struct dns_rr_srv *result, data)
730 dns_parse_fn dns_parse_srv;
731 struct dns_query *
732 dns_submit_srv(ctx, const char *name, const char *service, const char *protocol,
733 int flags, dns_query_txt_fn *cbck, data);
734 struct dns_rr_srv *
735 dns_resolve_srv(ctx, const char *name, const char *service, const char *protocol,
736 int flags);
737
738 The dns_rr_srv structure holds a result of an IN SRV (rfc2782) query,
739 which is an array of servers (together with port numbers) which are
740 performing operations for a given service using given protocol on a
741 target domain name. Callback routine for IN SRV queries expected to be
742 of type dns_query_srv_fn, which expects pointer to dns_rr_srv structure
743 as query result instead of raw DNS packet. The dns_parse_srv() is used
744 to convert raw DNS reply packet into dns_rr_srv structure (it is used
745 internally and may be used directly too with generic query interface).
746 Routines dns_submit_srv() and dns_resolve_srv() are used to perform IN
747 SRV queries in a type-safe manner. The name parameter is the domain
748 name in question, service and protocl specifies the service and the
749 protocol in question (the library will construct query DN according to
750 rfc2782 rules) and may be NULL (in this case the library assumes name
751 parameter holds the complete SRV query), and flags is query flags bit‐
752 mask, with one bit, DNS_NOSRCH, of practical interest (if the name is
753 absolute, that is, it ends up with a dot, DNS_NOSRCH flag will be set
754 automatically).
755
756
757 NAPTR Queries
758 struct dns_naptr { /* single NAPTR record */
759 int order; /* record order */
760 int preference; /* preference of this record */
761 char *flags; /* application-specific flags */
762 char *service; /* service parameter */
763 char *regexp; /* substitutional regular expression */
764 char *replacement; /* replacement string */
765 };
766 struct dns_rr_naptr { /* NAPTR RRset */
767 char *dnsnaptr_qname; /* original query name */
768 char *dnsnaptr_cname; /* canonical name */
769 unsigned dnsnaptr_ttl; /* Time-To-Live (TTL) value */
770 int dnsnaptr_nrr; /* number of text records in the set */
771 struct dns_naptr dnsnaptr_naptr[]; /* array of NAPTR records */
772 };
773 typedef void
774 dns_query_naptr_fn(ctx, struct dns_rr_naptr *result, data)
775 dns_parse_fn dns_parse_naptr;
776 struct dns_query *
777 dns_submit_naptr(ctx, const char *name, int flags,
778 dns_query_txt_fn *cbck, data);
779 struct dns_rr_naptr *
780 dns_resolve_naptr(ctx, const char *name, int flags);
781
782 The dns_rr_naptr structure holds a result of an IN NAPTR (rfc3403)
783 query. Callback routine for IN NAPTR queries expected to be of type
784 dns_query_naptr_fn, expects pointer to dns_rr_naptr structure as query
785 result instead of raw DNS packet. The dns_parse_naptr() is used to
786 convert raw DNS reply packet into dns_rr_naptr structure (it is used
787 internally and may be used directly too with generic query interface).
788 Routines dns_submit_naptr() and dns_resolve_naptr() are used to perform
789 IN NAPTR queries in a type-safe manner. The name parameter is the
790 domain name in question, and flags is query flags bitmask, with one
791 bit, DNS_NOSRCH, of practical interest (if the name is absolute, that
792 is, it ends up with a dot, DNS_NOSRCH flag will be set automatically).
793
794
795 DNSBL Interface
796 A DNS-based blocklists, or a DNSBLs, are in wide use nowadays, espe‐
797 cially to protect mailservers from spammers. The library provides
798 DNSBL interface, a set of routines to perform queries against DNSBLs.
799 Routines accepts an IP address (IPv4 and IPv6 are both supported) and a
800 base DNSBL zone as query parameters, and returns either dns_rr_a4 or
801 dns_rr_txt structure. Note that IPv6 interface return IPv4 RRset.
802
803 struct dns_query *
804 dns_submit_a4dnsbl(ctx,
805 const struct in_addr *addr, const char *dnsbl,
806 dns_query_a4_fn *cbck, void *data);
807 struct dns_query *
808 dns_submit_a4dnsbl_txt(ctx,
809 const struct in_addr *addr, const char *dnsbl,
810 dns_query_txt_fn *cbck, void *data);
811 struct dns_query *
812 dns_submit_a6dnsbl(ctx,
813 const struct in6_addr *addr, const char *dnsbl,
814 dns_query_a4_fn *cbck, void *data);
815 struct dns_query *
816 dns_submit_a6dnsbl_txt(ctx,
817 const struct in6_addr *addr, const char *dnsbl,
818 dns_query_txt_fn *cbck, void *data);
819 struct dns_rr_a4 *dns_resolve_a4dnsbl(ctx,
820 const struct in_addr *addr, const char *dnsbl)
821 struct dns_rr_txt *dns_resolve_a4dnsbl_txt(ctx,
822 const struct in_addr *addr, const char *dnsbl)
823 struct dns_rr_a4 *dns_resolve_a6dnsbl(ctx,
824 const struct in6_addr *addr, const char *dnsbl)
825 struct dns_rr_txt *dns_resolve_a6dnsbl_txt(ctx,
826 const struct in6_addr *addr, const char *dnsbl)
827 Perform (submit or resolve) a DNSBL query for the given dnsbl domain
828 and an IP addr in question, requesting either A or TXT records.
829
830
831 RHSBL Interface
832 RHSBL is similar to DNSBL, but instead of an IP address, the parameter
833 is a domain name.
834
835 struct dns_query *
836 dns_submit_rhsbl(ctx, const char *name, const char *rhsbl,
837 dns_query_a4_fn *cbck, void *data);
838 struct dns_query *
839 dns_submit_rhsbl_txt(ctx, const char *name, const char *rhsbl,
840 dns_query_txt_fn *cbck, void *data);
841 struct dns_rr_a4 *
842 dns_resolve_rhsbl(ctx, const char *name, const char *rhsbl);
843 struct dns_rr_txt *
844 dns_resolve_rhsbl_txt(ctx, const char *name, const char *rhsbl);
845 Perform (submit or resolve) a RHSBL query for the given rhsbl domain
846 and name in question, requesting either A or TXT records.
847
848
849
851 Domain Names (DNs)
852 A DN is a series of domain name labels each starts with length byte,
853 followed by empty label (label with zero length). The following rou‐
854 tines to work with DNs are provided.
855
856
857 unsigned dns_dnlen(const unsigned char *dn)
858 return length of the domain name dn, including the terminating
859 label.
860
861
862 unsigned dns_dnlabels(const unsigned char *dn)
863 return number of non-zero labels in domain name dn.
864
865
866 unsigned dns_dnequal(dn1, dn2)
867 const unsigned char *dn1, *dn2;
868 test whenever the two domain names, dn1 and dn2, are equal
869 (case-insensitive). Return domain name length if equal or 0 if
870 not.
871
872
873 unsigned dns_dntodn(sdn, ddn, dnsiz)
874 const unsigned char *sdn;
875 unsigned char *ddn;
876 unsigned dnsiz;
877 copies the source domain name sdn to destination buffer ddn of
878 size dnsiz. Return domain name length or 0 if ddn is too small.
879
880
881 int dns_ptodn(name, namelen, dn, dnsiz, isabs)
882 int dns_sptodn(name, dn, dnsiz)
883 const char *name; unsigned namelen;
884 unsigned char *dn; unsigned dnsiz;
885 int *isabs;
886 convert asciiz name name of length namelen to DN format, placing
887 result into buffer dn of size dnsiz. Return length of the DN if
888 successeful, 0 if the dn buffer supplied is too small, or nega‐
889 tive value if name is invalid. If isabs is non-NULL and conver‐
890 sion was successeful, *isabs will be set to either 1 or 0
891 depending whenever name was absolute (i.e. ending with a dot) or
892 not. Name length, namelength, may be zero, in which case
893 strlen(name) will be used. Second form, dns_sptodn(), is a sim‐
894 plified form of dns_ptodn(), equivalent to
895 dns_ptodn(name, 0, dn, dnlen, 0).
896
897
898 extern const unsigned char dns_inaddr_arpa_dn[]
899 int dns_a4todn(const struct in_addr *addr, const unsigned char *tdn,
900 unsigned char *dn, unsigned dnsiz)
901 int dns_a4ptodn(const struct in_addr *addr, const char *tname,
902 unsigned char *dn, unsigned dnsiz)
903 extern const unsigned char dns_ip6_arpa_dn[]
904 int dns_a6todn(const struct in6_addr *addr, const unsigned char *tdn,
905 unsigned char *dn, unsigned dnsiz)
906 int dns_a6ptodn(const struct in6_addr *addr, const char *tname,
907 unsigned char *dn, unsigned dnsiz)
908 several variants of routines to convert IPv4 and IPv6 address
909 addr into reverseDNS-like domain name in DN format, storing
910 result in dn of size dnsiz. tdn (or tname) is the base zone
911 name, like in-addr.arpa for IPv4 or in6.arpa for IPv6. If tdn
912 (or tname) is NULL, dns_inaddr_arpa_dn (or dns_ip6_arpa_dn) will
913 be used. The routines may be used to construct a DN for a DNSBL
914 lookup for example. All routines return length of the resulting
915 DN on success, -1 if resulting DN is invalid, or 0 if the dn
916 buffer (dnsiz) is too small. To hold standard rDNS DN, a buffer
917 of size DNS_A4RSIZE (30 bytes) for IPv4 address, or DNS_A6RSIZE
918 (74 bytes) for IPv6 address, is sufficient.
919
920
921 int dns_dntop(dn, name, namesiz)
922 const unsigned char *dn;
923 const char *name; unsigned namesiz;
924 convert domain name dn in DN format to asciiz string, placing
925 result into name buffer of size namesiz. Maximum length of
926 asciiz representation of domain name is DNS_MAXNAME [22m(1024)
927 bytes. Root domain is represented as empty string. Return
928 length of the resulting name (including terminating character,
929 i.e. strlen(name)+1) on success, 0 if the name buffer is too
930 small, or negative value if dn is invalid (last case should
931 never happen since all routines in this library which produce
932 domain names ensure the DNs generated are valid).
933
934
935 const char *dns_dntosp(const unsigned char *dn)
936 convert domain name dn in DN format to asciiz string using
937 static buffer. Return the resulting asciiz string on success or
938 NULL on failure. Note since this routine uses static buffer, it
939 is not thread-safe.
940
941
942 unsigned dns_dntop_size(const unsigned char *dn)
943 return the buffer size needed to convert the dn domain name in
944 DN format to asciiz string, for dns_dntop(). The routine return
945 either the size of buffer required, including the trailing zero
946 byte, or 0 if dn is invalid.
947
948
949 Working with DNS Packets
950 The following routines are provided to encode and decode DNS on-wire
951 packets. This is low-level interface.
952
953
954 DNS response codes (returned by dns_rcode() routine) are defined as
955 constants prefixed with DNS_R_. See udns.h header file for the com‐
956 plete list. In particular, constants DNS_R_NOERROR (0), DNS_R_SERV‐
957 FAIL, DNS_R_NXDOMAIN may be of interest to an application.
958
959
960 unsigned dns_get16(const unsigned char *p)
961 unsigned dns_get32(const unsigned char *p)
962 helper routines, convert 16-bit or 32-bit integer in on-wire
963 format pointed to by p to unsigned.
964
965
966 unsigned char *dns_put16(unsigned char *d, unsigned n)
967 unsigned char *dns_put32(unsigned char *d, unsigned n)
968 helper routine, convert unsigned 16-bit or 32-bit integer n to
969 on-wire format to buffer pointed to by d, return d+2 or d+4.
970
971
972 DNS_HSIZE (12)
973 defines size of DNS header. Data section in the DNS packet
974 immediately follows the header. In the header, there are query
975 identifier (id), various flags and codes, and number of resource
976 records in various data sections. See udns.h header file for
977 complete list of DNS header definitions.
978
979
980 unsigned dns_qid(const unsigned char *pkt)
981 int dns_rd(const unsigned char *pkt)
982 int dns_tc(const unsigned char *pkt)
983 int dns_aa(const unsigned char *pkt)
984 int dns_qr(const unsigned char *pkt)
985 int dns_ra(const unsigned char *pkt)
986 unsigned dns_opcode(const unsigned char *pkt)
987 unsigned dns_rcode(const unsigned char *pkt)
988 unsigned dns_numqd(const unsigned char *pkt)
989 unsigned dns_numan(const unsigned char *pkt)
990 unsigned dns_numns(const unsigned char *pkt)
991 unsigned dns_numar(const unsigned char *pkt)
992 const unsigned char *dns_payload(const unsigned char *pkt)
993 return various parts from the DNS packet header pkt: query iden‐
994 tifier (qid), recursion desired (rd) flag, truncation occured
995 (tc) flag, authoritative answer (aa) flag, query response (qr)
996 flag, recursion available (ra) flag, operation code (opcode),
997 result code (rcode), number of entries in question section
998 (numqd), number of answers (numan), number of authority records
999 (numns), number of additional records (numar), and the pointer
1000 to the packet data (payload).
1001
1002
1003 int dns_getdn(pkt, curp, pkte, dn, dnsiz)
1004 const unsigned char *dns_skipdn(cur, pkte)
1005 const unsigned char *pkt, *pkte, **curp, *cur;
1006 unsigned char *dn; unsigned dnsiz;
1007 dns_getdn() extract DN from DNS packet pkt which ends before
1008 pkte starting at position *curp into buffer pointed to by dn of
1009 size dnsiz. Upon successeful completion, *curp will point to
1010 the next byte in the packet after the extracted domain name. It
1011 return positive number (length of the DN if dn) upon successeful
1012 completion, negative value on error (when the packet contains
1013 invalid data), or zero if the dnsiz is too small (maximum length
1014 of a domain name is DNS_MAXDN). dns_skipdn() return pointer to
1015 the next byte in DNS packet which ends up before pkte after a
1016 domain name which starts at the cur byte, or NULL if the packet
1017 is invalid. dns_skipdn() is more or less equivalent to what
1018 dns_getdn() does, except it does not actually extract the domain
1019 name in question, and uses simpler interface.
1020
1021
1022 struct dns_rr {
1023 unsigned char dnsrr_dn[DNS_MAXDN]; /* the RR DN name */
1024 enum dns_class dnsrr_cls; /* class of the RR */
1025 enum dns_type dnsrr_typ; /* type of the RR */
1026 unsigned dnsrr_ttl; /* TTL value */
1027 unsigned dnsrr_dsz; /* size of data in bytes */
1028 const unsigned char *dnsrr_dptr; /* pointer to the first data byte */
1029 const unsigned char *dnsrr_dend; /* next byte after RR */
1030 };
1031 The dns_rr structure is used to hold information about single
1032 DNS Resource Record (RR) in an easy to use form.
1033
1034
1035 struct dns_parse {
1036 const unsigned char *dnsp_pkt; /* pointer to the packet being parsed */
1037 const unsigned char *dnsp_end; /* end of the packet pointer */
1038 const unsigned char *dnsp_cur; /* current packet positionn */
1039 const unsigned char *dnsp_ans; /* pointer to the answer section */
1040 int dnsp_rrl; /* number of RRs left */
1041 int dnsp_nrr; /* number of relevant RRs seen so far */
1042 unsigned dnsp_ttl; /* TTL value so far */
1043 const unsigned char *dnsp_qdn; /* the domain of interest or NULL */
1044 enum dns_class dnsp_qcls; /* class of interest or 0 for any */
1045 enum dns_type dnsp_qtyp; /* type of interest or 0 for any */
1046 unsigned char dnsp_dnbuf[DNS_MAXDN]; /* domain name buffer */
1047 };
1048 The dns_parse structure is used to parse DNS reply packet. It
1049 holds information about the packet being parsed (dnsp_pkt,
1050 dnsp_end and dnsp_cur fields), number of RRs in the current sec‐
1051 tion left to do, and the information about specific RR which
1052 we're looking for (dnsp_qdn, dnsp_qcls and dnsp_qtyp fields).
1053
1054
1055 int dns_initparse(struct dns_parse *p,
1056 const unsigned char *qdn,
1057 const unsigned char *pkt,
1058 const unsigned char *cur,
1059 const unsigned char *end)
1060 initializes the RR parsing structure p. Arguments pkt, cur and
1061 end should describe the received packet: pkt is the start of the
1062 packet, end points to the next byte after the end of the packet,
1063 and cur points past the query DN in query section (to query
1064 class+type information). And qdn points to the query DN. This
1065 is the arguments passed to dns_parse_fn() routine. dns_init‐
1066 parse() initializes dnsp_pkt, dnsp_end and dnsp_qdn fields to
1067 the corresponding arguments, extracts and initializes dnsp_qcls
1068 and dnsp_qtyp fields to the values found at cur pointer, ini‐
1069 tializes dnsp_cur and dnsp_ans fields to be cur+4 (to the start
1070 of answer section), and initializes dnsp_rrl field to be number
1071 of entries in answer section. dnsp_ttl will be set to max TTL
1072 value, 0xffffffff, and dnsp_nrr to 0.
1073
1074
1075 int dns_nextrr(struct dns_parse *p, struct dns_rr *rr);
1076 searches for next RR in the packet based on the criteria pro‐
1077 vided in the p structure, filling in the rr structure and
1078 advancing p->dnsp_cur to the next RR in the packet. RR selec‐
1079 tion is based on dnsp_qdn, dnsp_qcls and dnsp_qtyp fields in the
1080 dns_parse structure. Any (or all) of the 3 fields may be 0,
1081 which means any actual value from the packet is acceptable. In
1082 case the field isn't 0 (or NULL for dnsp_qdn), only RRs with
1083 corresponding characteristics are acceptable. Additionally,
1084 when dnsp_qdn is non-NULL, dns_nextrr() performs automatic CNAME
1085 expansion. Routine will return positive value on success, 0 in
1086 case it reached the end of current section in the packet
1087 (p->dnsp_rrl is zero), or negative value if next RR can not be
1088 decoded (packet format is invalid). The routine updates
1089 p->dnsp_qdn automatically when this field is non-NULL and it
1090 encounters appropriate CNAME RRs (saving CNAME target in
1091 p->dnsp_dnbuf), so after end of the process, p->dnsp_qdn will
1092 point to canonical name of the domain in question. The routine
1093 updates p->dnsp_ttl value to be the minimum TTL of all RRs
1094 found.
1095
1096
1097 void dns_rewind(struct dns_parse *p, const unsigned char *qdn)
1098 this routine "rewinds" the packet parse state structure to be at
1099 the same state as after a call to dns_initparse(), i.e. reposi‐
1100 tion the parse structure p to the start of answer section and
1101 initialize p->dnsp_rrl to the number of entries in answer sec‐
1102 tion.
1103
1104
1105 int dns_stdrr_size(const struct dns_parse *p);
1106 return size to hold standard RRset structure information, as
1107 shown in dns_rr_null structure (for the query and canonical
1108 names). Used to calculate amount of memory to allocate for com‐
1109 mon part of type-specific RR structures in parsing routines.
1110
1111
1112 void *dns_stdrr_finish(struct dns_rr_null *ret, char *cp,
1113 const struct dns_parse *p);
1114 initializes standard RRset fields in ret structure using buffer
1115 pointed to by cp, which should have at least as many bytes as
1116 dns_stdrr_size(p) returned. Used to finalize common part of
1117 type-specific RR structures in parsing routines.
1118
1119
1120 See library source for usage examples of all the above low-level rou‐
1121 tines, especially source of the parsing routines.
1122
1123
1124 Auxilary Routines
1125 int dns_pton(int af, const char *src, void *dst);
1126 privides functionality similar to standard inet_pton() routine,
1127 to convert printable representation of an IP address of family
1128 af (either AF_INET or AF_INET6) pointed to by src into binary
1129 form suitable for socket addresses and transmission over net‐
1130 work, in buffer pointed to by dst. The destination buffer
1131 should be of size 4 for AF_INET family or 16 for AF_INET6. The
1132 return value is positive on success, 0 if src is not a valid
1133 text representation of an address of family af, or negative if
1134 the given address family is not supported.
1135
1136
1137 const char *dns_ntop(int af, const void *src,
1138 char *dst, int dstsize)
1139 privides functionality similar to standard inet_ntop() routine,
1140 to convert binary representation of an IP address of family af
1141 (either AF_INET or AF_INET6) pointed to by src (either 4 or 16
1142 bytes) into printable form in buffer in buffer pointed to by dst
1143 of size dstsize. The destination buffer should be at least of
1144 size 16 bytes for AF_INET family or 46 bytes for AF_INET6. The
1145 return value is either dst, or NULL pointer if dstsize is too
1146 small to hold this address or if the given address family is not
1147 supported.
1148
1149
1151 The udns library has been written by Michael Tokarev,
1152 mjt+udns@tls.msk.ru.
1153
1154
1156 This manual page corresponds to udns version 0.4, released Jan-2014.
1157
1158
1159
1160Library Functions Jan 2014 udns(3)