<middle>
-<section title="API">
+<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>
-</section> <!-- API -->
+<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="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 seperate 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>
+
+</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" -->
+
</middle>
<back>
</back>