*/
/**
- * @file include/gnunet_dnsparse_lib.h
+ * @file include/gnunet_dnsparser_lib.h
* @brief API for helper library to parse DNS packets.
* @author Philipp Toelke
+ * @author Christian Grothoff
*/
#ifndef GNUNET_DNSPARSER_LIB_H
#define GNUNET_DNSPARSER_LIB_H
#define GNUNET_DNSPARSER_TYPE_MX 15
#define GNUNET_DNSPARSER_TYPE_TXT 16
#define GNUNET_DNSPARSER_TYPE_AAAA 28
-#define GNUNET_DNSPARSER_TYPE_IXFR 251
-#define GNUNET_DNSPARSER_TYPE_AXFR 252
+#define GNUNET_DNSPARSER_TYPE_SRV 33
/**
* A few common DNS classes (ok, only one is common, but I list a
*/
struct GNUNET_DNSPARSER_Flags
{
+#if __BYTE_ORDER == __LITTLE_ENDIAN
/**
* Set to 1 if recursion is desired (client -> server)
*/
* Set to 1 if recursion is available (server -> client)
*/
unsigned int recursion_available : 1 GNUNET_PACKED;
+#elif __BYTE_ORDER == __BIG_ENDIAN
-};
+ /**
+ * query:0, response:1
+ */
+ unsigned int query_or_response : 1 GNUNET_PACKED;
+
+ /**
+ * See GNUNET_DNSPARSER_OPCODE_ defines.
+ */
+ unsigned int opcode : 4 GNUNET_PACKED;
+
+ /**
+ * Set to 1 if this is an authoritative answer
+ */
+ unsigned int authoritative_answer : 1 GNUNET_PACKED;
+
+ /**
+ * Set to 1 if message is truncated
+ */
+ unsigned int message_truncated : 1 GNUNET_PACKED;
+
+ /**
+ * Set to 1 if recursion is desired (client -> server)
+ */
+ unsigned int recursion_desired : 1 GNUNET_PACKED;
+
+
+ /**
+ * Set to 1 if recursion is available (server -> client)
+ */
+ unsigned int recursion_available : 1 GNUNET_PACKED;
+
+ /**
+ * Always zero.
+ */
+ unsigned int zero : 1 GNUNET_PACKED;
+
+ /**
+ * Response has been cryptographically verified, RFC 4035.
+ */
+ unsigned int authenticated_data : 1 GNUNET_PACKED;
+
+ /**
+ * See RFC 4035.
+ */
+ unsigned int checking_disabled : 1 GNUNET_PACKED;
+
+ /**
+ * See GNUNET_DNSPARSER_RETURN_CODE_ defines.
+ */
+ unsigned int return_code : 4 GNUNET_PACKED;
+#else
+ #error byteorder undefined
+#endif
+
+} GNUNET_GCC_STRUCT_LAYOUT;
/**
/**
- * A DNS response record.
+ * Information from MX records (RFC 1035).
*/
-struct GNUNET_DNSPARSER_Record
+struct GNUNET_DNSPARSER_MxRecord
{
+
+ /**
+ * Preference for this entry (lower value is higher preference).
+ */
+ uint16_t preference;
/**
- * Name of the record that the query is for (0-terminated).
+ * Name of the mail server.
*/
- char *name;
+ char *mxhost;
+
+};
+
+
+/**
+ * Information from SRV records (RFC 2782). The 'service', 'proto'
+ * and 'domain_name' fields together give the DNS-name which for SRV
+ * records is of the form "_$SERVICE._$PROTO.$DOMAIN_NAME". The DNS
+ * parser provides the full name in 'struct DNSPARSER_Record' and the
+ * individual components in the respective fields of this struct.
+ * When serializing, you CAN set the 'name' field of 'struct
+ * GNUNET_DNSPARSER_Record' to NULL, in which case the DNSPARSER code
+ * will populate 'name' from the 'service', 'proto' and 'domain_name'
+ * fields in this struct.
+ */
+struct GNUNET_DNSPARSER_SrvRecord
+{
+
+ /**
+ * Service name without the underscore (!). Note that RFC 6335 clarifies the
+ * set of legal characters for service names.
+ */
+ char *service;
+
+ /**
+ * Transport protocol (typcially "tcp" or "udp", but others might be allowed).
+ * Without the underscore (!).
+ */
+ char *proto;
+
+ /**
+ * Domain name for which the record is valid
+ */
+ char *domain_name;
+
+ /**
+ * Hostname offering the service.
+ */
+ char *target;
+
+ /**
+ * Preference for this entry (lower value is higher preference). Clients
+ * will contact hosts from the lowest-priority group first and fall back
+ * to higher priorities if the low-priority entries are unavailable.
+ */
+ uint16_t priority;
+
+ /**
+ * Relative weight for records with the same priority. Clients will use
+ * the hosts of the same (lowest) priority with a probability proportional
+ * to the weight given.
+ */
+ uint16_t weight;
+
+ /**
+ * TCP or UDP port of the service.
+ */
+ uint16_t port;
+
+};
+
+
+/**
+ * Information from SOA records (RFC 1035).
+ */
+struct GNUNET_DNSPARSER_SoaRecord
+{
+
+ /**
+ *The domainname of the name server that was the
+ * original or primary source of data for this zone.
+ */
+ char *mname;
+
+ /**
+ * A domainname which specifies the mailbox of the
+ * person responsible for this zone.
+ */
+ char *rname;
+
+ /**
+ * The version number of the original copy of the zone.
+ */
+ uint32_t serial;
+
+ /**
+ * Time interval before the zone should be refreshed.
+ */
+ uint32_t refresh;
+
+ /**
+ * Time interval that should elapse before a failed refresh should
+ * be retried.
+ */
+ uint32_t retry;
+
+ /**
+ * Time value that specifies the upper limit on the time interval
+ * that can elapse before the zone is no longer authoritative.
+ */
+ uint32_t expire;
/**
- * Raw data, NOT a 0-terminated string (at least not always).
+ * The bit minimum TTL field that should be exported with any RR
+ * from this zone.
*/
- char *data;
+ uint32_t minimum_ttl;
+
+};
+
+
+/**
+ * Binary record information (unparsed).
+ */
+struct GNUNET_DNSPARSER_RawRecord
+{
+
+ /**
+ * Binary record data.
+ */
+ void *data;
/**
* Number of bytes in data.
*/
size_t data_len;
+};
+
+
+/**
+ * A DNS response record.
+ */
+struct GNUNET_DNSPARSER_Record
+{
+
+ /**
+ * Name of the record that the query is for (0-terminated).
+ */
+ char *name;
+
+ /**
+ * Payload of the record (which one of these is valid depends on the 'type').
+ */
+ union
+ {
+
+ /**
+ * For NS, CNAME and PTR records, this is the uncompressed 0-terminated hostname.
+ */
+ char *hostname;
+
+ /**
+ * SOA data for SOA records.
+ */
+ struct GNUNET_DNSPARSER_SoaRecord *soa;
+
+ /**
+ * MX data for MX records.
+ */
+ struct GNUNET_DNSPARSER_MxRecord *mx;
+
+ /**
+ * SRV data for SRV records.
+ */
+ struct GNUNET_DNSPARSER_SrvRecord *srv;
+
+ /**
+ * Raw data for all other types.
+ */
+ struct GNUNET_DNSPARSER_RawRecord raw;
+
+ } data;
+
/**
* When does the record expire?
* Given a DNS packet, generate the corresponding UDP payload.
*
* @param p packet to pack
+ * @param max maximum allowed size for the resulting UDP payload
* @param buf set to a buffer with the packed message
* @param buf_length set to the length of buf
* @return GNUNET_SYSERR if 'p' is invalid
* GNUNET_OK if 'p' was packed completely into '*buf'
*/
int
-GNUNET_DNSPARSER_pack (struct GNUNET_DNSPARSER_Packet *p,
+GNUNET_DNSPARSER_pack (const struct GNUNET_DNSPARSER_Packet *p,
+ uint16_t max,
char **buf,
size_t *buf_length);
-
-
-/* legacy API below */
-
-// DNS-Stuff
-GNUNET_NETWORK_STRUCT_BEGIN
-
-struct dns_static
-{
- uint16_t id GNUNET_PACKED;
-
- unsigned rd:1 GNUNET_PACKED; // recursion desired (client -> server)
- unsigned tc:1 GNUNET_PACKED; // message is truncated
- unsigned aa:1 GNUNET_PACKED; // authoritative answer
- unsigned op:4 GNUNET_PACKED; // query:0, inverse q.:1, status: 2
- unsigned qr:1 GNUNET_PACKED; // query:0, response:1
-
- unsigned rcode:4 GNUNET_PACKED; // 0 No error
- // 1 Format error
- // 2 Server failure
- // 3 Name Error
- // 4 Not Implemented
- // 5 Refused
- unsigned z:3 GNUNET_PACKED; // reserved
- unsigned ra:1 GNUNET_PACKED; // recursion available (server -> client)
-
- uint16_t qdcount GNUNET_PACKED; // number of questions
- uint16_t ancount GNUNET_PACKED; // number of answers
- uint16_t nscount GNUNET_PACKED; // number of authority-records
- uint16_t arcount GNUNET_PACKED; // number of additional records
-};
-GNUNET_NETWORK_STRUCT_END
-
-
-struct dns_pkt
-{
- struct dns_static s;
- unsigned char data[1];
-};
-
-struct dns_pkt_parsed
-{
- struct dns_static s;
- struct dns_query **queries;
- struct dns_record **answers;
- struct dns_record **nameservers;
- struct dns_record **additional;
-};
-
-struct dns_query_line
-{
- uint16_t type;
- uint16_t class;
-};
-
-struct dns_query
-{
- char *name;
- unsigned char namelen;
- uint16_t qtype;
- uint16_t qclass;
-};
-
-struct dns_record_line
-{
- uint16_t type;
- uint16_t class;
- uint32_t ttl;
- uint16_t data_len;
- unsigned char data;
-};
-
-struct dns_record
-{
- char *name;
- unsigned char namelen;
- uint16_t type;
- uint16_t class;
- uint32_t ttl;
- uint16_t data_len;
- unsigned char *data;
-};
-
-
-struct dns_pkt_parsed *
-parse_dns_packet (struct dns_pkt *pkt);
-
-struct dns_pkt *
-unparse_dns_packet (struct dns_pkt_parsed *pkt);
-
-void
-free_parsed_dns_packet (struct dns_pkt_parsed *ppkt);
-
#endif