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. | |
| 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. | |
| 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. | |
| 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. | |
| static int | parse_query_section (sldns_buffer *pkt, struct msg_parse *msg) | 
| Parse query section. | |
| size_t | get_rdf_size (sldns_rdf_type rdf) | 
| Obtain size in the packet of an rr type, that is before dname type. | |
| 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. | |
| int | parse_packet (sldns_buffer *pkt, struct msg_parse *msg, struct regional *region) | 
| Parse the packet. | |
| 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. | |
| 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 | |
| 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. | |
| 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. | |
| 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 | |
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(), and rrset_parse::type.
Referenced by change_rrsig_rrset(), mark_additional_rrset(), scrub_sanitize(), 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.
Referenced by change_rrsig_rrset(), and remove_rrset().
| 
 | 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(), rrset_parse::dname, rrset_parse::hash, LDNS_RR_TYPE_RRSIG, LDNS_RR_TYPE_SOA, msgparse_hashtable_lookup(), PACKED_RRSET_NSEC_AT_APEX, PACKED_RRSET_SOA_NEG, pkt_hash_rrset_first(), pkt_hash_rrset_rest(), pkt_rrset_flags(), pkt_rrsig_covered(), pkt_rrsig_covered_equals(), rrset_has_sigover(), rrset_parse::section, sldns_buffer_current(), smart_compare(), and rrset_parse::type.
Referenced by parse_section().
| 
 | 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, msg_parse::qtype, sldns_buffer_current(), sldns_buffer_read_u16(), and sldns_buffer_remaining().
Referenced by parse_packet().
| 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(), decompress_rr_into_buffer(), and rdata_copy().
| 
 | 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_struct_rr_descriptor::_name, add_rr_to_rrset(), rrset_parse::dname, dname_print(), find_rrset(), rrset_parse::hash, LDNS_RR_TYPE_RRSIG, new_rrset(), pkt_dname_len(), pkt_rrsig_covered(), rrset_parse::section, sldns_buffer_current(), sldns_buffer_read(), sldns_buffer_read_u16(), sldns_buffer_remaining(), sldns_rr_classes, sldns_rr_descript(), and rrset_parse::type.
Referenced by parse_packet().
| 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 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, msg_parse::rrset_count, sldns_buffer_read(), sldns_buffer_read_u16(), and sldns_buffer_remaining().
Referenced by createResponse(), parse_reply_in_temp_region(), process_response(), and reply_info_parse().
| 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 msg_parse::ar_rrsets, msg_parse::arcount, edns_data::bits, edns_data::cookie_present, edns_data::cookie_valid, rrset_parse::dname, rrset_parse::dname_len, edns_opt_list_append(), edns_data::edns_present, edns_data::edns_version, edns_data::ext_rcode, LDNS_RR_TYPE_OPT, log_assert, log_err(), edns_data::opt_list_in, edns_data::opt_list_inplace_cb_out, edns_data::opt_list_out, edns_data::padding_block_size, 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::size, rr_parse::ttl_data, rrset_parse::type, and edns_data::udp_size.
Referenced by createResponse(), process_response(), and reply_info_parse().
| int skip_pkt_rrs | ( | sldns_buffer * | pkt, | 
| int | num | ||
| ) | 
skip RRs from packet
Skip RRs from packet.
References skip_pkt_rr().
Referenced by parse_edns_from_query_pkt().
| 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 partial 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 edns_data::bits, edns_data::cookie_present, edns_data::cookie_valid, edns_data::edns_present, edns_data::edns_version, edns_data::ext_rcode, LDNS_RR_TYPE_OPT, log_assert, edns_data::opt_list_in, edns_data::opt_list_inplace_cb_out, edns_data::opt_list_out, edns_data::padding_block_size, parse_edns_options_from_query(), pkt_dname_len(), skip_pkt_rrs(), sldns_buffer_begin(), sldns_buffer_current(), sldns_buffer_read_u16(), sldns_buffer_read_u8(), sldns_buffer_remaining(), and edns_data::udp_size.
Referenced by worker_handle_request().
| 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 edns_option::next, edns_option::opt_code, edns_option::opt_data, edns_option::opt_len, sldns_wire2str_edns_option_print(), verbose(), and 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.
References rrset_parse::dname, rrset_parse::dname_len, dname_pkt_copy(), LDNS_MAX_DOMAINLEN, log_name_addr(), log_nametypeclass(), rr_parse::next, rrset_parse::rr_count, rrset_parse::rr_first, rrset_parse::rr_last, rrset_parse::rrset_class, rrset_parse::size, rr_parse::size, rrset_parse::type, VERB_QUERY, and verbosity.
Referenced by priv_rrset_bad(), and scrub_sanitize_rr_length().