106 lines
2.7 KiB
C
106 lines
2.7 KiB
C
|
#ifndef HV_DNS_H_
|
||
|
#define HV_DNS_H_
|
||
|
|
||
|
#include "hexport.h"
|
||
|
#include "hplatform.h"
|
||
|
|
||
|
#define DNS_PORT 53
|
||
|
|
||
|
#define DNS_QUERY 0
|
||
|
#define DNS_RESPONSE 1
|
||
|
|
||
|
#define DNS_TYPE_A 1 // ipv4
|
||
|
#define DNS_TYPE_NS 2
|
||
|
#define DNS_TYPE_CNAME 5
|
||
|
#define DNS_TYPE_SOA 6
|
||
|
#define DNS_TYPE_WKS 11
|
||
|
#define DNS_TYPE_PTR 12
|
||
|
#define DNS_TYPE_HINFO 13
|
||
|
#define DNS_TYPE_MX 15
|
||
|
#define DNS_TYPE_AAAA 28 // ipv6
|
||
|
#define DNS_TYPE_AXFR 252
|
||
|
#define DNS_TYPE_ANY 255
|
||
|
|
||
|
#define DNS_CLASS_IN 1
|
||
|
|
||
|
#define DNS_NAME_MAXLEN 256
|
||
|
|
||
|
// sizeof(dnshdr_t) = 12
|
||
|
typedef struct dnshdr_s {
|
||
|
uint16_t transaction_id;
|
||
|
// flags
|
||
|
#if BYTE_ORDER == LITTLE_ENDIAN
|
||
|
uint8_t rd:1;
|
||
|
uint8_t tc:1;
|
||
|
uint8_t aa:1;
|
||
|
uint8_t opcode:4;
|
||
|
uint8_t qr:1;
|
||
|
|
||
|
uint8_t rcode:4;
|
||
|
uint8_t cd:1;
|
||
|
uint8_t ad:1;
|
||
|
uint8_t res:1;
|
||
|
uint8_t ra:1;
|
||
|
#elif BYTE_ORDER == BIG_ENDIAN
|
||
|
uint8_t qr:1; // DNS_QUERY or DNS_RESPONSE
|
||
|
uint8_t opcode:4;
|
||
|
uint8_t aa:1; // authoritative
|
||
|
uint8_t tc:1; // truncated
|
||
|
uint8_t rd:1; // recursion desired
|
||
|
|
||
|
uint8_t ra:1; // recursion available
|
||
|
uint8_t res:1; // reserved
|
||
|
uint8_t ad:1; // authenticated data
|
||
|
uint8_t cd:1; // checking disable
|
||
|
uint8_t rcode:4;
|
||
|
#else
|
||
|
#error "BYTE_ORDER undefined!"
|
||
|
#endif
|
||
|
uint16_t nquestion;
|
||
|
uint16_t nanswer;
|
||
|
uint16_t nauthority;
|
||
|
uint16_t naddtional;
|
||
|
} dnshdr_t;
|
||
|
|
||
|
typedef struct dns_rr_s {
|
||
|
char name[DNS_NAME_MAXLEN]; // original domain, such as www.example.com
|
||
|
uint16_t rtype;
|
||
|
uint16_t rclass;
|
||
|
uint32_t ttl;
|
||
|
uint16_t datalen;
|
||
|
char* data;
|
||
|
} dns_rr_t;
|
||
|
|
||
|
typedef struct dns_s {
|
||
|
dnshdr_t hdr;
|
||
|
dns_rr_t* questions;
|
||
|
dns_rr_t* answers;
|
||
|
dns_rr_t* authorities;
|
||
|
dns_rr_t* addtionals;
|
||
|
} dns_t;
|
||
|
|
||
|
BEGIN_EXTERN_C
|
||
|
|
||
|
// www.example.com => 3www7example3com
|
||
|
HV_EXPORT int dns_name_encode(const char* domain, char* buf);
|
||
|
// 3www7example3com => www.example.com
|
||
|
HV_EXPORT int dns_name_decode(const char* buf, char* domain);
|
||
|
|
||
|
HV_EXPORT int dns_rr_pack(dns_rr_t* rr, char* buf, int len);
|
||
|
HV_EXPORT int dns_rr_unpack(char* buf, int len, dns_rr_t* rr, int is_question);
|
||
|
|
||
|
HV_EXPORT int dns_pack(dns_t* dns, char* buf, int len);
|
||
|
HV_EXPORT int dns_unpack(char* buf, int len, dns_t* dns);
|
||
|
// NOTE: free dns->rrs
|
||
|
HV_EXPORT void dns_free(dns_t* dns);
|
||
|
|
||
|
// dns_pack -> sendto -> recvfrom -> dns_unpack
|
||
|
HV_EXPORT int dns_query(dns_t* query, dns_t* response, const char* nameserver DEFAULT("127.0.1.1"));
|
||
|
|
||
|
// domain -> dns_t query; -> dns_query -> dns_t response; -> addrs
|
||
|
HV_EXPORT int nslookup(const char* domain, uint32_t* addrs, int naddr, const char* nameserver DEFAULT("127.0.1.1"));
|
||
|
|
||
|
END_EXTERN_C
|
||
|
|
||
|
#endif // HV_DNS_H_
|