Home | History | Annotate | Line # | Download | only in dist
      1 /*
      2  * packet.h -- low-level DNS packet encoding and decoding functions.
      3  *
      4  * Copyright (c) 2001-2006, NLnet Labs. All rights reserved.
      5  *
      6  * See LICENSE for the license.
      7  *
      8  */
      9 
     10 #ifndef PACKET_H
     11 #define PACKET_H
     12 
     13 #include <sys/types.h>
     14 
     15 #include "dns.h"
     16 #include "namedb.h"
     17 
     18 struct query;
     19 
     20 /*
     21  * Set of macro's to deal with the dns message header as specified
     22  * in RFC1035 in portable way.
     23  *
     24  */
     25 
     26 /*
     27  *
     28  *                                    1  1  1  1  1  1
     29  *      0  1  2  3  4  5  6  7  8  9  0  1  2  3  4  5
     30  *    +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+
     31  *    |                      ID                       |
     32  *    +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+
     33  *    |QR|   Opcode  |AA|TC|RD|RA| Z|AD|CD|   RCODE   |
     34  *    +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+
     35  *    |                    QDCOUNT                    |
     36  *    +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+
     37  *    |                    ANCOUNT                    |
     38  *    +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+
     39  *    |                    NSCOUNT                    |
     40  *    +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+
     41  *    |                    ARCOUNT                    |
     42  *    +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+
     43  *
     44  */
     45 
     46 /* The length of the header */
     47 #define	QHEADERSZ	12
     48 
     49 /* First octet of flags */
     50 #define	RD_MASK		0x01U
     51 #define	RD_SHIFT	0
     52 #define	RD(packet)      (*buffer_at((packet), 2) & RD_MASK)
     53 #define	RD_SET(packet)	(*buffer_at((packet), 2) |= RD_MASK)
     54 #define	RD_CLR(packet)	(*buffer_at((packet), 2) &= ~RD_MASK)
     55 
     56 #define TC_MASK		0x02U
     57 #define TC_SHIFT	1
     58 #define	TC(packet)	(*buffer_at((packet), 2) & TC_MASK)
     59 #define	TC_SET(packet)	(*buffer_at((packet), 2) |= TC_MASK)
     60 #define	TC_CLR(packet)	(*buffer_at((packet), 2) &= ~TC_MASK)
     61 
     62 #define	AA_MASK		0x04U
     63 #define	AA_SHIFT	2
     64 #define	AA(packet)	(*buffer_at((packet), 2) & AA_MASK)
     65 #define	AA_SET(packet)	(*buffer_at((packet), 2) |= AA_MASK)
     66 #define	AA_CLR(packet)	(*buffer_at((packet), 2) &= ~AA_MASK)
     67 
     68 #define	OPCODE_MASK	0x78U
     69 #define	OPCODE_SHIFT	3
     70 #define	OPCODE(packet)	((*buffer_at((packet), 2) & OPCODE_MASK) >> OPCODE_SHIFT)
     71 #define	OPCODE_SET(packet, opcode) \
     72 	(*buffer_at((packet), 2) = (*buffer_at((packet), 2) & ~OPCODE_MASK) | ((opcode) << OPCODE_SHIFT))
     73 
     74 #define	QR_MASK		0x80U
     75 #define	QR_SHIFT	7
     76 #define	QR(packet)	(*buffer_at((packet), 2) & QR_MASK)
     77 #define	QR_SET(packet)	(*buffer_at((packet), 2) |= QR_MASK)
     78 #define	QR_CLR(packet)	(*buffer_at((packet), 2) &= ~QR_MASK)
     79 
     80 /* Second octet of flags */
     81 #define	RCODE_MASK	0x0fU
     82 #define	RCODE_SHIFT	0
     83 #define	RCODE(packet)	(*buffer_at((packet), 3) & RCODE_MASK)
     84 #define	RCODE_SET(packet, rcode) \
     85 	(*buffer_at((packet), 3) = (*buffer_at((packet), 3) & ~RCODE_MASK) | (rcode))
     86 
     87 #define	CD_MASK		0x10U
     88 #define	CD_SHIFT	4
     89 #define	CD(packet)	(*buffer_at((packet), 3) & CD_MASK)
     90 #define	CD_SET(packet)	(*buffer_at((packet), 3) |= CD_MASK)
     91 #define	CD_CLR(packet)	(*buffer_at((packet), 3) &= ~CD_MASK)
     92 
     93 #define	AD_MASK		0x20U
     94 #define	AD_SHIFT	5
     95 #define	AD(packet)	(*buffer_at((packet), 3) & AD_MASK)
     96 #define	AD_SET(packet)	(*buffer_at((packet), 3) |= AD_MASK)
     97 #define	AD_CLR(packet)	(*buffer_at((packet), 3) &= ~AD_MASK)
     98 
     99 #define	Z_MASK		0x40U
    100 #define	Z_SHIFT		6
    101 #define	Z(packet)	(*buffer_at((packet), 3) & Z_MASK)
    102 #define	Z_SET(packet)	(*buffer_at((packet), 3) |= Z_MASK)
    103 #define	Z_CLR(packet)	(*buffer_at((packet), 3) &= ~Z_MASK)
    104 
    105 #define	RA_MASK		0x80U
    106 #define	RA_SHIFT	7
    107 #define	RA(packet)	(*buffer_at((packet), 3) & RA_MASK)
    108 #define	RA_SET(packet)	(*buffer_at((packet), 3) |= RA_MASK)
    109 #define	RA_CLR(packet)	(*buffer_at((packet), 3) &= ~RA_MASK)
    110 
    111 /* Query ID */
    112 #define	ID(packet)		(buffer_read_u16_at((packet), 0))
    113 #define	ID_SET(packet, id)	(buffer_write_u16_at((packet), 0, (id)))
    114 
    115 /* Flags, RCODE, and OPCODE. */
    116 #define FLAGS(packet)		(buffer_read_u16_at((packet), 2))
    117 #define FLAGS_SET(packet, f)	(buffer_write_u16_at((packet), 2, (f)))
    118 
    119 /* Counter of the question section */
    120 #define	QDCOUNT(packet)		(buffer_read_u16_at((packet), 4))
    121 #define QDCOUNT_SET(packet, c)	(buffer_write_u16_at((packet), 4, (c)))
    122 
    123 /* Counter of the answer section */
    124 #define	ANCOUNT(packet)		(buffer_read_u16_at((packet), 6))
    125 #define ANCOUNT_SET(packet, c)	(buffer_write_u16_at((packet), 6, (c)))
    126 
    127 /* Counter of the authority section */
    128 #define	NSCOUNT(packet)		(buffer_read_u16_at((packet), 8))
    129 #define NSCOUNT_SET(packet, c)	(buffer_write_u16_at((packet), 8, (c)))
    130 
    131 /* Counter of the additional section */
    132 #define	ARCOUNT(packet)		(buffer_read_u16_at((packet), 10))
    133 #define ARCOUNT_SET(packet, c)	(buffer_write_u16_at((packet), 10, (c)))
    134 
    135 /* Miscellaneous limits */
    136 #define MAX_PACKET_SIZE         65535   /* Maximum supported size of DNS packets.  */
    137 
    138 #define	QIOBUFSZ		(MAX_PACKET_SIZE + MAX_RR_SIZE)
    139 
    140 #define	MAXRRSPP		10240    /* Maximum number of rr's per packet */
    141 #define MAX_COMPRESSED_DNAMES	MAXRRSPP /* Maximum number of compressed domains. */
    142 #define MAX_COMPRESSION_OFFSET  16383	 /* Compression pointers are 14 bit. */
    143 #define IPV4_MINIMAL_RESPONSE_SIZE 1232	 /* Recommended minimal edns size for IPv4 */
    144 #define IPV6_MINIMAL_RESPONSE_SIZE 1220	 /* Recommended minimal edns size for IPv6 */
    145 
    146 /* use round robin rotation */
    147 extern int round_robin;
    148 /* use minimal responses (more minimal, with additional only for referrals) */
    149 extern int minimal_responses;
    150 
    151 /*
    152  * Encode RR with OWNER as owner name into QUERY.  Returns the number
    153  * of RRs successfully encoded.
    154  */
    155 int packet_encode_rr(struct query *query,
    156 		     domain_type *owner,
    157 		     rr_type *rr,
    158 		     uint32_t ttl);
    159 
    160 /*
    161  * Encode RRSET with OWNER as the owner name into QUERY.  Returns the
    162  * number of RRs successfully encoded.  If TRUNCATE_RRSET the entire
    163  * RRset is truncated in case an RR (or the RRsets signature) does not
    164  * fit.
    165  */
    166 int packet_encode_rrset(struct query *query,
    167 			domain_type *owner,
    168 			rrset_type *rrset,
    169 			int truncate_rrset,
    170 			size_t minimal_respsize,
    171 			int* done);
    172 
    173 /*
    174  * Skip the RR at the current position in PACKET.
    175  */
    176 int packet_skip_rr(buffer_type *packet, int question_section);
    177 
    178 /*
    179  * Skip the dname at the current position in PACKET.
    180  */
    181 int packet_skip_dname(buffer_type *packet);
    182 
    183 /*
    184  * Read the RR at the current position in PACKET.
    185  */
    186 rr_type *packet_read_rr(region_type *region,
    187 			domain_table_type *owners,
    188 			buffer_type *packet,
    189 			int question_section);
    190 
    191 /*
    192  * read a query entry from network packet given in buffer.
    193  * does not follow compression ptrs, checks for errors (returns 0).
    194  * Dest must be at least MAXDOMAINLEN long.
    195  */
    196 int packet_read_query_section(buffer_type *packet,
    197 			uint8_t* dest,
    198 			uint16_t* qtype,
    199 			uint16_t* qclass);
    200 
    201 /* read notify SOA serial from packet. buffer position is unmodified on return.
    202  * returns false on no-serial found or parse failure. */
    203 int packet_find_notify_serial(buffer_type *packet, uint32_t* serial);
    204 
    205 #endif /* PACKET_H */
    206