2 This file is part of GNUnet
3 (C) 2010-2013 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
30 #include "gnunet_common.h"
31 #include "gnunet_tun_lib.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
62 struct GNUNET_DNSPARSER_Query
66 * Name of the record that the query is for (0-terminated).
67 * In UTF-8 format. The library will convert from and to DNS-IDNA
68 * as necessary. Use 'GNUNET_DNSPARSER_check_label' to test if an
69 * individual label is well-formed. If a given name is not well-formed,
70 * creating the DNS packet will fail.
75 * See GNUNET_DNSPARSER_TYPE_*.
80 * See GNUNET_TUN_DNS_CLASS_*.
88 * Information from MX records (RFC 1035).
90 struct GNUNET_DNSPARSER_MxRecord
94 * Preference for this entry (lower value is higher preference).
99 * Name of the mail server.
100 * In UTF-8 format. The library will convert from and to DNS-IDNA
101 * as necessary. Use 'GNUNET_DNSPARSER_check_label' to test if an
102 * individual label is well-formed. If a given name is not well-formed,
103 * creating the DNS packet will fail.
111 * Information from SRV records (RFC 2782). The 'service', 'proto'
112 * and 'domain_name' fields together give the DNS-name which for SRV
113 * records is of the form "_$SERVICE._$PROTO.$DOMAIN_NAME". The DNS
114 * parser provides the full name in 'struct DNSPARSER_Record' and the
115 * individual components in the respective fields of this struct.
116 * When serializing, you CAN set the 'name' field of 'struct
117 * GNUNET_DNSPARSER_Record' to NULL, in which case the DNSPARSER code
118 * will populate 'name' from the 'service', 'proto' and 'domain_name'
119 * fields in this struct.
121 struct GNUNET_DNSPARSER_SrvRecord
125 * Service name without the underscore (!). Note that RFC 6335 clarifies the
126 * set of legal characters for service names.
127 * In UTF-8 format. The library will convert from and to DNS-IDNA
128 * as necessary. Use 'GNUNET_DNSPARSER_check_label' to test if an
129 * individual label is well-formed. If a given name is not well-formed,
130 * creating the DNS packet will fail.
135 * Transport protocol (typcially "tcp" or "udp", but others might be allowed).
136 * Without the underscore (!).
141 * Domain name for which the record is valid
142 * In UTF-8 format. The library will convert from and to DNS-IDNA
143 * as necessary. Use 'GNUNET_DNSPARSER_check_label' to test if an
144 * individual label is well-formed. If a given name is not well-formed,
145 * creating the DNS packet will fail.
150 * Hostname offering the service.
151 * In UTF-8 format. The library will convert from and to DNS-IDNA
152 * as necessary. Use 'GNUNET_DNSPARSER_check_label' to test if an
153 * individual label is well-formed. If a given name is not well-formed,
154 * creating the DNS packet will fail.
159 * Preference for this entry (lower value is higher preference). Clients
160 * will contact hosts from the lowest-priority group first and fall back
161 * to higher priorities if the low-priority entries are unavailable.
166 * Relative weight for records with the same priority. Clients will use
167 * the hosts of the same (lowest) priority with a probability proportional
168 * to the weight given.
173 * TCP or UDP port of the service.
181 * Information from SOA records (RFC 1035).
183 struct GNUNET_DNSPARSER_SoaRecord
187 *The domainname of the name server that was the
188 * original or primary source of data for this zone.
189 * In UTF-8 format. The library will convert from and to DNS-IDNA
190 * as necessary. Use 'GNUNET_DNSPARSER_check_label' to test if an
191 * individual label is well-formed. If a given name is not well-formed,
192 * creating the DNS packet will fail.
197 * A domainname which specifies the mailbox of the
198 * person responsible for this zone.
199 * In UTF-8 format. The library will convert from and to DNS-IDNA
200 * as necessary. Use 'GNUNET_DNSPARSER_check_label' to test if an
201 * individual label is well-formed. If a given name is not well-formed,
202 * creating the DNS packet will fail.
207 * The version number of the original copy of the zone.
212 * Time interval before the zone should be refreshed.
217 * Time interval that should elapse before a failed refresh should
223 * Time value that specifies the upper limit on the time interval
224 * that can elapse before the zone is no longer authoritative.
229 * The bit minimum TTL field that should be exported with any RR
232 uint32_t minimum_ttl;
238 * Binary record information (unparsed).
240 struct GNUNET_DNSPARSER_RawRecord
244 * Binary record data.
249 * Number of bytes in data.
256 * A DNS response record.
258 struct GNUNET_DNSPARSER_Record
262 * Name of the record that the query is for (0-terminated).
263 * In UTF-8 format. The library will convert from and to DNS-IDNA
264 * as necessary. Use #GNUNET_DNSPARSER_check_label to test if an
265 * individual label is well-formed. If a given name is not well-formed,
266 * creating the DNS packet will fail.
271 * Payload of the record (which one of these is valid depends on the 'type').
277 * For NS, CNAME and PTR records, this is the uncompressed 0-terminated hostname.
278 * In UTF-8 format. The library will convert from and to DNS-IDNA
279 * as necessary. Use #GNUNET_DNSPARSER_check_label to test if an
280 * individual label is well-formed. If a given name is not well-formed,
281 * creating the DNS packet will fail.
286 * SOA data for SOA records.
288 struct GNUNET_DNSPARSER_SoaRecord *soa;
291 * MX data for MX records.
293 struct GNUNET_DNSPARSER_MxRecord *mx;
296 * SRV data for SRV records.
298 struct GNUNET_DNSPARSER_SrvRecord *srv;
301 * Raw data for all other types.
303 struct GNUNET_DNSPARSER_RawRecord raw;
309 * When does the record expire?
311 struct GNUNET_TIME_Absolute expiration_time;
314 * See GNUNET_DNSPARSER_TYPE_*.
319 * See GNUNET_TUN_DNS_CLASS_*.
327 * Easy-to-process, parsed version of a DNS packet.
329 struct GNUNET_DNSPARSER_Packet
332 * Array of all queries in the packet, must contain "num_queries" entries.
334 struct GNUNET_DNSPARSER_Query *queries;
337 * Array of all answers in the packet, must contain "num_answers" entries.
339 struct GNUNET_DNSPARSER_Record *answers;
342 * Array of all authority records in the packet, must contain "num_authority_records" entries.
344 struct GNUNET_DNSPARSER_Record *authority_records;
347 * Array of all additional answers in the packet, must contain "num_additional_records" entries.
349 struct GNUNET_DNSPARSER_Record *additional_records;
352 * Number of queries in the packet.
354 unsigned int num_queries;
357 * Number of answers in the packet, should be 0 for queries.
359 unsigned int num_answers;
362 * Number of authoritative answers in the packet, should be 0 for queries.
364 unsigned int num_authority_records;
367 * Number of additional records in the packet, should be 0 for queries.
369 unsigned int num_additional_records;
372 * Bitfield of DNS flags.
374 struct GNUNET_TUN_DnsFlags flags;
377 * DNS ID (to match replies to requests).
385 * Check if a label in UTF-8 format can be coded into valid IDNA.
386 * This can fail if the ASCII-conversion becomes longer than 63 characters.
388 * @param label label to check (UTF-8 string)
389 * @return GNUNET_OK if the label can be converted to IDNA,
390 * GNUNET_SYSERR if the label is not valid for DNS names
393 GNUNET_DNSPARSER_check_label (const char *label);
397 * Check if a hostname in UTF-8 format can be coded into valid IDNA.
398 * This can fail if a label becomes longer than 63 characters or if
399 * the entire name exceeds 253 characters.
401 * @param name name to check (UTF-8 string)
402 * @return GNUNET_OK if the label can be converted to IDNA,
403 * GNUNET_SYSERR if the label is not valid for DNS names
406 GNUNET_DNSPARSER_check_name (const char *name);
410 * Parse a UDP payload of a DNS packet in to a nice struct for further
411 * processing and manipulation.
413 * @param udp_payload wire-format of the DNS packet
414 * @param udp_payload_length number of bytes in udp_payload
415 * @return NULL on error, otherwise the parsed packet
417 struct GNUNET_DNSPARSER_Packet *
418 GNUNET_DNSPARSER_parse (const char *udp_payload,
419 size_t udp_payload_length);
423 * Free memory taken by a packet.
425 * @param p packet to free
428 GNUNET_DNSPARSER_free_packet (struct GNUNET_DNSPARSER_Packet *p);
432 * Given a DNS packet, generate the corresponding UDP payload.
434 * @param p packet to pack
435 * @param max maximum allowed size for the resulting UDP payload
436 * @param buf set to a buffer with the packed message
437 * @param buf_length set to the length of buf
438 * @return GNUNET_SYSERR if 'p' is invalid
439 * GNUNET_NO if 'p' was truncated (but there is still a result in 'buf')
440 * GNUNET_OK if 'p' was packed completely into '*buf'
443 GNUNET_DNSPARSER_pack (const struct GNUNET_DNSPARSER_Packet *p,