2 This file is part of GNUnet
3 (C) 2010, 2011, 2012 Christian Grothoff (and other contributing authors)
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.
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.
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.
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
27 #ifndef GNUNET_DNSPARSER_LIB_H
28 #define GNUNET_DNSPARSER_LIB_H
31 #include "gnunet_common.h"
34 * Maximum length of a label in DNS.
36 #define GNUNET_DNSPARSER_MAX_LABEL_LENGTH 63
39 * Maximum length of a name in DNS.
41 #define GNUNET_DNSPARSER_MAX_NAME_LENGTH 253
45 * A few common DNS types.
47 #define GNUNET_DNSPARSER_TYPE_A 1
48 #define GNUNET_DNSPARSER_TYPE_NS 2
49 #define GNUNET_DNSPARSER_TYPE_CNAME 5
50 #define GNUNET_DNSPARSER_TYPE_SOA 6
51 #define GNUNET_DNSPARSER_TYPE_PTR 12
52 #define GNUNET_DNSPARSER_TYPE_MX 15
53 #define GNUNET_DNSPARSER_TYPE_TXT 16
54 #define GNUNET_DNSPARSER_TYPE_AAAA 28
55 #define GNUNET_DNSPARSER_TYPE_SRV 33
56 #define GNUNET_DNSPARSER_TYPE_TLSA 52
59 * A few common DNS classes (ok, only one is common, but I list a
60 * couple more to make it clear what we're talking about here).
62 #define GNUNET_DNSPARSER_CLASS_INTERNET 1
63 #define GNUNET_DNSPARSER_CLASS_CHAOS 3
64 #define GNUNET_DNSPARSER_CLASS_HESIOD 4
66 #define GNUNET_DNSPARSER_OPCODE_QUERY 0
67 #define GNUNET_DNSPARSER_OPCODE_INVERSE_QUERY 1
68 #define GNUNET_DNSPARSER_OPCODE_STATUS 2
73 #define GNUNET_DNSPARSER_RETURN_CODE_NO_ERROR 0
74 #define GNUNET_DNSPARSER_RETURN_CODE_FORMAT_ERROR 1
75 #define GNUNET_DNSPARSER_RETURN_CODE_SERVER_FAILURE 2
76 #define GNUNET_DNSPARSER_RETURN_CODE_NAME_ERROR 3
77 #define GNUNET_DNSPARSER_RETURN_CODE_NOT_IMPLEMENTED 4
78 #define GNUNET_DNSPARSER_RETURN_CODE_REFUSED 5
83 #define GNUNET_DNSPARSER_RETURN_CODE_YXDOMAIN 6
84 #define GNUNET_DNSPARSER_RETURN_CODE_YXRRSET 7
85 #define GNUNET_DNSPARSER_RETURN_CODE_NXRRSET 8
86 #define GNUNET_DNSPARSER_RETURN_CODE_NOT_AUTH 9
87 #define GNUNET_DNSPARSER_RETURN_CODE_NOT_ZONE 10
90 * DNS flags (largely RFC 1035 / RFC 2136).
92 struct GNUNET_DNSPARSER_Flags
94 #if __BYTE_ORDER == __LITTLE_ENDIAN
96 * Set to 1 if recursion is desired (client -> server)
98 unsigned int recursion_desired : 1 GNUNET_PACKED;
101 * Set to 1 if message is truncated
103 unsigned int message_truncated : 1 GNUNET_PACKED;
106 * Set to 1 if this is an authoritative answer
108 unsigned int authoritative_answer : 1 GNUNET_PACKED;
111 * See GNUNET_DNSPARSER_OPCODE_ defines.
113 unsigned int opcode : 4 GNUNET_PACKED;
116 * query:0, response:1
118 unsigned int query_or_response : 1 GNUNET_PACKED;
121 * See GNUNET_DNSPARSER_RETURN_CODE_ defines.
123 unsigned int return_code : 4 GNUNET_PACKED;
128 unsigned int checking_disabled : 1 GNUNET_PACKED;
131 * Response has been cryptographically verified, RFC 4035.
133 unsigned int authenticated_data : 1 GNUNET_PACKED;
138 unsigned int zero : 1 GNUNET_PACKED;
141 * Set to 1 if recursion is available (server -> client)
143 unsigned int recursion_available : 1 GNUNET_PACKED;
144 #elif __BYTE_ORDER == __BIG_ENDIAN
147 * query:0, response:1
149 unsigned int query_or_response : 1 GNUNET_PACKED;
152 * See GNUNET_DNSPARSER_OPCODE_ defines.
154 unsigned int opcode : 4 GNUNET_PACKED;
157 * Set to 1 if this is an authoritative answer
159 unsigned int authoritative_answer : 1 GNUNET_PACKED;
162 * Set to 1 if message is truncated
164 unsigned int message_truncated : 1 GNUNET_PACKED;
167 * Set to 1 if recursion is desired (client -> server)
169 unsigned int recursion_desired : 1 GNUNET_PACKED;
173 * Set to 1 if recursion is available (server -> client)
175 unsigned int recursion_available : 1 GNUNET_PACKED;
180 unsigned int zero : 1 GNUNET_PACKED;
183 * Response has been cryptographically verified, RFC 4035.
185 unsigned int authenticated_data : 1 GNUNET_PACKED;
190 unsigned int checking_disabled : 1 GNUNET_PACKED;
193 * See GNUNET_DNSPARSER_RETURN_CODE_ defines.
195 unsigned int return_code : 4 GNUNET_PACKED;
197 #error byteorder undefined
200 } GNUNET_GCC_STRUCT_LAYOUT;
206 struct GNUNET_DNSPARSER_Query
210 * Name of the record that the query is for (0-terminated).
211 * In UTF-8 format. The library will convert from and to DNS-IDNA
212 * as necessary. Use 'GNUNET_DNSPARSER_check_label' to test if an
213 * individual label is well-formed. If a given name is not well-formed,
214 * creating the DNS packet will fail.
219 * See GNUNET_DNSPARSER_TYPE_*.
224 * See GNUNET_DNSPARSER_CLASS_*.
232 * Information from MX records (RFC 1035).
234 struct GNUNET_DNSPARSER_MxRecord
238 * Preference for this entry (lower value is higher preference).
243 * Name of the mail server.
244 * In UTF-8 format. The library will convert from and to DNS-IDNA
245 * as necessary. Use 'GNUNET_DNSPARSER_check_label' to test if an
246 * individual label is well-formed. If a given name is not well-formed,
247 * creating the DNS packet will fail.
255 * Information from SRV records (RFC 2782). The 'service', 'proto'
256 * and 'domain_name' fields together give the DNS-name which for SRV
257 * records is of the form "_$SERVICE._$PROTO.$DOMAIN_NAME". The DNS
258 * parser provides the full name in 'struct DNSPARSER_Record' and the
259 * individual components in the respective fields of this struct.
260 * When serializing, you CAN set the 'name' field of 'struct
261 * GNUNET_DNSPARSER_Record' to NULL, in which case the DNSPARSER code
262 * will populate 'name' from the 'service', 'proto' and 'domain_name'
263 * fields in this struct.
265 struct GNUNET_DNSPARSER_SrvRecord
269 * Service name without the underscore (!). Note that RFC 6335 clarifies the
270 * set of legal characters for service names.
271 * In UTF-8 format. The library will convert from and to DNS-IDNA
272 * as necessary. Use 'GNUNET_DNSPARSER_check_label' to test if an
273 * individual label is well-formed. If a given name is not well-formed,
274 * creating the DNS packet will fail.
279 * Transport protocol (typcially "tcp" or "udp", but others might be allowed).
280 * Without the underscore (!).
285 * Domain name for which the record is valid
286 * In UTF-8 format. The library will convert from and to DNS-IDNA
287 * as necessary. Use 'GNUNET_DNSPARSER_check_label' to test if an
288 * individual label is well-formed. If a given name is not well-formed,
289 * creating the DNS packet will fail.
294 * Hostname offering the service.
295 * In UTF-8 format. The library will convert from and to DNS-IDNA
296 * as necessary. Use 'GNUNET_DNSPARSER_check_label' to test if an
297 * individual label is well-formed. If a given name is not well-formed,
298 * creating the DNS packet will fail.
303 * Preference for this entry (lower value is higher preference). Clients
304 * will contact hosts from the lowest-priority group first and fall back
305 * to higher priorities if the low-priority entries are unavailable.
310 * Relative weight for records with the same priority. Clients will use
311 * the hosts of the same (lowest) priority with a probability proportional
312 * to the weight given.
317 * TCP or UDP port of the service.
325 * Information from SOA records (RFC 1035).
327 struct GNUNET_DNSPARSER_SoaRecord
331 *The domainname of the name server that was the
332 * original or primary source of data for this zone.
333 * In UTF-8 format. The library will convert from and to DNS-IDNA
334 * as necessary. Use 'GNUNET_DNSPARSER_check_label' to test if an
335 * individual label is well-formed. If a given name is not well-formed,
336 * creating the DNS packet will fail.
341 * A domainname which specifies the mailbox of the
342 * person responsible for this zone.
343 * In UTF-8 format. The library will convert from and to DNS-IDNA
344 * as necessary. Use 'GNUNET_DNSPARSER_check_label' to test if an
345 * individual label is well-formed. If a given name is not well-formed,
346 * creating the DNS packet will fail.
351 * The version number of the original copy of the zone.
356 * Time interval before the zone should be refreshed.
361 * Time interval that should elapse before a failed refresh should
367 * Time value that specifies the upper limit on the time interval
368 * that can elapse before the zone is no longer authoritative.
373 * The bit minimum TTL field that should be exported with any RR
376 uint32_t minimum_ttl;
382 * Binary record information (unparsed).
384 struct GNUNET_DNSPARSER_RawRecord
388 * Binary record data.
393 * Number of bytes in data.
400 * A DNS response record.
402 struct GNUNET_DNSPARSER_Record
406 * Name of the record that the query is for (0-terminated).
407 * In UTF-8 format. The library will convert from and to DNS-IDNA
408 * as necessary. Use 'GNUNET_DNSPARSER_check_label' to test if an
409 * individual label is well-formed. If a given name is not well-formed,
410 * creating the DNS packet will fail.
415 * Payload of the record (which one of these is valid depends on the 'type').
421 * For NS, CNAME and PTR records, this is the uncompressed 0-terminated hostname.
422 * In UTF-8 format. The library will convert from and to DNS-IDNA
423 * as necessary. Use 'GNUNET_DNSPARSER_check_label' to test if an
424 * individual label is well-formed. If a given name is not well-formed,
425 * creating the DNS packet will fail.
430 * SOA data for SOA records.
432 struct GNUNET_DNSPARSER_SoaRecord *soa;
435 * MX data for MX records.
437 struct GNUNET_DNSPARSER_MxRecord *mx;
440 * SRV data for SRV records.
442 struct GNUNET_DNSPARSER_SrvRecord *srv;
445 * Raw data for all other types.
447 struct GNUNET_DNSPARSER_RawRecord raw;
453 * When does the record expire?
455 struct GNUNET_TIME_Absolute expiration_time;
458 * See GNUNET_DNSPARSER_TYPE_*.
463 * See GNUNET_DNSPARSER_CLASS_*.
471 * Easy-to-process, parsed version of a DNS packet.
473 struct GNUNET_DNSPARSER_Packet
476 * Array of all queries in the packet, must contain "num_queries" entries.
478 struct GNUNET_DNSPARSER_Query *queries;
481 * Array of all answers in the packet, must contain "num_answers" entries.
483 struct GNUNET_DNSPARSER_Record *answers;
486 * Array of all authority records in the packet, must contain "num_authority_records" entries.
488 struct GNUNET_DNSPARSER_Record *authority_records;
491 * Array of all additional answers in the packet, must contain "num_additional_records" entries.
493 struct GNUNET_DNSPARSER_Record *additional_records;
496 * Number of queries in the packet.
498 unsigned int num_queries;
501 * Number of answers in the packet, should be 0 for queries.
503 unsigned int num_answers;
506 * Number of authoritative answers in the packet, should be 0 for queries.
508 unsigned int num_authority_records;
511 * Number of additional records in the packet, should be 0 for queries.
513 unsigned int num_additional_records;
516 * Bitfield of DNS flags.
518 struct GNUNET_DNSPARSER_Flags flags;
521 * DNS ID (to match replies to requests).
529 * Check if a label in UTF-8 format can be coded into valid IDNA.
530 * This can fail if the ASCII-conversion becomes longer than 63 characters.
532 * @param label label to check (UTF-8 string)
533 * @return GNUNET_OK if the label can be converted to IDNA,
534 * GNUNET_SYSERR if the label is not valid for DNS names
537 GNUNET_DNSPARSER_check_label (const char *label);
541 * Check if a hostname in UTF-8 format can be coded into valid IDNA.
542 * This can fail if a label becomes longer than 63 characters or if
543 * the entire name exceeds 253 characters.
545 * @param name name to check (UTF-8 string)
546 * @return GNUNET_OK if the label can be converted to IDNA,
547 * GNUNET_SYSERR if the label is not valid for DNS names
550 GNUNET_DNSPARSER_check_name (const char *name);
554 * Parse a UDP payload of a DNS packet in to a nice struct for further
555 * processing and manipulation.
557 * @param udp_payload wire-format of the DNS packet
558 * @param udp_payload_length number of bytes in udp_payload
559 * @return NULL on error, otherwise the parsed packet
561 struct GNUNET_DNSPARSER_Packet *
562 GNUNET_DNSPARSER_parse (const char *udp_payload,
563 size_t udp_payload_length);
567 * Free memory taken by a packet.
569 * @param p packet to free
572 GNUNET_DNSPARSER_free_packet (struct GNUNET_DNSPARSER_Packet *p);
576 * Given a DNS packet, generate the corresponding UDP payload.
578 * @param p packet to pack
579 * @param max maximum allowed size for the resulting UDP payload
580 * @param buf set to a buffer with the packed message
581 * @param buf_length set to the length of buf
582 * @return GNUNET_SYSERR if 'p' is invalid
583 * GNUNET_NO if 'p' was truncated (but there is still a result in 'buf')
584 * GNUNET_OK if 'p' was packed completely into '*buf'
587 GNUNET_DNSPARSER_pack (const struct GNUNET_DNSPARSER_Packet *p,