Routines for message parsing a packet buffer to a descriptive structure. More...
#include "config.h"
#include "util/config_file.h"
#include "util/data/msgparse.h"
#include "util/data/msgreply.h"
#include "util/data/dname.h"
#include "util/data/packed_rrset.h"
#include "util/netevent.h"
#include "util/storage/lookup3.h"
#include "util/regional.h"
#include "util/rfc_1982.h"
#include "util/edns.h"
#include "util/net_help.h"
#include "sldns/rrdef.h"
#include "sldns/sbuffer.h"
#include "sldns/parseutil.h"
#include "sldns/wire2str.h"
Functions | |
static int | smart_compare (sldns_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_type hash, uint32_t rrset_flags, sldns_pkt_section section, struct regional *region) |
Allocate new rrset in region, fill with data. | |
static int | nsec_at_apex (sldns_buffer *pkt) |
See if next rrset is nsec at zone apex. | |
static uint32_t | pkt_rrset_flags (sldns_buffer *pkt, uint16_t type, sldns_pkt_section sec) |
Calculate rrset flags. | |
hashvalue_type | pkt_hash_rrset (sldns_buffer *pkt, uint8_t *dname, uint16_t type, uint16_t dclass, uint32_t rrset_flags) |
Calculate hash value for rrset in packet. More... | |
static hashvalue_type | pkt_hash_rrset_first (sldns_buffer *pkt, uint8_t *dname) |
create partial dname hash for rrset hash | |
static hashvalue_type | pkt_hash_rrset_rest (hashvalue_type 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, sldns_buffer *pkt, hashvalue_type 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, sldns_buffer *pkt, hashvalue_type 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. More... | |
static int | pkt_rrsig_covered (sldns_buffer *pkt, uint8_t *here, uint16_t *type) |
return type networkformat that rrsig in packet covers | |
static int | pkt_rrsig_covered_equals (sldns_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. More... | |
static void | change_section (struct msg_parse *msg, struct rrset_parse *rrset, sldns_pkt_section section) |
change section of rrset from previous to current section | |
static int | rrset_has_sigover (sldns_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 (sldns_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, sldns_buffer *pkt, uint16_t datatype, uint32_t rrset_flags, int hasother, sldns_pkt_section section, struct regional *region) |
change an rrsig rrset for use as data rrset | |
static int | find_rrset (struct msg_parse *msg, sldns_buffer *pkt, uint8_t *dname, size_t dnamelen, uint16_t type, uint16_t dclass, hashvalue_type *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, sldns_pkt_section section, struct regional *region) |
Find rrset. More... | |
static int | parse_query_section (sldns_buffer *pkt, struct msg_parse *msg) |
Parse query section. More... | |
size_t | get_rdf_size (sldns_rdf_type rdf) |
Obtain size in the packet of an rr type, that is before dname type. More... | |
static int | calc_size (sldns_buffer *pkt, uint16_t type, struct rr_parse *rr) |
calculate the size of one rr | |
static int | skip_ttl_rdata (sldns_buffer *pkt) |
skip rr ttl and rdata | |
static int | sig_is_double (sldns_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, sldns_buffer *pkt, struct msg_parse *msg, struct regional *region, sldns_pkt_section section, uint16_t type) |
Add rr (from packet here) to rrset, skips rr. | |
static int | parse_section (sldns_buffer *pkt, struct msg_parse *msg, struct regional *region, sldns_pkt_section section, uint16_t num_rrs, size_t *num_rrsets) |
Parse packet RR section, for answer, authority and additional sections. More... | |
int | parse_packet (sldns_buffer *pkt, struct msg_parse *msg, struct regional *region) |
Parse the packet. More... | |
static int | parse_edns_options_from_query (uint8_t *rdata_ptr, size_t rdata_len, struct edns_data *edns, struct config_file *cfg, struct comm_point *c, struct comm_reply *repinfo, uint32_t now, struct regional *region, struct cookie_secrets *cookie_secrets) |
parse EDNS options from EDNS wireformat rdata | |
int | parse_extract_edns_from_response_msg (struct msg_parse *msg, struct edns_data *edns, struct regional *region) |
After parsing the packet, extract EDNS data from packet. More... | |
static int | skip_pkt_rr (sldns_buffer *pkt) |
skip RR in packet | |
int | skip_pkt_rrs (sldns_buffer *pkt, int num) |
skip RRs from packet More... | |
int | parse_edns_from_query_pkt (sldns_buffer *pkt, struct edns_data *edns, struct config_file *cfg, struct comm_point *c, struct comm_reply *repinfo, time_t now, struct regional *region, struct cookie_secrets *cookie_secrets) |
If EDNS data follows a query section, extract it and initialize edns struct. More... | |
void | log_edns_opt_list (enum verbosity_value level, const char *info_str, struct edns_option *list) |
Log the edns options in the edns option list. More... | |
int | msgparse_rrset_remove_rr (const char *str, sldns_buffer *pkt, struct rrset_parse *rrset, struct rr_parse *prev, struct rr_parse *rr, struct sockaddr_storage *addr, socklen_t addrlen) |
remove RR from msgparse RRset, return true if rrset is entirely bad More... | |
Routines for message parsing a packet buffer to a descriptive structure.
hashvalue_type pkt_hash_rrset | ( | struct sldns_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 rrset_parse::dname, dname_pkt_hash(), hashlittle(), and rrset_parse::type.
Referenced by change_rrsig_rrset(), mark_additional_rrset(), and synth_cname_rrset().
struct rrset_parse* msgparse_hashtable_lookup | ( | struct msg_parse * | msg, |
struct sldns_buffer * | pkt, | ||
hashvalue_type | 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.
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 rrset_parse::dname, msg_parse::hashtable, PARSE_TABLE_SIZE, rrset_parse::rrset_bucket_next, rrset_parse_equals(), and rrset_parse::type.
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.
|
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 rrset_parse::dname, rrset_parse::hash, LDNS_RR_TYPE_RRSIG, msgparse_hashtable_lookup(), pkt_hash_rrset_first(), pkt_hash_rrset_rest(), pkt_rrset_flags(), pkt_rrsig_covered(), pkt_rrsig_covered_equals(), rrset_parse::section, sldns_buffer_current(), smart_compare(), and rrset_parse::type.
|
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 msg_parse::qdcount.
size_t get_rdf_size | ( | sldns_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 LDNS_RDF_TYPE_A, LDNS_RDF_TYPE_AAAA, LDNS_RDF_TYPE_ALG, LDNS_RDF_TYPE_CERT_ALG, LDNS_RDF_TYPE_CLASS, LDNS_RDF_TYPE_INT16, LDNS_RDF_TYPE_INT32, LDNS_RDF_TYPE_INT8, LDNS_RDF_TYPE_PERIOD, LDNS_RDF_TYPE_TIME, LDNS_RDF_TYPE_TSIGTIME, LDNS_RDF_TYPE_TYPE, and log_assert.
Referenced by analyze_rdata(), calc_size(), canonical_compare_byfield(), compress_rdata(), and decompress_rr_into_buffer().
|
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 sldns_buffer_remaining().
int parse_packet | ( | struct sldns_buffer * | pkt, |
struct msg_parse * | msg, | ||
struct regional * | region | ||
) |
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 sldns_buffer_remaining().
Referenced by createResponse(), and parse_reply_in_temp_region().
int parse_extract_edns_from_response_msg | ( | struct msg_parse * | msg, |
struct edns_data * | edns, | ||
struct regional * | region | ||
) |
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. |
region | region to alloc results in (edns option contents) |
References LDNS_RR_TYPE_OPT, msg_parse::rrset_first, and rrset_parse::type.
int skip_pkt_rrs | ( | sldns_buffer * | pkt, |
int | num | ||
) |
int parse_edns_from_query_pkt | ( | struct sldns_buffer * | pkt, |
struct edns_data * | edns, | ||
struct config_file * | cfg, | ||
struct comm_point * | c, | ||
struct comm_reply * | repinfo, | ||
time_t | now, | ||
struct regional * | region, | ||
struct cookie_secrets * | cookie_secrets | ||
) |
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. |
cfg | the configuration (with nsid value etc.) |
c | commpoint to determine transport (if needed) |
repinfo | commreply to determine the client address |
now | current time |
region | region to alloc results in (edns option contents) |
cookie_secrets | the cookie secrets for EDNS COOKIE validation. |
References log_assert.
void log_edns_opt_list | ( | enum verbosity_value | level, |
const char * | info_str, | ||
struct edns_option * | list | ||
) |
Log the edns options in the edns option list.
level | the verbosity level. |
info_str | the informational string to be printed before the options. |
list | the edns option list. |
References verbosity.
int msgparse_rrset_remove_rr | ( | const char * | str, |
sldns_buffer * | pkt, | ||
struct rrset_parse * | rrset, | ||
struct rr_parse * | prev, | ||
struct rr_parse * | rr, | ||
struct sockaddr_storage * | addr, | ||
socklen_t | addrlen | ||
) |
remove RR from msgparse RRset, return true if rrset is entirely bad
Remove RR from msgparse RRset.