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