1 /* 2 * Copyright (c) 2009, 2012-2015, 2018 by Farsight Security, Inc. 3 * 4 * Licensed under the Apache License, Version 2.0 (the "License"); 5 * you may not use this file except in compliance with the License. 6 * You may obtain a copy of the License at 7 * 8 * http://www.apache.org/licenses/LICENSE-2.0 9 * 10 * Unless required by applicable law or agreed to in writing, software 11 * distributed under the License is distributed on an "AS IS" BASIS, 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 * See the License for the specific language governing permissions and 14 * limitations under the License. 15 */ 16 17 #ifndef WDNS_H 18 #define WDNS_H 19 20 #ifdef __cplusplus 21 extern "C" { 22 #endif 23 24 #include <stdbool.h> 25 #include <stdint.h> 26 #include <stdio.h> 27 28 /* Constants. */ 29 30 #define WDNS_LEN_HEADER 12 31 #define WDNS_MAXLEN_NAME 255 32 33 #define WDNS_MSG_SEC_QUESTION 0 34 #define WDNS_MSG_SEC_ANSWER 1 35 #define WDNS_MSG_SEC_AUTHORITY 2 36 #define WDNS_MSG_SEC_ADDITIONAL 3 37 #define WDNS_MSG_SEC_MAX 4 38 39 #define WDNS_PRESLEN_NAME 1025 40 #define WDNS_PRESLEN_TYPE_A 16 41 #define WDNS_PRESLEN_TYPE_AAAA 46 42 43 #define WDNS_OP_QUERY 0 44 #define WDNS_OP_IQUERY 1 45 #define WDNS_OP_STATUS 2 46 #define WDNS_OP_NOTIFY 4 47 #define WDNS_OP_UPDATE 5 48 49 #define WDNS_R_NOERROR 0 50 #define WDNS_R_FORMERR 1 51 #define WDNS_R_SERVFAIL 2 52 #define WDNS_R_NXDOMAIN 3 53 #define WDNS_R_NOTIMP 4 54 #define WDNS_R_REFUSED 5 55 #define WDNS_R_YXDOMAIN 6 56 #define WDNS_R_YXRRSET 7 57 #define WDNS_R_NXRRSET 8 58 #define WDNS_R_NOTAUTH 9 59 #define WDNS_R_NOTZONE 10 60 #define WDNS_R_BADVERS 16 61 62 #define WDNS_CLASS_IN 1 63 #define WDNS_CLASS_CH 3 64 #define WDNS_CLASS_HS 4 65 #define WDNS_CLASS_NONE 254 66 #define WDNS_CLASS_ANY 255 67 68 #define WDNS_TYPE_A 1 69 #define WDNS_TYPE_NS 2 70 #define WDNS_TYPE_MD 3 71 #define WDNS_TYPE_MF 4 72 #define WDNS_TYPE_CNAME 5 73 #define WDNS_TYPE_SOA 6 74 #define WDNS_TYPE_MB 7 75 #define WDNS_TYPE_MG 8 76 #define WDNS_TYPE_MR 9 77 #define WDNS_TYPE_NULL 10 78 #define WDNS_TYPE_WKS 11 79 #define WDNS_TYPE_PTR 12 80 #define WDNS_TYPE_HINFO 13 81 #define WDNS_TYPE_MINFO 14 82 #define WDNS_TYPE_MX 15 83 #define WDNS_TYPE_TXT 16 84 #define WDNS_TYPE_RP 17 85 #define WDNS_TYPE_AFSDB 18 86 #define WDNS_TYPE_X25 19 87 #define WDNS_TYPE_ISDN 20 88 #define WDNS_TYPE_RT 21 89 #define WDNS_TYPE_NSAP 22 90 #define WDNS_TYPE_NSAP_PTR 23 91 #define WDNS_TYPE_SIG 24 92 #define WDNS_TYPE_KEY 25 93 #define WDNS_TYPE_PX 26 94 #define WDNS_TYPE_GPOS 27 95 #define WDNS_TYPE_AAAA 28 96 #define WDNS_TYPE_LOC 29 97 #define WDNS_TYPE_NXT 30 98 #define WDNS_TYPE_EID 31 99 #define WDNS_TYPE_NIMLOC 32 100 #define WDNS_TYPE_SRV 33 101 #define WDNS_TYPE_ATMA 34 102 #define WDNS_TYPE_NAPTR 35 103 #define WDNS_TYPE_KX 36 104 #define WDNS_TYPE_CERT 37 105 #define WDNS_TYPE_A6 38 106 #define WDNS_TYPE_DNAME 39 107 #define WDNS_TYPE_SINK 40 108 #define WDNS_TYPE_OPT 41 109 #define WDNS_TYPE_APL 42 110 #define WDNS_TYPE_DS 43 111 #define WDNS_TYPE_SSHFP 44 112 #define WDNS_TYPE_IPSECKEY 45 113 #define WDNS_TYPE_RRSIG 46 114 #define WDNS_TYPE_NSEC 47 115 #define WDNS_TYPE_DNSKEY 48 116 #define WDNS_TYPE_DHCID 49 117 #define WDNS_TYPE_NSEC3 50 118 #define WDNS_TYPE_NSEC3PARAM 51 119 #define WDNS_TYPE_TLSA 52 120 /* Unassigned: 53 - 54 */ 121 #define WDNS_TYPE_HIP 55 122 #define WDNS_TYPE_NINFO 56 123 #define WDNS_TYPE_RKEY 57 124 #define WDNS_TYPE_TALINK 58 125 #define WDNS_TYPE_CDS 59 126 #define WDNS_TYPE_CDNSKEY 60 127 #define WDNS_TYPE_OPENPGPKEY 61 128 #define WDNS_TYPE_CSYNC 62 129 /* Unassigned: 63 - 98 */ 130 #define WDNS_TYPE_SPF 99 131 #define WDNS_TYPE_UINFO 100 132 #define WDNS_TYPE_UID 101 133 #define WDNS_TYPE_GID 102 134 #define WDNS_TYPE_UNSPEC 103 135 #define WDNS_TYPE_NID 104 136 #define WDNS_TYPE_L32 105 137 #define WDNS_TYPE_L64 106 138 #define WDNS_TYPE_LP 107 139 #define WDNS_TYPE_EUI48 108 140 #define WDNS_TYPE_EUI64 109 141 /* Unassigned: 110 - 248 */ 142 #define WDNS_TYPE_TKEY 249 143 #define WDNS_TYPE_TSIG 250 144 #define WDNS_TYPE_IXFR 251 145 #define WDNS_TYPE_AXFR 252 146 #define WDNS_TYPE_MAILB 253 147 #define WDNS_TYPE_MAILA 254 148 #define WDNS_TYPE_ANY 255 149 #define WDNS_TYPE_URI 256 150 #define WDNS_TYPE_CAA 257 151 /* Unassigned: 258 - 32767 */ 152 #define WDNS_TYPE_TA 32768 153 #define WDNS_TYPE_DLV 32769 154 /* Unassigned: 32770 - 65279 */ 155 /* Private use: 65280 - 65534 */ 156 /* Reserved: 65535 */ 157 158 #define WDNS_LIBRARY_VERSION "0.10.0" 159 #define WDNS_LIBRARY_VERSION_NUMBER 0 * 1000000L + 10 * 1000L + 0 160 161 /* Macros. */ 162 163 #define WDNS_FLAGS_QR(msg) ((((msg).flags) >> 15) & 0x01) 164 #define WDNS_FLAGS_OPCODE(msg) ((((msg).flags) >> 11) & 0x0f) 165 #define WDNS_FLAGS_AA(msg) ((((msg).flags) >> 10) & 0x01) 166 #define WDNS_FLAGS_TC(msg) ((((msg).flags) >> 9) & 0x01) 167 #define WDNS_FLAGS_RD(msg) ((((msg).flags) >> 8) & 0x01) 168 #define WDNS_FLAGS_RA(msg) ((((msg).flags) >> 7) & 0x01) 169 #define WDNS_FLAGS_Z(msg) ((((msg).flags) >> 6) & 0x01) 170 #define WDNS_FLAGS_AD(msg) ((((msg).flags) >> 5) & 0x01) 171 #define WDNS_FLAGS_CD(msg) ((((msg).flags) >> 4) & 0x01) 172 #define WDNS_FLAGS_RCODE(msg) ((msg).rcode) 173 174 #if defined(__GNUC__) 175 # define WDNS_WARN_UNUSED_RESULT __attribute__ ((warn_unused_result)) 176 #else 177 # define WDNS_WARN_UNUSED_RESULT 178 #endif 179 180 /* Data structures and definitions. */ 181 182 typedef enum { 183 wdns_res_success, 184 wdns_res_failure, 185 wdns_res_invalid_compression_pointer, 186 wdns_res_invalid_length_octet, 187 wdns_res_invalid_opcode, 188 wdns_res_invalid_rcode, 189 wdns_res_len, 190 wdns_res_malloc, 191 wdns_res_name_len, 192 wdns_res_name_overflow, 193 wdns_res_out_of_bounds, 194 wdns_res_overflow, 195 wdns_res_parse_error, 196 wdns_res_qdcount, 197 wdns_res_unknown_opcode, 198 wdns_res_unknown_rcode, 199 } wdns_res; 200 201 typedef struct { 202 uint8_t len; 203 uint8_t *data; 204 } wdns_name_t; 205 206 typedef struct { 207 uint16_t len; 208 uint8_t data[]; 209 } wdns_rdata_t; 210 211 typedef struct { 212 uint32_t rrttl; 213 uint16_t rrtype; 214 uint16_t rrclass; 215 wdns_name_t name; 216 wdns_rdata_t *rdata; 217 } wdns_rr_t; 218 219 typedef struct { 220 uint32_t rrttl; 221 uint16_t rrtype; 222 uint16_t rrclass; 223 uint16_t n_rdatas; 224 wdns_name_t name; 225 wdns_rdata_t **rdatas; 226 } wdns_rrset_t; 227 228 typedef struct { 229 uint16_t n_rrs; 230 uint16_t n_rrsets; 231 wdns_rr_t *rrs; 232 wdns_rrset_t *rrsets; 233 } wdns_rrset_array_t; 234 235 typedef struct { 236 bool present; 237 uint8_t version; 238 uint16_t flags; 239 uint16_t size; 240 wdns_rdata_t *options; 241 } wdns_edns_t; 242 243 typedef struct { 244 wdns_rrset_array_t sections[4]; 245 wdns_edns_t edns; 246 uint16_t id; 247 uint16_t flags; 248 uint16_t rcode; 249 } wdns_message_t; 250 251 /* Function prototypes. */ 252 253 typedef void (*wdns_callback_name)(wdns_name_t *name, void *user); 254 255 /* Functions for converting objects to presentation format strings. */ 256 257 const char * wdns_res_to_str(wdns_res res); 258 const char * wdns_opcode_to_str(uint16_t dns_opcode); 259 const char * wdns_rcode_to_str(uint16_t dns_rcode); 260 const char * wdns_rrclass_to_str(uint16_t dns_class); 261 const char * wdns_rrtype_to_str(uint16_t dns_type); 262 size_t wdns_domain_to_str(const uint8_t *src, size_t src_len, char *dst); 263 264 char * wdns_message_to_str(wdns_message_t *m); 265 char * wdns_rrset_array_to_str(wdns_rrset_array_t *a, unsigned sec); 266 char * wdns_rrset_to_str(wdns_rrset_t *rrset, unsigned sec); 267 char * wdns_rr_to_str(wdns_rr_t *rr, unsigned sec); 268 char * wdns_rdata_to_str(const uint8_t *rdata, uint16_t rdlen, 269 uint16_t rrtype, uint16_t rrclass); 270 271 /* Functions for converting presentation format strings to objects. */ 272 273 WDNS_WARN_UNUSED_RESULT 274 wdns_res 275 wdns_str_to_name(const char *str, wdns_name_t *name); 276 277 WDNS_WARN_UNUSED_RESULT 278 wdns_res 279 wdns_str_to_name_case(const char *str, wdns_name_t *name); 280 281 wdns_res 282 wdns_str_to_rcode(const char *str, uint16_t *out); 283 284 uint16_t 285 wdns_str_to_rrtype(const char *str); 286 287 uint16_t 288 wdns_str_to_rrclass(const char *str); 289 290 wdns_res 291 wdns_str_to_rdata(const char * str, uint16_t rrtype, uint16_t rrclass, 292 uint8_t **rdata, size_t *rdlen); 293 294 /* Comparison functions. */ 295 296 bool wdns_compare_rr_rrset(const wdns_rr_t *rr, const wdns_rrset_t *rrset); 297 298 /* Functions for clearing wdns objects. */ 299 300 void wdns_clear_message(wdns_message_t *m); 301 void wdns_clear_rr(wdns_rr_t *rr); 302 void wdns_clear_rrset(wdns_rrset_t *rrset); 303 void wdns_clear_rrset_array(wdns_rrset_array_t *a); 304 305 /* Functions for printing formatted output. */ 306 307 void wdns_print_message(FILE *fp, wdns_message_t *m); 308 void wdns_print_rr(FILE *fp, wdns_rr_t *rr, unsigned sec); 309 void wdns_print_rrset(FILE *fp, wdns_rrset_t *rrset, unsigned sec); 310 void wdns_print_rrset_array(FILE *fp, wdns_rrset_array_t *a, unsigned sec); 311 312 /* Utility functions. */ 313 314 size_t wdns_skip_name(const uint8_t **data, const uint8_t *eod); 315 316 wdns_res 317 wdns_copy_uname(const uint8_t *p, const uint8_t *eop, const uint8_t *src, 318 uint8_t *dst, size_t *sz); 319 320 wdns_res 321 wdns_len_uname(const uint8_t *p, const uint8_t *eop, size_t *sz); 322 323 wdns_res 324 wdns_sort_rrset(wdns_rrset_t *); 325 326 wdns_res 327 wdns_unpack_name(const uint8_t *p, const uint8_t *eop, const uint8_t *src, 328 uint8_t *dst, size_t *sz); 329 330 wdns_res 331 wdns_count_labels(wdns_name_t *name, size_t *nlabels); 332 333 wdns_res 334 wdns_is_subdomain(wdns_name_t *n0, wdns_name_t *n1, bool *is_subdomain); 335 336 wdns_res 337 wdns_file_load_names(const char *fname, wdns_callback_name cb, void *user); 338 339 wdns_res 340 wdns_left_chop(wdns_name_t *name, wdns_name_t *chop); 341 342 WDNS_WARN_UNUSED_RESULT 343 wdns_res 344 wdns_reverse_name(const uint8_t *name, size_t len_name, uint8_t *rev_name); 345 346 /** 347 * Retrieve the semantic library version as a string. This function was 348 * Introduced in version 0.10.0. 349 */ 350 const char *wdns_get_version(void); 351 352 /** 353 * Retrieve the semantic library version as a packed integer. The number is a 354 * combination of the major, minor, and patchelevel numbers as per: 355 * MAJOR * 1000000 + MINOR * 1000 + PATCHLEVEL. This function was introduced 356 * in version 0.10.0. 357 */ 358 uint32_t wdns_get_version_number(void); 359 360 /* Parsing functions. */ 361 362 wdns_res 363 wdns_parse_message(wdns_message_t *m, const uint8_t *pkt, size_t len); 364 365 /* Deserialization functions. */ 366 367 wdns_res 368 wdns_deserialize_rrset(wdns_rrset_t *rrset, const uint8_t *buf, size_t sz); 369 370 /* Serialization functions. */ 371 372 wdns_res 373 wdns_serialize_rrset(const wdns_rrset_t *rrset, uint8_t *buf, size_t *sz); 374 375 /* Downcasing functions. */ 376 377 void 378 wdns_downcase_name(wdns_name_t *name); 379 380 wdns_res 381 wdns_downcase_rdata(wdns_rdata_t *rdata, uint16_t rrtype, uint16_t rrclass); 382 383 wdns_res 384 wdns_downcase_rrset(wdns_rrset_t *rrset); 385 386 #ifdef __cplusplus 387 } 388 #endif 389 390 #endif /* WDNS_H */ 391