rdata.html revision 0c27b3fe77ac1d5094ba3521e8142d9e7973133f
4632N/A<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 3.2//EN">
4632N/A<!--
4632N/A - Copyright (C) 1999-2001, 2004, 2007, 2016 Internet Systems Consortium, Inc. ("ISC")
4632N/A -
4632N/A - This Source Code Form is subject to the terms of the Mozilla Public
4632N/A - License, v. 2.0. If a copy of the MPL was not distributed with this
4632N/A - file, You can obtain one at http://mozilla.org/MPL/2.0/.
4632N/A-->
4632N/A
4632N/A<!-- $Id: rdata.html,v 1.15 2007/06/19 23:47:13 tbox Exp $ -->
4632N/A
4632N/A<HTML>
4632N/A<HEAD>
4632N/A <TITLE>Adding new RDATA type</TITLE>
4632N/A</HEAD>
4632N/A<BODY>
4632N/A<H2>Overview</H2>
4632N/AThe dns rdata routines (<CODE>dns_rdata_fromtext()</CODE>,
4632N/A<CODE>dns_rdata_totext()</CODE>, <CODE>dns_rdata_fromwire()</CODE>,
4632N/A<CODE>dns_rdata_towire()</CODE> <CODE>dns_rdata_fromstruct()</CODE>,
4632N/A<CODE>dns_rdata_tostruct()</CODE> and <CODE>dns_rdata_compare()</CODE>)
4632N/Aare designed to provide a single set of routines
4632N/Afor encoding, decoding and comparing dns data preventing the problems that
4632N/Aoccurred in BIND 8.x and earlier where there were multiple places in the
4632N/Acode base that
4632N/Adecoded wire format to internal format or compared rdata sometimes with
4632N/Asubtly different behaviour (bugs) or didn't support a particular type leading
4632N/Ato internal inconsistancy.
4632N/A<P>
4632N/AEach of these generic routines calls type specific routines that provide
4632N/Athe type specific details.
4632N/A<P>
4632N/AFrom time to time new types are defined and it is necessary to add these types
5276N/Ainto the existing structure.
5276N/AThis document is written to provide instruction on how to do this.
5276N/A<H2>Adding new RDATA types</H2>
4632N/A
4632N/AAdding a new rdata type requires determining if the new rdata type is class
5276N/Aspecific or generic.
4632N/AWriting code to perform the following set of operations
4632N/Aand then integrating it into the build by placing the code into the rdata
4632N/Ahierachy at the correct place.
4632N/ARunning <CODE>make clean</CODE> followed <CODE>make</CODE> in
4632N/A<CODE>lib/dns</CODE> will cause the new rdata type to be picked up.
4632N/A<P>
4632N/AEach rdata module must perform the following operations:
4632N/A<DL>
4632N/A<DT>Convert from text format to internal format</DT>
4632N/A<DT>Convert from internal format to text format</DT>
4632N/A<DT>Convert from wire format to internal format</DT>
5276N/A<DT>Convert from internal format to wire format</DT>
4632N/A<DT>Convert from a structure to internal format</DT>
4632N/A<DT>Convert from internal format to a structure</DT>
4632N/A<DT>Compare two rdata in internal format<DT>
4632N/A</DL>
4632N/A<P>
4632N/AThere is an additional set of support <A HREF="#functions">functions</A> and
4632N/A<A HREF="#macros">macros</A> only available to
4632N/Ato rdata code.
4632N/A<H2>RDATA Hierarchy</H2>
4632N/AThe <CODE>rdata</CODE> hierarchy has the following format.
4632N/A<PRE>
4632N/A rdata/
4632N/A generic/
4632N/A <I>typename_typenumber</I>.h
4632N/A <I>classname_classnumber</I>/
4632N/A <I>typename_typenumber</I>.h
4632N/A<PRE>
4632N/A<P>
4632N/AInitial rdata hierarchy:
4632N/A<P>
4632N/A<PRE>
5276N/A rdata/
4632N/A generic/
4632N/A ns_2.h
4632N/A md_3.h
4632N/A mf_4.h
4632N/A cname_5.h
4632N/A soa_6.h
4632N/A mb_7.h
4632N/A mg_8.h
4632N/A mr_9.h
4632N/A null_10.h
4632N/A ptr_12.h
4632N/A hinfo_13.h
4632N/A minfo_14.h
4632N/A mx_15.h
4632N/A txt_16.h
4632N/A rp_17.h
4632N/A afsdb_18.h
4632N/A x25_19.h
4632N/A isdn_20.h
4632N/A rt_21.h
4632N/A sig_24.h
4632N/A key_25.h
4632N/A gpos_27.h
4632N/A loc_29.h
4632N/A nxt_30.h
4632N/A cert_37.h
4632N/A dname_39.h
4632N/A unspec_103.h
4632N/A tkey_249.h
4632N/A in_1/
4632N/A a_1.h
4632N/A wks_11.h
4632N/A nsap_22.h
4632N/A nsap-ptr_23.h
4632N/A px_26.h
4632N/A aaaa_28.h
4632N/A srv_33.h
4632N/A naptr_35.h
4632N/A kx_36.h
4632N/A a6_38.h
4632N/A any_255/
4632N/A tsig_250.h
4632N/A</PRE>
4632N/A
4632N/A<H2>CLASSNAME and TYPENAME</H2>
4632N/AClass and type names must be from the following alphabet and less that 11
4632N/Acharacters in length or otherwise they will be ignored.
4632N/APermissible alphabet: a to z, 0 to 9 and dash (-).
4632N/ADash is mapped to underscore (_) for the C function names below.
4632N/A
4632N/A<H2>Internal Format</H2>
4632N/AThe internal format chosen is DNS wire format without any compression being
4632N/Aapplied to domain names in the rdata.
4632N/A
4632N/A<H2>Convert from text format to internal format</H2>
4632N/AThe functions to convert from text format has the following call formats and
4632N/Ais declared as follows for class generic functions.
4632N/A<PRE>
4632N/A<CODE>static dns_result_t
4632N/Afromtext_<I>typename</I>(dns_rdataclass_t class, dns_rdatatype_t type,
4632N/A isc_lex_t *lexer, dns_name_t *origin,
4632N/A isc_boolean_t downcase, isc_buffer_t *target);</CODE>
4632N/A</PRE>
4632N/AClass specific functions contain the class name in addition to the
4632N/Atype name.
4632N/A<PRE>
4632N/A<CODE>static dns_result_t
4632N/Afromtext_<I>classname_typename</I>(dns_rdataclass_t class, dns_rdatatype_t type,
4670N/A isc_lex_t *lexer, dns_name_t *origin,
4670N/A isc_boolean_t downcase, isc_buffer_t *target);</CODE>
4670N/A</PRE>
4670N/A
4632N/A<DL>
4632N/A<DT><CODE>class</CODE></DT>
4632N/A<DD>
4632N/AThis argument should be ignored when used with a class generic RR type
4632N/Aotherwise <CODE>REQUIRE(class == #)</CODE> should be present at the start
4632N/Aof the function.
4632N/A<DT><CODE>type</CODE></DT>
4632N/A<DD>
4632N/AThis should be tested with a <CODE>REQUIRE(type == #)</CODE> statement at
4632N/Athe begining of the function.
4632N/A<DT><CODE>lexer</CODE></DT>
4632N/A<DD>
4632N/AThis is used to read the input text stream.
4632N/A<DT><CODE>origin</CODE></DT>
4632N/A<DD>
4632N/AThis is a absolute name used to qualify unqualified / partially qualified
4632N/Adomainnames in the text stream.
4632N/AIt is passed to the name parsing routines.
4632N/A<DT><CODE>downcase</CODE></DT>
4632N/A<DD>
4632N/AThis is passed to the name parsing routines to determine whether to downcase
4632N/Athe names it generates or leave them in the case they are pesented in.
4632N/A<DT><CODE>target</CODE></DT>
4632N/A<DD>
4632N/AThis is a <CODE>BINARY</CODE> buffer used to write the internal format of the rdata record being read in to.
4632N/A</DL>
4632N/A
4632N/A<CODE>fromtext_<I>typename</I>()</CODE> reads tokens from <CODE>lexer</CODE>,
4632N/Aup to but not including the end of line (EOL) token or end of file (EOF) token.
4632N/AIf the EOL / EOF token is read it should be returned to the input stream.
4632N/A<A HREF="#gettoken"><CODE>gettoken()</CODE></A>
4632N/Ashould be used to read the next token from the input stream and
4632N/Awill return EOL / EOF tokens
4632N/Aautomatically unless
4632N/Athey are specifcally requested.
4632N/A<CODE>isc_lex_ungettoken()</CODE> should
4632N/Abe used to return EOL / EOF (or any other token) to the input stream if
4632N/Athe EOL / EOF token is read.
4632N/AUnused tokens will cause <CODE>dns_rdata_fromtext()</CODE> to return
4632N/A<CODE>DNS_R_EXTRATOKEN</CODE> if <CODE>fromtext_<I>typename</I>()</CODE> was successful.
4632N/A<P>
4632N/A<CODE>fromtext_<I>typename</I>()</CODE> reads external input and as such is a high security area and must be paranoid about its input.
4632N/A<H2>Convert from internal format to text format</H2>
4632N/A<PRE>
4632N/A<CODE>static dns_result_t
4632N/Atotext_<I>typename</I>(dns_rdata_t *rdata, dns_name_t *origin,
4632N/A isc_buffer_t *target);</CODE>
4632N/A</PRE>
4632N/A<PRE>
4632N/A<CODE>static dns_result_t
4632N/Atotext_<I>classname_typename</I>(dns_rdata_t *rdata, dns_name_t *origin,
4632N/A isc_buffer_t *target);</CODE>
4632N/A</PRE>
4632N/A<DL>
4632N/A<DT><CODE>rdata</CODE></DT>
4632N/A<DD>
4632N/AThis is the rdata record to be converted from internal format to text.
4632N/A<CODE>rdata->type</CODE> and <CODE>rdata->class</CODE> for class specific
4632N/ARR types should be checked at the start of the function with
4632N/A<CODE>REQUIRE(rdata->type ==�#)</CODE> statements.
4632N/A<DT><CODE>origin</CODE></DT>
4632N/A<DD>
4632N/AIf this in non <CODE>NULL</CODE> then any domainnames with this suffix
4632N/Ashould be written out unqualified.
4632N/A<A HREF="#name_prefix"><CODE>name_prefix()</CODE></A> can be used to
4632N/Acheck if <CODE>origin</CODE> is <CODE>NULL</CODE> and provide the correct
4632N/Aarguments to the name conversion routines.
4632N/A<DT><CODE>target</CODE></DT>
4632N/A<DD>
4632N/AThis is a <CODE>TEXT</CODE> buffer used to hold the output.
4632N/A</DL>
4632N/A<H2>Convert from wire format to internal format</H2>
4632N/A<PRE>
4632N/A<CODE>static dns_result_t
4632N/Afromwire_<I>typename</I>(dns_rdataclass_t class, dns_rdatatype_t type,
4632N/A isc_buffer_t *source, dns_decompress_t *dctx,
4632N/A isc_boolean_t downcase, isc_buffer_t *target);</CODE>
4632N/A</PRE>
4632N/A<PRE>
4632N/A<CODE>static dns_result_t
4632N/Afromwire_<I>classname_typename</I>(dns_rdataclass_t class, dns_rdatatype_t type,
4632N/A isc_buffer_t *source, dns_decompress_t *dctx,
4632N/A isc_boolean_t downcase, isc_buffer_t *target);</CODE>
4632N/A</PRE>
4632N/A<P>
4632N/A<CODE>fromwire_<I>classname_typename</I>()</CODE> is required to set the valid
4632N/Adecompression methods if there is a domain name in the rdata.
4632N/A<PRE>
4632N/A<CODE>if (dns_decompress_edns(dctx) >= # || !dns_decompress_strict(dctx))
4632N/A dns_decompress_setmethods(dctx, DNS_COMPRESS_ALL);
4632N/Aelse
4632N/A dns_decompress_setmethods(dctx, DNS_COMPRESS_GLOBAL14);</CODE>
4632N/A</PRE>
4632N/A
4632N/A<DL>
4632N/A<DT><CODE>class</CODE></DT>
4632N/A<DD>
4632N/AThis argument should be ignored when used with a class generic RR type
4632N/Aotherwise <CODE>REQUIRE(class == #)</CODE> should be present at the start
4632N/Aof the function.
4632N/A<DT><CODE>type</CODE></DT>
4632N/A<DD>
4632N/AThis should be tested with a <CODE>REQUIRE(type == #)</CODE> statement at
4632N/Athe begining of the function.
5276N/A<DT><CODE>source</CODE></DT>
5276N/A<DD>
4632N/AThis is a <CODE>BINARY</CODE> buffer with the <CODE>active</CODE> region
4632N/Acontaining a RR record in wire format.
4632N/A<DT><CODE>dctx</CODE></DT>
4632N/A<DD>
4632N/AThis is the decompression context and is passed to
4632N/A<CODE>dns_name_fromwire()</CODE>,
4632N/Aalong with <CODE>downcase</CODE>, to enable a compressed domain name
4632N/Ato be extracted from the source.
4632N/A<DT><CODE>downcase</CODE></DT>
4632N/A<DD>
4632N/AThis is passed to <CODE>dns_name_fromwire()</CODE> to say whether the
4632N/Aextracted domainname should be downcased during the extraction.
4632N/A<DT><CODE>target</CODE></DT>
4632N/A<DD>
4632N/AThis is a <CODE>BINARY</CODE> buffer where the decompressed and checked
4632N/ARR record is written.
4632N/A</DL>
4632N/A<CODE>fromwire_<I>typename</I>()</CODE> is a security sensitive routine
4632N/Aas it reads external data and should take extreme care to ensure that
4632N/Athe input data matches its description.
4632N/A<P>
4632N/AIf the <CODE>active</CODE> buffer is not empty at completion and
4632N/A<CODE>fromwire_<I>typename</I>()</CODE> was otherwise successful
4632N/A<CODE>dns_rdata_fromwire()</CODE> will return <CODE>DNS_R_EXTRADATA</CODE>.
4632N/A<H2>Convert from internal format to wire format</H2>
4632N/A<PRE>
4632N/A<CODE>static dns_result_t
4639N/Atowire_<I>typename</I>(dns_rdata_t *rdata, dns_compress_t *cctx,
4639N/A isc_buffer_t *target);</CODE>
4639N/A</PRE>
4639N/A<PRE>
4639N/A<CODE>static dns_result_t
4639N/Atowire_<I>classname_typename</I>(dns_rdata_t *rdata, dns_compress_t *cctx,
4639N/A isc_buffer_t *target);<CODE>
4639N/A</PRE>
4639N/A<P>
4632N/A<CODE>towire_<I>classname_typename</I>()</CODE> is required to set the
4632N/Aallowed name compression methods based on EDNS version if there is a
4632N/Adomain name in the rdata.
4632N/A<PRE>
4632N/A<CODE>if (dns_compress_getedns(cctx) >= #)
4632N/A dns_compress_setmethods(cctx, DNS_COMPRESS_ALL);
4632N/Aelse
4632N/A dns_compress_setmethods(cctx, DNS_COMPRESS_GLOBAL14);</CODE>
4632N/A</PRE>
4632N/A<DL>
4632N/A<DT><CODE>rdata</CODE></DT>
4632N/A<DD>
4632N/AThis is the rdata record to be converted from internal format to text.
4632N/A<CODE>rdata->type</CODE> and <CODE>rdata->class</CODE> for class specific
4632N/ARR types should be checked at the start of the function with
4632N/A<CODE>REQUIRE(rdata->type ==�#)</CODE> statements.
4632N/A<DT><CODE>cctx</CODE></DT>
4632N/A<DD>
4632N/AThis is the compression context, it should be passed to <CODE>dns_name_towire()</CODE> when putting domainnames on the wire.
4632N/A<DT><CODE>target</CODE></DT>
4632N/A<DD>
4632N/AThis is a <CODE>BINARY</CODE> buffer used to write the rdata to.
4632N/A</DL>
4632N/ASimple RR types without domainnames can use the following code to
4632N/Atransfer the contents of the <CODE>rdata</CODE> to the target buffer.
4632N/A<PRE>
4632N/A <CODE>return (<A HREF="#mem_tobuffer">mem_tobuffer</A>(target, rdata->data, rdata->length));</CODE>
4632N/A</PRE>
4632N/A<H2>Convert from a structure to internal format</H2>
4632N/A<PRE>
4632N/A<CODE>static dns_result_t
4632N/Afromstruct_<I>typename</I>(dns_rdataclass_t class, dns_rdatatype_t type,
4632N/A void *source, isc_buffer_t *target);</CODE>
4632N/A</PRE>
4632N/A<PRE>
4632N/A<CODE>static dns_result_t
4632N/Afromstruct_<I>classname_typename</I>(dns_rdataclass_t class, dns_rdatatype_t type,
4632N/A void *source, isc_buffer_t *target);</CODE>
4632N/A</PRE>
4632N/A<DL>
4632N/A<DT><CODE>class</CODE></DT>
4632N/A<DD>
4632N/AThis argument should be ignored when used with a class generic RR type
4632N/Aotherwise <CODE>REQUIRE(class == #)</CODE> should be present at the start
4632N/Aof the function.
4632N/A<DT><CODE>type</CODE></DT>
4632N/A<DD>
4632N/AThis should be tested with a <CODE>REQUIRE(type == #)</CODE> statement at
4632N/Athe beginning of the function.
4632N/A<DT><CODE>source</CODE></DT>
4632N/A<DD>
4632N/AThis points to a type specific structure.
4632N/A<DT><CODE>target</CODE></DT>
4632N/A<DD>
4632N/AThis is a <CODE>BINARY</CODE> buffer used to write the internal format of the rdata record being read in to.
4632N/A</DL>
4632N/A<H2>Convert from internal format to a structure</H2>
4632N/A<PRE>
4632N/A<CODE>static dns_result_t
4632N/Atostruct_<I>typename</I>(dns_rdata_t *rdata, void *target);</CODE>
4632N/A</PRE>
4632N/A<PRE>
4632N/A<CODE>static dns_result_t
4632N/Atostruct_<I>classname_typename</I>(dns_rdata_t *rdata, void *target);</CODE>
4632N/A</PRE>
4632N/A<DL>
4632N/A<DT><CODE>rdata</CODE></DT>
4632N/A<DD>
4632N/AThis is the rdata record to be converted from internal format to a structure.
4632N/A<CODE>rdata->type</CODE> and <CODE>rdata->class</CODE> for class specific
4632N/ARR types should be checked at the start of the function with
4632N/A<CODE>REQUIRE(rdata->type ==�#)</CODE> statements.
4632N/A<DT><CODE>target</CODE></DT>
4632N/A<DD>
4632N/APointer to a type specific structure.
4632N/A</DL>
4632N/A<H2>Compare two rdata in internal format</H2>
4632N/A<PRE>
4632N/A<CODE>static int
4632N/Acompare_<I>typename</I>(dns_rdata_t *rdata1, dns_rdata_t *rdata2);</CODE>
4632N/A</PRE>
4632N/A<PRE>
4632N/A<CODE>static int
4632N/Acompare_<I>classname_typename</I>(dns_rdata_t *rdata1, dns_rdata_t *rdata2);</CODE>
4632N/A</PRE>
4632N/ACompares <CODE>rdata1</CODE> and <CODE>rdata2<CODE> as required for DNSSEC
4632N/Aordering. The routine should
4632N/Aensure that the <CODE>type</CODE> and <CODE>class</CODE> of the two rdata
4632N/Amatch with <CODE>REQUIRE(rdata1->type == rdata2->type);</CODE> and
4632N/A<CODE>REQUIRE(rdata1->class == rdata2->class);</CODE> statements. The
4632N/A<CODE>rdata->type</CODE> should also be verified and if the RR type is
4632N/Aclass specific the <CODE>rdata->class</CLASS>.
4632N/A<P>
4632N/A<CODE>compare_<I>classname_typename</I>()</CODE> returns -1, 0, 1.
4632N/A<H2><A NAME="functions">Support Functions</A></H2>
4632N/AThe following static support functions are available to use.
4632N/A<DL>
4632N/A<DT><CODE>static unsigned int<BR>
4632N/Aname_length(dns_name_t *name);</CODE></DT>
4632N/A<DD>
4632N/A<P>
4632N/AReturns the length of <CODE>name</CODE>.
4632N/A<P>
4632N/A<DT><CODE>static dns_result_t<BR>
4632N/Atxt_totext(isc_region_t *source, isc_buffer_t *target);</CODE></DT>
4632N/A<DD>
4632N/A<P>
4632N/AExtracts the octet length tagged text string at the start of
4632N/A<CODE>source</CODE> and writes it as a quoted string to <CODE>target</CODE>.
4632N/A<CODE>source</CODE> is adjusted so that it points to first octet after the
4632N/Atext string.
4632N/A<P>
4632N/AReturns <CODE>DNS_R_NOSPACE</CODE> or <CODE>DNS_R_SUCCESS</CODE>.
4632N/A<P>
4632N/A<DT><CODE>static dns_result_t<BR>
4632N/Atxt_fromtext(isc_textregion_t *source, isc_buffer_t *target);</CODE></DT>
4632N/A<DD>
4632N/A<P>
4632N/ATake the text region <CODE>source</CODE> and convert it to a length tagged
4632N/Atext string writing it to <CODE>target</CODE>.
4632N/A<P>
4632N/AReturns <CODE>DNS_R_NOSPACE</CODE>, <CODE>DNS_R_TEXTTOLONG</CODE>
4632N/Aor <CODE>DNS_R_SUCCESS</CODE>.
4632N/A<P>
4632N/A<DT><CODE>static dns_result_t<BR>
4632N/Atxt_fromwire(isc_buffer_t *source, isc_buffer_t *target);</CODE></DT>
4632N/A<DD>
4632N/A<P>
4632N/ARead a octet length tagged text string from <CODE>source</CODE> and
4632N/Awrite it to <CODE>target</CODE>.
4632N/AEnsures that octet length tagged text string was wholly within the active
4632N/Aarea of <CODE>source</CODE>.
4632N/AAdjusts the active area of <CODE>source</CODE> so that it refers to the first
4632N/Aoctet after the octet length tagged text string.
4632N/A<P>
4632N/AReturns <CODE>DNS_R_UNEXPECTEDEND</CODE>, <CODE>DNS_R_NOSPACE</CODE> or
4632N/A<CODE>DNS_R_SUCCESS</CODE>.
4632N/A<P>
4632N/A<DT><A NAME="name_prefix"><CODE>static isc_boolean_t<BR>
4632N/Aname_prefix(dns_name_t *name, dns_name_t *origin, dns_name_t *target);</CODE>
4632N/A</A></DT>
4632N/A<DD>
4632N/A<P>
4632N/AIf <CODE>origin</CODE> is NULL or the root label set <CODE>target<CODE> to
4632N/Arefer to <CODE>name</CODE> and return <CODE>ISC_FALSE</CODE>.
4632N/AOtherwise see if <CODE>name</CODE> is a sub domain of <CODE>origin</CODE>
4632N/Aand are not equal.
4632N/AIf so make <CODE>target</CODE> refer to the prefix of <CODE>name</CODE> and
4632N/Areturn <CODE>ISC_TRUE</CODE>.
4632N/AOtherwise make <CODE>target</CODE> refer to <CODE>name</CODE> and return
4632N/A<CODE>ISC_FALSE</CODE>.
4632N/A<P>
4632N/ATypical use:
4632N/A<PRE><CODE>
4632N/Astatic dns_result_t
4632N/Atotext_<I>typename</I>(dns_rdata_t *rdata, dns_name_t *origin,
4632N/A isc_buffer_t * target)
4632N/A{
4632N/A isc_region_t region;
4632N/A dns_name_t name, prefix;
4632N/A isc_boolean_t sub;
4632N/A
4632N/A dns_name_init(&amp;name, NULL);
4632N/A dns_name_init(&amp;prefix, NULL);
4632N/A dns_rdata_toregion(rdata, &amp;region);
4632N/A dns_name_fromregion(&amp;name, &amp;region);
4632N/A sub = <B>name_prefix</B>(&amp;name, origin, &amp;prefix);
4632N/A return (dns_name_totext(&amp;prefix, sub, target));
4632N/A}
4632N/A</CODE></PRE>
4632N/A<DT><CODE>static dns_result_t<BR>
4632N/Astr_totext(char *source, isc_buffer_t *target);</CODE></DT>
4632N/A<DD>
4632N/A<P>
4632N/AThis adds the <CODE>NULL</CODE> terminated string <CODE>source</CODE>
4632N/Aup to but not including <CODE>NULL</CODE> to <CODE>target</CODE>.
4632N/A<P>
4632N/AReturns <CODE>DNS_R_NOSPACE</CODE> and <CODE>DNS_R_SUCCESS</CODE>.
4632N/A<P>
4632N/A<DT><CODE>static isc_boolean_t<BR>
4632N/Abuffer_empty(isc_buffer_t *source);</CODE></DT>
4632N/A<DD>
4632N/A<P>
4632N/AReturns <CODE>ISC_TRUE</CODE> if the active region of <CODE>source</CODE> is
4632N/Aempty otherwise <CODE>ISC_FALSE</CODE>.
4632N/A<P>
4632N/A<DT><CODE>static void<BR>
4632N/Abuffer_fromregion(isc_buffer_t *buffer, isc_region_t *region,
4632N/Aunsigned int type);</CODE></DT>
4632N/A<DD>
4632N/A<P>
4632N/AMake <CODE>buffer</CODE> refer to the memory in <CODE>region</CODE> and
4632N/Amake it active.
4632N/A<P>
4632N/A<DT><CODE>static dns_result_t<BR>
4632N/Auint32_tobuffer(isc_uint32_t value, isc_buffer_t *target);</CODE></DT>
4632N/A<DD>
4632N/A<P>
4632N/AWrite the 32 bit <CODE>value</CODE> in network order to <CODE>target</CODE>.
4632N/A<P>
5276N/AReturns <CODE>DNS_R_NOSPACE</CODE> and <CODE>DNS_R_SUCCESS</CODE>.
5276N/A<P>
5276N/A<DT><CODE>static dns_result_t<BR>
5276N/Auint16_tobuffer(isc_uint32_t value, isc_buffer_t *target);</CODE></DT>
5276N/A<DD>
5276N/A<P>
5276N/AWrite them 16 bit <CODE>value</CODE> in network order to <CODE>target</CODE>.
5276N/A<P>
5276N/AReturns <CODE>ISC_R_RANGE</CODE>, <CODE>DNS_R_NOSPACE</CODE> and <CODE>DNS_R_SUCCESS</CODE>.
5276N/A<P>
5276N/A<DT><CODE>static isc_uint32_t<BR>
5276N/Auint32_fromregion(isc_region_t *region);</CODE></DT>
5276N/A<DD>
5276N/A<P>
5276N/AReturns the 32 bit at the start of <CODE>region</CODE> in host order.
5276N/A<P>
5276N/ARequires <CODE>(region->length >= 4)</CODE>.
5276N/A<P>
5276N/A<DT><CODE>static isc_uint16_t<BR>
5276N/Auint16_fromregion(isc_region_t *region);</CODE></DT>
5276N/A<DD>
5276N/A<P>
5276N/AReturns the 16 bit at the start of <CODE>region</CODE> in host order.
5276N/A<P>
5276N/ARequires <CODE>(region->length >= 2)</CODE>.
5276N/A<P>
5276N/A<DT><CODE>static dns_result_t<BR>
5276N/A<A NAME="gettoken">gettoken</A>(isc_lex_t *lexer, isc_token_t *token, isc_tokentype_t expect, isc_boolean_t eol);</CODE></DT>
5276N/A<DD>
5276N/A<P>
5276N/AGets the next token from the input stream <CODE>lexer</CODE>. Ensure that the
5276N/Areturned token matches <CODE>expect</CODE> (isc_tokentype_qstring can also
5276N/Areturn isc_tokentype_string), or isc_tokentype_eol and isc_tokentype_eof if
5276N/A<CODE>eol</CODE> is <CODE>ISC_TRUE</CODE>.
5276N/A<P>
5276N/AReturns <CODE>DNS_R_UNEXPECTED</CODE>, <CODE>DNS_R_UNEXPECTEDEND</CODE>,
5276N/A<CODE>DNS_R_UNEXPECTEDTOKEN</CODE> and <CODE>DNS_R_SUCCESS</CODE>.
5276N/A<P>
5276N/A</DT>
5276N/A<DT><CODE>static dns_result_t<BR>
5276N/A<A NAME="mem_tobuffer">mem_tobuffer</A>(isc_buffer_t *target, void *base, unsigned int length);</CODE></DT>
5276N/A<DD>
5276N/A<P>
5276N/AAdd the memory referred to by <CODE>base</CODE> to <CODE>target</CODE>.
5276N/A<P>
5276N/AReturns <CODE>DNS_R_NOSPACE</CODE> and <CODE>DNS_R_SUCCESS</CODE>.
4632N/A<P>
<DT><CODE>static int<BR>
compare_region(isc_region_t *r1, isc_region_t *r2)</CODE></DT>
<DD>
<P>
Compares two regions returning -1, 0, 1 based on their DNSSEC ordering.
<P>
<DT><CODE>static int<BR>
hexvalue(char value);</CODE></DT>
<DD>
<P>
Returns the hexadecimal value of <CODE>value</CODE> or -1 if not
a hexadecimal character.
<P>
<DT><CODE>static int<BR>
decvalue(char value);</CODE></DT>
<DD>
<P>
Returns the decimal value of <CODE>value</CODE> or -1 if not
a decimal character.
<P>
<DT><CODE>static dns_result_t<BR>
base64_totext(isc_region_t *source, isc_buffer_t *target);</CODE></DT>
<DD>
<P>
Convert the region referred to by <CODE>source</CODE> to base64 encoded text
and put it into <CODE>target</CODE>.
<P>
Returns <CODE>DNS_R_NOSPACE</CODE> or <CODE>DNS_R_SUCCESS</CODE>.
<P>
<DT><CODE>static dns_result_t<BR>
base64_tobuffer(isc_lex_t *lexer, isc_buffer_t *target,
int length);</CODE></DT>
<DD>
<P>
Read a series of tokens from <CODE>lexer</CODE> that containing base64 data
until one of end of line, <CODE>length</CODE> (<CODE>length</CODE> &gt;= 0)
bytes have been read or base64 pad characters are seen.
If <CODE>length</CODE> &lt; 0 it is ignored otherwise it is an error if there
are not <CODE>length</CODE> octets of data or when processing a token
<CODE>length</CODE> octets would have been exceeded.
<P>
Returns <CODE>DNS_R_BADBASE64</CODE>, <CODE>DNS_R_UNEXPECTED</CODE>,
<CODE>DNS_R_UNEXPECTEDEND</CODE>, <CODE>DNS_R_UNEXPECTEDTOKEN</CODE>
and <CODE>DNS_R_SUCCESS</CODE>.
<P>
<DT><CODE>static dns_result_t<BR>
time_totext(unsigned long value, isc_buffer_t *target);</CODE></DT>
<DD>
<P>
Convert the date represented by <CODE>value</CODE> into YYYYMMDDHHMMSS format
taking into account the active epochs. This code is Y2K and Y2038 compliant.
<P>
Returns <CODE>DNS_R_NOSPACE</CODE> and <CODE>DNS_R_SUCCESS</CODE>.
<DT><CODE>static dns_result_t<BR>
time_tobuffer(char *source, isc_buffer_t *target);</CODE></DT>
<DD>
<P>
Take the date in <CODE>source</CODE> and convert it seconds since January 1,
1970 (ignoring leap seconds) and place the least significant 32 bits into
<CODE>target</CODE>.
<P>
Returns <CODE>ISC_R_RANGE</CODE>, <CODE>DNS_R_SYNTAX</CODE>,
<CODE>DNS_R_NOSPACE</CODE> and <CODE>DNS_R_SUCCESS</CODE>.
</DL>
<H2><A NAME="macros">Support Macros<A></H2>
The following macro is available:
<DL>
<DT><CODE>RETERR(x)</CODE><DT>
<DD>
<P>
Evaluate <CODE>x</CODE> and call <CODE>return (<I>&lt;value of x&gt;</I>);</CODE> if the result is not <CODE>DNS_R_SUCCESS</CODE>.
</DL>
</BODY>
</HTML>