1 #ifndef DNS_H 2 #define DNS_H 3 4 #include "sysdeps.h" 5 #include "systime.h" 6 #include "ipv4.h" 7 #include "ipv6.h" 8 #include "str.h" 9 #include "uint16.h" 10 11 /** True if \c struct \c timeval \c A is less than \c B */ 12 #define TV_LESS(A,B) (((A)->tv_sec < (B)->tv_sec) || ((A)->tv_sec == (B)->tv_sec && (A)->tv_usec < (B)->tv_usec)) 13 14 /** \defgroup dns dns: DNS Resolver Library 15 16 @{ 17 18 The DNS resolver library is a modified copy of the public domain library 19 used in djbdns (http://cr.yp.to/djbdns.html). Many modifications have 20 been made, both to make it fit within the bglibs library and to extend 21 the functionality. 22 23 Notable enhancements are: 24 25 - support for IPv6 lookups (both forward and reverse) 26 27 - qualification support for lookup types other than IPv4 addresses 28 29 - support for multiple outstanding requests 30 31 \return Functions that return an \c int return -1 on error and set \c errno. 32 33 */ 34 35 /** Record class: Internet protocol */ 36 #define DNS_C_IN 1 37 /** Record class: Any */ 38 #define DNS_C_ANY 255 39 40 /** Record type: Address (IPv4) */ 41 #define DNS_T_A 1 42 /** Record type: Name server */ 43 #define DNS_T_NS 2 44 /** Record type: Canonical name (alias) */ 45 #define DNS_T_CNAME 5 46 /** Record type: Start of authority */ 47 #define DNS_T_SOA 6 48 /** Record type: Pointer */ 49 #define DNS_T_PTR 12 50 /** Record type: Host information */ 51 #define DNS_T_HINFO 13 52 /** Record type: Mail exchanger */ 53 #define DNS_T_MX 15 54 /** Record type: Text */ 55 #define DNS_T_TXT 16 56 /** Record type: Responsible person */ 57 #define DNS_T_RP 17 58 /** Record type: Signature */ 59 #define DNS_T_SIG 24 60 /** Record type: Key record */ 61 #define DNS_T_KEY 25 62 /** Record type: Address (IPv6) */ 63 #define DNS_T_AAAA 28 64 /** Record type: Authoritative zone transfer */ 65 #define DNS_T_AXFR 252 66 /** Record type: Any (all known records) */ 67 #define DNS_T_ANY 255 68 69 /** Size of data used by \c dns_random_init */ 70 #define DNS_RANDOM_SEED (32*4) 71 /** Maximum number of IPs returned by \c dns_resolvconfip or used by \c dns_transmit_start */ 72 #define DNS_MAX_IPS 16 73 /** Maximum output size of \c dns_name4_domain */ 74 #define DNS_NAME4_DOMAIN (4*4+14) 75 /** Maximum output size of \c dns_name6_domain */ 76 #define DNS_NAME6_DOMAIN (32*2+10) 77 78 /** DNS transmission record */ 79 struct dns_transmit { 80 /** The transmitted query packet. This will either be \c NULL or dynamically allocated. */ 81 char *query; 82 /** The length of the transmitted query packet. */ 83 unsigned int querylen; 84 /** The received response packet. This will either be \c NULL or dynamically allocated. */ 85 char *packet; 86 /** The length of the received response packet. */ 87 unsigned int packetlen; 88 /** The socket file descriptor used for data transmission. This will 89 either be 0 or 1 + an open file descriptor. The addition is done 90 to allow the uninitialized state to be all zeros. */ 91 int s1; 92 /** Current state of the TCP connection. Valid values are: 93 94 \li 0 is uninitialized (ie using UDP) 95 \li 1 is connecting 96 \li 2 is connected, sending query 97 \li 3 is query sent, waiting for start of response 98 \li 4 is reading response length 99 \li 5 is read packet length, reading response 100 */ 101 int tcpstate; 102 /** Count of number of times the UDP query was sent to each server. */ 103 unsigned int udploop; 104 /** Index of the server we are currently sending to. */ 105 unsigned int curserver; 106 /** Deadline for considering a request timed out. */ 107 struct timeval deadline; 108 /** Current sending/receiving position within the buffer, for TCP transmissions. */ 109 unsigned int pos; 110 /** The list of servers to try. */ 111 const ipv4addr *servers; 112 /** The local IP address to transmit with. */ 113 ipv4addr localip; 114 /** The requested query type. */ 115 uint16 qtype; 116 }; 117 118 /** An individual result from a \c dns_mx query. */ 119 struct dns_mx 120 { 121 /** The distance (or preference) number for this MX. */ 122 uint16 distance; 123 /** The domain name of this MX. */ 124 char* name; 125 }; 126 127 union dns_result_rrs 128 { 129 void* __ptr; 130 ipv4addr* ip4; 131 ipv6addr* ip6; 132 struct dns_mx* mx; 133 char** name; 134 }; 135 136 /** DNS query results. */ 137 struct dns_result 138 { 139 /** The number of results present. */ 140 int count; 141 /** The record type of the results. */ 142 int type; 143 /** The individual record arrays. */ 144 union dns_result_rrs rr; 145 /** Internal use buffer pointer. */ 146 void* __buffer; 147 }; 148 149 extern int dns_result_alloc(struct dns_result* d, int type, int count, int size); 150 extern void dns_result_free(struct dns_result* d); 151 152 extern void dns_random_init(const char [DNS_RANDOM_SEED]); 153 extern unsigned int dns_random(unsigned int); 154 155 extern void dns_rotate(unsigned char*, unsigned int n, unsigned int shift); 156 extern void dns_rotateipv4(ipv4addr*, unsigned int); 157 extern void dns_rotateipv6(ipv6addr*, unsigned int); 158 159 extern void dns_sort_mx(struct dns_mx* mxs, int count); 160 161 extern void dns_domain_free(char **); 162 extern int dns_domain_copy(char **,const char *); 163 extern unsigned int dns_domain_length(const char *); 164 extern int dns_domain_equal(const char *,const char *); 165 extern int dns_domain_suffix(const char *,const char *); 166 extern unsigned int dns_domain_suffixpos(const char *,const char *); 167 extern int dns_domain_fromdot(char **,const char *,unsigned int); 168 extern int dns_domain_todot_cat(str *,const char *); 169 170 extern unsigned int dns_packet_copy(const char *,unsigned int,unsigned int,unsigned char *,unsigned int); 171 extern unsigned int dns_packet_getname(const char *,unsigned int,unsigned int,char **); 172 extern unsigned int dns_packet_skipname(const char *,unsigned int,unsigned int); 173 extern int dns_packet_extract(struct dns_result* out, const char* buf, unsigned int len, uint16 rrtype, uint16 rrclass, 174 int (*sizefn)(const char* buf, unsigned int len, unsigned int pos, uint16 datalen), 175 int (*copy)(struct dns_result* out, unsigned int index, unsigned int offset, 176 const char* buf, unsigned int len, unsigned int pos, uint16 datalen)); 177 178 extern int dns_transmit_start(struct dns_transmit *,const ipv4addr [DNS_MAX_IPS],int,const char *,uint16,const ipv4addr *); 179 extern void dns_transmit_free(struct dns_transmit *); 180 extern void dns_transmit_io(const struct dns_transmit *,iopoll_fd *,struct timeval *); 181 extern int dns_transmit_get(struct dns_transmit *,const iopoll_fd *,const struct timeval *); 182 183 extern int dns_read_resolvconf(str *out); 184 extern int dns_resolvconfip(ipv4addr [DNS_MAX_IPS]); 185 extern int dns_resolve(struct dns_transmit *,const char *,uint16); 186 187 extern int dns_ip4_packet(struct dns_result*, const char*, unsigned int); 188 extern int dns_ip4_r(struct dns_transmit*, struct dns_result*, const char *); 189 extern int dns_ip4(struct dns_result*, const char *); 190 extern int dns_ip6_packet(struct dns_result*, const char*, unsigned int); 191 extern int dns_ip6_r(struct dns_transmit*, struct dns_result*, const char *); 192 extern int dns_ip6(struct dns_result*, const char*); 193 extern int dns_name_packet(struct dns_result*, const char *,unsigned int); 194 extern void dns_name4_domain(char [DNS_NAME4_DOMAIN],const ipv4addr *); 195 extern void dns_name6_domain(char [DNS_NAME6_DOMAIN],const ipv6addr *); 196 extern int dns_name4_r(struct dns_transmit*, struct dns_result*, const ipv4addr*); 197 extern int dns_name4(struct dns_result*, const ipv4addr*); 198 extern int dns_name6_r(struct dns_transmit*, struct dns_result*, const ipv6addr*); 199 extern int dns_name6(struct dns_result*, const ipv6addr*); 200 extern int dns_txt_packet(struct dns_result*, const char *,unsigned int); 201 extern int dns_txt_r(struct dns_transmit *,struct dns_result*, const char *); 202 extern int dns_txt(struct dns_result*, const char *); 203 extern int dns_mx_packet(struct dns_result*, const char *,unsigned int); 204 extern int dns_mx_r(struct dns_transmit *,struct dns_result*, const char *); 205 extern int dns_mx(struct dns_result*, const char *); 206 207 extern int dns_resolvconfrewrite(str *); 208 extern int dns_qualify_rules(struct dns_result*,str *,const char *,const str *, 209 int (*)(struct dns_transmit*, struct dns_result*, const char*)); 210 extern int dns_qualify(struct dns_result*,str *,const char *, 211 int (*)(struct dns_transmit*, struct dns_result*, const char*)); 212 213 extern unsigned fmt_dns_domain(char*, const char*); 214 215 /** Wrapper macro to create a non-reentrant function from a \c dns_*_r function. */ 216 #define DNS_R_FN_WRAP(NAME,TYPE) \ 217 int dns_##NAME(struct dns_result* out,TYPE in) \ 218 { \ 219 struct dns_transmit tx = {0}; \ 220 int r = dns_##NAME##_r(&tx,out,in); \ 221 dns_transmit_free(&tx); \ 222 return r; \ 223 } 224 225 /** @} */ 226 227 #endif 228