1 /* dns.h - Declarations for dns handling and generic dns functions 2 3 Copyright (C) 2000, 2001 Thomas Moestl 4 Copyright (C) 2002, 2003, 2004, 2005, 2009, 2011 Paul A. Rombouts 5 6 This file is part of the pdnsd package. 7 8 pdnsd is free software; you can redistribute it and/or modify 9 it under the terms of the GNU General Public License as published by 10 the Free Software Foundation; either version 3 of the License, or 11 (at your option) any later version. 12 13 pdnsd is distributed in the hope that it will be useful, 14 but WITHOUT ANY WARRANTY; without even the implied warranty of 15 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 16 GNU General Public License for more details. 17 18 You should have received a copy of the GNU General Public License 19 along with pdnsd; see the file COPYING. If not, see 20 <http://www.gnu.org/licenses/>. 21 */ 22 23 24 #ifndef DNS_H 25 #define DNS_H 26 27 #include <config.h> 28 #include <arpa/inet.h> 29 #include <sys/socket.h> 30 #include <net/if.h> 31 #include <sys/types.h> 32 #include <inttypes.h> 33 #include "rr_types.h" 34 #include "list.h" 35 #include "ipvers.h" 36 37 #if (TARGET==TARGET_BSD) 38 # if !defined(__BIG_ENDIAN) 39 # if defined(BIG_ENDIAN) 40 # define __BIG_ENDIAN BIG_ENDIAN 41 # elif defined(_BIG_ENDIAN) 42 # define __BIG_ENDIAN _BIG_ENDIAN 43 # endif 44 # endif 45 # if !defined(__LITTLE_ENDIAN) 46 # if defined(LITTLE_ENDIAN) 47 # define __LITTLE_ENDIAN LITTLE_ENDIAN 48 # elif defined(_LITTLE_ENDIAN) 49 # define __LITTLE_ENDIAN _LITTLE_ENDIAN 50 # endif 51 # endif 52 # if !defined(__BYTE_ORDER) 53 # if defined(BYTE_ORDER) 54 # define __BYTE_ORDER BYTE_ORDER 55 # elif defined(_BYTE_ORDER) 56 # define __BYTE_ORDER _BYTE_ORDER 57 # endif 58 # endif 59 #endif 60 61 /* Deal with byte orders */ 62 #ifndef __BYTE_ORDER 63 # if defined(__LITTLE_ENDIAN) && defined(__BIG_ENDIAN) 64 # error Fuzzy endianness system! Both __LITTLE_ENDIAN and __BIG_ENDIAN have been defined! 65 # endif 66 # if !defined(__LITTLE_ENDIAN) && !defined(__BIG_ENDIAN) 67 # error Strange Endianness-less system! Neither __LITTLE_ENDIAN nor __BIG_ENDIAN has been defined! 68 # endif 69 # if defined(__LITTLE_ENDIAN) 70 # define __BYTE_ORDER __LITTLE_ENDIAN 71 # elif defined(__BIG_ENDIAN) 72 # define __BYTE_ORDER __BIG_ENDIAN 73 # endif 74 #endif 75 76 /* special rr type codes for queries */ 77 #define QT_MIN 251 78 #define QT_IXFR 251 79 #define QT_AXFR 252 80 #define QT_MAILB 253 81 #define QT_MAILA 254 82 #define QT_ALL 255 83 #define QT_MAX 255 84 #define QT_NUM 5 85 86 /* rr classes */ 87 #define C_MIN 1 88 #define C_IN 1 89 #define C_CS 2 90 #define C_CH 3 91 #define C_HS 4 92 #define C_MAX 4 93 #define C_NUM 4 94 95 /* special classes for queries */ 96 #define QC_ALL 255 97 98 /* status codes */ 99 #define RC_OK 0 100 #define RC_FORMAT 1 101 #define RC_SERVFAIL 2 102 #define RC_NAMEERR 3 103 #define RC_NOTSUPP 4 104 #define RC_REFUSED 5 105 #define RC_BADVERS 16 106 107 /* 108 * special internal retvals 109 */ 110 #define RC_NOTCACHED 0xfffa 111 #define RC_CACHED 0xfffb 112 #define RC_STALE 0xfffc 113 #define RC_TCPREFUSED 0xfffd 114 #define RC_TRUNC 0xfffe 115 #define RC_FATALERR 0xffff 116 117 /* query/response */ 118 #define QR_QUERY 0 119 #define QR_RESP 1 120 121 /*opcodes */ 122 #define OP_QUERY 0 123 #define OP_IQUERY 1 124 #define OP_STATUS 2 125 126 #if 0 127 typedef struct { 128 /* the name is the first field. It has variable length, so it can't be put in the struct */ 129 uint16_t type; 130 uint16_t class; 131 uint32_t ttl; 132 uint16_t rdlength; 133 /* rdata follows */ 134 } __attribute__((packed)) rr_hdr_t; 135 136 #define sizeof_rr_hdr_t (sizeof rr_hdr_t) 137 #else 138 139 /* We will not actually use the rr_hdr_t type, only its size: 140 sizeof(rr_hdr_t) = 2 + 2 + 4 + 2 */ 141 #define sizeof_rr_hdr_t 10 142 #endif 143 144 #define sizeof_opt_pseudo_rr (1+sizeof_rr_hdr_t) 145 146 #if 0 147 typedef struct { 148 /* The server name and maintainer mailbox are the first two fields. It has variable length, */ 149 /* so they can't be put in the struct */ 150 uint32_t serial; 151 uint32_t refresh; 152 uint32_t retry; 153 uint32_t expire; 154 uint32_t minimum; 155 } __attribute__((packed)) soa_r_t; 156 157 158 typedef struct { 159 /* char qname[];*/ 160 uint16_t qtype; 161 uint16_t qclass; 162 } __attribute__((packed)) std_query_t; 163 #endif 164 165 166 typedef struct { 167 uint16_t id; 168 #if __BYTE_ORDER == __LITTLE_ENDIAN 169 unsigned int rd:1; 170 unsigned int tc:1; 171 unsigned int aa:1; 172 unsigned int opcode:4; 173 unsigned int qr:1; 174 unsigned int rcode:4; 175 unsigned int cd:1; 176 unsigned int ad:1; 177 unsigned int z :1; 178 unsigned int ra:1; 179 #elif __BYTE_ORDER == __BIG_ENDIAN 180 unsigned int qr:1; 181 unsigned int opcode:4; 182 unsigned int aa:1; 183 unsigned int tc:1; 184 unsigned int rd:1; 185 unsigned int ra:1; 186 unsigned int z :1; 187 unsigned int ad:1; 188 unsigned int cd:1; 189 unsigned int rcode:4; 190 #else 191 # error "Please define __BYTE_ORDER to be __LITTLE_ENDIAN or __BIG_ENDIAN" 192 #endif 193 uint16_t qdcount; 194 uint16_t ancount; 195 uint16_t nscount; 196 uint16_t arcount; 197 } __attribute__((packed)) dns_hdr_t; 198 199 200 /* A structure that can also be used for DNS messages over TCP. */ 201 typedef struct { 202 #ifndef NO_TCP_QUERIES 203 uint16_t len; 204 #endif 205 dns_hdr_t hdr; 206 } __attribute__((packed)) dns_msg_t; 207 208 #ifdef NO_TCP_QUERIES 209 # define dnsmsghdroffset 0 210 #else 211 # define dnsmsghdroffset 2 212 #endif 213 214 215 /* Structure for storing EDNS (Extension mechanisms for DNS) information. */ 216 typedef struct { 217 unsigned short udpsize; 218 unsigned short rcode; 219 unsigned short version; 220 unsigned char do_flg; 221 } edns_info_t; 222 223 224 /* Macros to retrieve or store integer data that is not necessarily aligned. 225 Also takes care of network to host byte order. 226 The pointer cp is advanced and should be of type void* or char*. 227 These are actually adapted versions of the NS_GET16 and NS_GET32 228 macros in the arpa/nameser.h include file in the BIND 9 source. 229 */ 230 231 #define GETINT16(s,cp) do { \ 232 register uint16_t t_s; \ 233 register const unsigned char *t_cp = (const unsigned char *)(cp); \ 234 t_s = (uint16_t)*t_cp++ << 8; \ 235 t_s |= (uint16_t)*t_cp++; \ 236 (s) = t_s; \ 237 (cp) = (void *)t_cp; \ 238 } while (0) 239 240 #define GETINT32(l,cp) do { \ 241 register uint32_t t_l; \ 242 register const unsigned char *t_cp = (const unsigned char *)(cp); \ 243 t_l = (uint32_t)*t_cp++ << 24; \ 244 t_l |= (uint32_t)*t_cp++ << 16; \ 245 t_l |= (uint32_t)*t_cp++ << 8; \ 246 t_l |= (uint32_t)*t_cp++; \ 247 (l) = t_l; \ 248 (cp) = (void *)t_cp; \ 249 } while (0) 250 251 #define PUTINT16(s,cp) do { \ 252 register uint16_t t_s = (uint16_t)(s); \ 253 register unsigned char *t_cp = (unsigned char *)(cp); \ 254 *t_cp++ = t_s >> 8; \ 255 *t_cp++ = t_s; \ 256 (cp) = (void *)t_cp; \ 257 } while (0) 258 259 #define PUTINT32(l,cp) do { \ 260 register uint32_t t_l = (uint32_t)(l); \ 261 register unsigned char *t_cp = (unsigned char *)(cp); \ 262 *t_cp++ = t_l >> 24; \ 263 *t_cp++ = t_l >> 16; \ 264 *t_cp++ = t_l >> 8; \ 265 *t_cp++ = t_l; \ 266 (cp) = (void *)t_cp; \ 267 } while (0) 268 269 270 /* Size (number of bytes) of buffers used to hold domain names. */ 271 #define DNSNAMEBUFSIZE 256 272 273 /* Recursion depth. */ 274 #define MAX_HOPS 20 275 276 /* 277 * Types for compression buffers. 278 */ 279 typedef struct { 280 unsigned int index; 281 unsigned char s[0]; 282 } compel_t; 283 284 285 286 int decompress_name(unsigned char *msg, size_t msgsz, unsigned char **src, size_t *sz, unsigned char *tgt, unsigned int *len); 287 /* int domain_name_match(const unsigned char *ms, const unsigned char *md, int *os, int *od); */ 288 unsigned int domain_match(const unsigned char *ms, const unsigned char *md, unsigned int *os, unsigned int *od); 289 unsigned int compress_name(unsigned char *in, unsigned char *out, unsigned int offs, dlist *cb); 290 int a2ptrstr(pdnsd_ca *a, int tp, unsigned char *buf); 291 int read_hosts(const char *fn, unsigned char *rns, time_t ttl, unsigned flags, int aliases, char **errstr); 292 293 const char *getrrtpname(int tp); 294 #if DEBUG>0 295 const char *get_cname(int id); 296 const char *get_tname(int id); 297 const char *get_ename(int id); 298 #define DNSFLAGSMAXSTRSIZE (7*3+1) 299 char *dnsflags2str(dns_hdr_t *hdr, char *buf); 300 #endif 301 302 #if DEBUG>=9 303 void debug_dump_dns_msg(void *data, size_t len); 304 #define DEBUG_DUMP_DNS_MSG(d,l) {if(debug_p && global.verbosity>=9) debug_dump_dns_msg(d,l);} 305 #else 306 #define DEBUG_DUMP_DNS_MSG(d,l) 307 #endif 308 309 #endif 310