#ifndef PACKET_H
#define PACKET_H
#include <sys/types.h>
#include "dns.h"
#include "namedb.h"
struct query;
#define QHEADERSZ 12
#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)
#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)
#define ID(packet) (buffer_read_u16_at((packet), 0))
#define ID_SET(packet, id) (buffer_write_u16_at((packet), 0, (id)))
#define FLAGS(packet) (buffer_read_u16_at((packet), 2))
#define FLAGS_SET(packet, f) (buffer_write_u16_at((packet), 2, (f)))
#define QDCOUNT(packet) (buffer_read_u16_at((packet), 4))
#define QDCOUNT_SET(packet, c) (buffer_write_u16_at((packet), 4, (c)))
#define ANCOUNT(packet) (buffer_read_u16_at((packet), 6))
#define ANCOUNT_SET(packet, c) (buffer_write_u16_at((packet), 6, (c)))
#define NSCOUNT(packet) (buffer_read_u16_at((packet), 8))
#define NSCOUNT_SET(packet, c) (buffer_write_u16_at((packet), 8, (c)))
#define ARCOUNT(packet) (buffer_read_u16_at((packet), 10))
#define ARCOUNT_SET(packet, c) (buffer_write_u16_at((packet), 10, (c)))
#define MAX_PACKET_SIZE 65535
#define QIOBUFSZ (MAX_PACKET_SIZE + MAX_RR_SIZE)
#define MAXRRSPP 10240
#define MAX_COMPRESSED_DNAMES MAXRRSPP
#define MAX_COMPRESSION_OFFSET 16383
#define IPV4_MINIMAL_RESPONSE_SIZE 1232
#define IPV6_MINIMAL_RESPONSE_SIZE 1220
extern int round_robin;
extern int minimal_responses;
int packet_encode_rr(struct query *query,
domain_type *owner,
rr_type *rr,
uint32_t ttl);
int packet_encode_rrset(struct query *query,
domain_type *owner,
rrset_type *rrset,
int truncate_rrset,
size_t minimal_respsize,
int* done);
int packet_skip_rr(buffer_type *packet, int question_section);
int packet_skip_dname(buffer_type *packet);
rr_type *packet_read_rr(region_type *region,
domain_table_type *owners,
buffer_type *packet,
int question_section);
int packet_read_query_section(buffer_type *packet,
uint8_t* dest,
uint16_t* qtype,
uint16_t* qclass);
int packet_find_notify_serial(buffer_type *packet, uint32_t* serial);
#endif