BLOG | DOCUMENTATION | TRAC

Home --> Documentations --> PJLIB-UTIL Reference

Low-level DNS Message Parsing and Packetization

Data Structures

struct  pj_dns_hdr
 
struct  pj_dns_parsed_query
 
struct  pj_dns_parsed_rr
 
union  pj_dns_parsed_rr::rdata
 
struct  pj_dns_parsed_rr::rdata::srv
 
struct  pj_dns_parsed_rr::rdata::cname
 
struct  pj_dns_parsed_rr::rdata::ns
 
struct  pj_dns_parsed_rr::rdata::ptr
 
struct  pj_dns_parsed_rr::rdata::a
 
struct  pj_dns_parsed_rr::rdata::aaaa
 
struct  pj_dns_parsed_packet
 

Macros

#define PJ_DNS_SET_RCODE(c)   ((pj_uint16_t)((c) & 0x0F))
 
#define PJ_DNS_SET_RA(on)   ((pj_uint16_t)((on) << 7))
 
#define PJ_DNS_SET_RD(on)   ((pj_uint16_t)((on) << 8))
 
#define PJ_DNS_SET_TC(on)   ((pj_uint16_t)((on) << 9))
 
#define PJ_DNS_SET_AA(on)   ((pj_uint16_t)((on) << 10))
 
#define PJ_DNS_SET_OPCODE(o)   ((pj_uint16_t)((o) << 11))
 
#define PJ_DNS_SET_QR(on)   ((pj_uint16_t)((on) << 15))
 
#define PJ_DNS_GET_RCODE(val)   (((val) & PJ_DNS_SET_RCODE(0x0F)) >> 0)
 
#define PJ_DNS_GET_RA(val)   (((val) & PJ_DNS_SET_RA(1)) >> 7)
 
#define PJ_DNS_GET_RD(val)   (((val) & PJ_DNS_SET_RD(1)) >> 8)
 
#define PJ_DNS_GET_TC(val)   (((val) & PJ_DNS_SET_TC(1)) >> 9)
 
#define PJ_DNS_GET_AA(val)   (((val) & PJ_DNS_SET_AA(1)) >> 10)
 
#define PJ_DNS_GET_OPCODE(val)   (((val) & PJ_DNS_SET_OPCODE(0x0F)) >> 11)
 
#define PJ_DNS_GET_QR(val)   (((val) & PJ_DNS_SET_QR(1)) >> 15)
 

Enumerations

enum  { PJ_DNS_CLASS_IN = 1 }
 
enum  pj_dns_type {
  PJ_DNS_TYPE_A = 1, PJ_DNS_TYPE_NS = 2, PJ_DNS_TYPE_MD = 3, PJ_DNS_TYPE_MF = 4,
  PJ_DNS_TYPE_CNAME = 5, PJ_DNS_TYPE_SOA = 6, PJ_DNS_TYPE_MB = 7, PJ_DNS_TYPE_MG = 8,
  PJ_DNS_TYPE_MR = 9, PJ_DNS_TYPE_NULL = 10, PJ_DNS_TYPE_WKS = 11, PJ_DNS_TYPE_PTR = 12,
  PJ_DNS_TYPE_HINFO = 13, PJ_DNS_TYPE_MINFO = 14, PJ_DNS_TYPE_MX = 15, PJ_DNS_TYPE_TXT = 16,
  PJ_DNS_TYPE_RP = 17, PJ_DNS_TYPE_AFSB = 18, PJ_DNS_TYPE_X25 = 19, PJ_DNS_TYPE_ISDN = 20,
  PJ_DNS_TYPE_RT = 21, PJ_DNS_TYPE_NSAP = 22, PJ_DNS_TYPE_NSAP_PTR = 23, PJ_DNS_TYPE_SIG = 24,
  PJ_DNS_TYPE_KEY = 25, PJ_DNS_TYPE_PX = 26, PJ_DNS_TYPE_GPOS = 27, PJ_DNS_TYPE_AAAA = 28,
  PJ_DNS_TYPE_LOC = 29, PJ_DNS_TYPE_NXT = 30, PJ_DNS_TYPE_EID = 31, PJ_DNS_TYPE_NIMLOC = 32,
  PJ_DNS_TYPE_SRV = 33, PJ_DNS_TYPE_ATMA = 34, PJ_DNS_TYPE_NAPTR = 35, PJ_DNS_TYPE_KX = 36,
  PJ_DNS_TYPE_CERT = 37, PJ_DNS_TYPE_A6 = 38, PJ_DNS_TYPE_DNAME = 39, PJ_DNS_TYPE_OPT = 41,
  PJ_DNS_TYPE_APL = 42, PJ_DNS_TYPE_DS = 43, PJ_DNS_TYPE_SSHFP = 44, PJ_DNS_TYPE_IPSECKEY = 45,
  PJ_DNS_TYPE_RRSIG = 46, PJ_DNS_TYPE_NSEC = 47, PJ_DNS_TYPE_DNSKEY = 48
}
 
enum  pj_dns_rcode {
  PJ_DNS_RCODE_FORMERR = 1, PJ_DNS_RCODE_SERVFAIL = 2, PJ_DNS_RCODE_NXDOMAIN = 3, PJ_DNS_RCODE_NOTIMPL = 4,
  PJ_DNS_RCODE_REFUSED = 5, PJ_DNS_RCODE_YXDOMAIN = 6, PJ_DNS_RCODE_YXRRSET = 7, PJ_DNS_RCODE_NXRRSET = 8,
  PJ_DNS_RCODE_NOTAUTH = 9, PJ_DNS_RCODE_NOTZONE = 10
}
 
enum  pj_dns_dup_options { PJ_DNS_NO_QD = 1, PJ_DNS_NO_ANS = 2, PJ_DNS_NO_NS = 4, PJ_DNS_NO_AR = 8 }
 

Functions

pj_status_t pj_dns_make_query (void *packet, unsigned *size, pj_uint16_t id, int qtype, const pj_str_t *name)
 
pj_status_t pj_dns_parse_packet (pj_pool_t *pool, const void *packet, unsigned size, pj_dns_parsed_packet **p_res)
 
void pj_dns_packet_dup (pj_pool_t *pool, const pj_dns_parsed_packet *p, unsigned options, pj_dns_parsed_packet **p_dst)
 
const char * pj_dns_get_type_name (int type)
 
void pj_dns_init_srv_rr (pj_dns_parsed_rr *rec, const pj_str_t *res_name, unsigned dnsclass, unsigned ttl, unsigned prio, unsigned weight, unsigned port, const pj_str_t *target)
 
void pj_dns_init_cname_rr (pj_dns_parsed_rr *rec, const pj_str_t *res_name, unsigned dnsclass, unsigned ttl, const pj_str_t *name)
 
void pj_dns_init_a_rr (pj_dns_parsed_rr *rec, const pj_str_t *res_name, unsigned dnsclass, unsigned ttl, const pj_in_addr *ip_addr)
 
void pj_dns_init_aaaa_rr (pj_dns_parsed_rr *rec, const pj_str_t *res_name, unsigned dnsclass, unsigned ttl, const pj_in6_addr *ip_addr)
 
void pj_dns_dump_packet (const pj_dns_parsed_packet *res)
 

Detailed Description

This module provides low-level services to parse and packetize DNS queries and responses. The functions support building a DNS query packet and parse the data in the DNS response. This implementation conforms to the following specifications:

  • RFC 1035: DOMAIN NAMES - IMPLEMENTATION AND SPECIFICATION
  • RFC 1886: DNS Extensions to support IP version 6

To create a DNS query packet, application should call pj_dns_make_query() function, specifying the desired DNS query type, the name to be resolved, and the buffer where the DNS packet will be built into.

When incoming DNS query or response packet arrives, application can use pj_dns_parse_packet() to parse the TCP/UDP payload into parsed DNS packet structure.

This module does not provide any networking functionalities to send or receive DNS packets. This functionality should be provided by higher layer modules such as DNS Asynchronous/Caching Resolution Engine.

Macro Definition Documentation

#define PJ_DNS_GET_AA (   val)    (((val) & PJ_DNS_SET_AA(1)) >> 10)

Get AA bit

#define PJ_DNS_GET_OPCODE (   val)    (((val) & PJ_DNS_SET_OPCODE(0x0F)) >> 11)

Get OPCODE value

#define PJ_DNS_GET_QR (   val)    (((val) & PJ_DNS_SET_QR(1)) >> 15)

Get QR bit

#define PJ_DNS_GET_RA (   val)    (((val) & PJ_DNS_SET_RA(1)) >> 7)

Get RA bit

#define PJ_DNS_GET_RCODE (   val)    (((val) & PJ_DNS_SET_RCODE(0x0F)) >> 0)

Get RCODE value

#define PJ_DNS_GET_RD (   val)    (((val) & PJ_DNS_SET_RD(1)) >> 8)

Get RD bit

#define PJ_DNS_GET_TC (   val)    (((val) & PJ_DNS_SET_TC(1)) >> 9)

Get TC bit

#define PJ_DNS_SET_AA (   on)    ((pj_uint16_t)((on) << 10))

Create AA (Authoritative Answer) bit

#define PJ_DNS_SET_OPCODE (   o)    ((pj_uint16_t)((o) << 11))

Create four bits opcode

#define PJ_DNS_SET_QR (   on)    ((pj_uint16_t)((on) << 15))

Create query/response bit

#define PJ_DNS_SET_RA (   on)    ((pj_uint16_t)((on) << 7))

Create RA (Recursion Available) bit

#define PJ_DNS_SET_RCODE (   c)    ((pj_uint16_t)((c) & 0x0F))

Create RCODE flag

#define PJ_DNS_SET_RD (   on)    ((pj_uint16_t)((on) << 8))

Create RD (Recursion Desired) bit

#define PJ_DNS_SET_TC (   on)    ((pj_uint16_t)((on) << 9))

Create TC (Truncated) bit

Enumeration Type Documentation

anonymous enum
Enumerator
PJ_DNS_CLASS_IN 

DNS class IN.

Option flags to be specified when calling pj_dns_packet_dup() function. These flags can be combined with bitwise OR operation.

Enumerator
PJ_DNS_NO_QD 

Do not duplicate the query section.

PJ_DNS_NO_ANS 

Do not duplicate the answer section.

PJ_DNS_NO_NS 

Do not duplicate the NS section.

PJ_DNS_NO_AR 

Do not duplicate the additional rec section

These constants describe DNS RCODEs. Application can fold these constants into PJLIB pj_status_t namespace by calling PJ_STATUS_FROM_DNS_RCODE() macro.

Enumerator
PJ_DNS_RCODE_FORMERR 

Format error.

PJ_DNS_RCODE_SERVFAIL 

Server failure.

PJ_DNS_RCODE_NXDOMAIN 

Name Error.

PJ_DNS_RCODE_NOTIMPL 

Not Implemented.

PJ_DNS_RCODE_REFUSED 

Refused.

PJ_DNS_RCODE_YXDOMAIN 

The name exists.

PJ_DNS_RCODE_YXRRSET 

The RRset (name, type) exists.

PJ_DNS_RCODE_NXRRSET 

The RRset (name, type) doesn't exist

PJ_DNS_RCODE_NOTAUTH 

Not authorized.

PJ_DNS_RCODE_NOTZONE 

The zone specified is not a zone.

This enumeration describes standard DNS record types as described by RFC 1035, RFC 2782, and others.

Enumerator
PJ_DNS_TYPE_A 

Host address (A) record.

PJ_DNS_TYPE_NS 

Authoritative name server (NS)

PJ_DNS_TYPE_MD 

Mail destination (MD) record.

PJ_DNS_TYPE_MF 

Mail forwarder (MF) record.

PJ_DNS_TYPE_CNAME 

Canonical name (CNAME) record.

PJ_DNS_TYPE_SOA 

Marks start of zone authority.

PJ_DNS_TYPE_MB 

Mailbox domain name (MB).

PJ_DNS_TYPE_MG 

Mail group member (MG).

PJ_DNS_TYPE_MR 

Mail rename domain name.

PJ_DNS_TYPE_NULL 

NULL RR.

PJ_DNS_TYPE_WKS 

Well known service description

PJ_DNS_TYPE_PTR 

Domain name pointer.

PJ_DNS_TYPE_HINFO 

Host information.

PJ_DNS_TYPE_MINFO 

Mailbox or mail list information.

PJ_DNS_TYPE_MX 

Mail exchange record.

PJ_DNS_TYPE_TXT 

Text string.

PJ_DNS_TYPE_RP 

Responsible person.

PJ_DNS_TYPE_AFSB 

AFS cell database.

PJ_DNS_TYPE_X25 

X.25 calling address.

PJ_DNS_TYPE_ISDN 

ISDN calling address.

PJ_DNS_TYPE_RT 

Router.

PJ_DNS_TYPE_NSAP 

NSAP address.

PJ_DNS_TYPE_NSAP_PTR 

NSAP reverse address.

PJ_DNS_TYPE_SIG 

Signature.

PJ_DNS_TYPE_KEY 

Key.

PJ_DNS_TYPE_PX 

X.400 mail mapping.

PJ_DNS_TYPE_GPOS 

Geographical position (withdrawn)

PJ_DNS_TYPE_AAAA 

IPv6 address.

PJ_DNS_TYPE_LOC 

Location.

PJ_DNS_TYPE_NXT 

Next valid name in the zone.

PJ_DNS_TYPE_EID 

Endpoint idenfitier.

PJ_DNS_TYPE_NIMLOC 

Nimrod locator.

PJ_DNS_TYPE_SRV 

Server selection (SRV) record.

PJ_DNS_TYPE_ATMA 

DNS ATM address record.

PJ_DNS_TYPE_NAPTR 

DNS Naming authority pointer record.

PJ_DNS_TYPE_KX 

DNS key exchange record.

PJ_DNS_TYPE_CERT 

DNS certificate record.

PJ_DNS_TYPE_A6 

DNS IPv6 address (experimental)

PJ_DNS_TYPE_DNAME 

DNS non-terminal name redirection rec.

PJ_DNS_TYPE_OPT 

DNS options - contains EDNS metadata.

PJ_DNS_TYPE_APL 

DNS Address Prefix List (APL) record.

PJ_DNS_TYPE_DS 

DNS Delegation Signer (DS)

PJ_DNS_TYPE_SSHFP 

DNS SSH Key Fingerprint

PJ_DNS_TYPE_IPSECKEY 

DNS IPSEC Key.

PJ_DNS_TYPE_RRSIG 

DNS Resource Record signature.

PJ_DNS_TYPE_NSEC 

DNS Next Secure Name.

PJ_DNS_TYPE_DNSKEY 

DNSSEC Key.

Function Documentation

void pj_dns_dump_packet ( const pj_dns_parsed_packet res)

Dump DNS packet to standard log.

Parameters
resThe DNS packet.
const char* pj_dns_get_type_name ( int  type)

Utility function to get the type name string of the specified DNS type.

Parameters
typeDNS type (see pj_dns_type).
Returns
String name of the type (e.g. "A", "SRV", etc.).
void pj_dns_init_a_rr ( pj_dns_parsed_rr rec,
const pj_str_t res_name,
unsigned  dnsclass,
unsigned  ttl,
const pj_in_addr ip_addr 
)

Initialize DNS record as DNS A record.

Parameters
recThe DNS resource record to be initialized as DNS A record.
res_nameResource name.
dnsclassDNS class.
ttlResource TTL value.
ip_addrHost address.
void pj_dns_init_aaaa_rr ( pj_dns_parsed_rr rec,
const pj_str_t res_name,
unsigned  dnsclass,
unsigned  ttl,
const pj_in6_addr ip_addr 
)

Initialize DNS record as DNS AAAA record.

Parameters
recThe DNS resource record to be initialized as DNS AAAA record.
res_nameResource name.
dnsclassDNS class.
ttlResource TTL value.
ip_addrHost address.
void pj_dns_init_cname_rr ( pj_dns_parsed_rr rec,
const pj_str_t res_name,
unsigned  dnsclass,
unsigned  ttl,
const pj_str_t name 
)

Initialize DNS record as DNS CNAME record.

Parameters
recThe DNS resource record to be initialized as DNS CNAME record.
res_nameResource name.
dnsclassDNS class.
ttlResource TTL value.
nameHost name.
void pj_dns_init_srv_rr ( pj_dns_parsed_rr rec,
const pj_str_t res_name,
unsigned  dnsclass,
unsigned  ttl,
unsigned  prio,
unsigned  weight,
unsigned  port,
const pj_str_t target 
)

Initialize DNS record as DNS SRV record.

Parameters
recThe DNS resource record to be initialized as DNS SRV record.
res_nameResource name.
dnsclassDNS class.
ttlResource TTL value.
prioDNS SRV priority.
weightDNS SRV weight.
portTarget port.
targetTarget name.
pj_status_t pj_dns_make_query ( void *  packet,
unsigned *  size,
pj_uint16_t  id,
int  qtype,
const pj_str_t name 
)

Create DNS query packet to resolve the specified names. This function can be used to build any types of DNS query, such as A record or DNS SRV record.

Application specifies the type of record and the name to be queried, and the function will build the DNS query packet into the buffer specified. Once the packet is successfully built, application can send the packet via TCP or UDP connection.

Parameters
packetThe buffer to put the DNS query packet.
sizeOn input, it specifies the size of the buffer. On output, it will be filled with the actual size of the DNS query packet.
idDNS query ID to associate DNS response with the query.
qtypeDNS type of record to be queried (see pj_dns_type).
nameName to be queried from the DNS server.
Returns
PJ_SUCCESS on success, or the appropriate error code.
void pj_dns_packet_dup ( pj_pool_t pool,
const pj_dns_parsed_packet p,
unsigned  options,
pj_dns_parsed_packet **  p_dst 
)

Duplicate DNS packet.

Parameters
poolThe pool to allocate memory for the duplicated packet.
pThe DNS packet to be cloned.
optionsOption flags, from pj_dns_dup_options.
p_dstPointer to store the cloned DNS packet.
pj_status_t pj_dns_parse_packet ( pj_pool_t pool,
const void *  packet,
unsigned  size,
pj_dns_parsed_packet **  p_res 
)

Parse raw DNS packet into parsed DNS packet structure. This function is able to parse few DNS resource records such as A record, PTR record, CNAME record, NS record, and SRV record.

Parameters
poolPool to allocate memory for the parsed packet.
packetPointer to the DNS packet (the TCP/UDP payload of the raw packet).
sizeThe size of the DNS packet.
p_resPointer to store the resulting parsed packet.
Returns
PJ_SUCCESS on success, or the appropriate error code.

 


PJLIB-UTIL Open Source, small footprint, and portable asynchronous/caching DNS resolver, text scanner, STUN client, and XML library
Copyright (C) 2006-2009 Teluu Inc.