gnunet_dnsparser_lib.h 25 KB

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