1 |
hedin |
15 |
/*********************************************************************
|
2 |
|
|
*
|
3 |
|
|
* Domain Name System (DNS) Client
|
4 |
|
|
* Module for Microchip TCP/IP Stack
|
5 |
|
|
* -Provides hostname to IP address translation
|
6 |
|
|
* -Reference: RFC 1035
|
7 |
|
|
*
|
8 |
|
|
*********************************************************************
|
9 |
|
|
* FileName: DNS.c
|
10 |
|
|
* Dependencies: UDP, ARP, Tick
|
11 |
|
|
* Processor: PIC18, PIC24F, PIC24H, dsPIC30F, dsPIC33F
|
12 |
|
|
* Complier: Microchip C18 v3.02 or higher
|
13 |
|
|
* Microchip C30 v2.05 or higher
|
14 |
|
|
* Company: Microchip Technology, Inc.
|
15 |
|
|
*
|
16 |
|
|
* Software License Agreement
|
17 |
|
|
*
|
18 |
|
|
* Copyright © 2002-2007 Microchip Technology Inc. All rights
|
19 |
|
|
* reserved.
|
20 |
|
|
*
|
21 |
|
|
* Microchip licenses to you the right to use, modify, copy, and
|
22 |
|
|
* distribute:
|
23 |
|
|
* (i) the Software when embedded on a Microchip microcontroller or
|
24 |
|
|
* digital signal controller product (“Device”) which is
|
25 |
|
|
* integrated into Licensee’s product; or
|
26 |
|
|
* (ii) ONLY the Software driver source files ENC28J60.c and
|
27 |
|
|
* ENC28J60.h ported to a non-Microchip device used in
|
28 |
|
|
* conjunction with a Microchip ethernet controller for the
|
29 |
|
|
* sole purpose of interfacing with the ethernet controller.
|
30 |
|
|
*
|
31 |
|
|
* You should refer to the license agreement accompanying this
|
32 |
|
|
* Software for additional information regarding your rights and
|
33 |
|
|
* obligations.
|
34 |
|
|
*
|
35 |
|
|
* THE SOFTWARE AND DOCUMENTATION ARE PROVIDED “AS IS” WITHOUT
|
36 |
|
|
* WARRANTY OF ANY KIND, EITHER EXPRESS OR IMPLIED, INCLUDING WITHOUT
|
37 |
|
|
* LIMITATION, ANY WARRANTY OF MERCHANTABILITY, FITNESS FOR A
|
38 |
|
|
* PARTICULAR PURPOSE, TITLE AND NON-INFRINGEMENT. IN NO EVENT SHALL
|
39 |
|
|
* MICROCHIP BE LIABLE FOR ANY INCIDENTAL, SPECIAL, INDIRECT OR
|
40 |
|
|
* CONSEQUENTIAL DAMAGES, LOST PROFITS OR LOST DATA, COST OF
|
41 |
|
|
* PROCUREMENT OF SUBSTITUTE GOODS, TECHNOLOGY OR SERVICES, ANY CLAIMS
|
42 |
|
|
* BY THIRD PARTIES (INCLUDING BUT NOT LIMITED TO ANY DEFENSE
|
43 |
|
|
* THEREOF), ANY CLAIMS FOR INDEMNITY OR CONTRIBUTION, OR OTHER
|
44 |
|
|
* SIMILAR COSTS, WHETHER ASSERTED ON THE BASIS OF CONTRACT, TORT
|
45 |
|
|
* (INCLUDING NEGLIGENCE), BREACH OF WARRANTY, OR OTHERWISE.
|
46 |
|
|
*
|
47 |
|
|
*
|
48 |
|
|
* Author Date Comment
|
49 |
|
|
*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
50 |
|
|
* Howard Schlunder 7/31/06 Original
|
51 |
|
|
* Howard Schlunder 10/09/06 Added DNSBeginUsage(), DNSEndUsage()
|
52 |
|
|
* module ownership semaphore
|
53 |
|
|
********************************************************************/
|
54 |
|
|
#define __DNS_C
|
55 |
|
|
|
56 |
|
|
#include "TCPIP Stack/TCPIP.h"
|
57 |
|
|
|
58 |
|
|
#if defined(STACK_USE_DNS)
|
59 |
|
|
|
60 |
|
|
|
61 |
|
|
#define DNS_PORT 53u
|
62 |
|
|
#define DNS_TIMEOUT (TICK_SECOND*2)
|
63 |
|
|
|
64 |
|
|
|
65 |
|
|
|
66 |
|
|
static UDP_SOCKET MySocket = INVALID_UDP_SOCKET;
|
67 |
|
|
static BYTE *DNSHostName;
|
68 |
|
|
static ROM BYTE *DNSHostNameROM;
|
69 |
|
|
static BYTE RecordType;
|
70 |
|
|
static union
|
71 |
|
|
{
|
72 |
|
|
BYTE Val;
|
73 |
|
|
struct
|
74 |
|
|
{
|
75 |
|
|
unsigned char DNSInUse : 1;
|
76 |
|
|
unsigned char AddressValid : 1;
|
77 |
|
|
unsigned char filler : 6;
|
78 |
|
|
} bits;
|
79 |
|
|
} Flags = {0x00};
|
80 |
|
|
static enum
|
81 |
|
|
{
|
82 |
|
|
DNS_HOME = 0,
|
83 |
|
|
DNS_RESOLVE_ARP,
|
84 |
|
|
DNS_OPEN_SOCKET,
|
85 |
|
|
DNS_QUERY,
|
86 |
|
|
DNS_GET_RESULT,
|
87 |
|
|
DNS_DONE
|
88 |
|
|
} smDNS = DNS_DONE;
|
89 |
|
|
|
90 |
|
|
typedef struct _DNS_HEADER
|
91 |
|
|
{
|
92 |
|
|
WORD_VAL TransactionID;
|
93 |
|
|
WORD_VAL Flags;
|
94 |
|
|
WORD_VAL Questions;
|
95 |
|
|
WORD_VAL Answers;
|
96 |
|
|
WORD_VAL AuthoritativeRecords;
|
97 |
|
|
WORD_VAL AdditionalRecords;
|
98 |
|
|
} DNS_HEADER;
|
99 |
|
|
|
100 |
|
|
typedef struct _DNS_ANSWER_HEADER
|
101 |
|
|
{
|
102 |
|
|
WORD_VAL ResponseName;
|
103 |
|
|
WORD_VAL ResponseType;
|
104 |
|
|
WORD_VAL ResponseClass;
|
105 |
|
|
DWORD_VAL ResponseTTL;
|
106 |
|
|
WORD_VAL ResponseLen;
|
107 |
|
|
} DNS_ANSWER_HEADER;
|
108 |
|
|
|
109 |
|
|
static void DNSPutString(BYTE *String);
|
110 |
|
|
static void DNSPutROMString(ROM BYTE *String);
|
111 |
|
|
static void DNSGetString(BYTE *String);
|
112 |
|
|
|
113 |
|
|
|
114 |
|
|
/*********************************************************************
|
115 |
|
|
* Function: BOOL DNSBeginUsage(void)
|
116 |
|
|
*
|
117 |
|
|
* PreCondition: Stack is initialized()
|
118 |
|
|
*
|
119 |
|
|
* Input: None
|
120 |
|
|
*
|
121 |
|
|
* Output: TRUE: If no DNS resolution operations are in progress and this application has successfully taken ownership of the DNS module
|
122 |
|
|
* FALSE: If the DNS module is currently being used by some other module. Call DNSBeginUsage() some time later (after returning to the main() program loop).
|
123 |
|
|
*
|
124 |
|
|
* Side Effects: None
|
125 |
|
|
*
|
126 |
|
|
* Overview: Call DNSBeginUsage() and make sure it returns TRUE before calling any DNS APIs. Call DNSEndUsage() when this application no longer needs the DNS module so that other applications may make use of it.
|
127 |
|
|
*
|
128 |
|
|
* Note: None
|
129 |
|
|
********************************************************************/
|
130 |
|
|
BOOL DNSBeginUsage(void)
|
131 |
|
|
{
|
132 |
|
|
if(Flags.bits.DNSInUse)
|
133 |
|
|
return FALSE;
|
134 |
|
|
|
135 |
|
|
Flags.bits.DNSInUse = TRUE;
|
136 |
|
|
return TRUE;
|
137 |
|
|
}
|
138 |
|
|
|
139 |
|
|
|
140 |
|
|
/*********************************************************************
|
141 |
|
|
* Function: BOOL DNSEndUsage(void)
|
142 |
|
|
*
|
143 |
|
|
* PreCondition: DNSBeginUsage() returned TRUE on a previous call.
|
144 |
|
|
*
|
145 |
|
|
* Input: None
|
146 |
|
|
*
|
147 |
|
|
* Output: TRUE: If the address to the host name was
|
148 |
|
|
* successfully resolved
|
149 |
|
|
* FALSE: If the DNS failed or address does not
|
150 |
|
|
* exists. The contents of *Hostname are
|
151 |
|
|
* unchanged.
|
152 |
|
|
*
|
153 |
|
|
* Side Effects: None
|
154 |
|
|
*
|
155 |
|
|
* Overview: Call DNSBeginUsage() and make sure it returns
|
156 |
|
|
* TRUE before calling any DNS APIs. Call
|
157 |
|
|
* DNSEndUsage() when this application no longer
|
158 |
|
|
* needs the DNS module so that other applications
|
159 |
|
|
* may make use of it.
|
160 |
|
|
*
|
161 |
|
|
* Note: None
|
162 |
|
|
********************************************************************/
|
163 |
|
|
BOOL DNSEndUsage(void)
|
164 |
|
|
{
|
165 |
|
|
if(MySocket != INVALID_UDP_SOCKET)
|
166 |
|
|
{
|
167 |
|
|
UDPClose(MySocket);
|
168 |
|
|
MySocket = INVALID_UDP_SOCKET;
|
169 |
|
|
}
|
170 |
|
|
smDNS = DNS_DONE;
|
171 |
|
|
Flags.bits.DNSInUse = FALSE;
|
172 |
|
|
|
173 |
|
|
return Flags.bits.AddressValid;
|
174 |
|
|
}
|
175 |
|
|
|
176 |
|
|
|
177 |
|
|
/*********************************************************************
|
178 |
|
|
* Function: void DNSResolve(BYTE *Hostname, BYTE RecordType)
|
179 |
|
|
*
|
180 |
|
|
* PreCondition: Stack is initialized()
|
181 |
|
|
*
|
182 |
|
|
* Input: *Hostname: Null terminated string specifying the
|
183 |
|
|
* host address to resolve to an IP
|
184 |
|
|
* address.
|
185 |
|
|
* Type: DNS_TYPE_A (1d): Host Address (normal IP address)
|
186 |
|
|
* DNS_TYPE_MX (15d): Mail eXchange
|
187 |
|
|
* All other values are reserved
|
188 |
|
|
*
|
189 |
|
|
* Output: None
|
190 |
|
|
*
|
191 |
|
|
* Side Effects: None
|
192 |
|
|
*
|
193 |
|
|
* Overview: Call DNSIsResolved() until the host is resolved.
|
194 |
|
|
*
|
195 |
|
|
* Note: A UDP socket must be available before this
|
196 |
|
|
* function is called. It is freed at the end of
|
197 |
|
|
* the resolution. MAX_UDP_SOCKETS may need to be
|
198 |
|
|
* increased if other modules use UDP sockets.
|
199 |
|
|
*
|
200 |
|
|
* You must not modify *Hostname until DNSIsResolved()
|
201 |
|
|
* returns TRUE.
|
202 |
|
|
********************************************************************/
|
203 |
|
|
void DNSResolve(BYTE *Hostname, BYTE Type)
|
204 |
|
|
{
|
205 |
|
|
DNSHostName = Hostname;
|
206 |
|
|
DNSHostNameROM = NULL;
|
207 |
|
|
smDNS = DNS_HOME;
|
208 |
|
|
RecordType = Type;
|
209 |
|
|
Flags.bits.AddressValid = FALSE;
|
210 |
|
|
}
|
211 |
|
|
|
212 |
|
|
void DNSResolveROM(ROM BYTE *Hostname, BYTE Type)
|
213 |
|
|
{
|
214 |
|
|
DNSHostName = NULL;
|
215 |
|
|
DNSHostNameROM = Hostname;
|
216 |
|
|
smDNS = DNS_HOME;
|
217 |
|
|
RecordType = Type;
|
218 |
|
|
Flags.bits.AddressValid = FALSE;
|
219 |
|
|
}
|
220 |
|
|
|
221 |
|
|
|
222 |
|
|
/*********************************************************************
|
223 |
|
|
* Function: BOOL DNSIsResolved(IP_ADDR *HostIP)
|
224 |
|
|
*
|
225 |
|
|
* PreCondition: DNSResolve() was called.
|
226 |
|
|
*
|
227 |
|
|
* Input: HostIP: Pointer to IP_ADDR structure to store the
|
228 |
|
|
* returned host IP address when DNS
|
229 |
|
|
* resolution is complete.
|
230 |
|
|
*
|
231 |
|
|
* Output: *HostIP, 4 byte IP address
|
232 |
|
|
*
|
233 |
|
|
* Side Effects: None
|
234 |
|
|
*
|
235 |
|
|
* Overview: Call DNSIsResolved() until the host is resolved.
|
236 |
|
|
*
|
237 |
|
|
* Note: You cannot start two DNS resolution proceedures
|
238 |
|
|
* concurrently.
|
239 |
|
|
*
|
240 |
|
|
* You must not modify *Hostname until DNSIsResolved()
|
241 |
|
|
* returns TRUE.
|
242 |
|
|
********************************************************************/
|
243 |
|
|
BOOL DNSIsResolved(IP_ADDR *HostIP)
|
244 |
|
|
{
|
245 |
|
|
static NODE_INFO Remote;
|
246 |
|
|
static TICK StartTime;
|
247 |
|
|
static WORD_VAL SentTransactionID __attribute__((persistent));
|
248 |
|
|
BYTE i;
|
249 |
|
|
WORD_VAL w;
|
250 |
|
|
DNS_HEADER DNSHeader;
|
251 |
|
|
DNS_ANSWER_HEADER DNSAnswerHeader;
|
252 |
|
|
|
253 |
|
|
switch(smDNS)
|
254 |
|
|
{
|
255 |
|
|
case DNS_HOME:
|
256 |
|
|
ARPResolve(&AppConfig.PrimaryDNSServer);
|
257 |
|
|
StartTime = TickGet();
|
258 |
|
|
smDNS++;
|
259 |
|
|
break;
|
260 |
|
|
|
261 |
|
|
case DNS_RESOLVE_ARP:
|
262 |
|
|
if(!ARPIsResolved(&AppConfig.PrimaryDNSServer, &Remote.MACAddr))
|
263 |
|
|
{
|
264 |
|
|
if(TickGet() - StartTime > DNS_TIMEOUT)
|
265 |
|
|
{
|
266 |
|
|
smDNS--;
|
267 |
|
|
}
|
268 |
|
|
break;
|
269 |
|
|
}
|
270 |
|
|
Remote.IPAddr.Val = AppConfig.PrimaryDNSServer.Val;
|
271 |
|
|
smDNS++;
|
272 |
|
|
// No need to break, we can immediately open a socket
|
273 |
|
|
|
274 |
|
|
case DNS_OPEN_SOCKET:
|
275 |
|
|
MySocket = UDPOpen(0, &Remote, DNS_PORT);
|
276 |
|
|
if(MySocket == INVALID_UDP_SOCKET)
|
277 |
|
|
break;
|
278 |
|
|
|
279 |
|
|
smDNS++;
|
280 |
|
|
// No need to break, we can immediately start resolution
|
281 |
|
|
|
282 |
|
|
case DNS_QUERY:
|
283 |
|
|
if(!UDPIsPutReady(MySocket))
|
284 |
|
|
break;
|
285 |
|
|
|
286 |
|
|
// Put DNS query here
|
287 |
|
|
SentTransactionID.Val++;
|
288 |
|
|
UDPPut(SentTransactionID.v[1]);// User chosen transaction ID
|
289 |
|
|
UDPPut(SentTransactionID.v[0]);
|
290 |
|
|
UDPPut(0x01); // Standard query with recursion
|
291 |
|
|
UDPPut(0x00);
|
292 |
|
|
UDPPut(0x00); // 0x0001 questions
|
293 |
|
|
UDPPut(0x01);
|
294 |
|
|
UDPPut(0x00); // 0x0000 answers
|
295 |
|
|
UDPPut(0x00);
|
296 |
|
|
UDPPut(0x00); // 0x0000 name server resource records
|
297 |
|
|
UDPPut(0x00);
|
298 |
|
|
UDPPut(0x00); // 0x0000 additional records
|
299 |
|
|
UDPPut(0x00);
|
300 |
|
|
|
301 |
|
|
// Put hostname string to resolve
|
302 |
|
|
if(DNSHostName)
|
303 |
|
|
DNSPutString(DNSHostName);
|
304 |
|
|
else
|
305 |
|
|
DNSPutROMString(DNSHostNameROM);
|
306 |
|
|
|
307 |
|
|
UDPPut(0x00); // Type: DNS_TYPE_A A (host address) or DNS_TYPE_MX for mail exchange
|
308 |
|
|
UDPPut(RecordType);
|
309 |
|
|
UDPPut(0x00); // Class: IN (Internet)
|
310 |
|
|
UDPPut(0x01);
|
311 |
|
|
|
312 |
|
|
UDPFlush();
|
313 |
|
|
StartTime = TickGet();
|
314 |
|
|
smDNS++;
|
315 |
|
|
break;
|
316 |
|
|
|
317 |
|
|
case DNS_GET_RESULT:
|
318 |
|
|
if(!UDPIsGetReady(MySocket))
|
319 |
|
|
{
|
320 |
|
|
if(TickGet() - StartTime > DNS_TIMEOUT)
|
321 |
|
|
{
|
322 |
|
|
smDNS--;
|
323 |
|
|
}
|
324 |
|
|
break;
|
325 |
|
|
}
|
326 |
|
|
|
327 |
|
|
// Retrieve the DNS header and de-big-endian it
|
328 |
|
|
UDPGet(&DNSHeader.TransactionID.v[1]);
|
329 |
|
|
UDPGet(&DNSHeader.TransactionID.v[0]);
|
330 |
|
|
|
331 |
|
|
// Throw this packet away if it isn't in response to our last query
|
332 |
|
|
if(DNSHeader.TransactionID.Val != SentTransactionID.Val)
|
333 |
|
|
{
|
334 |
|
|
UDPDiscard();
|
335 |
|
|
break;
|
336 |
|
|
}
|
337 |
|
|
|
338 |
|
|
UDPGet(&DNSHeader.Flags.v[1]);
|
339 |
|
|
UDPGet(&DNSHeader.Flags.v[0]);
|
340 |
|
|
UDPGet(&DNSHeader.Questions.v[1]);
|
341 |
|
|
UDPGet(&DNSHeader.Questions.v[0]);
|
342 |
|
|
UDPGet(&DNSHeader.Answers.v[1]);
|
343 |
|
|
UDPGet(&DNSHeader.Answers.v[0]);
|
344 |
|
|
UDPGet(&DNSHeader.AuthoritativeRecords.v[1]);
|
345 |
|
|
UDPGet(&DNSHeader.AuthoritativeRecords.v[0]);
|
346 |
|
|
UDPGet(&DNSHeader.AdditionalRecords.v[1]);
|
347 |
|
|
UDPGet(&DNSHeader.AdditionalRecords.v[0]);
|
348 |
|
|
|
349 |
|
|
// Remove all questions
|
350 |
|
|
while(DNSHeader.Questions.Val--)
|
351 |
|
|
{
|
352 |
|
|
DNSGetString(NULL);
|
353 |
|
|
UDPGet(&w.v[1]); // Question type
|
354 |
|
|
UDPGet(&w.v[0]);
|
355 |
|
|
UDPGet(&w.v[1]); // Question class
|
356 |
|
|
UDPGet(&w.v[0]);
|
357 |
|
|
}
|
358 |
|
|
|
359 |
|
|
// Scan through answers
|
360 |
|
|
while(DNSHeader.Answers.Val--)
|
361 |
|
|
{
|
362 |
|
|
UDPGet(&DNSAnswerHeader.ResponseName.v[1]); // Response name
|
363 |
|
|
UDPGet(&DNSAnswerHeader.ResponseName.v[0]);
|
364 |
|
|
UDPGet(&DNSAnswerHeader.ResponseType.v[1]); // Response type
|
365 |
|
|
UDPGet(&DNSAnswerHeader.ResponseType.v[0]);
|
366 |
|
|
UDPGet(&DNSAnswerHeader.ResponseClass.v[1]); // Response class
|
367 |
|
|
UDPGet(&DNSAnswerHeader.ResponseClass.v[0]);
|
368 |
|
|
UDPGet(&DNSAnswerHeader.ResponseTTL.v[3]); // Time to live
|
369 |
|
|
UDPGet(&DNSAnswerHeader.ResponseTTL.v[2]);
|
370 |
|
|
UDPGet(&DNSAnswerHeader.ResponseTTL.v[1]);
|
371 |
|
|
UDPGet(&DNSAnswerHeader.ResponseTTL.v[0]);
|
372 |
|
|
UDPGet(&DNSAnswerHeader.ResponseLen.v[1]); // Response length
|
373 |
|
|
UDPGet(&DNSAnswerHeader.ResponseLen.v[0]);
|
374 |
|
|
|
375 |
|
|
// Make sure that this is a 4 byte IP address, response type A or MX, class 1
|
376 |
|
|
// Check if this is Type A or MX
|
377 |
|
|
if( DNSAnswerHeader.ResponseType.Val == 0x0001u &&
|
378 |
|
|
DNSAnswerHeader.ResponseClass.Val == 0x0001u && // Internet class
|
379 |
|
|
DNSAnswerHeader.ResponseLen.Val == 0x0004u)
|
380 |
|
|
{
|
381 |
|
|
Flags.bits.AddressValid = TRUE;
|
382 |
|
|
UDPGet(&HostIP->v[0]);
|
383 |
|
|
UDPGet(&HostIP->v[1]);
|
384 |
|
|
UDPGet(&HostIP->v[2]);
|
385 |
|
|
UDPGet(&HostIP->v[3]);
|
386 |
|
|
goto DoneSearchingRecords;
|
387 |
|
|
}
|
388 |
|
|
else
|
389 |
|
|
{
|
390 |
|
|
while(DNSAnswerHeader.ResponseLen.Val--)
|
391 |
|
|
{
|
392 |
|
|
UDPGet(&i);
|
393 |
|
|
}
|
394 |
|
|
}
|
395 |
|
|
}
|
396 |
|
|
|
397 |
|
|
// Remove all Authoritative Records
|
398 |
|
|
while(DNSHeader.AuthoritativeRecords.Val--)
|
399 |
|
|
{
|
400 |
|
|
UDPGet(&DNSAnswerHeader.ResponseName.v[1]); // Response name
|
401 |
|
|
UDPGet(&DNSAnswerHeader.ResponseName.v[0]);
|
402 |
|
|
UDPGet(&DNSAnswerHeader.ResponseType.v[1]); // Response type
|
403 |
|
|
UDPGet(&DNSAnswerHeader.ResponseType.v[0]);
|
404 |
|
|
UDPGet(&DNSAnswerHeader.ResponseClass.v[1]); // Response class
|
405 |
|
|
UDPGet(&DNSAnswerHeader.ResponseClass.v[0]);
|
406 |
|
|
UDPGet(&DNSAnswerHeader.ResponseTTL.v[3]); // Time to live
|
407 |
|
|
UDPGet(&DNSAnswerHeader.ResponseTTL.v[2]);
|
408 |
|
|
UDPGet(&DNSAnswerHeader.ResponseTTL.v[1]);
|
409 |
|
|
UDPGet(&DNSAnswerHeader.ResponseTTL.v[0]);
|
410 |
|
|
UDPGet(&DNSAnswerHeader.ResponseLen.v[1]); // Response length
|
411 |
|
|
UDPGet(&DNSAnswerHeader.ResponseLen.v[0]);
|
412 |
|
|
|
413 |
|
|
// Make sure that this is a 4 byte IP address, response type A or MX, class 1
|
414 |
|
|
// Check if this is Type A
|
415 |
|
|
if( DNSAnswerHeader.ResponseType.Val == 0x0001u &&
|
416 |
|
|
DNSAnswerHeader.ResponseClass.Val == 0x0001u && // Internet class
|
417 |
|
|
DNSAnswerHeader.ResponseLen.Val == 0x0004u)
|
418 |
|
|
{
|
419 |
|
|
Flags.bits.AddressValid = TRUE;
|
420 |
|
|
UDPGet(&HostIP->v[0]);
|
421 |
|
|
UDPGet(&HostIP->v[1]);
|
422 |
|
|
UDPGet(&HostIP->v[2]);
|
423 |
|
|
UDPGet(&HostIP->v[3]);
|
424 |
|
|
goto DoneSearchingRecords;
|
425 |
|
|
}
|
426 |
|
|
else
|
427 |
|
|
{
|
428 |
|
|
while(DNSAnswerHeader.ResponseLen.Val--)
|
429 |
|
|
{
|
430 |
|
|
UDPGet(&i);
|
431 |
|
|
}
|
432 |
|
|
}
|
433 |
|
|
}
|
434 |
|
|
|
435 |
|
|
// Remove all Additional Records
|
436 |
|
|
while(DNSHeader.AdditionalRecords.Val--)
|
437 |
|
|
{
|
438 |
|
|
UDPGet(&DNSAnswerHeader.ResponseName.v[1]); // Response name
|
439 |
|
|
UDPGet(&DNSAnswerHeader.ResponseName.v[0]);
|
440 |
|
|
UDPGet(&DNSAnswerHeader.ResponseType.v[1]); // Response type
|
441 |
|
|
UDPGet(&DNSAnswerHeader.ResponseType.v[0]);
|
442 |
|
|
UDPGet(&DNSAnswerHeader.ResponseClass.v[1]); // Response class
|
443 |
|
|
UDPGet(&DNSAnswerHeader.ResponseClass.v[0]);
|
444 |
|
|
UDPGet(&DNSAnswerHeader.ResponseTTL.v[3]); // Time to live
|
445 |
|
|
UDPGet(&DNSAnswerHeader.ResponseTTL.v[2]);
|
446 |
|
|
UDPGet(&DNSAnswerHeader.ResponseTTL.v[1]);
|
447 |
|
|
UDPGet(&DNSAnswerHeader.ResponseTTL.v[0]);
|
448 |
|
|
UDPGet(&DNSAnswerHeader.ResponseLen.v[1]); // Response length
|
449 |
|
|
UDPGet(&DNSAnswerHeader.ResponseLen.v[0]);
|
450 |
|
|
|
451 |
|
|
// Make sure that this is a 4 byte IP address, response type A or MX, class 1
|
452 |
|
|
// Check if this is Type A
|
453 |
|
|
if( DNSAnswerHeader.ResponseType.Val == 0x0001u &&
|
454 |
|
|
DNSAnswerHeader.ResponseClass.Val == 0x0001u && // Internet class
|
455 |
|
|
DNSAnswerHeader.ResponseLen.Val == 0x0004u)
|
456 |
|
|
{
|
457 |
|
|
Flags.bits.AddressValid = TRUE;
|
458 |
|
|
UDPGet(&HostIP->v[0]);
|
459 |
|
|
UDPGet(&HostIP->v[1]);
|
460 |
|
|
UDPGet(&HostIP->v[2]);
|
461 |
|
|
UDPGet(&HostIP->v[3]);
|
462 |
|
|
goto DoneSearchingRecords;
|
463 |
|
|
}
|
464 |
|
|
else
|
465 |
|
|
{
|
466 |
|
|
while(DNSAnswerHeader.ResponseLen.Val--)
|
467 |
|
|
{
|
468 |
|
|
UDPGet(&i);
|
469 |
|
|
}
|
470 |
|
|
}
|
471 |
|
|
}
|
472 |
|
|
|
473 |
|
|
DoneSearchingRecords:
|
474 |
|
|
|
475 |
|
|
UDPDiscard();
|
476 |
|
|
UDPClose(MySocket);
|
477 |
|
|
MySocket = INVALID_UDP_SOCKET;
|
478 |
|
|
smDNS++;
|
479 |
|
|
// No need to break, we are done and need to return TRUE
|
480 |
|
|
|
481 |
|
|
case DNS_DONE:
|
482 |
|
|
return TRUE;
|
483 |
|
|
}
|
484 |
|
|
|
485 |
|
|
return FALSE;
|
486 |
|
|
}
|
487 |
|
|
|
488 |
|
|
static void DNSPutString(BYTE *String)
|
489 |
|
|
{
|
490 |
|
|
BYTE *RightPtr;
|
491 |
|
|
BYTE i;
|
492 |
|
|
BYTE Len;
|
493 |
|
|
|
494 |
|
|
RightPtr = String;
|
495 |
|
|
|
496 |
|
|
while(1)
|
497 |
|
|
{
|
498 |
|
|
do
|
499 |
|
|
{
|
500 |
|
|
i = *RightPtr++;
|
501 |
|
|
} while((i != 0x00u) && (i != '.') && (i != '/') && (i != ',') && (i != '>'));
|
502 |
|
|
|
503 |
|
|
// Put the length parameter
|
504 |
|
|
Len = (BYTE)(RightPtr-String-1);
|
505 |
|
|
UDPPut(Len);
|
506 |
|
|
while(Len--)
|
507 |
|
|
{
|
508 |
|
|
UDPPut(*String++);
|
509 |
|
|
}
|
510 |
|
|
if(i == 0x00u || i == '/' || i == ',' || i == '>')
|
511 |
|
|
break;
|
512 |
|
|
|
513 |
|
|
// Skip over the '.' in the input string
|
514 |
|
|
String++;
|
515 |
|
|
}
|
516 |
|
|
|
517 |
|
|
// Put the string terminator character
|
518 |
|
|
UDPPut(0x00);
|
519 |
|
|
}
|
520 |
|
|
|
521 |
|
|
static void DNSPutROMString(ROM BYTE *String)
|
522 |
|
|
{
|
523 |
|
|
ROM BYTE *RightPtr;
|
524 |
|
|
BYTE i;
|
525 |
|
|
BYTE Len;
|
526 |
|
|
|
527 |
|
|
RightPtr = String;
|
528 |
|
|
|
529 |
|
|
while(1)
|
530 |
|
|
{
|
531 |
|
|
do
|
532 |
|
|
{
|
533 |
|
|
i = *RightPtr++;
|
534 |
|
|
} while((i != 0x00u) && (i != '.') && (i != '/') && (i != ',') && (i != '>'));
|
535 |
|
|
|
536 |
|
|
// Put the length parameter
|
537 |
|
|
Len = (BYTE)(RightPtr-String-1);
|
538 |
|
|
UDPPut(Len);
|
539 |
|
|
UDPPutROMArray(String, Len);
|
540 |
|
|
String += Len + 1;
|
541 |
|
|
|
542 |
|
|
if(i == 0x00u || i == '/' || i == ',' || i == '>')
|
543 |
|
|
break;
|
544 |
|
|
}
|
545 |
|
|
|
546 |
|
|
// Put the string terminator character
|
547 |
|
|
UDPPut(0x00);
|
548 |
|
|
}
|
549 |
|
|
|
550 |
|
|
|
551 |
|
|
static void DNSGetString(BYTE *String)
|
552 |
|
|
{
|
553 |
|
|
BYTE i;
|
554 |
|
|
BYTE j;
|
555 |
|
|
|
556 |
|
|
if(String == NULL)
|
557 |
|
|
{
|
558 |
|
|
UDPGet(&i);
|
559 |
|
|
while(i)
|
560 |
|
|
{
|
561 |
|
|
while(i--)
|
562 |
|
|
{
|
563 |
|
|
UDPGet(&j);
|
564 |
|
|
}
|
565 |
|
|
UDPGet(&i);
|
566 |
|
|
}
|
567 |
|
|
}
|
568 |
|
|
else
|
569 |
|
|
{
|
570 |
|
|
UDPGet(&i);
|
571 |
|
|
while(i)
|
572 |
|
|
{
|
573 |
|
|
while(i--)
|
574 |
|
|
{
|
575 |
|
|
UDPGet(String);
|
576 |
|
|
String++;
|
577 |
|
|
}
|
578 |
|
|
UDPGet(&i);
|
579 |
|
|
}
|
580 |
|
|
}
|
581 |
|
|
}
|
582 |
|
|
|
583 |
|
|
|
584 |
|
|
#endif //#if defined(STACK_USE_DNS)
|