diff options
Diffstat (limited to 'doc/API.xml')
-rw-r--r-- | doc/API.xml | 462 |
1 files changed, 462 insertions, 0 deletions
diff --git a/doc/API.xml b/doc/API.xml new file mode 100644 index 0000000..554420d --- /dev/null +++ b/doc/API.xml @@ -0,0 +1,462 @@ +<?xml version="1.0"?> + +<!DOCTYPE rfc SYSTEM "rfc2629.dtd"> +<!-- $Id --> + +<?rfc toc="yes" ?> +<?rfc compact="yes" ?> +<?rfc editing="no" ?> +<?rfc iprnotified="no" ?> +<?rfc private="LibDNS API" ?> + +<rfc ipr="none" category="info" docName="libdns-api-00.txt"> + +<front> +<title>LibDNS API</title> + <author initials="R." surname="Gieben" fullname="Miek Gieben"> + <organization>NLnet Labs</organization> + <address> + <postal> + <street>Kruislaan 419</street> + <city>Amsterdam</city> + <code>1098 VA</code> + <country>The Netherlands</country> + </postal> + <email>miek@nlnetlabs.nl</email> + <uri>http://www.nlnetlabs.nl</uri> + </address> + </author> + <author initials="J." surname="Jansen" fullname="Jelte Jansen"> + <organization>NLnet Labs</organization> + <address> + <postal> + <street>Kruislaan 419</street> + <city>Amsterdam</city> + <code>1098 VA</code> + <country>The Netherlands</country> + </postal> + <email>jelte@nlnetlabs.nl</email> + <uri>http://www.nlnetlabs.nl</uri> + </address> + </author> + <author initials="E." surname="Rozendaal" fullname="Erik Rozendaal"> + <organization>NLnet Labs</organization> + <address> + <postal> + <street>Kruislaan 419</street> + <city>Amsterdam</city> + <code>1098 VA</code> + <country>The Netherlands</country> + </postal> + <email>erik@nlnetlabs.nl</email> + <uri>http://www.nlnetlabs.nl</uri> + </address> + </author> +<date month="January" year="2005" /> +<keyword>DNS</keyword> +<keyword>Elite</keyword> +<keyword>Hacking</keyword> +<abstract> +<t> +A small abstract will come here, TBD. +</t> +</abstract> +</front> + +<middle> + +<section title="Introduction"> +<t> +LibDNS (or lDNS) is modelled after the Net::DNS perl library. It has +been shown that Net::DNS can be used vefficiently for +programming DNS aware applications. We want to bring the same +level of efficiency to C programmers. +</t> +<t> +The lDNS API consist of two layers. The top-layer, this is +what is actually exported to the application via the library. And the +bottom-layer, this is what lDNS needs to compile and function. +</t> +</section> <!-- "Introduction" --> + +<section title="Differences With Other Libraries"> +<t> +Short intermezzo detailing differences with other libraries. Most important +ones are the libc resolver interface (from BIND8) and the lwres_ interface +from BIND9. +</t> +</section> <!-- "Differences with other libraries" --> + +<section title="Interfaces"> +<t> +At its lowest level lDNS is only dependent on libc. It uses a +few networking systems calls; socket, bind, send/recv and friends. +</t> +<t> +Further more it is to be expected that lDNS will depend on OpenSSL for +its cryptography. +</t> +<t> +As said, lDNS is modelled after Net::DNS, therefor its application API +looks very much like the one used for Net::DNS. Some modification are made +ofcourse, because not all functionality of Perl can be caught in C. +</t> + +<t> +This API document was written by carefully looking at the documentation +contained in the Net::DNS Perl module. +</t> +</section> <!-- "Interfaces" --> + +<section title="RDF Structure"> +<t> +The rdf structure, the RData Field, is a type that contains the different +types in the rdata of an RR. Consider the following example: +<artwork> +example.com. IN MX 10 mx.example.com. +</artwork> +The "10 mx.example.com." is the rdata in this case. It consists of two +fields, "10" and "mx.example.com". These have the types (in this case) +LDNS_RDF_TYPE_INT8 and LDNS_RDF_TYPE_DNAME. +</t> +<t> +The following functions operate on this structure. +</t> +<t> +<list style="hanging"> +<t hangText="dns_rdf *ldns_rdf_new(uint16_t s, ldns_rdf_type t, uint8_t *d):"> +Create a new rdf structure. Return a pointer to it. +</t> +<t hangText="uint16_t ldns_rdf_size(ldns_rdf *r):"> +Get the size of a rdf structure. +</t> +<t hangText="void ldns_rdf_set_size(ldns_rdf *r, uint16_t):"> +Set the size of a rdf structure. +</t> +<t hangText="void ldns_rdf_set_type(ldns_rdf *r, ldns_rdf_type t):"> +Set the type of a rdf structure. +</t> +<t hangText="ldns_rdf_type ldns_rdf_get_type(ldns_rdf *r):"> +Get the type of a rdf structure. +</t> +<t hangText="void ldns_rdf_set_data(ldns_rdf *r, uint8_t *n):"> +Set the (binary/network order) data of a rdf structure. +</t> +<t hangText="uint8_t *ldns_rdf_data(ldns_rdf *r):"> +Get a pointer to the data in a rdf structure. +</t> +<t hangText="void ldns_rdf_free(ldns_rdf *r):"> +Free a rdf structure. +</t> +<t hangText="ldns_rdf_new_frm_str(uint8_t *s, ldns_rdf_type t):"> +Create a new rdf structure from a string and a specific rdf_type. +The type is needed to perform the correct conversion. +</t> +</list> +</t> +</section> <!-- "RDF Structure" --> + +<section title="RR Structure"> +<t> +These functions operate on ldns_rr structures. +</t> +<t> +<list style="hanging"> +<t hangText="ldns_rr *ldns_rr_new(void):"> +Returns a pointer to the newly created ldns_rr structure. +</t> +<t hangText="void ldns_rr_print(FILE *s, ldns_rr *r):"> +Prints the record to the stream s. +</t> +<t hangText="ldns_buffer ldns_rr_rdatastr(ldns_rr *r):"> +Returns a pointer to a ldns_buffer containing with string containing +RR-specific data. +</t> +<t hangText="ldns_rdf *ldns_rr_name(ldns_rr *r):"> +Returns the record's owner name as a ldns_rdf type. +</t> +<t hangText="ldns_rdf_rr_type ldns_rr_get_type(ldns_rr *r):"> +Returns the record's type. +</t> +<t hangText="ldns_rr_class ldns_rr_get_class(ldns_rr *r):"> +Returns the record's class. +</t> +<t hangText="uint32_t ldns_rr_get_ttl(ldns_rr *r):"> +Returns the record's time-to-live (TTL). +</t> +</list> +</t> + +<t> +TODO the 'set' functions of the 'get' +</t> +</section> <!-- "RR Structure" --> + +<section title="RR list Structure"> +<t> +In the DNS the atomic data type is an RRset. This is a list +of RRs with the same ownername, type and class. Net::DNS doesn't +have rrsets as a separate object. +</t> +<t> +In lDNS we have the ldns_rr_list, which just holds a bunch of RR's. +No specific check are made on the RRs that can be put in such a list. +Special wrapper functions exist which allow the usage of ldns_rr_list +of real (RFC compliant) RR sets. +</t> +<t> +TODO: See rr.c +</t> +</section> <!-- "RR list Structure" --> + +<section title="Resolver Structure"> +<t> +<list style="hanging"> +<t hangText="ldns_resolver* ldns_resolver_new(void):"> +Create a new resolver structure and return the pointer to that. +</t> +<t hangText="uint8_t ldns_version(resolver *res):"> +Returns the version of lDNS. +</t> +<t hangText="ldns_pkt *ldns_mx(ldns_resolver *res, ldns_rdf_type *dname):"> +Returns a ldns_pkt representing the MX records +for the specified dname. Function is documented differently in Net::DNS. +Do we need stuff like this?? XXX +</t> +<t hangText="ldns_status ldns_resolver_domain(resolver *res, ldns_rdf +*domain):"> + Set the default domain for this resolver. This domain is added + when a query is made with a name without a trailing dot. + + +</t> +<t hangText="ldns_status ldns_resolver_nameserver_push(resolver *res, +ldns_rdf *ip):"> +Add a new nameserver to the resolver. These nameservers are queried + when a search() or query() is done. + +</t> +<t hangText="ldns_status ldns_resolver_searchlist_push(resolver *res, +ldns_rdf *domain):"> + Add a domain to the searchlist of a resolver. +</t> +<t hangText=" ldns_pkt * ldns_resolver_search(ldns_resolver *res, + ldns_rdf *domain, + ldns_rr_type *type, + ldns_class *class):"> + Perform a query. Try all the nameservers in the *res structure. Apply + the search list. And default domain. +If type is NULL it defaults to 'A', +If class is NULL it default to 'IN'. +</t> +<t hangText="ldns_pkt * ldns_resolver_query(ldns_resolver *res, + ldns_rdf *dom, + ldns_type *t, + ldns_class *cl):"> +Perform a query. Only the default domain is added. +If type is NULL it defaults to 'A', +If class is NULL it default to 'IN'. +</t> +<t hangText=" ldns_pkt * ldns_resolver_send(ldns_resolver *res, + ldns_rdf *domain, + ldns_type *type, + ldns_class *class):"> +No search list nor default domain is applied. Return a pointer to a ldns_pkt +structure with the information from the nameserver. +If type is NULL it defaults to 'A', +If class is NULL it default to 'IN'. +</t> +</list> +</t> +<t> +TODO XX Gazillion helper functions to set port, src-port, etc. etc. +</t> +</section> <!-- "Resolver Structure" --> + +<section title="Packet Structure"> +<t> +A packet structure (ldns_pkt) has five sections: +<list style="numbers"> +<t>The header section, a ldns_hdr structure.</t> +<t>The question section, a ldns_rr_list structure.</t> +<t>The answer section, a ldns_rr_list structure.</t> +<t>The authority section, a ldns_rr_list structure.</t> +<t>The additional section, a ldns_rr_list structure.</t> +</list> +</t> +<t> +<list style="hanging"> +<t hangText="Header Structure (ldns_hdr):"> +ldns_hdr represents the header section of a DNS packet. +</t> +<t hangText="Question Section (ldns_rr_list):"> +A list of RRs in the Question section of a DNS packet. +</t> +<t hangText="Answer Section (ldns_rr_list):"> +A list of RRs in the Question section of a DNS packet. +</t> +<t hangText="Authority Section (ldns_rr_list):"> +A list of RRs in the Question section of a DNS packet. +</t> +<t hangText="Additional Section (ldns_rr_list):"> +A list of RRs in the Question section of a DNS packet. +</t> +</list> +</t> + +<t> +<list style="hanging"> +<t hangText="ldns_pkt * ldns_pkt_new(void):"> +Creates a new empty packet. +</t> +<t hangText="ldns_buffer* ldns_pkt_data(ldns_pkt *pkt):"> +Returns the packet data in binary format, suitable for sending to a +nameserver. [XXX, suitable for sending to a NS?] +</t> +<t hangText="ldns_hdr *ldns_header(ldn_pkt *pkt):"> +Returns a ldns_hdr structure representing the header section of +the packet. +</t> +<t hangText="ldns_rr_list *ldns_question(ldns_pkt *pkt):"> + Returns a pointer to a ldns_rr_list representing the question section +of the packet. +</t> +<t hangText="ldns_rr_list *ldns_answer(ldns_pkt *pkt):"> + Returns a pointer to a ldns_rr_list representing the answer section of +the packet. + +</t> +<t hangText=" ldns_rr_list *ldns_authority(ldns_pkt *pkt):"> +Returns a pointer to a ldns_rr_list representing the authority section +of the packet. + +</t> +<t hangText=" ldns_rr_list *ldns_additional(ldns_pkt *pkt):"> +Returns a pointer to a ldns_rr_list of representing the additional +section of the packet. + +</t> +<t hangText=" void ldsn_pkt_print(ldns_pkt *pkt):"> +Prints the packet data on the standard output in an ASCII format similar +to that used in DNS zone files. See RFC1035. + +</t> +<t hangText="ldns_buffer *ldns_pkt_string(ldns_pkt *pkt):"> +Returns a ldns_buffer containing the string representation of the packet. + +</t> +<t hangText="ldns_rdf* ldns_pkt_answerfrom(ldns_pkt *pkt):"> +Returns the IP address from which we received this packet. User-created +packets will return NULL. + +</t> +<t hangText="uint16_t ldns_pkt_answersize(ldns_pkt *pkt):"> +Returns the size of the packet in bytes as it was received from a +nameserver. User-created packets will return 0. [XXX +user-created??] + +</t> +<t hangText="ldns_status ldns_push(ldns_pkt *pkt, ldns_pkt_section section, +ldns_rr *rr):"> +Adds *rr to the specified section of the packet. Return LDNS_STATUS_OK +on success, LDNS_STATUS_ERR otherwise. + +</t> +<t hangText="ldns_status ldns_unique_push(ldns_pkt *pkt, ldns_pkt_section +section, ldns_rr *rr):"> +Adds *rr to the specified section of the packet provided that the RR +does not already exist in the packet. Return LDNS_STATUS_OK +on success, LDNS_STATUS_ERR otherwise. +</t> +<t hangText="ldns_rr *ldns_pop(ldns_pkt, ldns_pkt_section):"> +Removes a RR from the specified section of the packet. Returns NULL if +no RR's could be popped. +</t> +<t hangText="ldns_rr_list *ldns_pkt_rrset(ldns_pkt *pkt,...):"> +Retrieve all RRs in a packet matching certain criteria. XXX function needs +to be specified better. +</t> +<t hangText="void *ldns_pkt_print(FILE *s, ldns_pkt *p):"> +Print packet p to stream s. +</t> + +</list> +</t> +</section> <!-- "Packet Structure" --> + +<section title="Specific RR Structures"> +<t> +Some resource records can have special access function no other RR has. +Those are detailed here. XXX TODO don't exist (yet?). +</t> +</section> <!-- "Specific RR Structures" --> + +<section title="Exported Defines and Macros"> +<t> +insert your long list here. +</t> +</section> <!-- "Exported defines and macros" --> + +<section title="Examples"> +<t> +A small example, which queries a nameserver on localhost +to diplay the MX records for miek.nl. +</t> + +<t> +<figure> +<artwork> +/** + * An example ldns program + * In semi-C code + * + * Setup a resolver + * Query a nameserver + * Print the result + */ + +#include <ldns.h> + +int +main(void) +{ + ldns_resolver *res; + ldns_rdf *default_dom; + ldns_rdf *nameserver; + ldns_rdf *qname; + ldns_pkt *pkt; + + /* init */ + res = ldns_resolver_new(); + if (!res) + return 1; + + /* create a default domain and add it */ + default_dom = ldns_rdf_new_frm_str("miek.nl.", LDNS_RDF_TYPE_DNAME); + nameserver = ldns_rdf_new_frm_str("127.0.0.1", LDNS_RDF_TYPE_A); + + if (ldns_resolver_domain(res, default_dom) != LDNS_STATUS_OK) + return 1; + if (ldns_resolver_nameserver_push(res, nameserver) != LDNS_STATUS_OK) + return 1; + + /* setup the question */ + qname = ldns_rdf_new_frm_str("www", LDNS_RDF_TYPE_DNAME); + + /* fire it off. "miek.nl." will be added */ + pkt = ldns_resolver_query(res, qname, LDNS_RR_TYPE_MX, NULL); + + /* print the resulting pkt to stdout */ + ldns_pkt_print(stdout, pkt); + + return 0; +} +</artwork> +</figure> +</t> +</section> <!-- title="Short Example" --> + +</middle> +<back> +</back> +</rfc> |