Maintained by: NLnet Labs
Macros | Enumerations | Functions | Variables
testpkts.c File Reference

This is a debugging aid. More...

#include "config.h"
#include <errno.h>
#include <stdarg.h>
#include <ctype.h>
#include "testcode/testpkts.h"
#include "util/net_help.h"
#include "sldns/sbuffer.h"
#include "sldns/rrdef.h"
#include "sldns/pkthdr.h"
#include "sldns/str2wire.h"
#include "sldns/wire2str.h"


#define MAX_PACKETLEN   65536
 max size of a packet
#define MAX_LINE   10240
 max line length


enum  verbosity_value {
 verbosity definition for compat More...


void verbose (enum verbosity_value lvl, const char *msg,...) ATTR_FORMAT(printf
 logging routine, provided by caller
void static void error (const char *msg,...)
 print error and exit
static int isendline (char c)
 return if string is empty or comment
static int str_keyword (char **str, const char *keyword)
 true if the string starts with the keyword given. More...
static struct reply_packetentry_add_reply (struct entry *entry)
 Add reply packet to entry.
static void matchline (char *line, struct entry *e)
 parse MATCH line
static void replyline (char *line, uint8_t *reply, size_t reply_len, int *do_flag)
 parse REPLY line
static void adjustline (char *line, struct entry *e, struct reply_packet *pkt)
 parse ADJUST line
static struct entrynew_entry (void)
 create new entry
static size_t hexstr2bin (char *hexstr, int len, uint8_t *buf, size_t offset, size_t buf_len)
 Converts a hex string to binary data. More...
static sldns_bufferhex_buffer2wire (sldns_buffer *data_buffer)
 convert hex buffer to binary buffer
static void get_origin (const char *name, struct sldns_file_parse_state *pstate, char *parse)
 parse ORIGIN
static void add_rr (char *rrstr, uint8_t *pktbuf, size_t pktsize, size_t *pktlen, struct sldns_file_parse_state *pstate, sldns_pkt_section add_section, const char *fname)
 add RR to packet
static void add_edns (uint8_t *pktbuf, size_t pktsize, int do_flag, uint8_t *ednsdata, uint16_t ednslen, size_t *pktlen)
struct entryread_entry (FILE *in, const char *name, struct sldns_file_parse_state *pstate, int skip_whitespace)
 Read one entry from the data file. More...
struct entryread_datafile (const char *name, int skip_whitespace)
 reads the canned reply file and returns a list of structs does an exit on error. More...
static sldns_rr_type get_qtype (uint8_t *pkt, size_t pktlen)
 get qtype from packet
static size_t get_qname_len (uint8_t *pkt, size_t pktlen)
 get qtype from packet
static uint8_t * get_qname (uint8_t *pkt, size_t pktlen)
 returns owner from packet
static int get_opcode (uint8_t *pkt, size_t pktlen)
 returns opcode from packet
static int get_rcode (uint8_t *pkt, size_t pktlen)
 returns rcode from packet
static uint32_t get_serial (uint8_t *p, size_t plen)
 get authority section SOA serial value
static int pkt_find_edns_opt (uint8_t **p, size_t *plen)
 get ptr to EDNS OPT record (and remaining length); behind the type u16
static int get_has_edns (uint8_t *pkt, size_t len)
 return true if the packet has EDNS OPT record
static int get_do_flag (uint8_t *pkt, size_t len)
 return true if the DO flag is set
static void zerottls (uint8_t *pkt, size_t pktlen)
 zero TTLs in packet
static int get_line (char **s, char **n)
 get one line (
) from a string, move next to after the
, zero

static int match_noloc_section (char **q, char **nq, char **p, char **np, uint16_t num)
 match two RR sections without ordering
static int match_noloc (char *q, char *p, uint8_t *q_pkt, size_t q_pkt_len, uint8_t *p_pkt, size_t p_pkt_len)
 match two strings for unordered equality of RRs and everything else
static void lowercase_dname (uint8_t **p, size_t *remain)
 lowercase domain name - does not follow compression pointers
static void lowercase_rdata (uint8_t **p, size_t *remain, uint16_t rdatalen, uint16_t t)
 lowercase rdata of type
static void lowercase_pkt (uint8_t *pkt, size_t pktlen)
 lowercase all names in the message
static int match_question (uint8_t *q, size_t qlen, uint8_t *p, size_t plen, int mttl)
 match question section of packet
static int match_answer (uint8_t *q, size_t qlen, uint8_t *p, size_t plen, int mttl)
 match answer section of packet
int match_all (uint8_t *q, size_t qlen, uint8_t *p, size_t plen, int mttl, int noloc)
 match all of the packet More...
static int equal_dname (uint8_t *q, size_t qlen, uint8_t *p, size_t plen)
 see if domain names are equal
static int subdomain_dname (uint8_t *q, size_t qlen, uint8_t *p, size_t plen)
 see if domain names are subdomain q of p
static int match_ednsdata (uint8_t *q, size_t qlen, uint8_t *p, size_t plen)
 Match OPT RDATA (not the EDNS payload size or flags)
struct entryfind_match (struct entry *entries, uint8_t *query_pkt, size_t len, enum transport_type transport)
 finds entry in list, or returns NULL.
void adjust_packet (struct entry *match, uint8_t **answer_pkt, size_t *answer_len, uint8_t *query_pkt, size_t query_len)
 copy & adjust packet, mallocs a copy. More...
void handle_query (uint8_t *inbuf, ssize_t inlen, struct entry *entries, int *count, enum transport_type transport, void(*sendfunc)(uint8_t *, size_t, void *), void *userdata, FILE *verbose_out)
 Parses data buffer to a query, finds the correct answer and calls the given function for every packet to send. More...
void delete_replylist (struct reply_packet *replist)
 delete the list of reply packets
void delete_entry (struct entry *list)
 Delete linked list of entries.


static const char * prog_name = "testpkts"
 string to show in warnings and errors

Detailed Description

This is a debugging aid.

It is not efficient, especially with a long config file, but it can give any reply to any query. This can help the developer pre-script replies for queries.

You can specify a packet RR by RR with header flags to return.

Missing features:

Enumeration Type Documentation

◆ verbosity_value

verbosity definition for compat


0 - no verbose messages


1 - operational information


2 - detailed information


3 - query level information


4 - algorithm level information


5 - querier client information

Function Documentation

◆ str_keyword()

static int str_keyword ( char **  str,
const char *  keyword 

true if the string starts with the keyword given.

Moves the str ahead.

strbefore keyword, afterwards after keyword and spaces.
keywordthe keyword to match
: true if keyword present. False otherwise, and str unchanged.

Referenced by adjustline(), and matchline().

◆ hexstr2bin()

static size_t hexstr2bin ( char *  hexstr,
int  len,
uint8_t *  buf,
size_t  offset,
size_t  buf_len 

Converts a hex string to binary data.

hexstrstring of hex.
lenis the length of the string
bufis the buffer to store the result in
offsetis the starting position in the result buffer
buf_lenis the length of buf.
This function returns the length of the result

Referenced by hex_buffer2wire().

◆ read_entry()

struct entry* read_entry ( FILE *  in,
const char *  name,
struct sldns_file_parse_state pstate,
int  skip_whitespace 

Read one entry from the data file.

infile to read from. Filepos must be at the start of a new line.
namename of the file for prettier errors.
pstatefile parse state with lineno, default_ttl, origin and prev_rr name.
skip_whitespaceskip leftside whitespace.
: The entry read (malloced) or NULL if no entry could be read.

References MAX_LINE.

Referenced by read_datafile(), and replay_range_read().

◆ read_datafile()

struct entry* read_datafile ( const char *  name,
int  skip_whitespace 

reads the canned reply file and returns a list of structs does an exit on error.

namename of the file to read.
skip_whitespaceskip leftside whitespace.

References error(), entry::next, prog_name, read_entry(), and verbose().

Referenced by dstest_file(), nsec3_hash_test(), and verifytest_file().

◆ match_all()

int match_all ( uint8_t *  q,
size_t  qlen,
uint8_t *  p,
size_t  plen,
int  mttl,
int  noloc 

match all of the packet

match two packets, all must match

References error(), lowercase_pkt(), match_noloc(), memdup(), sldns_wire2str_pkt(), verbose(), and zerottls().

Referenced by test_buffers().

◆ adjust_packet()

void adjust_packet ( struct entry match,
uint8_t **  answer_pkt,
size_t *  answer_len,
uint8_t *  query_pkt,
size_t  query_len 

copy & adjust packet, mallocs a copy.

Assume there is only one EDNS option, which is ECS. Copy source mask from query to scope mask in reply. Assume rest of ECS data in response (eg address) matches the query.

References entry::copy_query.

◆ handle_query()

void handle_query ( uint8_t *  inbuf,
ssize_t  inlen,
struct entry entries,
int *  count,
enum transport_type  transport,
void(*)(uint8_t *, size_t, void *)  sendfunc,
void *  userdata,
FILE *  verbose_out 

Parses data buffer to a query, finds the correct answer and calls the given function for every packet to send.

if verbose_out filename is given, packets are dumped there.

inbufthe packet that came in
inlenlength of packet.
entriesentries read in from datafile.
countis increased to count number of queries answered.
transportset to UDP or TCP to match some types of entries.
sendfunccalled to send answer (buffer, size, userarg).
userdatauserarg to give to sendfunc.
verbose_outif not NULL, verbose messages are printed there.

References verbose().