2 * testpkts. Data file parse for test packets, and query matching.
4 * Data storage for specially crafted replies for testing purposes.
6 * (c) NLnet Labs, 2005, 2006, 2007
7 * See the file LICENSE for the license
13 struct sldns_file_parse_state
;
18 * This is a debugging aid. It is not efficient, especially
19 * with a long config file, but it can give any reply to any query.
20 * This can help the developer pre-script replies for queries.
22 * You can specify a packet RR by RR with header flags to return.
25 * - matching content different from reply content.
26 * - find way to adjust mangled packets?
31 The data file format is as follows:
34 ; a number of entries, these are processed first to last.
35 ; a line based format.
41 ; first give MATCH lines, that say what queries are matched
43 ; 'opcode' makes the query match the opcode from the reply
44 ; if you leave it out, any opcode matches this entry.
45 ; 'qtype' makes the query match the qtype from the reply
46 ; 'qname' makes the query match the qname from the reply
47 ; 'subdomain' makes the query match subdomains of qname from the reply
48 ; 'serial=1023' makes the query match if ixfr serial is 1023.
49 ; 'all' has to match header byte for byte and all rrs in packet.
50 ; 'ttl' used with all, rrs in packet must also have matching TTLs.
51 ; 'DO' will match only queries with DO bit set.
52 ; 'noedns' matches queries without EDNS OPT records.
53 MATCH [opcode] [qtype] [qname] [serial=<value>] [all] [ttl]
56 ; Then the REPLY header is specified.
57 REPLY opcode, rcode or flags.
58 (opcode) QUERY IQUERY STATUS NOTIFY UPDATE
59 (rcode) NOERROR FORMERR SERVFAIL NXDOMAIN NOTIMPL YXDOMAIN
60 YXRRSET NXRRSET NOTAUTH NOTZONE
61 (flags) QR AA TC RD CD RA AD DO
63 ; any additional actions to do.
64 ; 'copy_id' copies the ID from the query to the answer.
66 ; 'copy_query' copies the query name, type and class to the answer.
68 ; 'sleep=10' sleeps for 10 seconds before giving the answer (TCP is open)
69 ADJUST [sleep=<num>] ; sleep before giving any reply
70 ADJUST [packet_sleep=<num>] ; sleep before this packet in sequence
72 <RRs, one per line> ; the RRcount is determined automatically.
79 EXTRA_PACKET ; follow with SECTION, REPLY for more packets.
80 HEX_ANSWER_BEGIN ; follow with hex data
81 ; this replaces any answer packet constructed
82 ; with the SECTION keywords (only SECTION QUERY
83 ; is used to match queries). If the data cannot
84 ; be parsed, ADJUST rules for the answer packet
85 ; are ignored. Only copy_id is done.
99 www.nlnetlabs.nl. IN A
101 www.nlnetlabs.nl. IN A 195.169.215.155
103 nlnetlabs.nl. IN NS www.nlnetlabs.nl.
111 www2.nlnetlabs.nl. IN A
113 ; 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19
114 ;-- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
115 00 bf 81 80 00 01 00 01 00 02 00 02 03 77 77 77 0b 6b 61 6e ; 1- 20
116 61 72 69 65 70 69 65 74 03 63 6f 6d 00 00 01 00 01 03 77 77 ; 21- 40
117 77 0b 6b 61 6e 61 72 69 65 70 69 65 74 03 63 6f 6d 00 00 01 ; 41- 60
118 00 01 00 01 50 8b 00 04 52 5e ed 32 0b 6b 61 6e 61 72 69 65 ; 61- 80
119 70 69 65 74 03 63 6f 6d 00 00 02 00 01 00 01 50 8b 00 11 03 ; 81- 100
120 6e 73 31 08 68 65 78 6f 6e 2d 69 73 02 6e 6c 00 0b 6b 61 6e ; 101- 120
121 61 72 69 65 70 69 65 74 03 63 6f 6d 00 00 02 00 01 00 01 50 ; 121- 140
122 8b 00 11 03 6e 73 32 08 68 65 78 6f 6e 2d 69 73 02 6e 6c 00 ; 141- 160
123 03 6e 73 31 08 68 65 78 6f 6e 2d 69 73 02 6e 6c 00 00 01 00 ; 161- 180
124 01 00 00 46 53 00 04 52 5e ed 02 03 6e 73 32 08 68 65 78 6f ; 181- 200
125 6e 2d 69 73 02 6e 6c 00 00 01 00 01 00 00 46 53 00 04 d4 cc ; 201- 220
132 note that this file will link with your
133 void verbose(int level, char* format, ...); output function.
136 /** Type of transport, since some entries match based on UDP or TCP of query */
137 enum transport_type
{transport_any
= 0, transport_udp
, transport_tcp
};
139 /** struct to keep a linked list of reply packets for a query */
140 struct reply_packet
{
141 /** next in list of reply packets, for TCP multiple pkts on wire */
142 struct reply_packet
* next
;
145 /** length of reply pkt */
147 /** or reply pkt in hex if not parsable */
148 struct sldns_buffer
* reply_from_hex
;
149 /** seconds to sleep before giving packet */
150 unsigned int packet_sleep
;
153 /** data structure to keep the canned queries in.
154 format is the 'matching query' and the 'canned answer' */
157 /* How to match an incoming query with this canned reply */
158 /** match query opcode with answer opcode */
159 uint8_t match_opcode
;
160 /** match qtype with answer qtype */
162 /** match qname with answer qname */
164 /** match qname as subdomain of answer qname */
165 uint8_t match_subdomain
;
166 /** match SOA serial number, from auth section */
167 uint8_t match_serial
;
168 /** match all of the packet */
170 /** match ttls in the packet */
174 /** match absence of EDNS OPT record in query */
175 uint8_t match_noedns
;
176 /** match query serial with this value. */
177 uint32_t ixfr_soa_serial
;
178 /** match on UDP/TCP */
179 enum transport_type match_transport
;
181 /** pre canned reply */
182 struct reply_packet
*reply_list
;
184 /** how to adjust the reply packet */
185 /** copy over the ID from the query into the answer */
187 /** copy the query nametypeclass from query into the answer */
190 unsigned int sleeptime
;
192 /** some number that names this entry, line number in file or so */
200 * reads the canned reply file and returns a list of structs
201 * does an exit on error.
202 * @param name: name of the file to read.
203 * @param skip_whitespace: skip leftside whitespace.
205 struct entry
* read_datafile(const char* name
, int skip_whitespace
);
208 * Delete linked list of entries.
210 void delete_entry(struct entry
* list
);
213 * Read one entry from the data file.
214 * @param in: file to read from. Filepos must be at the start of a new line.
215 * @param name: name of the file for prettier errors.
216 * @param pstate: file parse state with lineno, default_ttl,
217 * oirigin and prev_rr name.
218 * @param skip_whitespace: skip leftside whitespace.
219 * @return: The entry read (malloced) or NULL if no entry could be read.
221 struct entry
* read_entry(FILE* in
, const char* name
,
222 struct sldns_file_parse_state
* pstate
, int skip_whitespace
);
225 * finds entry in list, or returns NULL.
227 struct entry
* find_match(struct entry
* entries
, uint8_t* query_pkt
,
228 size_t query_pkt_len
, enum transport_type transport
);
231 * match two packets, all must match
233 * @param qlen: length of q.
235 * @param plen: length of p.
236 * @param mttl: if true, ttls must match, if false, ttls do not need to match
237 * @param noloc: if true, rrs may be reordered in their packet-section.
238 * rrs are then matches without location of the rr being important.
239 * @return true if matched.
241 int match_all(uint8_t* q
, size_t qlen
, uint8_t* p
, size_t plen
, int mttl
,
245 * copy & adjust packet, mallocs a copy.
247 void adjust_packet(struct entry
* match
, uint8_t** answer_pkt
,
248 size_t* answer_pkt_len
, uint8_t* query_pkt
, size_t query_pkt_len
);
251 * Parses data buffer to a query, finds the correct answer
252 * and calls the given function for every packet to send.
253 * if verbose_out filename is given, packets are dumped there.
254 * @param inbuf: the packet that came in
255 * @param inlen: length of packet.
256 * @param entries: entries read in from datafile.
257 * @param count: is increased to count number of queries answered.
258 * @param transport: set to UDP or TCP to match some types of entries.
259 * @param sendfunc: called to send answer (buffer, size, userarg).
260 * @param userdata: userarg to give to sendfunc.
261 * @param verbose_out: if not NULL, verbose messages are printed there.
263 void handle_query(uint8_t* inbuf
, ssize_t inlen
, struct entry
* entries
,
264 int* count
, enum transport_type transport
,
265 void (*sendfunc
)(uint8_t*, size_t, void*), void* userdata
,
268 #endif /* TESTPKTS_H */