1 /*
2  * FreeRTOS+TCP V3.1.0
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 /* Standard includes. */
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 dnsCLASS_IN               0x01U /**< DNS class IN (Internet). */
78 
79 /* Maximum hostname length as defined in RFC 1035 section 3.1. */
80     #define dnsMAX_HOSTNAME_LENGTH    0xFFU
81 
82     #ifndef _lint
83         /* LLMNR constants. */
84         #define dnsLLMNR_TTL_VALUE           300U     /**< LLMNR time to live value of 5 minutes. */
85         #define dnsLLMNR_FLAGS_IS_REPONSE    0x8000U  /**< LLMNR flag value for response. */
86     #endif /* _lint */
87 
88 /* NBNS constants. */
89     #if ( ipconfigUSE_NBNS != 0 )
90         #define dnsNBNS_TTL_VALUE               3600UL  /**< NBNS TTL: 1 hour valid. */
91         #define dnsNBNS_TYPE_NET_BIOS           0x0020U /**< NBNS Type: NetBIOS. */
92         #define dnsNBNS_CLASS_IN                0x01U   /**< NBNS Class: IN (Internet). */
93         #define dnsNBNS_NAME_FLAGS              0x6000U /**< NBNS name flags. */
94         #define dnsNBNS_ENCODED_NAME_LENGTH     32      /**< NBNS encoded name length. */
95 
96 /** @brief If the queried NBNS name matches with the device's name,
97  * the query will be responded to with these flags: */
98         #define dnsNBNS_QUERY_RESPONSE_FLAGS    ( 0x8500U )
99     #endif /* ( ipconfigUSE_NBNS != 0 ) */
100 
101 
102     #ifndef _lint
103         #if ( ipconfigUSE_DNS_CACHE == 0 )
104             #if ( ipconfigDNS_CACHE_ADDRESSES_PER_ENTRY != 1 )
105                 #error When DNS caching is disabled, please make ipconfigDNS_CACHE_ADDRESSES_PER_ENTRY equal to 1.
106             #endif
107         #endif
108     #endif
109 
110 /** @brief Define the ASCII value of '.' (Period/Full-stop). */
111     #define ASCII_BASELINE_DOT    46U
112 
113 /* The Link-local Multicast Name Resolution (LLMNR)
114  * is included.
115  * Note that a special MAC address is required in addition to the NIC's actual
116  * MAC address: 01:00:5E:00:00:FC
117  *
118  * The target IP address will be 224.0.0.252
119  */
120     #if ( ipconfigBYTE_ORDER == pdFREERTOS_BIG_ENDIAN )
121         #define ipLLMNR_IP_ADDR    0xE00000FCUL
122     #else
123         #define ipLLMNR_IP_ADDR    0xFC0000E0UL
124     #endif /* ipconfigBYTE_ORDER == pdFREERTOS_BIG_ENDIAN */
125 
126     #define ipLLMNR_PORT           5355 /* Standard LLMNR port. */
127     #define ipDNS_PORT             53   /* Standard DNS port. */
128     #define ipDHCP_CLIENT          67
129     #define ipDHCP_SERVER          68
130     #define ipNBNS_PORT            137 /* NetBIOS Name Service. */
131     #define ipNBDGM_PORT           138 /* Datagram Service, not included. */
132 
133 /* DNS answer record header. */
134     #include "pack_struct_start.h"
135     struct xDNSAnswerRecord
136     {
137         uint16_t usType;       /**< Type of DNS answer record. */
138         uint16_t usClass;      /**< Class of DNS answer record. */
139         uint32_t ulTTL;        /**< Number of seconds the result can be cached. */
140         uint16_t usDataLength; /**< Length of the data field. */
141     }
142     #include "pack_struct_end.h"
143     typedef struct xDNSAnswerRecord DNSAnswerRecord_t;
144 
145 /* Below #include just tells the compiler to pack the structure.
146  * It is included in to make the code more readable */
147     #include "pack_struct_start.h"
148     struct xDNSMessage
149     {
150         uint16_t usIdentifier;    /**< Query identifier. Used to match up replies to outstanding queries. */
151         uint16_t usFlags;         /**< Flags. */
152         uint16_t usQuestions;     /**< Number of questions asked in this query. */
153         uint16_t usAnswers;       /**< Number of answers being provided in this query. */
154         uint16_t usAuthorityRRs;  /**< Authoritative name server resource records. */
155         uint16_t usAdditionalRRs; /**< Additional resource records.*/
156     }
157     #include "pack_struct_end.h"
158     typedef struct xDNSMessage DNSMessage_t;
159 
160     #if ( ipconfigUSE_LLMNR == 1 )
161 
162         #include "pack_struct_start.h"
163         struct xLLMNRAnswer
164         {
165             uint8_t ucNameCode;    /**< Name type. */
166             uint8_t ucNameOffset;  /**< The name is not repeated in the answer, only the offset is given with "0xc0 <offs>" */
167             uint16_t usType;       /**< Type of the Resource record. */
168             uint16_t usClass;      /**< Class of the Resource record. */
169             uint32_t ulTTL;        /**< Seconds till this entry can be cached. */
170             uint16_t usDataLength; /**< Length of the address in this record. */
171             uint32_t ulIPAddress;  /**< The IP-address. */
172         }
173         #include "pack_struct_end.h"
174         typedef struct xLLMNRAnswer LLMNRAnswer_t;
175     #endif /* if ( ipconfigUSE_LLMNR == 1 ) */
176 
177     #if ( ipconfigUSE_NBNS == 1 )
178 
179         #include "pack_struct_start.h"
180         struct xNBNSRequest
181         {
182             uint16_t usRequestId;                          /**< NBNS request ID. */
183             uint16_t usFlags;                              /**< Flags of the DNS message. */
184             uint16_t ulRequestCount;                       /**< The number of requests/questions in this query. */
185             uint16_t usAnswerRSS;                          /**< The number of answers in this query. */
186             uint16_t usAuthRSS;                            /**< Number of authoritative resource records. */
187             uint16_t usAdditionalRSS;                      /**< Number of additional resource records. */
188             uint8_t ucNameSpace;                           /**< Length of name. */
189             uint8_t ucName[ dnsNBNS_ENCODED_NAME_LENGTH ]; /**< The domain name. */
190             uint8_t ucNameZero;                            /**< Terminator of the name. */
191             uint16_t usType;                               /**< Type of NBNS record. */
192             uint16_t usClass;                              /**< Class of NBNS request. */
193         }
194         #include "pack_struct_end.h"
195         typedef struct xNBNSRequest NBNSRequest_t;
196 
197         #include "pack_struct_start.h"
198         struct xNBNSAnswer
199         {
200             uint16_t usType;       /**< Type of NBNS answer. */
201             uint16_t usClass;      /**< Class of NBNS answer. */
202             uint32_t ulTTL;        /**< Time in seconds for which the answer can be cached. */
203             uint16_t usDataLength; /**< Data length. */
204             uint16_t usNbFlags;    /**< NetBIOS flags 0x6000 : IP-address, big-endian. */
205             uint32_t ulIPAddress;  /**< The IPv4 address. */
206         }
207         #include "pack_struct_end.h"
208         typedef struct xNBNSAnswer NBNSAnswer_t;
209     #endif /* if ( ipconfigUSE_NBNS == 1 ) */
210 
211     #if ( ipconfigDNS_USE_CALLBACKS != 0 )
212 
213 /*
214  * Users may define this type of function as a callback.
215  * It will be called when a DNS reply is received or when a timeout has been reached.
216  */
217         typedef void (* FOnDNSEvent ) ( const char * /* pcName */,
218                                         void * /* pvSearchID */,
219                                         uint32_t /* ulIPAddress */ );
220         /** @brief The structure to hold information for a DNS callback. */
221         typedef struct xDNS_Callback
222         {
223             TickType_t uxRemainingTime;    /**< Timeout in ms */
224             FOnDNSEvent pCallbackFunction; /**< Function to be called when the address has been found or when a timeout has been reached */
225             TimeOut_t uxTimeoutState;      /**< Timeout state. */
226             void * pvSearchID;             /**< Search ID of the callback function. */
227             struct xLIST_ITEM xListItem;   /**< List struct. */
228             char pcName[ 1 ];              /**< 1 character name. */
229         } DNSCallback_t;
230     #endif /* if ( ipconfigDNS_USE_CALLBACKS != 0 ) */
231 
232 /**
233  * @brief structure to hold the buffer, its size and the data length
234  */
235     typedef struct xDNSBuffer
236     {
237         uint8_t * pucPayloadBuffer; /**< Buffer pointer */
238         size_t uxPayloadLength;     /**< Payload size */
239         size_t uxPayloadSize;       /**< Total buffer size */
240     } DNSBuffer_t;
241 
242     #if ( ipconfigUSE_LLMNR == 1 ) || ( ipconfigUSE_NBNS == 1 )
243 
244 /*
245  * The following function should be provided by the user and return true if it
246  * matches the domain name.
247  */
248         extern BaseType_t xApplicationDNSQueryHook( const char * pcName );
249     #endif /* ( ipconfigUSE_LLMNR == 1 ) || ( ipconfigUSE_NBNS == 1 ) */
250 #endif /* ipconfigUSE_DNS */
251 #endif /* ifndef FREERTOS_DNS_GLOBALS_H */
252