1 /* 2 * Copyright (c) 2022-2023 Apple Inc. All rights reserved. 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 * https://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 DNS_OBJ_COMMON_H 18 #define DNS_OBJ_COMMON_H 19 20 //====================================================================================================================== 21 // MARK: - Headers 22 23 #include "ref_count.h" 24 #include <stdint.h> 25 #include <stdbool.h> 26 #include <ctype.h> 27 28 #include "nullability.h" 29 30 //====================================================================================================================== 31 // MARK: - Macro Helpers 32 33 #ifndef MIN 34 #define MIN(A, B) (((A) < (B)) ? (A) : (B)) 35 #endif 36 37 #ifndef MAX 38 #define MAX(A, B) (((A) > (B)) ? (A) : (B)) 39 #endif 40 41 #ifndef countof 42 #define countof(X) (sizeof(X) / sizeof(X[0])) 43 #endif 44 45 #ifndef countof_field 46 #define countof_field(TYPE, FIELD) countof(((TYPE *)0)->FIELD) 47 #endif 48 49 #ifndef likely 50 #define likely(EXPRESSSION) __builtin_expect(!!(EXPRESSSION), 1) 51 #endif 52 53 #ifndef unlikely 54 #define unlikely(EXPRESSSION) __builtin_expect(!!(EXPRESSSION), 0) 55 #endif 56 57 #ifndef isdigit_safe 58 #define isdigit_safe(X) isdigit(((unsigned char)((X) & 0xFF))) 59 #endif 60 61 #if (defined(__clang__) && __clang__) 62 #define DNS_OBJ_CLANG_WARNING_HELPER_0(X) #X 63 #define DNS_OBJ_CLANG_WARNING_HELPER_1(X) DNS_OBJ_CLANG_WARNING_HELPER_0(clang diagnostic ignored X) 64 #define DNS_OBJ_CLANG_WARNING_HELPER_2(Y) DNS_OBJ_CLANG_WARNING_HELPER_1(#Y) 65 #define DNS_OBJ_CLANG_WARNING(X) _Pragma(DNS_OBJ_CLANG_WARNING_HELPER_2(X)) 66 67 #define DNS_OBJ_CLANG_WARNING_IGNORE_BEGIN(X) \ 68 _Pragma( "clang diagnostic push" ) \ 69 DNS_OBJ_CLANG_WARNING(X) \ 70 do {} while( 0 ) 71 #else 72 #define DNS_OBJ_CLANG_WARNING_IGNORE_BEGIN(X) do {} while(0) 73 #endif 74 75 #if (defined(__clang__) && __clang__) 76 #define DNS_OBJ_CLANG_WARNING_IGNORE_END() _Pragma( "clang diagnostic pop" ) do {} while(0) 77 #else 78 #define DNS_OBJ_CLANG_WARNING_IGNORE_END() do {} while(0) 79 #endif 80 81 //====================================================================================================================== 82 // MARK: - Constants 83 84 typedef int32_t dns_obj_error_t; 85 #define DNS_OBJ_ERROR_NO_ERROR 0 // No error occurred. 86 87 #define DNS_OBJ_ERROR_GENERIC_ERROR_BASE -6700 // Starting error code for all generic errors. 88 #define DNS_OBJ_ERROR_UNKNOWN_ERR -6700 // Unknown error occurred. 89 #define DNS_OBJ_ERROR_PARAM_ERR -6705 // Parameter is incorrect, missing, or not appropriate. 90 #define DNS_OBJ_ERROR_STATE_ERR -6709 // Not in appropriate state to perform operation. 91 #define DNS_OBJ_ERROR_RANGE_ERR -6710 // Index is out of range or not valid. 92 #define DNS_OBJ_ERROR_REQUEST_ERR -6711 // Request was improperly formed or not appropriate. 93 #define DNS_OBJ_ERROR_NOT_INITIALIZED_ERR -6718 // Action request before needed services were initialized. 94 #define DNS_OBJ_ERROR_ALREADY_INITIALIZED_ERR -6719 // Attempt made to initialize when already initialized. 95 #define DNS_OBJ_ERROR_NOT_IN_USE_ERR -6720 // Object not in use (e.g. cannot abort if not already in use). 96 #define DNS_OBJ_ERROR_NOT_FOUND_ERR -6727 // Something was not found. 97 #define DNS_OBJ_ERROR_NO_MEMORY -6728 // Not enough memory was available to perform the operation. 98 #define DNS_OBJ_ERROR_NO_RESOURCES -6729 // Resources unavailable to perform the operation. 99 #define DNS_OBJ_ERROR_DUPLICATE_ERR -6730 // Duplicate found or something is a duplicate. 100 #define DNS_OBJ_ERROR_UNSUPPORTED_ERR -6735 // Feature or option is not supported. 101 #define DNS_OBJ_ERROR_UNEXPECTED_ERR -6736 // Error occurred that was not expected. 102 #define DNS_OBJ_ERROR_MALFORMED_ERR -6742 // Something was not formed correctly. 103 #define DNS_OBJ_ERROR_NOT_READY_ERR -6745 // Device or service is not ready. 104 #define DNS_OBJ_ERROR_MISMATCH_ERR -6748 // Something does not match. 105 #define DNS_OBJ_ERROR_DATE_ERR -6749 // Date is invalid or out-of-range. 106 #define DNS_OBJ_ERROR_AUTHENTICATION_ERR -6754 // Authentication failed or is not supported. 107 #define DNS_OBJ_ERROR_UNDER_RUN -6750 // Less data than expected. 108 #define DNS_OBJ_ERROR_OVER_RUN -6751 // More data than expected. 109 #define DNS_OBJ_ERROR_TYPE_ERR -6756 // Incorrect or incompatible type (e.g. file, data, etc.). 110 #define DNS_OBJ_ERROR_GENERIC_ERROR_END -6779 // Last generic error code (inclusive) 111 112 //====================================================================================================================== 113 // MARK: - DNS Message Common Values 114 115 #ifndef MAX_ESCAPED_DOMAIN_NAME 116 #define MAX_ESCAPED_DOMAIN_NAME 1009 117 #endif 118 119 #ifndef MAX_DOMAIN_NAME 120 #define MAX_DOMAIN_NAME 256 121 #endif 122 123 #ifndef MAX_DOMAIN_LABEL 124 #define MAX_DOMAIN_LABEL 63 125 #endif 126 127 #define MAX_UNICAST_TTL_IN_SECONDS ((uint32_t)3600) 128 129 // Record types 130 #ifndef kDNSRecordType_Enum 131 #define kDNSRecordType_Enum 132 typedef enum 133 { 134 kDNSRecordType_Invalid = 0, 135 kDNSRecordType_A = 1, 136 kDNSRecordType_NS = 2, 137 kDNSRecordType_MD = 3, 138 kDNSRecordType_MF = 4, 139 kDNSRecordType_CNAME = 5, 140 kDNSRecordType_SOA = 6, 141 kDNSRecordType_MB = 7, 142 kDNSRecordType_MG = 8, 143 kDNSRecordType_MR = 9, 144 kDNSRecordType_NULL = 10, 145 kDNSRecordType_WKS = 11, 146 kDNSRecordType_PTR = 12, 147 kDNSRecordType_HINFO = 13, 148 kDNSRecordType_MINFO = 14, 149 kDNSRecordType_MX = 15, 150 kDNSRecordType_TXT = 16, 151 kDNSRecordType_RP = 17, 152 kDNSRecordType_AFSDB = 18, 153 kDNSRecordType_X25 = 19, 154 kDNSRecordType_ISDN = 20, 155 kDNSRecordType_RT = 21, 156 kDNSRecordType_NSAP = 22, 157 kDNSRecordType_NSAP_PTR = 23, 158 kDNSRecordType_SIG = 24, 159 kDNSRecordType_KEY = 25, 160 kDNSRecordType_PX = 26, 161 kDNSRecordType_GPOS = 27, 162 kDNSRecordType_AAAA = 28, 163 kDNSRecordType_LOC = 29, 164 kDNSRecordType_NXT = 30, 165 kDNSRecordType_EID = 31, 166 kDNSRecordType_NIMLOC = 32, 167 kDNSRecordType_SRV = 33, 168 kDNSRecordType_ATMA = 34, 169 kDNSRecordType_NAPTR = 35, 170 kDNSRecordType_KX = 36, 171 kDNSRecordType_CERT = 37, 172 kDNSRecordType_A6 = 38, 173 kDNSRecordType_DNAME = 39, 174 kDNSRecordType_SINK = 40, 175 kDNSRecordType_OPT = 41, 176 kDNSRecordType_APL = 42, 177 kDNSRecordType_DS = 43, 178 kDNSRecordType_SSHFP = 44, 179 kDNSRecordType_IPSECKEY = 45, 180 kDNSRecordType_RRSIG = 46, 181 kDNSRecordType_NSEC = 47, 182 kDNSRecordType_DNSKEY = 48, 183 kDNSRecordType_DHCID = 49, 184 kDNSRecordType_NSEC3 = 50, 185 kDNSRecordType_NSEC3PARAM = 51, 186 kDNSRecordType_TLSA = 52, 187 kDNSRecordType_SMIMEA = 53, 188 kDNSRecordType_HIP = 55, 189 kDNSRecordType_NINFO = 56, 190 kDNSRecordType_RKEY = 57, 191 kDNSRecordType_TALINK = 58, 192 kDNSRecordType_CDS = 59, 193 kDNSRecordType_CDNSKEY = 60, 194 kDNSRecordType_OPENPGPKEY = 61, 195 kDNSRecordType_CSYNC = 62, 196 kDNSRecordType_ZONEMD = 63, 197 kDNSRecordType_SVCB = 64, 198 kDNSRecordType_HTTPS = 65, 199 kDNSRecordType_SPF = 99, 200 kDNSRecordType_UINFO = 100, 201 kDNSRecordType_UID = 101, 202 kDNSRecordType_GID = 102, 203 kDNSRecordType_UNSPEC = 103, 204 kDNSRecordType_NID = 104, 205 kDNSRecordType_L32 = 105, 206 kDNSRecordType_L64 = 106, 207 kDNSRecordType_LP = 107, 208 kDNSRecordType_EUI48 = 108, 209 kDNSRecordType_EUI64 = 109, 210 kDNSRecordType_TKEY = 249, 211 kDNSRecordType_TSIG = 250, 212 kDNSRecordType_IXFR = 251, 213 kDNSRecordType_AXFR = 252, 214 kDNSRecordType_MAILB = 253, 215 kDNSRecordType_MAILA = 254, 216 kDNSRecordType_ANY = 255, 217 kDNSRecordType_URI = 256, 218 kDNSRecordType_CAA = 257, 219 kDNSRecordType_AVC = 258, 220 kDNSRecordType_DOA = 259, 221 kDNSRecordType_AMTRELAY = 260, 222 kDNSRecordType_TA = 32768, 223 kDNSRecordType_DLV = 32769, 224 kDNSRecordType_Reserved = 65535, 225 226 } dns_record_type_t; 227 #endif // #ifndef kDNSRecordType_Enum 228 229 // Record class 230 #ifndef kDNSClassType_Enum 231 #define kDNSClassType_Enum 232 typedef enum 233 { 234 kDNSClassType_INVALID = 0, 235 kDNSClassType_IN = 1, 236 kDNSClassType_CHAOS = 3 237 238 } dns_class_type_t; 239 #endif //#ifndef kDNSClassType_Enum 240 241 //====================================================================================================================== 242 // MARK: - Resource Record Constants 243 244 #ifndef NSEC3_FLAG_TYPE_ENUM 245 #define NSEC3_FLAG_TYPE_ENUM 246 // NSEC3 hash flags 247 // Taken from https://www.iana.org/assignments/dnssec-nsec3-parameters/dnssec-nsec3-parameters.xhtml. 248 typedef enum nsec3_flag_type { 249 // Unassigned 0 - 6 250 NSEC3_FLAG_OPT_OUT = 0x01 251 } nsec3_flag_type_t; 252 #endif 253 254 #ifndef NSEC3_HASH_ALGORITHM_ENUM 255 #define NSEC3_HASH_ALGORITHM_ENUM 256 // NSEC3 hash algorithms 257 // Taken from https://www.iana.org/assignments/dnssec-nsec3-parameters/dnssec-nsec3-parameters.xhtml. 258 typedef enum nsec3_hash_algorithm_type { 259 // Reserved 0 260 NSEC3_HASH_ALGORITHM_SHA_1 = 1 261 // Unassigned 2 - 255 262 } nsec3_hash_algorithm_type_t; 263 #endif 264 265 //====================================================================================================================== 266 // MARK: - Functions 267 268 /*! 269 * @brief 270 * Get the uint16_t integer from the network-byte-order bytes. 271 * 272 * @param bytes 273 * The bytes that encode an uint16_t integer. 274 * 275 * @result 276 * The uint16_t integer. 277 */ 278 uint16_t 279 get_uint16_from_bytes(const uint8_t * NONNULL bytes); 280 281 /*! 282 * @brief 283 * Get the uint32_t integer from the network-byte-order bytes. 284 * 285 * @param bytes 286 * The bytes that encode an uint32_t integer. 287 * 288 * @result 289 * The uint32_t integer. 290 */ 291 uint32_t 292 get_uint32_from_bytes(const uint8_t * NONNULL bytes); 293 294 /*! 295 * @brief 296 * Put the uint16_t integer into network-byte-order bytes. 297 * 298 * @param u16 299 * The uint16_t integer. 300 * 301 * @param ptr 302 * The pointer to the buffer that stores the bytes in network byte order. 303 */ 304 void 305 put_uint16_to_bytes(uint16_t u16, uint8_t * NULLABLE * NONNULL ptr); 306 307 /*! 308 * @brief 309 * Put the uint32_t integer into network-byte-order bytes. 310 * 311 * @param u32 312 * The uint32_t integer. 313 * 314 * @param ptr 315 * The pointer to the buffer that stores the bytes in network byte order. 316 */ 317 void 318 put_uint32_to_bytes(uint32_t u32, uint8_t * NULLABLE * NONNULL ptr); 319 320 /*! 321 * @brief 322 * Convert the bytes to its hex representation in C string. 323 * 324 * @param bytes 325 * The bytes to be converted. 326 * 327 * @param len 328 * The length of the bytes. 329 * 330 * @param buffer 331 * The output buffer that holds the hex C string. 332 * 333 * @param buffer_len 334 * The max size of the buffer. 335 * 336 * @result 337 * If no error occurs, the next position of the hex C string end is returned. Otherwise, the value of <code>buffer</code> is returned. 338 * 339 * @discussion 340 * To do conversion successfully, the length of the buffer has to be greater than 2 times of the bytes length. 341 * 342 */ 343 char * NULLABLE 344 put_hex_from_bytes(const uint8_t * NULLABLE bytes, size_t len, char * const NONNULL buffer, size_t buffer_len); 345 346 /*! 347 * @brief 348 * Get the string description of the DNS record type. 349 * 350 * @param type 351 * The DNS record type. 352 * 353 * @result 354 * The string description. 355 */ 356 const char * NULLABLE 357 dns_record_type_value_to_string(uint16_t type); 358 359 /*! 360 * @brief 361 * Convert the integer error code to a string description. 362 * 363 * @param error 364 * The error to convert. 365 * 366 * @result 367 * The string description of the <code>error</code>. 368 */ 369 const char * NONNULL 370 dns_obj_error_get_error_description(dns_obj_error_t error); 371 372 #endif // DNS_OBJ_COMMON_H 373