Routines for message parsing a packet buffer to a descriptive structure. More...
#include "config.h"
#include "util/data/msgparse.h"
#include "util/net_help.h"
#include "util/data/dname.h"
#include "util/data/packed_rrset.h"
#include "util/storage/lookup3.h"
#include "util/regional.h"
Functions | |
static int | smart_compare (ldns_buffer *pkt, uint8_t *dnow, uint8_t *dprfirst, uint8_t *dprlast) |
smart comparison of (compressed, valid) dnames from packet | |
static struct rrset_parse * | new_rrset (struct msg_parse *msg, uint8_t *dname, size_t dnamelen, uint16_t type, uint16_t dclass, hashvalue_t hash, uint32_t rrset_flags, ldns_pkt_section section, struct regional *region) |
Allocate new rrset in region, fill with data. | |
static int | nsec_at_apex (ldns_buffer *pkt) |
See if next rrset is nsec at zone apex. | |
static uint32_t | pkt_rrset_flags (ldns_buffer *pkt, uint16_t type) |
Calculate rrset flags. | |
hashvalue_t | pkt_hash_rrset (ldns_buffer *pkt, uint8_t *dname, uint16_t type, uint16_t dclass, uint32_t rrset_flags) |
Calculate hash value for rrset in packet. | |
static hashvalue_t | pkt_hash_rrset_first (ldns_buffer *pkt, uint8_t *dname) |
create partial dname hash for rrset hash | |
static hashvalue_t | pkt_hash_rrset_rest (hashvalue_t dname_h, uint16_t type, uint16_t dclass, uint32_t rrset_flags) |
create a rrset hash from a partial dname hash | |
static int | rrset_parse_equals (struct rrset_parse *p, ldns_buffer *pkt, hashvalue_t h, uint32_t rrset_flags, uint8_t *dname, size_t dnamelen, uint16_t type, uint16_t dclass) |
compare rrset_parse with data | |
struct rrset_parse * | msgparse_hashtable_lookup (struct msg_parse *msg, ldns_buffer *pkt, hashvalue_t h, uint32_t rrset_flags, uint8_t *dname, size_t dnamelen, uint16_t type, uint16_t dclass) |
Lookup in msg hashtable to find a rrset. | |
static int | pkt_rrsig_covered (ldns_buffer *pkt, uint8_t *here, uint16_t *type) |
return type networkformat that rrsig in packet covers | |
static int | pkt_rrsig_covered_equals (ldns_buffer *pkt, uint8_t *here, uint16_t type) |
true if covered type equals prevtype | |
void | msgparse_bucket_remove (struct msg_parse *msg, struct rrset_parse *rrset) |
Remove rrset from hash table. | |
static void | change_section (struct msg_parse *msg, struct rrset_parse *rrset, ldns_pkt_section section) |
change section of rrset from previous to current section | |
static int | rrset_has_sigover (ldns_buffer *pkt, struct rrset_parse *rrset, uint16_t type, int *hasother) |
see if rrset of type RRSIG contains sig over given type | |
static int | moveover_rrsigs (ldns_buffer *pkt, struct regional *region, struct rrset_parse *sigset, struct rrset_parse *dataset, int duplicate) |
move rrsigs from sigset to dataset | |
static struct rrset_parse * | change_rrsig_rrset (struct rrset_parse *sigset, struct msg_parse *msg, ldns_buffer *pkt, uint16_t datatype, uint32_t rrset_flags, int hasother, ldns_pkt_section section, struct regional *region) |
change an rrsig rrset for use as data rrset | |
static int | find_rrset (struct msg_parse *msg, ldns_buffer *pkt, uint8_t *dname, size_t dnamelen, uint16_t type, uint16_t dclass, hashvalue_t *hash, uint32_t *rrset_flags, uint8_t **prev_dname_first, uint8_t **prev_dname_last, size_t *prev_dnamelen, uint16_t *prev_type, uint16_t *prev_dclass, struct rrset_parse **rrset_prev, ldns_pkt_section section, struct regional *region) |
Find rrset. | |
static int | parse_query_section (ldns_buffer *pkt, struct msg_parse *msg) |
Parse query section. | |
size_t | get_rdf_size (ldns_rdf_type rdf) |
Obtain size in the packet of an rr type, that is before dname type. | |
static int | calc_size (ldns_buffer *pkt, uint16_t type, struct rr_parse *rr) |
calculate the size of one rr | |
static int | skip_ttl_rdata (ldns_buffer *pkt) |
skip rr ttl and rdata | |
static int | sig_is_double (ldns_buffer *pkt, struct rrset_parse *rrset, uint8_t *ttldata) |
see if RRSIG is a duplicate of another | |
static int | add_rr_to_rrset (struct rrset_parse *rrset, ldns_buffer *pkt, struct msg_parse *msg, struct regional *region, ldns_pkt_section section, uint16_t type) |
Add rr (from packet here) to rrset, skips rr. | |
static int | parse_section (ldns_buffer *pkt, struct msg_parse *msg, struct regional *region, ldns_pkt_section section, uint16_t num_rrs, size_t *num_rrsets) |
Parse packet RR section, for answer, authority and additional sections. | |
int | parse_packet (ldns_buffer *pkt, struct msg_parse *msg, struct regional *region) |
Parse the packet. | |
int | parse_extract_edns (struct msg_parse *msg, struct edns_data *edns) |
After parsing the packet, extract EDNS data from packet. | |
int | parse_edns_from_pkt (ldns_buffer *pkt, struct edns_data *edns) |
If EDNS data follows a query section, extract it and initialize edns struct. |
Routines for message parsing a packet buffer to a descriptive structure.
hashvalue_t pkt_hash_rrset | ( | ldns_buffer * | pkt, | |
uint8_t * | dname, | |||
uint16_t | type, | |||
uint16_t | dclass, | |||
uint32_t | rrset_flags | |||
) |
Calculate hash value for rrset in packet.
pkt,: | the packet. | |
dname,: | pointer to uncompressed dname, or compressed dname in packet. | |
type,: | rrset type in host order. | |
dclass,: | rrset class in network order. | |
rrset_flags,: | rrset flags (same as packed_rrset flags). |
References dname_pkt_hash().
Referenced by change_rrsig_rrset(), mark_additional_rrset(), and synth_cname_rrset().
struct rrset_parse* msgparse_hashtable_lookup | ( | struct msg_parse * | msg, | |
ldns_buffer * | pkt, | |||
hashvalue_t | h, | |||
uint32_t | rrset_flags, | |||
uint8_t * | dname, | |||
size_t | dnamelen, | |||
uint16_t | type, | |||
uint16_t | dclass | |||
) | [read] |
Lookup in msg hashtable to find a rrset.
msg,: | with the hashtable. | |
pkt,: | packet for compressed names. | |
h,: | hash value | |
rrset_flags,: | flags of rrset sought for. | |
dname,: | name of rrset sought for. | |
dnamelen,: | len of dname. | |
type,: | rrset type, host order. | |
dclass,: | rrset class, network order. |
References msg_parse::hashtable, PARSE_TABLE_SIZE, rrset_parse::rrset_bucket_next, and rrset_parse_equals().
Referenced by find_rrset(), and mark_additional_rrset().
void msgparse_bucket_remove | ( | struct msg_parse * | msg, | |
struct rrset_parse * | rrset | |||
) |
Remove rrset from hash table.
msg,: | with hashtable. | |
rrset,: | with hash value and id info. |
References rrset_parse::hash, msg_parse::hashtable, PARSE_TABLE_SIZE, and rrset_parse::rrset_bucket_next.
Referenced by change_rrsig_rrset(), and remove_rrset().
static int find_rrset | ( | struct msg_parse * | msg, | |
ldns_buffer * | pkt, | |||
uint8_t * | dname, | |||
size_t | dnamelen, | |||
uint16_t | type, | |||
uint16_t | dclass, | |||
hashvalue_t * | hash, | |||
uint32_t * | rrset_flags, | |||
uint8_t ** | prev_dname_first, | |||
uint8_t ** | prev_dname_last, | |||
size_t * | prev_dnamelen, | |||
uint16_t * | prev_type, | |||
uint16_t * | prev_dclass, | |||
struct rrset_parse ** | rrset_prev, | |||
ldns_pkt_section | section, | |||
struct regional * | region | |||
) | [static] |
Find rrset.
If equal to previous it is fast. hash if not so.
msg,: | the message with hash table. | |
pkt,: | the packet in wireformat (needed for compression ptrs). | |
dname,: | pointer to start of dname (compressed) in packet. | |
dnamelen,: | uncompressed wirefmt length of dname. | |
type,: | type of current rr. | |
dclass,: | class of current rr. | |
hash,: | hash value is returned if the rrset could not be found. | |
rrset_flags,: | is returned if the rrset could not be found. | |
prev_dname_first,: | dname of last seen RR. First seen dname. | |
prev_dname_last,: | dname of last seen RR. Last seen dname. | |
prev_dnamelen,: | dname len of last seen RR. | |
prev_type,: | type of last seen RR. | |
prev_dclass,: | class of last seen RR. | |
rrset_prev,: | last seen RRset. | |
section,: | the current section in the packet. | |
region,: | used to allocate temporary parsing data. |
References change_rrsig_rrset(), msgparse_hashtable_lookup(), PACKED_RRSET_NSEC_AT_APEX, pkt_hash_rrset_first(), pkt_hash_rrset_rest(), pkt_rrset_flags(), pkt_rrsig_covered(), pkt_rrsig_covered_equals(), rrset_has_sigover(), and smart_compare().
Referenced by parse_section().
static int parse_query_section | ( | ldns_buffer * | pkt, | |
struct msg_parse * | msg | |||
) | [static] |
Parse query section.
pkt,: | packet, position at call must be at start of query section. at end position is after query section. | |
msg,: | store results here. |
References log_assert, pkt_dname_len(), msg_parse::qclass, msg_parse::qdcount, msg_parse::qname, msg_parse::qname_len, and msg_parse::qtype.
Referenced by parse_packet().
size_t get_rdf_size | ( | ldns_rdf_type | rdf | ) |
Obtain size in the packet of an rr type, that is before dname type.
Do TYPE_DNAME, and type STR, yourself. Gives size for most regular types.
rdf,: | the rdf type from the descriptor. |
References log_assert.
Referenced by analyze_rdata(), calc_size(), canonical_compare_byfield(), compress_rdata(), and rdata_copy().
static int parse_section | ( | ldns_buffer * | pkt, | |
struct msg_parse * | msg, | |||
struct regional * | region, | |||
ldns_pkt_section | section, | |||
uint16_t | num_rrs, | |||
size_t * | num_rrsets | |||
) | [static] |
Parse packet RR section, for answer, authority and additional sections.
pkt,: | packet, position at call must be at start of section. at end position is after section. | |
msg,: | store results here. | |
region,: | how to alloc results. | |
section,: | section enum. | |
num_rrs,: | how many rrs are in the section. | |
num_rrsets,: | returns number of rrsets in the section. |
References add_rr_to_rrset(), rrset_parse::dname, dname_print(), find_rrset(), new_rrset(), pkt_dname_len(), pkt_rrsig_covered(), and rrset_parse::type.
Referenced by parse_packet().
Parse the packet.
pkt,: | packet, position at call must be at start of packet. at end position is after packet. | |
msg,: | where to store results. | |
region,: | how to alloc results. |
References msg_parse::an_rrsets, msg_parse::ancount, msg_parse::ar_rrsets, msg_parse::arcount, msg_parse::flags, msg_parse::id, msg_parse::ns_rrsets, msg_parse::nscount, parse_query_section(), parse_section(), msg_parse::qdcount, and msg_parse::rrset_count.
Referenced by createResponse(), parse_reply(), process_response(), and reply_info_parse().
After parsing the packet, extract EDNS data from packet.
If not present this is noted in the data structure. If a parse error happens, an error code is returned.
Quirks: o ignores OPT rdata. o ignores OPT owner name. o ignores extra OPT records, except the last one in the packet.
msg,: | parsed message structure. Modified on exit, if EDNS was present it is removed from the additional section. | |
edns,: | the edns data is stored here. Does not have to be initialised. |
References msg_parse::ar_rrsets, msg_parse::arcount, edns_data::bits, rrset_parse::dname, rrset_parse::dname_len, edns_data::edns_present, edns_data::edns_version, edns_data::ext_rcode, log_assert, rrset_parse::rr_count, rrset_parse::rr_first, rrset_parse::rr_last, rrset_parse::rrset_all_next, rrset_parse::rrset_class, msg_parse::rrset_count, msg_parse::rrset_first, msg_parse::rrset_last, rrset_parse::section, rr_parse::ttl_data, rrset_parse::type, and edns_data::udp_size.
Referenced by createResponse(), process_response(), and reply_info_parse().
int parse_edns_from_pkt | ( | ldns_buffer * | pkt, | |
struct edns_data * | edns | |||
) |
If EDNS data follows a query section, extract it and initialize edns struct.
pkt,: | the packet. position at start must be right after the query section. At end, right after EDNS data or no movement if failed. | |
edns,: | the edns data allocated by the caller. Does not have to be initialised. |
References edns_data::bits, edns_data::edns_present, edns_data::edns_version, edns_data::ext_rcode, log_assert, pkt_dname_len(), and edns_data::udp_size.
Referenced by worker_handle_request().