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 18struct 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 */ 147extern int round_robin; 148/* use minimal responses (more minimal, with additional only for referrals) */ 149extern int minimal_responses; 150 151/* 152 * Encode RR with OWNER as owner name into QUERY. Returns the number 153 * of RRs successfully encoded. 154 */ 155int 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 */ 166int 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 */ 176int packet_skip_rr(buffer_type *packet, int question_section); 177 178/* 179 * Skip the dname at the current position in PACKET. 180 */ 181int packet_skip_dname(buffer_type *packet); 182 183/* 184 * Read the RR at the current position in PACKET. 185 */ 186rr_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 */ 196int 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. */ 203int packet_find_notify_serial(buffer_type *packet, uint32_t* serial); 204 205#endif /* PACKET_H */ 206