#include <ldns/error.h>
#include <ldns/common.h>
#include <ldns/rr.h>
-#include <sys/time.h>
#include <ldns/edns.h>
+#include <sys/time.h>
#ifdef __cplusplus
extern "C" {
uint16_t _edns_z;
/** Arbitrary EDNS rdata */
ldns_rdf *_edns_data;
-
- /** Structured ENDS options */
- ldns_edns_option *_edns_options; // @TODO rewrite into "edns_option_list" struct
-
/** Question section */
ldns_rr_list *_question;
/** Answer section */
*/
ldns_rr_list *ldns_pkt_rr_list_by_name_and_type(const ldns_pkt *packet, const ldns_rdf *ownername, ldns_rr_type type, ldns_pkt_section sec);
-
/**
* check to see if an rr exist in the packet
* \param[in] pkt the packet to examine
void ldns_pkt_set_edns_unassigned(ldns_pkt *packet, uint16_t value);
/**
- * returns true if this packet needs an EDNS rr to be sent.
+ * returns true if this packet needs and EDNS rr to be sent.
* At the moment the only reason is an expected packet
* size larger than 512 bytes, but for instance dnssec would
* be a good reason too.
*/
bool ldns_pkt_edns(const ldns_pkt *packet);
+/**
+ * Returns a list of structured EDNS options
+ *
+ * \param[in] packet the packet which contains the parsed EDNS data
+ * \return list of ldns_edns_option structs
+ */
+ldns_edns_option_list* ldns_pkt_edns_option_list(const ldns_pkt *packet);
+
/**
* Set the packet's edns udp size
* \param[in] packet the packet
*/
void ldns_pkt_set_edns_data(ldns_pkt *packet, ldns_rdf *data);
-
-// *
-// * Set the packet's edns data
-// * \param[in] packet the packet
-// * \param[in] data the data
-// * \return 0 is there is no next EDNS option in the
-
-// uint16_t ldns_pkt_get_next_edns_option(ldns_pkt *packet, );
-
-
-
-
/**
* allocates and initializes a ldns_pkt structure.
* \return pointer to the new packet
}
bool
-ldns_pkt_edns(const ldns_pkt *pkt) {
+ldns_pkt_edns(const ldns_pkt *pkt)
+{
return (ldns_pkt_edns_udp_size(pkt) > 0 ||
ldns_pkt_edns_extended_rcode(pkt) > 0 ||
ldns_pkt_edns_data(pkt) ||
);
}
+ldns_edns_option_list*
+ldns_pkt_edns_option_list(const ldns_pkt *packet)
+{
+ size_t pos = 0;
+ ldns_edns_option_list* edns_list;
+ size_t max = ldns_rdf_size(ldns_pkt_edns_data(packet)); // @TODO is this ugly?
+ const uint8_t* wire = ldns_rdf_data(ldns_pkt_edns_data(packet)); // @TODO is this ugly?
+
+
+ // @TODO do checks so we don't read into un-auth memory (max !< 4)
+
+
+ edns_list = ldns_edns_option_list_new();
+ if (edns_list == NULL) {
+ return NULL;
+ }
+
+ while (pos < max) {
+ ldns_edns_option* edns;
+ uint8_t *data;
+ ldns_edns_option_code code = ldns_read_uint16(&wire[pos]);
+ size_t size = ldns_read_uint16(&wire[pos+2]);
+ pos += 4;
+
+ data = LDNS_XMALLOC(uint8_t, size);
+
+ // @TODO think about commented-out code
+ // if (!data) {
+ // status = LDNS_STATUS_MEM_ERR;
+ // goto status_error;
+ // printf("HERE: DATA == NULL\n");
+ // }
+ memcpy(data, &wire[pos], size);
+ pos += size;
+
+ edns = ldns_edns_new(code, size, data);
+
+ if (edns != NULL) {
+ ldns_edns_option_list_push(edns_list, edns);
+ }
+
+ // @TODO what do we do in case of edns == NULL?
+
+ }
+
+ return edns_list;
+}
+
/* Create/destroy/convert functions
*/
ldns_pkt_set_edns_z(packet, 0);
ldns_pkt_set_edns_data(packet, NULL);
packet->_edns_present = false;
-
- packet->_edns_options = NULL; //@TODO change this to set_function/list function
ldns_pkt_set_tsig(packet, NULL);