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_dnsparse_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 * A few common DNS types.
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_IXFR 251
45 #define GNUNET_DNSPARSER_TYPE_AXFR 252
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).
51 #define GNUNET_DNSPARSER_CLASS_INTERNET 1
52 #define GNUNET_DNSPARSER_CLASS_CHAOS 3
53 #define GNUNET_DNSPARSER_CLASS_HESIOD 4
55 #define GNUNET_DNSPARSER_OPCODE_QUERY 0
56 #define GNUNET_DNSPARSER_OPCODE_INVERSE_QUERY 1
57 #define GNUNET_DNSPARSER_OPCODE_STATUS 2
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
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
79 * DNS flags (largely RFC 1035 / RFC 2136).
81 struct GNUNET_DNSPARSER_Flags
84 * Set to 1 if recursion is desired (client -> server)
86 unsigned int recursion_desired : 1 GNUNET_PACKED;
89 * Set to 1 if message is truncated
91 unsigned int message_truncated : 1 GNUNET_PACKED;
94 * Set to 1 if this is an authoritative answer
96 unsigned int authoritative_answer : 1 GNUNET_PACKED;
99 * See GNUNET_DNSPARSER_OPCODE_ defines.
101 unsigned int opcode : 4 GNUNET_PACKED;
104 * query:0, response:1
106 unsigned int query_or_response : 1 GNUNET_PACKED;
109 * See GNUNET_DNSPARSER_RETURN_CODE_ defines.
111 unsigned int return_code : 4 GNUNET_PACKED;
116 unsigned int checking_disabled : 1 GNUNET_PACKED;
119 * Response has been cryptographically verified, RFC 4035.
121 unsigned int authenticated_data : 1 GNUNET_PACKED;
126 unsigned int zero : 1 GNUNET_PACKED;
129 * Set to 1 if recursion is available (server -> client)
131 unsigned int recursion_available : 1 GNUNET_PACKED;
139 struct GNUNET_DNSPARSER_Query
143 * Name of the record that the query is for (0-terminated).
148 * See GNUNET_DNSPARSER_TYPE_*.
153 * See GNUNET_DNSPARSER_CLASS_*.
161 * A DNS response record.
163 struct GNUNET_DNSPARSER_Record
167 * Name of the record that the query is for (0-terminated).
172 * Raw data, NOT a 0-terminated string (at least not always).
177 * Number of bytes in data.
182 * When does the record expire?
184 struct GNUNET_TIME_Absolute expiration_time;
187 * See GNUNET_DNSPARSER_TYPE_*.
192 * See GNUNET_DNSPARSER_CLASS_*.
200 * Easy-to-process, parsed version of a DNS packet.
202 struct GNUNET_DNSPARSER_Packet
205 * Array of all queries in the packet, must contain "num_queries" entries.
207 struct GNUNET_DNSPARSER_Query *queries;
210 * Array of all answers in the packet, must contain "num_answers" entries.
212 struct GNUNET_DNSPARSER_Record *answers;
215 * Array of all authority records in the packet, must contain "num_authority_records" entries.
217 struct GNUNET_DNSPARSER_Record *authority_records;
220 * Array of all additional answers in the packet, must contain "num_additional_records" entries.
222 struct GNUNET_DNSPARSER_Record *additional_records;
225 * Number of queries in the packet.
227 unsigned int num_queries;
230 * Number of answers in the packet, should be 0 for queries.
232 unsigned int num_answers;
235 * Number of authoritative answers in the packet, should be 0 for queries.
237 unsigned int num_authority_records;
240 * Number of additional records in the packet, should be 0 for queries.
242 unsigned int num_additional_records;
245 * Bitfield of DNS flags.
247 struct GNUNET_DNSPARSER_Flags flags;
250 * DNS ID (to match replies to requests).
258 * Parse a UDP payload of a DNS packet in to a nice struct for further
259 * processing and manipulation.
261 * @param udp_payload wire-format of the DNS packet
262 * @param udp_payload_length number of bytes in udp_payload
263 * @return NULL on error, otherwise the parsed packet
265 struct GNUNET_DNSPARSER_Packet *
266 GNUNET_DNSPARSER_parse (const char *udp_payload,
267 size_t udp_payload_length);
271 * Free memory taken by a packet.
273 * @param p packet to free
276 GNUNET_DNSPARSER_free_packet (struct GNUNET_DNSPARSER_Packet *p);
280 * Given a DNS packet, generate the corresponding UDP payload.
282 * @param p packet to pack
283 * @param buf set to a buffer with the packed message
284 * @param buf_length set to the length of buf
285 * @return GNUNET_SYSERR if 'p' is invalid
286 * GNUNET_NO if 'p' was truncated (but there is still a result in 'buf')
287 * GNUNET_OK if 'p' was packed completely into '*buf'
290 GNUNET_DNSPARSER_pack (struct GNUNET_DNSPARSER_Packet *p,
297 /* legacy API below */
300 GNUNET_NETWORK_STRUCT_BEGIN
304 uint16_t id GNUNET_PACKED;
306 unsigned rd:1 GNUNET_PACKED; // recursion desired (client -> server)
307 unsigned tc:1 GNUNET_PACKED; // message is truncated
308 unsigned aa:1 GNUNET_PACKED; // authoritative answer
309 unsigned op:4 GNUNET_PACKED; // query:0, inverse q.:1, status: 2
310 unsigned qr:1 GNUNET_PACKED; // query:0, response:1
312 unsigned rcode:4 GNUNET_PACKED; // 0 No error
318 unsigned z:3 GNUNET_PACKED; // reserved
319 unsigned ra:1 GNUNET_PACKED; // recursion available (server -> client)
321 uint16_t qdcount GNUNET_PACKED; // number of questions
322 uint16_t ancount GNUNET_PACKED; // number of answers
323 uint16_t nscount GNUNET_PACKED; // number of authority-records
324 uint16_t arcount GNUNET_PACKED; // number of additional records
326 GNUNET_NETWORK_STRUCT_END
332 unsigned char data[1];
335 struct dns_pkt_parsed
338 struct dns_query **queries;
339 struct dns_record **answers;
340 struct dns_record **nameservers;
341 struct dns_record **additional;
344 struct dns_query_line
353 unsigned char namelen;
358 struct dns_record_line
370 unsigned char namelen;
379 struct dns_pkt_parsed *
380 parse_dns_packet (struct dns_pkt *pkt);
383 unparse_dns_packet (struct dns_pkt_parsed *pkt);
386 free_parsed_dns_packet (struct dns_pkt_parsed *ppkt);