fix #5734
[oweals/gnunet.git] / src / include / gnunet_dnsparser_lib.h
1 /*
2       This file is part of GNUnet
3       Copyright (C) 2010-2014 GNUnet e.V.
4
5       GNUnet is free software: you can redistribute it and/or modify it
6       under the terms of the GNU Affero General Public License as published
7       by the Free Software Foundation, either version 3 of the License,
8       or (at your 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       Affero General Public License for more details.
14
15       You should have received a copy of the GNU Affero General Public License
16       along with this program.  If not, see <http://www.gnu.org/licenses/>.
17
18      SPDX-License-Identifier: AGPL3.0-or-later
19  */
20
21 /**
22  * @author Philipp Toelke
23  * @author Christian Grothoff
24  *
25  * @file
26  * API for helper library to parse DNS packets.
27  *
28  * @defgroup dns-parser  DNS parser library
29  * Helper library to parse DNS packets.
30  * @{
31  */
32 #ifndef GNUNET_DNSPARSER_LIB_H
33 #define GNUNET_DNSPARSER_LIB_H
34
35 #include "gnunet_util_lib.h"
36
37 /**
38  * Maximum length of a label in DNS.
39  */
40 #define GNUNET_DNSPARSER_MAX_LABEL_LENGTH 63
41
42 /**
43  * Maximum length of a name in DNS.
44  */
45 #define GNUNET_DNSPARSER_MAX_NAME_LENGTH 253
46
47
48 /**
49  * A few common DNS types.
50  */
51 #define GNUNET_DNSPARSER_TYPE_ANY 0
52 #define GNUNET_DNSPARSER_TYPE_A 1
53 #define GNUNET_DNSPARSER_TYPE_NS 2
54 #define GNUNET_DNSPARSER_TYPE_CNAME 5
55 #define GNUNET_DNSPARSER_TYPE_SOA 6
56 #define GNUNET_DNSPARSER_TYPE_PTR 12
57 #define GNUNET_DNSPARSER_TYPE_MX 15
58 #define GNUNET_DNSPARSER_TYPE_TXT 16
59 #define GNUNET_DNSPARSER_TYPE_RP 17
60 #define GNUNET_DNSPARSER_TYPE_AFSDB 18
61 #define GNUNET_DNSPARSER_TYPE_SIG 24
62 #define GNUNET_DNSPARSER_TYPE_KEY 25
63 #define GNUNET_DNSPARSER_TYPE_AAAA 28
64 #define GNUNET_DNSPARSER_TYPE_LOC 29
65 #define GNUNET_DNSPARSER_TYPE_SRV 33
66 #define GNUNET_DNSPARSER_TYPE_NAPTR 35
67 #define GNUNET_DNSPARSER_TYPE_KX 36
68 #define GNUNET_DNSPARSER_TYPE_CERT 37
69 #define GNUNET_DNSPARSER_TYPE_DNAME 39
70 #define GNUNET_DNSPARSER_TYPE_APL 42
71 #define GNUNET_DNSPARSER_TYPE_DS 43
72 #define GNUNET_DNSPARSER_TYPE_SSHFP 44
73 #define GNUNET_DNSPARSER_TYPE_IPSECKEY 45
74 #define GNUNET_DNSPARSER_TYPE_RRSIG 46
75 #define GNUNET_DNSPARSER_TYPE_NSEC 47
76 #define GNUNET_DNSPARSER_TYPE_DNSKEY 48
77 #define GNUNET_DNSPARSER_TYPE_DHCID 49
78 #define GNUNET_DNSPARSER_TYPE_NSEC3 50
79 #define GNUNET_DNSPARSER_TYPE_NSEC3PARAM 51
80 #define GNUNET_DNSPARSER_TYPE_TLSA 52
81 #define GNUNET_DNSPARSER_TYPE_HIP 55
82 #define GNUNET_DNSPARSER_TYPE_CDS 59
83 #define GNUNET_DNSPARSER_TYPE_CDNSKEY 60
84 #define GNUNET_DNSPARSER_TYPE_OPENPGPKEY 61
85 #define GNUNET_DNSPARSER_TYPE_TKEY 249
86 #define GNUNET_DNSPARSER_TYPE_TSIG 250
87 #define GNUNET_DNSPARSER_TYPE_ALL 255
88 #define GNUNET_DNSPARSER_TYPE_URI 256
89 #define GNUNET_DNSPARSER_TYPE_CAA 257
90 #define GNUNET_DNSPARSER_TYPE_TA 32768
91
92 /**
93  * A DNS query.
94  */
95 struct GNUNET_DNSPARSER_Query
96 {
97
98   /**
99    * Name of the record that the query is for (0-terminated).
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.
104    */
105   char *name;
106
107   /**
108    * See GNUNET_DNSPARSER_TYPE_*.
109    */
110   uint16_t type;
111
112   /**
113    * See GNUNET_TUN_DNS_CLASS_*.
114    */
115   uint16_t dns_traffic_class;
116
117 };
118
119
120 /**
121  * Information from MX records (RFC 1035).
122  */
123 struct GNUNET_DNSPARSER_MxRecord
124 {
125
126   /**
127    * Preference for this entry (lower value is higher preference).
128    */
129   uint16_t preference;
130
131   /**
132    * Name of the mail server.
133    * In UTF-8 format.  The library will convert from and to DNS-IDNA
134    * as necessary.  Use #GNUNET_DNSPARSER_check_label() to test if an
135    * individual label is well-formed.  If a given name is not well-formed,
136    * creating the DNS packet will fail.
137    */
138   char *mxhost;
139
140 };
141
142
143 /**
144  * Information from SRV records (RFC 2782).
145  */
146 struct GNUNET_DNSPARSER_SrvRecord
147 {
148
149   /**
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.
155    */
156   char *target;
157
158   /**
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.
162    */
163   uint16_t priority;
164
165   /**
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.
169    */
170   uint16_t weight;
171
172   /**
173    * TCP or UDP port of the service.
174    */
175   uint16_t port;
176
177 };
178
179
180 /**
181  * DNS CERT types as defined in RFC 4398.
182  */
183 enum GNUNET_DNSPARSER_CertType
184 {
185   /**
186    *  Reserved value
187    */
188   GNUNET_DNSPARSER_CERTTYPE_RESERVED = 0,
189
190   /**
191    * An x509 PKIX certificate
192    */
193   GNUNET_DNSPARSER_CERTTYPE_PKIX = 1,
194
195   /**
196    * A SKPI certificate
197    */
198   GNUNET_DNSPARSER_CERTTYPE_SKPI = 2,
199
200   /**
201    * A PGP certificate
202    */
203   GNUNET_DNSPARSER_CERTTYPE_PGP = 3,
204
205   /**
206    * An x509 PKIX cert URL
207    */
208   GNUNET_DNSPARSER_CERTTYPE_IPKIX = 4,
209
210   /**
211    * A SKPI cert URL
212    */
213   GNUNET_DNSPARSER_CERTTYPE_ISKPI = 5,
214
215   /**
216    * A PGP cert fingerprint and URL
217    */
218   GNUNET_DNSPARSER_CERTTYPE_IPGP = 6,
219
220   /**
221    * An attribute Certificate
222    */
223   GNUNET_DNSPARSER_CERTTYPE_ACPKIX = 7,
224
225   /**
226    * An attribute cert URL
227    */
228   GNUNET_DNSPARSER_CERTTYPE_IACKPIX = 8
229 };
230
231
232 /**
233  * DNSCERT algorithms as defined in http://www.iana.org/assignments/
234  *  dns-sec-alg-numbers/dns-sec-alg-numbers.xhtml, under dns-sec-alg-numbers-1
235  */
236 enum GNUNET_DNSPARSER_CertAlgorithm
237 {
238   /**
239    * No defined
240    */
241   GNUNET_DNSPARSER_CERTALGO_UNDEFINED = 0,
242
243   /**
244    * RSA/MD5
245    */
246   GNUNET_DNSPARSER_CERTALGO_RSAMD5 = 1,
247
248   /**
249    * Diffie-Hellman
250    */
251   GNUNET_DNSPARSER_CERTALGO_DH = 2,
252
253   /**
254    * DSA/SHA1
255    */
256   GNUNET_DNSPARSER_CERTALGO_DSASHA = 3,
257
258   /**
259    * Reserved
260    */
261   GNUNET_DNSPARSER_CERTALGO_RSRVD4 = 4,
262
263   /**
264    * RSA/SHA1
265    */
266   GNUNET_DNSPARSER_CERTALGO_RSASHA = 5,
267
268   /**
269    * DSA/NSEC3/SHA
270    */
271   GNUNET_DNSPARSER_CERTALGO_DSANSEC3 = 6,
272
273   /**
274    * RSA/NSEC3/SHA
275    */
276   GNUNET_DNSPARSER_CERTALGO_RSANSEC3 = 7,
277
278   /**
279    * RSA/SHA256
280    */
281   GNUNET_DNSPARSER_CERTALGO_RSASHA256 = 8,
282
283   /**
284    * Reserved
285    */
286   GNUNET_DNSPARSER_CERTALGO_RSRVD9 = 9,
287
288   /**
289    * RSA/SHA512
290    */
291   GNUNET_DNSPARSER_CERTALGO_RSASHA512 = 10,
292
293   /**
294    * GOST R 34.10-2001
295    */
296   GNUNET_DNSPARSER_CERTALGO_GOST_R34 = 12,
297
298   /**
299    * ECDSA Curve P-256/SHA256
300    */
301   GNUNET_DNSPARSER_CERTALGO_ECDSA_P256SHA256 = 13,
302
303   /**
304    * ECDSA Curve P-384/SHA384
305    */
306   GNUNET_DNSPARSER_CERTALGO_ECDSA_P384SHA384 = 14
307
308 };
309
310
311 /**
312  * Information from CERT records (RFC 4034).
313  */
314 struct GNUNET_DNSPARSER_CertRecord
315 {
316
317   /**
318    * Certificate type
319    */
320   enum GNUNET_DNSPARSER_CertType cert_type;
321
322   /**
323    * Certificate KeyTag
324    */
325   uint16_t cert_tag;
326
327   /**
328    * Algorithm
329    */
330   enum GNUNET_DNSPARSER_CertAlgorithm algorithm;
331
332   /**
333    * Number of bytes in @e certificate_data
334    */
335   size_t certificate_size;
336
337   /**
338    * Data of the certificate.
339    */
340   char *certificate_data;
341
342 };
343
344
345 /**
346  * Information from SOA records (RFC 1035).
347  */
348 struct GNUNET_DNSPARSER_SoaRecord
349 {
350
351   /**
352    * The domainname of the name server that was the
353    * original or primary source of data for this zone.
354    * In UTF-8 format.  The library will convert from and to DNS-IDNA
355    * as necessary.  Use #GNUNET_DNSPARSER_check_label() to test if an
356    * individual label is well-formed.  If a given name is not well-formed,
357    * creating the DNS packet will fail.
358    */
359   char *mname;
360
361   /**
362    * A domainname which specifies the mailbox of the
363    * person responsible for this zone.
364    * In UTF-8 format.  The library will convert from and to DNS-IDNA
365    * as necessary.  Use #GNUNET_DNSPARSER_check_label() to test if an
366    * individual label is well-formed.  If a given name is not well-formed,
367    * creating the DNS packet will fail.
368    */
369   char *rname;
370
371   /**
372    * The version number of the original copy of the zone.
373    */
374   uint32_t serial;
375
376   /**
377    * Time interval before the zone should be refreshed.
378    */
379   uint32_t refresh;
380
381   /**
382    * Time interval that should elapse before a failed refresh should
383    * be retried.
384    */
385   uint32_t retry;
386
387   /**
388    * Time value that specifies the upper limit on the time interval
389    * that can elapse before the zone is no longer authoritative.
390    */
391   uint32_t expire;
392
393   /**
394    * The bit minimum TTL field that should be exported with any RR
395    * from this zone.
396    */
397   uint32_t minimum_ttl;
398
399 };
400
401
402 /**
403  * Information from CAA records (RFC 6844).
404  * The tag is followed by the tag_len.
405  * The value is followed by the tag for (d - tag_len - 2) bytes
406  */
407 struct GNUNET_DNSPARSER_CaaRecord
408 {
409   /**
410    * The flags of the CAA record.
411    */
412   uint8_t flags;
413
414   /**
415    * The length of the tag.
416    */
417   uint8_t tag_len;
418 };
419
420
421
422 /**
423  * Binary record information (unparsed).
424  */
425 struct GNUNET_DNSPARSER_RawRecord
426 {
427
428   /**
429    * Binary record data.
430    */
431   void *data;
432
433   /**
434    * Number of bytes in data.
435    */
436   size_t data_len;
437 };
438
439
440 /**
441  * A DNS response record.
442  */
443 struct GNUNET_DNSPARSER_Record
444 {
445
446   /**
447    * Name of the record that the query is for (0-terminated).
448    * In UTF-8 format.  The library will convert from and to DNS-IDNA
449    * as necessary.  Use #GNUNET_DNSPARSER_check_label() to test if an
450    * individual label is well-formed.  If a given name is not well-formed,
451    * creating the DNS packet will fail.
452    */
453   char *name;
454
455   /**
456    * Payload of the record (which one of these is valid depends on the 'type').
457    */
458   union
459   {
460
461     /**
462      * For NS, CNAME and PTR records, this is the uncompressed 0-terminated hostname.
463      * In UTF-8 format.  The library will convert from and to DNS-IDNA
464      * as necessary.  Use #GNUNET_DNSPARSER_check_label() to test if an
465      * individual label is well-formed.  If a given name is not well-formed,
466      * creating the DNS packet will fail.
467      */
468     char *hostname;
469
470     /**
471      * SOA data for SOA records.
472      */
473     struct GNUNET_DNSPARSER_SoaRecord *soa;
474
475     /**
476      * CERT data for CERT records.
477      */
478     struct GNUNET_DNSPARSER_CertRecord *cert;
479
480     /**
481      * MX data for MX records.
482      */
483     struct GNUNET_DNSPARSER_MxRecord *mx;
484
485     /**
486      * SRV data for SRV records.
487      */
488     struct GNUNET_DNSPARSER_SrvRecord *srv;
489
490     /**
491      * Raw data for all other types.
492      */
493     struct GNUNET_DNSPARSER_RawRecord raw;
494
495   } data;
496
497
498   /**
499    * When does the record expire?
500    */
501   struct GNUNET_TIME_Absolute expiration_time;
502
503   /**
504    * See GNUNET_DNSPARSER_TYPE_*.
505    */
506   uint16_t type;
507
508   /**
509    * See GNUNET_TUN_DNS_CLASS_*.
510    */
511   uint16_t dns_traffic_class;
512
513 };
514
515
516 /**
517  * Easy-to-process, parsed version of a DNS packet.
518  */
519 struct GNUNET_DNSPARSER_Packet
520 {
521   /**
522    * Array of all queries in the packet, must contain "num_queries" entries.
523    */
524   struct GNUNET_DNSPARSER_Query *queries;
525
526   /**
527    * Array of all answers in the packet, must contain "num_answers" entries.
528    */
529   struct GNUNET_DNSPARSER_Record *answers;
530
531   /**
532    * Array of all authority records in the packet, must contain "num_authority_records" entries.
533    */
534   struct GNUNET_DNSPARSER_Record *authority_records;
535
536   /**
537    * Array of all additional answers in the packet, must contain "num_additional_records" entries.
538    */
539   struct GNUNET_DNSPARSER_Record *additional_records;
540
541   /**
542    * Number of queries in the packet.
543    */
544   unsigned int num_queries;
545
546   /**
547    * Number of answers in the packet, should be 0 for queries.
548    */
549   unsigned int num_answers;
550
551   /**
552    * Number of authoritative answers in the packet, should be 0 for queries.
553    */
554   unsigned int num_authority_records;
555
556   /**
557    * Number of additional records in the packet, should be 0 for queries.
558    */
559   unsigned int num_additional_records;
560
561   /**
562    * Bitfield of DNS flags.
563    */
564   struct GNUNET_TUN_DnsFlags flags;
565
566   /**
567    * DNS ID (to match replies to requests).
568    */
569   uint16_t id;
570
571 };
572
573
574 /**
575  * Check if a label in UTF-8 format can be coded into valid IDNA.
576  * This can fail if the ASCII-conversion becomes longer than 63 characters.
577  *
578  * @param label label to check (UTF-8 string)
579  * @return #GNUNET_OK if the label can be converted to IDNA,
580  *         #GNUNET_SYSERR if the label is not valid for DNS names
581  */
582 int
583 GNUNET_DNSPARSER_check_label (const char *label);
584
585
586 /**
587  * Check if a hostname in UTF-8 format can be coded into valid IDNA.
588  * This can fail if a label becomes longer than 63 characters or if
589  * the entire name exceeds 253 characters.
590  *
591  * @param name name to check (UTF-8 string)
592  * @return #GNUNET_OK if the label can be converted to IDNA,
593  *         #GNUNET_SYSERR if the label is not valid for DNS names
594  */
595 int
596 GNUNET_DNSPARSER_check_name (const char *name);
597
598
599 /**
600  * Parse a UDP payload of a DNS packet in to a nice struct for further
601  * processing and manipulation.
602  *
603  * @param udp_payload wire-format of the DNS packet
604  * @param udp_payload_length number of bytes in @a udp_payload
605  * @return NULL on error, otherwise the parsed packet
606  */
607 struct GNUNET_DNSPARSER_Packet *
608 GNUNET_DNSPARSER_parse (const char *udp_payload,
609                         size_t udp_payload_length);
610
611
612 /**
613  * Free memory taken by a packet.
614  *
615  * @param p packet to free
616  */
617 void
618 GNUNET_DNSPARSER_free_packet (struct GNUNET_DNSPARSER_Packet *p);
619
620
621 /**
622  * Given a DNS packet @a p, generate the corresponding UDP payload.
623  * Note that we do not attempt to pack the strings with pointers
624  * as this would complicate the code and this is about being
625  * simple and secure, not fast, fancy and broken like bind.
626  *
627  * @param p packet to pack
628  * @param max maximum allowed size for the resulting UDP payload
629  * @param buf set to a buffer with the packed message
630  * @param buf_length set to the length of @a buf
631  * @return #GNUNET_SYSERR if @a p is invalid
632  *         #GNUNET_NO if @a p was truncated (but there is still a result in @a buf)
633  *         #GNUNET_OK if @a p was packed completely into @a buf
634  */
635 int
636 GNUNET_DNSPARSER_pack (const struct GNUNET_DNSPARSER_Packet *p,
637                        uint16_t max,
638                        char **buf,
639                        size_t *buf_length);
640
641 /* ***************** low-level packing API ******************** */
642
643 /**
644  * Add a DNS name to the UDP packet at the given location, converting
645  * the name to IDNA notation as necessary.
646  *
647  * @param dst where to write the name (UDP packet)
648  * @param dst_len number of bytes in @a dst
649  * @param off pointer to offset where to write the name (increment by bytes used)
650  *            must not be changed if there is an error
651  * @param name name to write
652  * @return #GNUNET_SYSERR if @a name is invalid
653  *         #GNUNET_NO if @a name did not fit
654  *         #GNUNET_OK if @a name was added to @a dst
655  */
656 int
657 GNUNET_DNSPARSER_builder_add_name (char *dst,
658                                    size_t dst_len,
659                                    size_t *off,
660                                    const char *name);
661
662
663 /**
664  * Add a DNS query to the UDP packet at the given location.
665  *
666  * @param dst where to write the query
667  * @param dst_len number of bytes in @a dst
668  * @param off pointer to offset where to write the query (increment by bytes used)
669  *            must not be changed if there is an error
670  * @param query query to write
671  * @return #GNUNET_SYSERR if @a query is invalid
672  *         #GNUNET_NO if @a query did not fit
673  *         #GNUNET_OK if @a query was added to @a dst
674  */
675 int
676 GNUNET_DNSPARSER_builder_add_query (char *dst,
677                                     size_t dst_len,
678                                     size_t *off,
679                                     const struct GNUNET_DNSPARSER_Query *query);
680
681
682 /**
683  * Add an MX record to the UDP packet at the given location.
684  *
685  * @param dst where to write the mx record
686  * @param dst_len number of bytes in @a dst
687  * @param off pointer to offset where to write the mx information (increment by bytes used);
688  *            can also change if there was an error
689  * @param mx mx information to write
690  * @return #GNUNET_SYSERR if @a mx is invalid
691  *         #GNUNET_NO if @a mx did not fit
692  *         #GNUNET_OK if @a mx was added to @a dst
693  */
694 int
695 GNUNET_DNSPARSER_builder_add_mx (char *dst,
696                                  size_t dst_len,
697                                  size_t *off,
698                                  const struct GNUNET_DNSPARSER_MxRecord *mx);
699
700
701 /**
702  * Add an SOA record to the UDP packet at the given location.
703  *
704  * @param dst where to write the SOA record
705  * @param dst_len number of bytes in @a dst
706  * @param off pointer to offset where to write the SOA information (increment by bytes used)
707  *            can also change if there was an error
708  * @param soa SOA information to write
709  * @return #GNUNET_SYSERR if @a soa is invalid
710  *         #GNUNET_NO if @a soa did not fit
711  *         #GNUNET_OK if @a soa was added to @a dst
712  */
713 int
714 GNUNET_DNSPARSER_builder_add_soa (char *dst,
715                                   size_t dst_len,
716                                   size_t *off,
717                                   const struct GNUNET_DNSPARSER_SoaRecord *soa);
718
719
720 /**
721  * Add CERT record to the UDP packet at the given location.
722  *
723  * @param dst where to write the CERT record
724  * @param dst_len number of bytes in @a dst
725  * @param off pointer to offset where to write the CERT information (increment by bytes used)
726  *            can also change if there was an error
727  * @param cert CERT information to write
728  * @return #GNUNET_SYSERR if @a soa is invalid
729  *         #GNUNET_NO if @a soa did not fit
730  *         #GNUNET_OK if @a soa was added to @a dst
731  */
732 int
733 GNUNET_DNSPARSER_builder_add_cert (char *dst,
734                                    size_t dst_len,
735                                    size_t *off,
736                                    const struct GNUNET_DNSPARSER_CertRecord *cert);
737
738
739 /**
740  * Add an SRV record to the UDP packet at the given location.
741  *
742  * @param dst where to write the SRV record
743  * @param dst_len number of bytes in @a dst
744  * @param off pointer to offset where to write the SRV information (increment by bytes used)
745  *            can also change if there was an error
746  * @param srv SRV information to write
747  * @return #GNUNET_SYSERR if @a srv is invalid
748  *         #GNUNET_NO if @a srv did not fit
749  *         #GNUNET_OK if @a srv was added to @a dst
750  */
751 int
752 GNUNET_DNSPARSER_builder_add_srv (char *dst,
753                                   size_t dst_len,
754                                   size_t *off,
755                                   const struct GNUNET_DNSPARSER_SrvRecord *srv);
756
757 /* ***************** low-level parsing API ******************** */
758
759 /**
760  * Parse a DNS record entry.
761  *
762  * @param udp_payload entire UDP payload
763  * @param udp_payload_length length of @a udp_payload
764  * @param off pointer to the offset of the record to parse in the udp_payload (to be
765  *                    incremented by the size of the record)
766  * @param r where to write the record information
767  * @return #GNUNET_OK on success, #GNUNET_SYSERR if the record is malformed
768  */
769 int
770 GNUNET_DNSPARSER_parse_record (const char *udp_payload,
771                                size_t udp_payload_length,
772                                size_t *off,
773                                struct GNUNET_DNSPARSER_Record *r);
774
775
776 /**
777  * Parse name inside of a DNS query or record.
778  *
779  * @param udp_payload entire UDP payload
780  * @param udp_payload_length length of @a udp_payload
781  * @param off pointer to the offset of the name to parse in the udp_payload (to be
782  *                    incremented by the size of the name)
783  * @return name as 0-terminated C string on success, NULL if the payload is malformed
784  */
785 char *
786 GNUNET_DNSPARSER_parse_name (const char *udp_payload,
787                              size_t udp_payload_length,
788                              size_t *off);
789
790
791 /**
792  * Parse a DNS query entry.
793  *
794  * @param udp_payload entire UDP payload
795  * @param udp_payload_length length of @a udp_payload
796  * @param off pointer to the offset of the query to parse in the udp_payload (to be
797  *                    incremented by the size of the query)
798  * @param q where to write the query information
799  * @return #GNUNET_OK on success, #GNUNET_SYSERR if the query is malformed
800  */
801 int
802 GNUNET_DNSPARSER_parse_query (const char *udp_payload,
803                               size_t udp_payload_length,
804                               size_t *off,
805                               struct GNUNET_DNSPARSER_Query *q);
806
807
808 /**
809  * Parse a DNS SOA record.
810  *
811  * @param udp_payload reference to UDP packet
812  * @param udp_payload_length length of @a udp_payload
813  * @param off pointer to the offset of the query to parse in the SOA record (to be
814  *                    incremented by the size of the record), unchanged on error
815  * @return the parsed SOA record, NULL on error
816  */
817 struct GNUNET_DNSPARSER_SoaRecord *
818 GNUNET_DNSPARSER_parse_soa (const char *udp_payload,
819                             size_t udp_payload_length,
820                             size_t *off);
821
822
823 /**
824  * Parse a DNS CERT record.
825  *
826  * @param udp_payload reference to UDP packet
827  * @param udp_payload_length length of @a udp_payload
828  * @param off pointer to the offset of the query to parse in the CERT record (to be
829  *                    incremented by the size of the record), unchanged on error
830  * @return the parsed CERT record, NULL on error
831  */
832 struct GNUNET_DNSPARSER_CertRecord *
833 GNUNET_DNSPARSER_parse_cert (const char *udp_payload,
834                              size_t udp_payload_length,
835                              size_t *off);
836
837
838 /**
839  * Parse a DNS MX record.
840  *
841  * @param udp_payload reference to UDP packet
842  * @param udp_payload_length length of @a udp_payload
843  * @param off pointer to the offset of the query to parse in the MX record (to be
844  *                    incremented by the size of the record), unchanged on error
845  * @return the parsed MX record, NULL on error
846  */
847 struct GNUNET_DNSPARSER_MxRecord *
848 GNUNET_DNSPARSER_parse_mx (const char *udp_payload,
849                            size_t udp_payload_length,
850                            size_t *off);
851
852
853 /**
854  * Parse a DNS SRV record.
855  *
856  * @param udp_payload reference to UDP packet
857  * @param udp_payload_length length of @a udp_payload
858  * @param off pointer to the offset of the query to parse in the SRV record (to be
859  *                    incremented by the size of the record), unchanged on error
860  * @return the parsed SRV record, NULL on error
861  */
862 struct GNUNET_DNSPARSER_SrvRecord *
863 GNUNET_DNSPARSER_parse_srv (const char *udp_payload,
864                             size_t udp_payload_length,
865                             size_t *off);
866
867 /* ***************** low-level duplication API ******************** */
868
869 /**
870  * Duplicate (deep-copy) the given DNS record
871  *
872  * @param r the record
873  * @return the newly allocated record
874  */
875 struct GNUNET_DNSPARSER_Record *
876 GNUNET_DNSPARSER_duplicate_record (const struct GNUNET_DNSPARSER_Record *r);
877
878
879 /**
880  * Duplicate (deep-copy) the given DNS record
881  *
882  * @param r the record
883  * @return the newly allocated record
884  */
885 struct GNUNET_DNSPARSER_SoaRecord *
886 GNUNET_DNSPARSER_duplicate_soa_record (const struct GNUNET_DNSPARSER_SoaRecord *r);
887
888
889 /**
890  * Duplicate (deep-copy) the given DNS record
891  *
892  * @param r the record
893  * @return the newly allocated record
894  */
895 struct GNUNET_DNSPARSER_CertRecord *
896 GNUNET_DNSPARSER_duplicate_cert_record (const struct GNUNET_DNSPARSER_CertRecord *r);
897
898
899 /**
900  * Duplicate (deep-copy) the given DNS record
901  *
902  * @param r the record
903  * @return the newly allocated record
904  */
905 struct GNUNET_DNSPARSER_MxRecord *
906 GNUNET_DNSPARSER_duplicate_mx_record (const struct GNUNET_DNSPARSER_MxRecord *r);
907
908
909 /**
910  * Duplicate (deep-copy) the given DNS record
911  *
912  * @param r the record
913  * @return the newly allocated record
914  */
915 struct GNUNET_DNSPARSER_SrvRecord *
916 GNUNET_DNSPARSER_duplicate_srv_record (const struct GNUNET_DNSPARSER_SrvRecord *r);
917
918
919 /* ***************** low-level deallocation API ******************** */
920
921 /**
922  * Free the given DNS record.
923  *
924  * @param r record to free
925  */
926 void
927 GNUNET_DNSPARSER_free_record (struct GNUNET_DNSPARSER_Record *r);
928
929
930 /**
931  * Free MX information record.
932  *
933  * @param mx record to free
934  */
935 void
936 GNUNET_DNSPARSER_free_mx (struct GNUNET_DNSPARSER_MxRecord *mx);
937
938
939 /**
940  * Free SRV information record.
941  *
942  * @param srv record to free
943  */
944 void
945 GNUNET_DNSPARSER_free_srv (struct GNUNET_DNSPARSER_SrvRecord *srv);
946
947
948 /**
949  * Free SOA information record.
950  *
951  * @param soa record to free
952  */
953 void
954 GNUNET_DNSPARSER_free_soa (struct GNUNET_DNSPARSER_SoaRecord *soa);
955
956
957 /**
958  * Free CERT information record.
959  *
960  * @param cert record to free
961  */
962 void
963 GNUNET_DNSPARSER_free_cert (struct GNUNET_DNSPARSER_CertRecord *cert);
964
965
966 /**
967  * Convert a block of binary data to HEX.
968  *
969  * @param data binary data to convert
970  * @param data_size number of bytes in @a data
971  * @return HEX string (lower case)
972  */
973 char *
974 GNUNET_DNSPARSER_bin_to_hex (const void *data,
975                              size_t data_size);
976
977
978 /**
979  * Convert a HEX string to block of binary data.
980  *
981  * @param hex HEX string to convert (may contain mixed case)
982  * @param data where to write result, must be
983  *             at least `strlen(hex)/2` bytes long
984  * @return number of bytes written to data
985  */
986 size_t
987 GNUNET_DNSPARSER_hex_to_bin (const char *hex,
988                              void *data);
989
990
991 #endif
992
993 /** @} */  /* end of group */