]> CyberLeo.Net >> Repos - FreeBSD/FreeBSD.git/blob - testcode/testpkts.h
Vendor import of Unbound 1.6.2.
[FreeBSD/FreeBSD.git] / testcode / testpkts.h
1 /*
2  * testpkts. Data file parse for test packets, and query matching.
3  *
4  * Data storage for specially crafted replies for testing purposes.
5  *
6  * (c) NLnet Labs, 2005, 2006, 2007
7  * See the file LICENSE for the license
8  */
9
10 #ifndef TESTPKTS_H
11 #define TESTPKTS_H
12 struct sldns_buffer;
13 struct sldns_file_parse_state;
14
15 /**
16  * \file
17  * 
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.
21  *
22  * You can specify a packet RR by RR with header flags to return.
23  *
24  * Missing features:
25  *              - matching content different from reply content.
26  *              - find way to adjust mangled packets?
27  *
28  */
29
30  /*
31         The data file format is as follows:
32         
33         ; comment.
34         ; a number of entries, these are processed first to last.
35         ; a line based format.
36
37         $ORIGIN origin
38         $TTL default_ttl
39
40         ENTRY_BEGIN
41         ; first give MATCH lines, that say what queries are matched
42         ; by this entry.
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         ; 'rcode' makes the query match the rcode from the reply
54         ; 'question' makes the query match the question section
55         ; 'answer' makes the query match the answer section
56         ; 'ednsdata' matches queries to HEX_EDNS section.
57         MATCH [opcode] [qtype] [qname] [serial=<value>] [all] [ttl]
58         MATCH [UDP|TCP] DO
59         MATCH ...
60         ; Then the REPLY header is specified.
61         REPLY opcode, rcode or flags.
62                 (opcode)  QUERY IQUERY STATUS NOTIFY UPDATE
63                 (rcode)   NOERROR FORMERR SERVFAIL NXDOMAIN NOTIMPL YXDOMAIN
64                                 YXRRSET NXRRSET NOTAUTH NOTZONE
65                 (flags)   QR AA TC RD CD RA AD DO
66         REPLY ...
67         ; any additional actions to do.
68         ; 'copy_id' copies the ID from the query to the answer.
69         ADJUST copy_id
70         ; 'copy_query' copies the query name, type and class to the answer.
71         ADJUST copy_query
72         ; 'sleep=10' sleeps for 10 seconds before giving the answer (TCP is open)
73         ADJUST [sleep=<num>]    ; sleep before giving any reply
74         ADJUST [packet_sleep=<num>]  ; sleep before this packet in sequence
75         SECTION QUESTION
76         <RRs, one per line>    ; the RRcount is determined automatically.
77         SECTION ANSWER
78         <RRs, one per line>
79         SECTION AUTHORITY
80         <RRs, one per line>
81         SECTION ADDITIONAL
82         <RRs, one per line>
83         EXTRA_PACKET            ; follow with SECTION, REPLY for more packets.
84         HEX_ANSWER_BEGIN        ; follow with hex data
85                                 ; this replaces any answer packet constructed
86                                 ; with the SECTION keywords (only SECTION QUERY
87                                 ; is used to match queries). If the data cannot
88                                 ; be parsed, ADJUST rules for the answer packet
89                                 ; are ignored. Only copy_id is done.
90         HEX_ANSWER_END
91         HEX_EDNS_BEGIN          ; follow with hex data.
92                                 ; Raw EDNS data to match against. It must be an 
93                                 ; exact match (all options are matched) and will be 
94                                 ; evaluated only when 'MATCH ednsdata' given.
95         HEX_EDNS_END
96         ENTRY_END
97
98
99         Example data file:
100 $ORIGIN nlnetlabs.nl
101 $TTL 3600
102
103 ENTRY_BEGIN
104 MATCH qname
105 REPLY NOERROR
106 ADJUST copy_id
107 SECTION QUESTION
108 www.nlnetlabs.nl.       IN      A
109 SECTION ANSWER
110 www.nlnetlabs.nl.       IN      A       195.169.215.155
111 SECTION AUTHORITY
112 nlnetlabs.nl.           IN      NS      www.nlnetlabs.nl.
113 ENTRY_END
114
115 ENTRY_BEGIN
116 MATCH qname
117 REPLY NOERROR
118 ADJUST copy_id
119 SECTION QUESTION
120 www2.nlnetlabs.nl.      IN      A
121 HEX_ANSWER_BEGIN
122 ; 0  1  2  3  4  5  6  7  8  9 10 11 12 13 14 15 16 17 18 19
123 ;-- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
124  00 bf 81 80 00 01 00 01 00 02 00 02 03 77 77 77 0b 6b 61 6e    ;          1-  20
125  61 72 69 65 70 69 65 74 03 63 6f 6d 00 00 01 00 01 03 77 77    ;         21-  40
126  77 0b 6b 61 6e 61 72 69 65 70 69 65 74 03 63 6f 6d 00 00 01    ;         41-  60
127  00 01 00 01 50 8b 00 04 52 5e ed 32 0b 6b 61 6e 61 72 69 65    ;         61-  80
128  70 69 65 74 03 63 6f 6d 00 00 02 00 01 00 01 50 8b 00 11 03    ;         81- 100
129  6e 73 31 08 68 65 78 6f 6e 2d 69 73 02 6e 6c 00 0b 6b 61 6e    ;        101- 120
130  61 72 69 65 70 69 65 74 03 63 6f 6d 00 00 02 00 01 00 01 50    ;        121- 140
131  8b 00 11 03 6e 73 32 08 68 65 78 6f 6e 2d 69 73 02 6e 6c 00    ;        141- 160
132  03 6e 73 31 08 68 65 78 6f 6e 2d 69 73 02 6e 6c 00 00 01 00    ;        161- 180
133  01 00 00 46 53 00 04 52 5e ed 02 03 6e 73 32 08 68 65 78 6f    ;        181- 200
134  6e 2d 69 73 02 6e 6c 00 00 01 00 01 00 00 46 53 00 04 d4 cc    ;        201- 220
135  db 5b
136 HEX_ANSWER_END
137 ENTRY_END
138
139
140
141    note that this file will link with your
142    void verbose(int level, char* format, ...); output function.
143 */
144
145 /** Type of transport, since some entries match based on UDP or TCP of query */
146 enum transport_type {transport_any = 0, transport_udp, transport_tcp };
147
148 /** struct to keep a linked list of reply packets for a query */
149 struct reply_packet {
150         /** next in list of reply packets, for TCP multiple pkts on wire */
151         struct reply_packet* next;
152         /** the reply pkt */
153         uint8_t* reply_pkt;
154         /** length of reply pkt */
155         size_t reply_len;
156         /** Additional EDNS data for matching queries. */
157         struct sldns_buffer* raw_ednsdata;
158         /** or reply pkt in hex if not parsable */
159         struct sldns_buffer* reply_from_hex;
160         /** seconds to sleep before giving packet */
161         unsigned int packet_sleep; 
162 };
163
164 /** data structure to keep the canned queries in.
165    format is the 'matching query' and the 'canned answer' */
166 struct entry {
167         /* match */
168         /* How to match an incoming query with this canned reply */
169         /** match query opcode with answer opcode */
170         uint8_t match_opcode; 
171         /** match qtype with answer qtype */
172         uint8_t match_qtype;  
173         /** match qname with answer qname */
174         uint8_t match_qname;  
175         /** match rcode with answer rcode */
176         uint8_t match_rcode;
177         /** match question section */
178         uint8_t match_question;
179         /** match answer section */
180         uint8_t match_answer;
181         /** match qname as subdomain of answer qname */
182         uint8_t match_subdomain;  
183         /** match SOA serial number, from auth section */
184         uint8_t match_serial; 
185         /** match all of the packet */
186         uint8_t match_all;
187         /** match ttls in the packet */
188         uint8_t match_ttl;
189         /** match DO bit */
190         uint8_t match_do;
191         /** match absence of EDNS OPT record in query */
192         uint8_t match_noedns;
193         /** match edns data field given in hex */
194         uint8_t match_ednsdata_raw;
195         /** match query serial with this value. */
196         uint32_t ixfr_soa_serial; 
197         /** match on UDP/TCP */
198         enum transport_type match_transport; 
199
200         /** pre canned reply */
201         struct reply_packet *reply_list;
202
203         /** how to adjust the reply packet */
204         /** copy over the ID from the query into the answer */
205         uint8_t copy_id; 
206         /** copy the query nametypeclass from query into the answer */
207         uint8_t copy_query;
208         /** copy ednsdata to reply, assume it is clientsubnet and
209          * adjust scopemask to match sourcemask */
210         uint8_t copy_ednsdata_assume_clientsubnet;
211         /** in seconds */
212         unsigned int sleeptime; 
213
214         /** some number that names this entry, line number in file or so */
215         int lineno;
216
217         /** next in list */
218         struct entry* next;
219 };
220
221 /**
222  * reads the canned reply file and returns a list of structs 
223  * does an exit on error.
224  * @param name: name of the file to read.
225  * @param skip_whitespace: skip leftside whitespace.
226  */
227 struct entry* read_datafile(const char* name, int skip_whitespace);
228
229 /**
230  * Delete linked list of entries.
231  */
232 void delete_entry(struct entry* list);
233
234 /**
235  * Read one entry from the data file.
236  * @param in: file to read from. Filepos must be at the start of a new line.
237  * @param name: name of the file for prettier errors.
238  * @param pstate: file parse state with lineno, default_ttl,
239  *      origin and prev_rr name.
240  * @param skip_whitespace: skip leftside whitespace.
241  * @return: The entry read (malloced) or NULL if no entry could be read.
242  */
243 struct entry* read_entry(FILE* in, const char* name, 
244         struct sldns_file_parse_state* pstate, int skip_whitespace);
245
246 /**
247  * finds entry in list, or returns NULL.
248  */
249 struct entry* find_match(struct entry* entries, uint8_t* query_pkt,
250         size_t query_pkt_len, enum transport_type transport);
251
252 /**
253  * match two packets, all must match
254  * @param q: packet 1
255  * @param qlen: length of q.
256  * @param p: packet 2
257  * @param plen: length of p.
258  * @param mttl: if true, ttls must match, if false, ttls do not need to match
259  * @param noloc: if true, rrs may be reordered in their packet-section.
260  *      rrs are then matches without location of the rr being important.
261  * @return true if matched.
262  */
263 int match_all(uint8_t* q, size_t qlen, uint8_t* p, size_t plen, int mttl,
264         int noloc);
265
266 /**
267  * copy & adjust packet, mallocs a copy.
268  */
269 void adjust_packet(struct entry* match, uint8_t** answer_pkt,
270         size_t* answer_pkt_len, uint8_t* query_pkt, size_t query_pkt_len);
271
272 /**
273  * Parses data buffer to a query, finds the correct answer 
274  * and calls the given function for every packet to send.
275  * if verbose_out filename is given, packets are dumped there.
276  * @param inbuf: the packet that came in
277  * @param inlen: length of packet.
278  * @param entries: entries read in from datafile.
279  * @param count: is increased to count number of queries answered.
280  * @param transport: set to UDP or TCP to match some types of entries.
281  * @param sendfunc: called to send answer (buffer, size, userarg).
282  * @param userdata: userarg to give to sendfunc.
283  * @param verbose_out: if not NULL, verbose messages are printed there.
284  */
285 void handle_query(uint8_t* inbuf, ssize_t inlen, struct entry* entries, 
286         int* count, enum transport_type transport, 
287         void (*sendfunc)(uint8_t*, size_t, void*), void* userdata,
288         FILE* verbose_out);
289
290 #endif /* TESTPKTS_H */