/* ********************************************************************************************** * File: dns_decoder.h * Description: dns decoder api * Authors: Liu XueLi * Date: 2024-02-07 * Copyright: (c) Since 2022 Geedge Networks, Ltd. All rights reserved. *********************************************************************************************** */ #pragma once #ifdef __cplusplus extern "C" { #endif #include #include #include #define DNS_MESSAGE_TOPIC "TOPIC_DNS" #define DNS_NAME_MAX (NAME_MAX + 1) // #define HINFO_NAME_MAX (40 + 1) /* https://www.ietf.org/rfc/rfc1010.txt */ #define DNS_CLASS_UNKNOWN 0 #define DNS_CLASS_IN 1 #define DNS_CLASS_CS 2 #define DNS_CLASS_CH 3 #define DNS_CLASS_HS 4 #define DNS_CLASS_ANY 255 /* RR(resource record) type, defined in https://www.ietf.org/rfc/rfc1035.txt */ enum dns_rr_type { DNS_RR_TYPE_A = 1, DNS_RR_TYPE_NS, DNS_RR_TYPE_MD, /* Obsolete - use MX, rfc973 */ DNS_RR_TYPE_MF, /* Obsolete - use MX, rfc973 */ DNS_RR_TYPE_CNAME, DNS_RR_TYPE_SOA, DNS_RR_TYPE_MB, /* EXPERIMENTAL, rfc883,rfc2505 */ DNS_RR_TYPE_MG, /* EXPERIMENTAL, rfc883,rfc2505 */ DNS_RR_TYPE_MR, /* EXPERIMENTAL, rfc883 */ DNS_RR_TYPE_NULL, /* EXPERIMENTAL, rfc1035 */ DNS_RR_TYPE_WKS, /* Not to be relied upon, rfc1123 */ DNS_RR_TYPE_PTR, DNS_RR_TYPE_HINFO, DNS_RR_TYPE_MINFO, DNS_RR_TYPE_MX, DNS_RR_TYPE_TXT, DNS_RR_TYPE_RP, DNS_RR_TYPE_ISDN = 20, DNS_RR_TYPE_AAAA = 28, /* dns_ipv6 */ DNS_RR_TYPE_SRV = 33, DNS_RR_TYPE_DNAME = 39, DNS_RR_TYPE_OPT = 41, DNS_RR_TYPE_DS = 43, DNS_RR_TYPE_RRSIG = 46, DNS_RR_TYPE_NSEC, DNS_RR_TYPE_DNSKEY, DNS_RR_TYPE_NSEC3 = 50, DNS_RR_TYPE_NSEC3PARAM, DNS_RR_TYPE_HTTPS = 65, DNS_RR_TYPE_AXFR = 252, DNS_RR_TYPE_MAILB, DNS_RR_TYPE_MAILA, /* Obsolete - see MX */ DNS_RR_TYPE_ANY, DNS_RR_TYPE_DLV = 32769, /* DSNSEC Lokkaside Validation */ DNS_RR_TYPE_UNKNOWN = 65534 }; struct dstring { size_t value_sz; uint8_t value[DNS_NAME_MAX]; }; struct rdata_hinfo { struct dstring os; struct dstring cpu; }; struct rdata_minfo { struct dstring rmailbx; struct dstring emailbx; }; struct rdata_mx { uint16_t preference; struct dstring exchange; }; struct rdata_soa { struct dstring mname; struct dstring rname; uint32_t serial; uint32_t refresh; uint32_t retry; uint32_t expire; uint32_t minimum; }; struct rdata_rp { struct dstring txt_rr; struct dstring mailbox; }; struct rdata_wks { uint8_t protocol; uint32_t addr; uint32_t size; uint8_t *bitmap; }; struct rdata_srv { uint16_t priority; uint16_t weight; uint16_t port; struct dstring target; }; struct rdata_ds { uint16_t key_tag; uint8_t algo; uint8_t digest_type; uint32_t digest_len; uint8_t *digest; }; struct rdata_rrsig { uint16_t type_covered; uint8_t algo; uint8_t labels; uint32_t original_ttl; uint32_t sig_expiration; uint32_t sig_inception; uint16_t key_tag; uint32_t signature_len; uint8_t *signature; struct dstring signer_name; }; struct rdata_nsec { uint16_t maps_len; struct dstring next_domain; struct dstring type_bit_maps; }; struct rdata_dnskey { uint16_t flags; uint8_t protocol; uint8_t algo; uint32_t public_key_len; uint8_t *public_key; }; struct rdata_nsec3 { uint8_t hash_algo; uint8_t flags; uint8_t salt_len; uint8_t hash_len; uint16_t iteration; uint16_t maps_len; uint8_t *salt_value; uint8_t *next_hash_owner; struct dstring type_bit_maps; }; struct rdata_nsec3param { uint8_t hash_algo; uint8_t flags; uint8_t salt_len; uint16_t iteration; uint8_t *salt_value; }; /* rr is short for resource record */ struct dns_resource_record { struct dstring qname; enum dns_rr_type type; uint16_t rr_class; uint32_t ttl; /* 1byte: extended RCODE; 1byte: version; 2bytes: Z(upper bit) if type is OPT */ uint16_t rdlength; union { struct dstring cname; struct dstring mb; struct dstring md; struct dstring mf; struct dstring mg; struct dstring mr; struct dstring ns; struct dstring ptr; struct dstring a; struct dstring aaaa; struct dstring dname; struct dstring isdn; struct dstring unknown; struct dstring txt; struct dstring null; struct rdata_hinfo hinfo; struct rdata_minfo minfo; struct rdata_mx mx; struct rdata_soa soa; struct rdata_rp rp; struct rdata_wks wks; struct rdata_srv srv; struct rdata_ds ds; struct rdata_rrsig rrsig; struct rdata_nsec nsec; struct rdata_dnskey dnskey; struct rdata_nsec3 nsec3; struct rdata_nsec3param nsec3param; struct dstring string; } rdata; }; struct dns_message; /*. First call DNS_MESSAGE_TRANSACTION_BEGIN to create the transaction, then publish the transaction's DNS_MESSAGE_QUERY/DNS_MESSAGE_RESPONSE, and finally call DNS_MESSAGE_TRANSACTION_END to release the transaction. */ enum dns_message_type { DNS_MESSAGE_QUERY=1, DNS_MESSAGE_RESPONSE, DNS_MESSAGE_TRANSACTION_BEGIN, DNS_MESSAGE_TRANSACTION_END, DNS_MESSAGE_MAX }; enum dns_message_type dns_message_type_get(struct dns_message *msg); struct dns_flag { uint8_t qr:1; uint8_t opcode:4; uint8_t aa:1; uint8_t tc:1; uint8_t rd:1; uint8_t ra:1; uint8_t z:3; uint8_t rcode:4; }; struct dns_query_question { enum dns_rr_type qtype; uint16_t qclass; size_t qname_sz; uint8_t qname[DNS_NAME_MAX]; }; int32_t dns_message_transaction_index_get(struct dns_message *msg); int32_t dns_message_header_id_get(struct dns_message *msg); struct dns_flag *dns_message_header_flag_get0(struct dns_message *msg); void dns_message_question_get0(struct dns_message *msg, struct dns_query_question **question, uint16_t *n_question); void dns_message_answer_resource_record_get0(struct dns_message *msg, struct dns_resource_record **answer_rr, uint16_t *n_answer_rr); void dns_message_authority_resource_record_get0(struct dns_message *msg, struct dns_resource_record **authority_rr, uint16_t *n_authority_rr); void dns_message_additional_resource_record_get0(struct dns_message *msg, struct dns_resource_record **additional_rr, uint16_t *n_additional_rr); #ifdef __cplusplus } #endif