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 21extern "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 "@WDNS_VERSION@" 159#define WDNS_LIBRARY_VERSION_NUMBER @WDNS_MAJOR_VERSION@ * 1000000L + @WDNS_MINOR_VERSION@ * 1000L + @WDNS_PATCHLEVEL_VERSION@ 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 182typedef 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 201typedef struct { 202 uint8_t len; 203 uint8_t *data; 204} wdns_name_t; 205 206typedef struct { 207 uint16_t len; 208 uint8_t data[]; 209} wdns_rdata_t; 210 211typedef 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 219typedef 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 228typedef 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 235typedef 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 243typedef 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 253typedef void (*wdns_callback_name)(wdns_name_t *name, void *user); 254 255/* Functions for converting objects to presentation format strings. */ 256 257const char * wdns_res_to_str(wdns_res res); 258const char * wdns_opcode_to_str(uint16_t dns_opcode); 259const char * wdns_rcode_to_str(uint16_t dns_rcode); 260const char * wdns_rrclass_to_str(uint16_t dns_class); 261const char * wdns_rrtype_to_str(uint16_t dns_type); 262size_t wdns_domain_to_str(const uint8_t *src, size_t src_len, char *dst); 263 264char * wdns_message_to_str(wdns_message_t *m); 265char * wdns_rrset_array_to_str(wdns_rrset_array_t *a, unsigned sec); 266char * wdns_rrset_to_str(wdns_rrset_t *rrset, unsigned sec); 267char * wdns_rr_to_str(wdns_rr_t *rr, unsigned sec); 268char * 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 273WDNS_WARN_UNUSED_RESULT 274wdns_res 275wdns_str_to_name(const char *str, wdns_name_t *name); 276 277WDNS_WARN_UNUSED_RESULT 278wdns_res 279wdns_str_to_name_case(const char *str, wdns_name_t *name); 280 281wdns_res 282wdns_str_to_rcode(const char *str, uint16_t *out); 283 284uint16_t 285wdns_str_to_rrtype(const char *str); 286 287uint16_t 288wdns_str_to_rrclass(const char *str); 289 290wdns_res 291wdns_str_to_rdata(const char * str, uint16_t rrtype, uint16_t rrclass, 292 uint8_t **rdata, size_t *rdlen); 293 294/* Comparison functions. */ 295 296bool wdns_compare_rr_rrset(const wdns_rr_t *rr, const wdns_rrset_t *rrset); 297 298/* Functions for clearing wdns objects. */ 299 300void wdns_clear_message(wdns_message_t *m); 301void wdns_clear_rr(wdns_rr_t *rr); 302void wdns_clear_rrset(wdns_rrset_t *rrset); 303void wdns_clear_rrset_array(wdns_rrset_array_t *a); 304 305/* Functions for printing formatted output. */ 306 307void wdns_print_message(FILE *fp, wdns_message_t *m); 308void wdns_print_rr(FILE *fp, wdns_rr_t *rr, unsigned sec); 309void wdns_print_rrset(FILE *fp, wdns_rrset_t *rrset, unsigned sec); 310void wdns_print_rrset_array(FILE *fp, wdns_rrset_array_t *a, unsigned sec); 311 312/* Utility functions. */ 313 314size_t wdns_skip_name(const uint8_t **data, const uint8_t *eod); 315 316wdns_res 317wdns_copy_uname(const uint8_t *p, const uint8_t *eop, const uint8_t *src, 318 uint8_t *dst, size_t *sz); 319 320wdns_res 321wdns_len_uname(const uint8_t *p, const uint8_t *eop, size_t *sz); 322 323wdns_res 324wdns_sort_rrset(wdns_rrset_t *); 325 326wdns_res 327wdns_unpack_name(const uint8_t *p, const uint8_t *eop, const uint8_t *src, 328 uint8_t *dst, size_t *sz); 329 330wdns_res 331wdns_count_labels(wdns_name_t *name, size_t *nlabels); 332 333wdns_res 334wdns_is_subdomain(wdns_name_t *n0, wdns_name_t *n1, bool *is_subdomain); 335 336wdns_res 337wdns_file_load_names(const char *fname, wdns_callback_name cb, void *user); 338 339wdns_res 340wdns_left_chop(wdns_name_t *name, wdns_name_t *chop); 341 342WDNS_WARN_UNUSED_RESULT 343wdns_res 344wdns_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 */ 350const 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 */ 358uint32_t wdns_get_version_number(void); 359 360/* Parsing functions. */ 361 362wdns_res 363wdns_parse_message(wdns_message_t *m, const uint8_t *pkt, size_t len); 364 365/* Deserialization functions. */ 366 367wdns_res 368wdns_deserialize_rrset(wdns_rrset_t *rrset, const uint8_t *buf, size_t sz); 369 370/* Serialization functions. */ 371 372wdns_res 373wdns_serialize_rrset(const wdns_rrset_t *rrset, uint8_t *buf, size_t *sz); 374 375/* Downcasing functions. */ 376 377void 378wdns_downcase_name(wdns_name_t *name); 379 380wdns_res 381wdns_downcase_rdata(wdns_rdata_t *rdata, uint16_t rrtype, uint16_t rrclass); 382 383wdns_res 384wdns_downcase_rrset(wdns_rrset_t *rrset); 385 386#ifdef __cplusplus 387} 388#endif 389 390#endif /* WDNS_H */ 391