Home | History | Annotate | Line # | Download | only in utilities
      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