1 /* 2 ** Copyright (C) 2006 Olivier DEMBOUR 3 ** $Id: dns.h,v 1.16.4.2 2010/06/01 16:05:05 collignon Exp $ 4 ** 5 ** 6 ** This program is free software; you can redistribute it and/or modify 7 ** it under the terms of the GNU General Public License as published by 8 ** the Free Software Foundation; either version 2 of the License, or 9 ** (at your option) any later version. 10 ** 11 ** This program is distributed in the hope that it will be useful, 12 ** but WITHOUT ANY WARRANTY; without even the implied warranty of 13 ** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 14 ** GNU General Public License for more details. 15 ** 16 ** You should have received a copy of the GNU General Public License 17 ** along with This program; if not, write to the Free Software 18 ** Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA 19 */ 20 21 #ifndef __DNS_H__ 22 #define __DNS_H__ 23 24 #include "config.h" 25 26 #ifndef _WIN32 27 #include <unistd.h> 28 #include <arpa/inet.h> 29 #else 30 #include "mywin32.h" 31 #endif 32 #include "base64.h" 33 34 #define MAX_DNS_LEN 512 35 #define MAX_EDNS_LEN 4096 36 37 #define EDNS_HEADER 11 38 39 #define MAX_HOST_NAME_ENCODED 200 /* need space for reply */ 40 #define MAX_HOST_NAME_DECODED DECODED_LEN((MAX_HOST_NAME_ENCODED)) 41 42 #define ENCODED_LEN(len) (((len) + (((len) / 63) + 1))) 43 #define DECODED_LEN(len) ( ((len)>0) ? (((len) - (((len) / 63) + 1))) : 0) 44 45 /* USE EDNS or std DNS */ 46 #define MAX_ENCODE_DATA(len, dns_size) \ 47 ( \ 48 (((len)+RR_HDR_SIZE) > (dns_size - AUTHORITATIVE_SIZE)) ? 0 : \ 49 DECODED_LEN(DECODED_BASE64_SIZE(\ 50 ( (dns_size - AUTHORITATIVE_SIZE) - (len) - (RR_HDR_SIZE)) ) \ 51 )) 52 53 #define MAX_RAW_DATA(len, dns_size) \ 54 ( \ 55 (((len)+RR_HDR_SIZE) > (dns_size - AUTHORITATIVE_SIZE)) ? 0 : \ 56 DECODED_BASE64_SIZE(\ 57 ( (dns_size - AUTHORITATIVE_SIZE) - (len) - (RR_HDR_SIZE) ) ) \ 58 ) 59 60 61 #define AUTHORITATIVE_SIZE 50 /* should be better defined ... */ 62 /* Additional record + Authoritative nameserver */ 63 64 65 #define ENCODE_DATA_AVAILABLE(len, query_len, dns_size) (client && (client->control.use_compress)) ? \ 66 ((MAX_ENCODE_DATA((len + 2), (dns_size)))) : \ 67 ((MAX_ENCODE_DATA((len + query_len), (dns_size)))) 68 69 #define RAW_DATA_AVAILABLE(len, query_len, dns_size) (client && (client->control.use_compress)) ? \ 70 ((MAX_RAW_DATA((len + 2), (dns_size)))) : \ 71 ((MAX_RAW_DATA((len + query_len), (dns_size)))) 72 73 /* 74 #define ENCODE_DATA_AVAILABLE(len, query_len, dns_size) (client && (client->control.use_compress)) ? \ 75 ((MAX_ENCODE_DATA((len) + 2, (dns_size + 1)))) : \ 76 ((MAX_ENCODE_DATA((len) + (query_len), (dns_size)))) 77 78 #define RAW_DATA_AVAILABLE(len, query_len, dns_size) (client && (client->control.use_compress)) ? \ 79 ((MAX_RAW_DATA((len) + 2, (dns_size + 1)))) : \ 80 ((MAX_RAW_DATA((len) + (query_len), (dns_size)))) 81 */ 82 #define MAX_QNAME_DATA(domain) (DECODED_BASE64_SIZE(MAX_HOST_NAME_DECODED - strlen(domain) - 1)) 83 84 /* GCC alignement padding workaround */ 85 86 #define DNS_HDR_SIZE 12 87 #define RR_HDR_SIZE 10 88 #define REQ_HDR_SIZE 4 89 90 #define JUMP_DNS_HDR(hdr) ((char *)hdr + DNS_HDR_SIZE) 91 #define JUMP_RR_HDR(hdr) ((char *)hdr + RR_HDR_SIZE) 92 #define JUMP_REQ_HDR(hdr) ((char *)hdr + REQ_HDR_SIZE) 93 94 #define COMPRESS_FLAG_CHAR 0xC0 95 #define COMPRESS_FLAG 0xC000 96 #define GET_DECOMPRESS_OFFSET(offset) ((ntohs(offset)) & ~(COMPRESS_FLAG)) 97 98 /* Why not */ 99 #define MAX_COMPRESS_DEPTH 10 100 101 102 /* Network order */ 103 #define PUT_16(dst, src) do \ 104 {\ 105 ((unsigned char *)(dst))[0] = (uint8_t) ((src ) >> 8) ; \ 106 ((unsigned char *)(dst))[1] = (uint8_t) (src) ; \ 107 } while (0) 108 109 #define PUT_32(dst, src) do \ 110 {\ 111 ((unsigned char *)(dst))[0] = (uint8_t) ((src ) >> 24) ; \ 112 ((unsigned char *)(dst))[1] = (uint8_t) ((src ) >> 16) ; \ 113 ((unsigned char *)(dst))[2] = (uint8_t) ((src ) >> 8) ; \ 114 ((unsigned char *)(dst))[3] = (uint8_t) (src) ; \ 115 } while (0) 116 117 /* Host order */ 118 #define GET_16(src) ((((unsigned char *)(src))[0] << 8) | (((unsigned char *)(src))[1]) ) 119 #define GET_32(src) (\ 120 (((unsigned char *)(src))[0] << 24) | \ 121 (((unsigned char *)(src))[1] << 16) | \ 122 (((unsigned char *)(src))[2] << 8) | \ 123 (((unsigned char *)(src))[3] ) \ 124 ) 125 126 /* FIXME hardcoded '=' is bad ! (check base64_padding ...) */ 127 #define RESOURCE "=resource." 128 #define AUTH "=auth." 129 #define CONNECT "=connect." 130 131 132 133 struct dns_hdr { 134 uint16_t id; 135 #ifndef WORDS_BIGENDIAN 136 uint16_t rd:1, /* recurse demand */ 137 tc:1, /* truncated */ 138 aa:1, /* authorative */ 139 opcode:4, 140 qr:1, 141 rcode:4, 142 z:3, 143 ra:1; /* recurse available */ 144 #else 145 uint16_t qr:1, 146 opcode:4, 147 aa:1, 148 tc:1, 149 rd:1, 150 ra:1, 151 z:3, 152 rcode:4; 153 #endif 154 #define RCODE_NO_ERR 0x0 155 #define RCODE_FORMAT_ERR 0x1 156 #define RCODE_SRV_FAILURE 0x2 157 #define RCODE_NAME_ERR 0x3 158 #define RCODE_NOT_IMPLEMENTED 0x4 159 #define RCODE_REFUSED 0x3 160 uint16_t qdcount; /* nb queries */ 161 uint16_t ancount; /* nb answers */ 162 uint16_t nscount; /* authority records */ 163 uint16_t arcount; /* additional records */ 164 } __attribute__((packed)); 165 166 167 #define MAX_DNS_ERROR 6 168 extern const char *dns_error[MAX_DNS_ERROR]; 169 170 struct req_hdr { 171 uint16_t qtype; /* TXT */ 172 uint16_t qclass; /* IN | CHAOS */ 173 } __attribute__((packed)); 174 175 struct rr_hdr { 176 uint16_t type; 177 #define TYPE_TXT 16 178 #define TYPE_KEY 25 179 uint16_t klass; 180 #define CLASS_IN 1 181 uint32_t ttl; 182 uint16_t rdlength; 183 } __attribute__((packed)); 184 185 struct add_record { 186 uint8_t name; 187 uint16_t type; 188 #define TYPE_EDNS 41 189 uint16_t payload_size; 190 uint8_t rcode; 191 uint8_t version; 192 uint16_t z; 193 uint16_t length; 194 } __attribute__((packed)); 195 196 void dns_simple_decode(char *input, char *output, int max_len); 197 void dns_simple_decode_strip_dot(char *input, char *output, int max_len); 198 void dns_encode(char *); 199 void *jump_end_query(void *, int, int); 200 void *jump_qname(void *, int); 201 void *jump_end_answer(void *buffer, int max_len); 202 void *jump_edns(void *buffer, int max_len); 203 204 #endif 205