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