extend API to enalbe exclusive port ranges to be specified for testing-system objects
[oweals/gnunet.git] / src / include / gnunet_dnsparser_lib.h
1 /*
2       This file is part of GNUnet
3       (C) 2010, 2011, 2012 Christian Grothoff (and other contributing authors)
4
5       GNUnet is free software; you can redistribute it and/or modify
6       it under the terms of the GNU General Public License as published
7       by the Free Software Foundation; either version 2, or (at your
8       option) any later version.
9
10       GNUnet is distributed in the hope that it will be useful, but
11       WITHOUT ANY WARRANTY; without even the implied warranty of
12       MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
13       General Public License for more details.
14
15       You should have received a copy of the GNU General Public License
16       along with GNUnet; see the file COPYING.  If not, write to the
17       Free Software Foundation, Inc., 59 Temple Place - Suite 330,
18       Boston, MA 02111-1307, USA.
19  */
20
21 /**
22  * @file include/gnunet_dnsparser_lib.h
23  * @brief API for helper library to parse DNS packets. 
24  * @author Philipp Toelke
25  * @author Christian Grothoff
26  */
27 #ifndef GNUNET_DNSPARSER_LIB_H
28 #define GNUNET_DNSPARSER_LIB_H
29
30 #include "platform.h"
31 #include "gnunet_common.h"
32
33 /**
34  * A few common DNS types.
35  */
36 #define GNUNET_DNSPARSER_TYPE_A 1
37 #define GNUNET_DNSPARSER_TYPE_NS 2
38 #define GNUNET_DNSPARSER_TYPE_CNAME 5
39 #define GNUNET_DNSPARSER_TYPE_SOA 6
40 #define GNUNET_DNSPARSER_TYPE_PTR 12
41 #define GNUNET_DNSPARSER_TYPE_MX 15
42 #define GNUNET_DNSPARSER_TYPE_TXT 16
43 #define GNUNET_DNSPARSER_TYPE_AAAA 28
44 #define GNUNET_DNSPARSER_TYPE_SRV 33
45 #define GNUNET_DNSPARSER_TYPE_TLSA 52
46
47 /**
48  * A few common DNS classes (ok, only one is common, but I list a
49  * couple more to make it clear what we're talking about here).
50  */
51 #define GNUNET_DNSPARSER_CLASS_INTERNET 1
52 #define GNUNET_DNSPARSER_CLASS_CHAOS 3
53 #define GNUNET_DNSPARSER_CLASS_HESIOD 4
54
55 #define GNUNET_DNSPARSER_OPCODE_QUERY 0
56 #define GNUNET_DNSPARSER_OPCODE_INVERSE_QUERY 1
57 #define GNUNET_DNSPARSER_OPCODE_STATUS 2
58
59 /**
60  * RFC 1035 codes.
61  */
62 #define GNUNET_DNSPARSER_RETURN_CODE_NO_ERROR 0
63 #define GNUNET_DNSPARSER_RETURN_CODE_FORMAT_ERROR 1
64 #define GNUNET_DNSPARSER_RETURN_CODE_SERVER_FAILURE 2
65 #define GNUNET_DNSPARSER_RETURN_CODE_NAME_ERROR 3
66 #define GNUNET_DNSPARSER_RETURN_CODE_NOT_IMPLEMENTED 4
67 #define GNUNET_DNSPARSER_RETURN_CODE_REFUSED 5
68
69 /**
70  * RFC 2136 codes
71  */
72 #define GNUNET_DNSPARSER_RETURN_CODE_YXDOMAIN 6
73 #define GNUNET_DNSPARSER_RETURN_CODE_YXRRSET 7
74 #define GNUNET_DNSPARSER_RETURN_CODE_NXRRSET 8
75 #define GNUNET_DNSPARSER_RETURN_CODE_NOT_AUTH 9
76 #define GNUNET_DNSPARSER_RETURN_CODE_NOT_ZONE 10
77
78 /**
79  * DNS flags (largely RFC 1035 / RFC 2136).
80  */
81 struct GNUNET_DNSPARSER_Flags
82 {
83 #if __BYTE_ORDER == __LITTLE_ENDIAN
84   /**
85    * Set to 1 if recursion is desired (client -> server)
86    */
87   unsigned int recursion_desired    : 1 GNUNET_PACKED;  
88   
89   /**
90    * Set to 1 if message is truncated
91    */
92   unsigned int message_truncated    : 1 GNUNET_PACKED; 
93   
94   /**
95    * Set to 1 if this is an authoritative answer
96    */
97   unsigned int authoritative_answer : 1 GNUNET_PACKED;
98   
99   /**
100    * See GNUNET_DNSPARSER_OPCODE_ defines.
101    */
102   unsigned int opcode               : 4 GNUNET_PACKED;  
103   
104   /**
105    * query:0, response:1
106    */
107   unsigned int query_or_response    : 1 GNUNET_PACKED;  
108   
109   /**
110    * See GNUNET_DNSPARSER_RETURN_CODE_ defines.
111    */
112   unsigned int return_code          : 4 GNUNET_PACKED; 
113   
114   /**
115    * See RFC 4035.
116    */
117   unsigned int checking_disabled    : 1 GNUNET_PACKED; 
118   
119   /**
120    * Response has been cryptographically verified, RFC 4035.
121    */
122   unsigned int authenticated_data   : 1 GNUNET_PACKED;
123   
124   /**
125    * Always zero.
126    */
127   unsigned int zero                 : 1 GNUNET_PACKED;
128   
129   /**
130    * Set to 1 if recursion is available (server -> client)
131    */
132   unsigned int recursion_available  : 1 GNUNET_PACKED; 
133 #elif __BYTE_ORDER == __BIG_ENDIAN
134   
135   /**
136    * query:0, response:1
137    */
138   unsigned int query_or_response    : 1 GNUNET_PACKED;  
139   
140   /**
141    * See GNUNET_DNSPARSER_OPCODE_ defines.
142    */
143   unsigned int opcode               : 4 GNUNET_PACKED;  
144   
145   /**
146    * Set to 1 if this is an authoritative answer
147    */
148   unsigned int authoritative_answer : 1 GNUNET_PACKED;
149   
150   /**
151    * Set to 1 if message is truncated
152    */
153   unsigned int message_truncated    : 1 GNUNET_PACKED; 
154   
155   /**
156    * Set to 1 if recursion is desired (client -> server)
157    */
158   unsigned int recursion_desired    : 1 GNUNET_PACKED;  
159
160  
161   /**
162    * Set to 1 if recursion is available (server -> client)
163    */
164   unsigned int recursion_available  : 1 GNUNET_PACKED;
165   
166   /**
167    * Always zero.
168    */
169   unsigned int zero                 : 1 GNUNET_PACKED;
170   
171   /**
172    * Response has been cryptographically verified, RFC 4035.
173    */
174   unsigned int authenticated_data   : 1 GNUNET_PACKED;
175   
176   /**
177    * See RFC 4035.
178    */
179   unsigned int checking_disabled    : 1 GNUNET_PACKED; 
180   
181   /**
182    * See GNUNET_DNSPARSER_RETURN_CODE_ defines.
183    */  
184   unsigned int return_code          : 4 GNUNET_PACKED; 
185 #else
186   #error byteorder undefined
187 #endif
188   
189 } GNUNET_GCC_STRUCT_LAYOUT;
190
191
192 /**
193  * A DNS query.
194  */
195 struct GNUNET_DNSPARSER_Query
196 {
197
198   /**
199    * Name of the record that the query is for (0-terminated).
200    */
201   char *name;
202
203   /**
204    * See GNUNET_DNSPARSER_TYPE_*.
205    */
206   uint16_t type;
207
208   /**
209    * See GNUNET_DNSPARSER_CLASS_*.
210    */
211   uint16_t class;
212
213 };
214
215
216 /**
217  * Information from MX records (RFC 1035).
218  */
219 struct GNUNET_DNSPARSER_MxRecord
220 {
221   
222   /**
223    * Preference for this entry (lower value is higher preference).
224    */
225   uint16_t preference;
226
227   /**
228    * Name of the mail server.
229    */
230   char *mxhost;
231
232 };
233
234
235 /**
236  * Information from SRV records (RFC 2782).  The 'service', 'proto'
237  * and 'domain_name' fields together give the DNS-name which for SRV
238  * records is of the form "_$SERVICE._$PROTO.$DOMAIN_NAME".  The DNS
239  * parser provides the full name in 'struct DNSPARSER_Record' and the
240  * individual components in the respective fields of this struct.
241  * When serializing, you CAN set the 'name' field of 'struct
242  * GNUNET_DNSPARSER_Record' to NULL, in which case the DNSPARSER code
243  * will populate 'name' from the 'service', 'proto' and 'domain_name'
244  * fields in this struct.
245  */
246 struct GNUNET_DNSPARSER_SrvRecord
247 {
248   
249   /**
250    * Service name without the underscore (!).  Note that RFC 6335 clarifies the
251    * set of legal characters for service names.
252    */
253   char *service;
254
255   /**
256    * Transport protocol (typcially "tcp" or "udp", but others might be allowed).
257    * Without the underscore (!).
258    */
259   char *proto;
260
261   /**
262    * Domain name for which the record is valid
263    */
264   char *domain_name;
265
266   /**
267    * Hostname offering the service.
268    */
269   char *target;
270
271   /**
272    * Preference for this entry (lower value is higher preference).  Clients
273    * will contact hosts from the lowest-priority group first and fall back
274    * to higher priorities if the low-priority entries are unavailable.
275    */
276   uint16_t priority;
277
278   /**
279    * Relative weight for records with the same priority.  Clients will use
280    * the hosts of the same (lowest) priority with a probability proportional
281    * to the weight given.
282    */
283   uint16_t weight;
284
285   /**
286    * TCP or UDP port of the service.
287    */
288   uint16_t port;
289
290 };
291
292   
293 /**
294  * Information from SOA records (RFC 1035).
295  */
296 struct GNUNET_DNSPARSER_SoaRecord
297 {
298   
299   /**
300    *The domainname of the name server that was the
301    * original or primary source of data for this zone.
302    */
303   char *mname;
304
305   /**
306    * A domainname which specifies the mailbox of the
307    * person responsible for this zone.
308    */
309   char *rname;
310
311   /**
312    * The version number of the original copy of the zone.  
313    */
314   uint32_t serial;
315
316   /**
317    * Time interval before the zone should be refreshed.
318    */
319   uint32_t refresh;
320
321   /**
322    * Time interval that should elapse before a failed refresh should
323    * be retried.
324    */
325   uint32_t retry;
326
327   /**
328    * Time value that specifies the upper limit on the time interval
329    * that can elapse before the zone is no longer authoritative.
330    */
331   uint32_t expire;
332
333   /**
334    * The bit minimum TTL field that should be exported with any RR
335    * from this zone.
336    */
337   uint32_t minimum_ttl;
338   
339 };
340
341
342 /**
343  * Binary record information (unparsed).
344  */
345 struct GNUNET_DNSPARSER_RawRecord
346 {
347
348   /**
349    * Binary record data.
350    */
351   void *data;
352
353   /**
354    * Number of bytes in data.
355    */
356   size_t data_len;
357 };
358
359
360 /**
361  * A DNS response record.
362  */
363 struct GNUNET_DNSPARSER_Record
364 {
365
366   /**
367    * Name of the record that the query is for (0-terminated).
368    */
369   char *name;
370
371   /**
372    * Payload of the record (which one of these is valid depends on the 'type').
373    */
374   union 
375   {
376
377     /**
378      * For NS, CNAME and PTR records, this is the uncompressed 0-terminated hostname.
379      */
380     char *hostname;
381     
382     /**
383      * SOA data for SOA records.
384      */
385     struct GNUNET_DNSPARSER_SoaRecord *soa;
386     
387     /**
388      * MX data for MX records.
389      */
390     struct GNUNET_DNSPARSER_MxRecord *mx;
391
392     /**
393      * SRV data for SRV records.
394      */
395     struct GNUNET_DNSPARSER_SrvRecord *srv;
396
397     /**
398      * Raw data for all other types.
399      */
400     struct GNUNET_DNSPARSER_RawRecord raw;
401
402   } data;
403
404
405   /**
406    * When does the record expire?
407    */
408   struct GNUNET_TIME_Absolute expiration_time;
409
410   /**
411    * See GNUNET_DNSPARSER_TYPE_*.
412    */
413   uint16_t type;
414
415   /**
416    * See GNUNET_DNSPARSER_CLASS_*.
417    */
418   uint16_t class;
419
420 };
421
422
423 /**
424  * Easy-to-process, parsed version of a DNS packet.
425  */
426 struct GNUNET_DNSPARSER_Packet
427 {
428   /**
429    * Array of all queries in the packet, must contain "num_queries" entries.
430    */
431   struct GNUNET_DNSPARSER_Query *queries;
432
433   /**
434    * Array of all answers in the packet, must contain "num_answers" entries.
435    */
436   struct GNUNET_DNSPARSER_Record *answers;
437
438   /**
439    * Array of all authority records in the packet, must contain "num_authority_records" entries.
440    */
441   struct GNUNET_DNSPARSER_Record *authority_records;
442
443   /**
444    * Array of all additional answers in the packet, must contain "num_additional_records" entries.
445    */
446   struct GNUNET_DNSPARSER_Record *additional_records;
447
448   /**
449    * Number of queries in the packet.
450    */
451   unsigned int num_queries;
452
453   /**
454    * Number of answers in the packet, should be 0 for queries.
455    */
456   unsigned int num_answers;
457
458   /**
459    * Number of authoritative answers in the packet, should be 0 for queries.
460    */
461   unsigned int num_authority_records;
462
463   /**
464    * Number of additional records in the packet, should be 0 for queries.
465    */
466   unsigned int num_additional_records;
467
468   /**
469    * Bitfield of DNS flags.
470    */ 
471   struct GNUNET_DNSPARSER_Flags flags;
472
473   /**
474    * DNS ID (to match replies to requests).
475    */
476   uint16_t id;
477
478 };
479
480
481 /**
482  * Parse a UDP payload of a DNS packet in to a nice struct for further
483  * processing and manipulation.
484  *
485  * @param udp_payload wire-format of the DNS packet
486  * @param udp_payload_length number of bytes in udp_payload 
487  * @return NULL on error, otherwise the parsed packet
488  */
489 struct GNUNET_DNSPARSER_Packet *
490 GNUNET_DNSPARSER_parse (const char *udp_payload,
491                         size_t udp_payload_length);
492
493
494 /**
495  * Free memory taken by a packet.
496  *
497  * @param p packet to free
498  */
499 void
500 GNUNET_DNSPARSER_free_packet (struct GNUNET_DNSPARSER_Packet *p);
501
502
503 /**
504  * Given a DNS packet, generate the corresponding UDP payload.
505  *
506  * @param p packet to pack
507  * @param max maximum allowed size for the resulting UDP payload
508  * @param buf set to a buffer with the packed message
509  * @param buf_length set to the length of buf
510  * @return GNUNET_SYSERR if 'p' is invalid
511  *         GNUNET_NO if 'p' was truncated (but there is still a result in 'buf')
512  *         GNUNET_OK if 'p' was packed completely into '*buf'
513  */
514 int
515 GNUNET_DNSPARSER_pack (const struct GNUNET_DNSPARSER_Packet *p,
516                        uint16_t max,
517                        char **buf,
518                        size_t *buf_length);
519
520
521 #endif