1 /* 2 * FreeRTOS+TCP <DEVELOPMENT BRANCH> 3 * Copyright (C) 2022 Amazon.com, Inc. or its affiliates. All Rights Reserved. 4 * 5 * SPDX-License-Identifier: MIT 6 * 7 * Permission is hereby granted, free of charge, to any person obtaining a copy of 8 * this software and associated documentation files (the "Software"), to deal in 9 * the Software without restriction, including without limitation the rights to 10 * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of 11 * the Software, and to permit persons to whom the Software is furnished to do so, 12 * subject to the following conditions: 13 * 14 * The above copyright notice and this permission notice shall be included in all 15 * copies or substantial portions of the Software. 16 * 17 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 18 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS 19 * FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR 20 * COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER 21 * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN 22 * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 23 * 24 * http://aws.amazon.com/freertos 25 * http://www.FreeRTOS.org 26 */ 27 28 #ifndef FREERTOS_DNS_GLOBALS_H 29 #define FREERTOS_DNS_GLOBALS_H 30 31 #include "FreeRTOS.h" 32 33 #include "FreeRTOSIPConfig.h" 34 #include "FreeRTOSIPConfigDefaults.h" 35 #include "IPTraceMacroDefaults.h" 36 37 #include "FreeRTOS_Sockets.h" 38 39 #define dnsPARSE_ERROR 0UL 40 41 #if ( ipconfigBYTE_ORDER == pdFREERTOS_LITTLE_ENDIAN ) 42 #define dnsDNS_PORT 0x3500U /**< Little endian: Port used for DNS. */ 43 #define dnsONE_QUESTION 0x0100U /**< Little endian representation of a DNS question.*/ 44 #define dnsOUTGOING_FLAGS 0x0001U /**< Little endian representation of standard query. */ 45 #define dnsRX_FLAGS_MASK 0x0f80U /**< Little endian: The bits of interest in the flags field of incoming DNS messages. */ 46 #define dnsEXPECTED_RX_FLAGS 0x0080U /**< Little Endian: Should be a response, without any errors. */ 47 #else 48 #define dnsDNS_PORT 0x0035U /**< Big endian: Port used for DNS. */ 49 #define dnsONE_QUESTION 0x0001U /**< Big endian representation of a DNS question.*/ 50 #define dnsOUTGOING_FLAGS 0x0100U /**< Big endian representation of standard query. */ 51 #define dnsRX_FLAGS_MASK 0x800fU /**< Big endian: The bits of interest in the flags field of incoming DNS messages. */ 52 #define dnsEXPECTED_RX_FLAGS 0x8000U /**< Big endian: Should be a response, without any errors. */ 53 54 #endif /* ipconfigBYTE_ORDER */ 55 #if ( ipconfigUSE_DNS != 0 ) 56 57 /** @brief If the top two bits in the first character of a name field are set then the 58 * name field is an offset to the string, rather than the string itself. */ 59 #define dnsNAME_IS_OFFSET ( ( uint8_t ) 0xc0 ) 60 61 /** @brief The maximum number of times a DNS request should be sent out if a response 62 * is not received, before giving up. */ 63 #ifndef ipconfigDNS_REQUEST_ATTEMPTS 64 #define ipconfigDNS_REQUEST_ATTEMPTS 5 65 #endif 66 67 68 /* NBNS flags. */ 69 #if ( ipconfigUSE_NBNS == 1 ) 70 #define dnsNBNS_FLAGS_RESPONSE 0x8000U /**< NBNS response flag. */ 71 #define dnsNBNS_FLAGS_OPCODE_MASK 0x7800U /**< NBNS opcode bitmask. */ 72 #define dnsNBNS_FLAGS_OPCODE_QUERY 0x0000U /**< NBNS opcode query. */ 73 #endif /* ( ipconfigUSE_NBNS == 1 ) */ 74 75 /* Host types. */ 76 #define dnsTYPE_A_HOST 0x01U /**< DNS type A host. */ 77 #define dnsTYPE_AAAA_HOST 0x001CU 78 #define dnsTYPE_ANY_HOST 0x00FFU 79 80 #define dnsCLASS_IN 0x01U /**< DNS class IN (Internet). */ 81 82 /* Maximum hostname length as defined in RFC 1035 section 3.1. */ 83 #define dnsMAX_HOSTNAME_LENGTH 0xFFU 84 85 #ifndef _lint 86 /* LLMNR constants. */ 87 #define dnsLLMNR_TTL_VALUE 300U /**< LLMNR time to live value of 5 minutes. */ 88 #define dnsLLMNR_FLAGS_IS_REPONSE 0x8000U /**< LLMNR flag value for response. */ 89 #endif /* _lint */ 90 91 /* NBNS constants. */ 92 #if ( ipconfigUSE_NBNS != 0 ) 93 #define dnsNBNS_TTL_VALUE 3600UL /**< NBNS TTL: 1 hour valid. */ 94 #define dnsNBNS_TYPE_NET_BIOS 0x0020U /**< NBNS Type: NetBIOS. */ 95 #define dnsNBNS_CLASS_IN 0x01U /**< NBNS Class: IN (Internet). */ 96 #define dnsNBNS_NAME_FLAGS 0x6000U /**< NBNS name flags. */ 97 #define dnsNBNS_ENCODED_NAME_LENGTH 32 /**< NBNS encoded name length. */ 98 99 /** @brief If the queried NBNS name matches with the device's name, 100 * the query will be responded to with these flags: */ 101 #define dnsNBNS_QUERY_RESPONSE_FLAGS ( 0x8500U ) 102 #endif /* ( ipconfigUSE_NBNS != 0 ) */ 103 104 105 #ifndef _lint 106 #if ( ipconfigUSE_DNS_CACHE == 0 ) 107 #if ( ipconfigDNS_CACHE_ADDRESSES_PER_ENTRY != 1 ) 108 #error When DNS caching is disabled, please make ipconfigDNS_CACHE_ADDRESSES_PER_ENTRY equal to 1. 109 #endif 110 #endif 111 #endif 112 113 /** @brief Define the ASCII value of '.' (Period/Full-stop). */ 114 #define ASCII_BASELINE_DOT 46U 115 116 /* The Link-local Multicast Name Resolution (LLMNR) 117 * is included. 118 * Note that a special MAC address is required in addition to the NIC's actual 119 * MAC address: 01:00:5E:00:00:FC 120 * 121 * The target IP address will be 224.0.0.252 122 */ 123 #if ( ipconfigBYTE_ORDER == pdFREERTOS_BIG_ENDIAN ) 124 #define ipLLMNR_IP_ADDR 0xE00000FCUL 125 #else 126 #define ipLLMNR_IP_ADDR 0xFC0000E0UL 127 #endif /* ipconfigBYTE_ORDER == pdFREERTOS_BIG_ENDIAN */ 128 129 #define ipMDNS_TIME_TO_LIVE 255U 130 131 #define ipLLMNR_PORT 5355U /* Standard LLMNR port. */ 132 #define ipDNS_PORT 53U /* Standard DNS port. */ 133 #define ipNBNS_PORT 137U /* NetBIOS Name Service. */ 134 #define ipNBDGM_PORT 138U /* Datagram Service, not included. */ 135 136 /** @brief freertos_addrinfo is the equivalent of 'struct addrinfo'. */ 137 struct freertos_addrinfo 138 { 139 BaseType_t ai_flags; /**< The field is included for completeness, but it is not used. */ 140 BaseType_t ai_family; /**< The type of IP-address, either FREERTOS_AF_INET4 or FREERTOS_AF_INET6. */ 141 BaseType_t ai_socktype; /**< n.a. */ 142 BaseType_t ai_protocol; /**< n.a. */ 143 socklen_t ai_addrlen; /**< The length of the address, either ipSIZE_OF_IPv4_ADDRESS or ipSIZE_OF_IPv6_ADDRESS. */ 144 struct freertos_sockaddr * ai_addr; /**< The socket address. */ 145 char * ai_canonname; /**< The name of the host. */ 146 struct freertos_addrinfo * ai_next; /**< A pointer to the next find result, or NULL. */ 147 struct 148 { 149 /* In order to avoid allocations, reserve space here for *ai_addr and *ai_canonname. */ 150 struct freertos_sockaddr sockaddr; 151 152 #if ( ipconfigUSE_DNS_CACHE != 0 ) 153 char ucName[ ipconfigDNS_CACHE_NAME_LENGTH ]; 154 #endif 155 } 156 xPrivateStorage; /**< In order to avoid extra calls to malloc, the necessary space is reserved 'statically'. */ 157 }; 158 /* DNS answer record header. */ 159 #include "pack_struct_start.h" 160 struct xDNSAnswerRecord 161 { 162 uint16_t usType; /**< Type of DNS answer record. */ 163 uint16_t usClass; /**< Class of DNS answer record. */ 164 uint32_t ulTTL; /**< Number of seconds the result can be cached. */ 165 uint16_t usDataLength; /**< Length of the data field. */ 166 } 167 #include "pack_struct_end.h" 168 typedef struct xDNSAnswerRecord DNSAnswerRecord_t; 169 170 /* Below #include just tells the compiler to pack the structure. 171 * It is included in to make the code more readable */ 172 #include "pack_struct_start.h" 173 struct xDNSMessage 174 { 175 uint16_t usIdentifier; /**< Query identifier. Used to match up replies to outstanding queries. */ 176 uint16_t usFlags; /**< Flags. */ 177 uint16_t usQuestions; /**< Number of questions asked in this query. */ 178 uint16_t usAnswers; /**< Number of answers being provided in this query. */ 179 uint16_t usAuthorityRRs; /**< Authoritative name server resource records. */ 180 uint16_t usAdditionalRRs; /**< Additional resource records.*/ 181 } 182 #include "pack_struct_end.h" 183 typedef struct xDNSMessage DNSMessage_t; 184 185 /** @brief A struct with a set of variables that are shared among the helper functions 186 * for the function 'DNS_ParseDNSReply()'. For internal use only. 187 */ 188 typedef struct xParseSet 189 { 190 DNSMessage_t * pxDNSMessageHeader; /**< A pointer to the UDP payload buffer where the DNS message is stored. */ 191 uint16_t usQuestions; /**< The number of DNS questions that were asked. */ 192 uint8_t * pucUDPPayloadBuffer; /**< A pointer to the original UDP load buffer. */ 193 uint8_t * pucByte; /**< A pointer that is used while parsing. */ 194 size_t uxBufferLength; /**< The total number of bytes received in the UDP payload. */ 195 size_t uxSourceBytesRemaining; /**< As pucByte is incremented, 'uxSourceBytesRemaining' will be decremented. */ 196 uint16_t usType; /**< The type of address, recognised are dnsTYPE_A_HOST ( Ipv4 ) and 197 * dnsTYPE_AAAA_HOST ( IPv6 ). */ 198 uint32_t ulIPAddress; /**< The IPv4 address found. In an IPv6 look-up, store a non-zero value when 199 * an IPv6 address was found. */ 200 size_t uxAddressLength; /**< The size of the address, either ipSIZE_OF_IPv4_ADDRESS or 201 * ipSIZE_OF_IPv6_ADDRESS */ 202 uint16_t usNumARecordsStored; /**< The number of A-records stored during a look-up. */ 203 uint16_t usPortNumber; /**< The port number that belong to the protocol ( DNS, MDNS etc ). */ 204 #if ( ipconfigUSE_LLMNR == 1 ) || ( ipconfigUSE_MDNS == 1 ) 205 uint16_t usClass; /**< Only the value 'dnsCLASS_IN' is recognised, which stands for "Internet". */ 206 char * pcRequestedName; /**< A pointer to the full name of the host being looked up. */ 207 #endif 208 #if ( ipconfigUSE_DNS_CACHE == 1 ) || ( ipconfigDNS_USE_CALLBACKS == 1 ) || ( ipconfigUSE_MDNS == 1 ) 209 BaseType_t xDoStore; /**< Becomes true when a DNS reply was requested by this device, 210 * i.e. it has a matching request ID. */ 211 char pcName[ ipconfigDNS_CACHE_NAME_LENGTH ]; /**< A copy of the name that is mentioned in the questions. */ 212 #endif 213 struct freertos_addrinfo * pxLastAddress; /**< This variable is used while creating a linked-list of IP-addresses. */ 214 struct freertos_addrinfo ** ppxLastAddress; /**< This variable is also used while creating a linked-list of IP-addresses. */ 215 } ParseSet_t; 216 #if ( ipconfigUSE_LLMNR == 1 ) || ( ipconfigUSE_MDNS == 1 ) 217 218 #include "pack_struct_start.h" 219 struct xLLMNRAnswer 220 { 221 uint8_t ucNameCode; /**< Name type. */ 222 uint8_t ucNameOffset; /**< The name is not repeated in the answer, only the offset is given with "0xc0 <offs>" */ 223 uint16_t usType; /**< Type of the Resource record. */ 224 uint16_t usClass; /**< Class of the Resource record. */ 225 uint32_t ulTTL; /**< Seconds till this entry can be cached. */ 226 uint16_t usDataLength; /**< Length of the address in this record. */ 227 uint32_t ulIPAddress; /**< The IP-address. */ 228 } 229 #include "pack_struct_end.h" 230 typedef struct xLLMNRAnswer LLMNRAnswer_t; 231 #endif /* if ( ipconfigUSE_LLMNR == 1 ) || ( ipconfigUSE_MDNS == 1 ) */ 232 233 #if ( ipconfigUSE_NBNS == 1 ) 234 235 #include "pack_struct_start.h" 236 struct xNBNSRequest 237 { 238 uint16_t usRequestId; /**< NBNS request ID. */ 239 uint16_t usFlags; /**< Flags of the DNS message. */ 240 uint16_t ulRequestCount; /**< The number of requests/questions in this query. */ 241 uint16_t usAnswerRSS; /**< The number of answers in this query. */ 242 uint16_t usAuthRSS; /**< Number of authoritative resource records. */ 243 uint16_t usAdditionalRSS; /**< Number of additional resource records. */ 244 uint8_t ucNameSpace; /**< Length of name. */ 245 uint8_t ucName[ dnsNBNS_ENCODED_NAME_LENGTH ]; /**< The domain name. */ 246 uint8_t ucNameZero; /**< Terminator of the name. */ 247 uint16_t usType; /**< Type of NBNS record. */ 248 uint16_t usClass; /**< Class of NBNS request. */ 249 } 250 #include "pack_struct_end.h" 251 typedef struct xNBNSRequest NBNSRequest_t; 252 253 #include "pack_struct_start.h" 254 struct xNBNSAnswer 255 { 256 uint16_t usType; /**< Type of NBNS answer. */ 257 uint16_t usClass; /**< Class of NBNS answer. */ 258 uint32_t ulTTL; /**< Time in seconds for which the answer can be cached. */ 259 uint16_t usDataLength; /**< Data length. */ 260 uint16_t usNbFlags; /**< NetBIOS flags 0x6000 : IP-address, big-endian. */ 261 uint32_t ulIPAddress; /**< The IPv4 address. */ 262 } 263 #include "pack_struct_end.h" 264 typedef struct xNBNSAnswer NBNSAnswer_t; 265 #endif /* if ( ipconfigUSE_NBNS == 1 ) */ 266 267 #if ( ipconfigDNS_USE_CALLBACKS != 0 ) 268 269 /* 270 * Users may define this type of function as a callback. 271 * It will be called when a DNS reply is received or when a timeout has been reached. 272 */ 273 typedef void (* FOnDNSEvent ) ( const char * /* pcName */, 274 void * /* pvSearchID */, 275 struct freertos_addrinfo * /* pxAddressInfo */ ); 276 /** @brief The structure to hold information for a DNS callback. */ 277 typedef struct xDNS_Callback 278 { 279 TickType_t uxRemainingTime; /**< Timeout in ms */ 280 FOnDNSEvent pCallbackFunction; /**< Function to be called when the address has been found or when a timeout has been reached */ 281 TimeOut_t uxTimeoutState; /**< Timeout state. */ 282 void * pvSearchID; /**< Search ID of the callback function. */ 283 struct xLIST_ITEM xListItem; /**< List struct. */ 284 BaseType_t xIsIPv6; /**< Remember whether this was a IPv6 lookup. */ 285 char pcName[ 1 ]; /**< 1 character name. */ 286 } DNSCallback_t; 287 #endif /* if ( ipconfigDNS_USE_CALLBACKS != 0 ) */ 288 289 /** 290 * @brief structure to hold the buffer, its size and the data length 291 */ 292 typedef struct xDNSBuffer 293 { 294 uint8_t * pucPayloadBuffer; /**< Buffer pointer */ 295 size_t uxPayloadLength; /**< Payload size */ 296 } DNSBuffer_t; 297 298 #if ( ipconfigUSE_MDNS == 1 ) || ( ipconfigUSE_LLMNR == 1 ) || ( ipconfigUSE_NBNS == 1 ) 299 300 /* 301 * The following function should be provided by the user and return true if it 302 * matches the domain name. 303 */ 304 #if ( ipconfigIPv4_BACKWARD_COMPATIBLE == 1 ) 305 /* Even though the function is defined in main.c, the rule is violated. */ 306 /* misra_c_2012_rule_8_6_violation */ 307 extern BaseType_t xApplicationDNSQueryHook( const char * pcName ); 308 #else 309 /* Even though the function is defined in main.c, the rule is violated. */ 310 /* misra_c_2012_rule_8_6_violation */ 311 extern BaseType_t xApplicationDNSQueryHook_Multi( struct xNetworkEndPoint * pxEndPoint, 312 const char * pcName ); 313 #endif 314 315 #endif /* ( ipconfigUSE_LLMNR == 1 ) || ( ipconfigUSE_NBNS == 1 ) */ 316 #endif /* ipconfigUSE_DNS */ 317 318 /* Keeping this outside of ipconfigUSE_DNS flag as these are used inside IPv4 UDP code */ 319 #define ipMDNS_PORT 5353U /* Standard mDNS port. */ 320 321 #if ( ipconfigBYTE_ORDER == pdFREERTOS_BIG_ENDIAN ) 322 #define ipMDNS_IP_ADDRESS 0xe00000fbU /* 224.0.0.251 */ 323 #else 324 #define ipMDNS_IP_ADDRESS 0xfb0000e0U /* 224.0.0.251 */ 325 #endif 326 327 #endif /* ifndef FREERTOS_DNS_GLOBALS_H */ 328