?lang_form? ?lang_select? ?lang_submit? ?lang_endform?
{HEADER END}
{BLAME START}

library

?curdirlinks? -

Blame information for rev 32

Line No. Rev Author Line
1 32 kaklik /*********************************************************************
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, PIC32
12 * Compiler: Microchip C32 v1.05 or higher
13 * Microchip C30 v3.12 or higher
14 * Microchip C18 v3.30 or higher
15 * HI-TECH PICC-18 PRO 9.63PL2 or higher
16 * Company: Microchip Technology, Inc.
17 *
18 * Software License Agreement
19 *
20 * Copyright (C) 2002-2009 Microchip Technology Inc. All rights
21 * reserved.
22 *
23 * Microchip licenses to you the right to use, modify, copy, and
24 * distribute:
25 * (i) the Software when embedded on a Microchip microcontroller or
26 * digital signal controller product ("Device") which is
27 * integrated into Licensee's product; or
28 * (ii) ONLY the Software driver source files ENC28J60.c, ENC28J60.h,
29 * ENCX24J600.c and ENCX24J600.h ported to a non-Microchip device
30 * used in conjunction with a Microchip ethernet controller for
31 * the sole purpose of interfacing with the ethernet controller.
32 *
33 * You should refer to the license agreement accompanying this
34 * Software for additional information regarding your rights and
35 * obligations.
36 *
37 * THE SOFTWARE AND DOCUMENTATION ARE PROVIDED "AS IS" WITHOUT
38 * WARRANTY OF ANY KIND, EITHER EXPRESS OR IMPLIED, INCLUDING WITHOUT
39 * LIMITATION, ANY WARRANTY OF MERCHANTABILITY, FITNESS FOR A
40 * PARTICULAR PURPOSE, TITLE AND NON-INFRINGEMENT. IN NO EVENT SHALL
41 * MICROCHIP BE LIABLE FOR ANY INCIDENTAL, SPECIAL, INDIRECT OR
42 * CONSEQUENTIAL DAMAGES, LOST PROFITS OR LOST DATA, COST OF
43 * PROCUREMENT OF SUBSTITUTE GOODS, TECHNOLOGY OR SERVICES, ANY CLAIMS
44 * BY THIRD PARTIES (INCLUDING BUT NOT LIMITED TO ANY DEFENSE
45 * THEREOF), ANY CLAIMS FOR INDEMNITY OR CONTRIBUTION, OR OTHER
46 * SIMILAR COSTS, WHETHER ASSERTED ON THE BASIS OF CONTRACT, TORT
47 * (INCLUDING NEGLIGENCE), BREACH OF WARRANTY, OR OTHERWISE.
48 *
49 *
50 * Author Date Comment
51 *~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
52 * Howard Schlunder 7/31/06 Original
53 * Howard Schlunder 10/09/06 Added DNSBeginUsage(), DNSEndUsage()
54 * module ownership semaphore
55 * Howard Schlunder 08/28/09 Fixed name compression parsing bug
56 ********************************************************************/
57 #define __DNS_C
58  
59 #include "TCPIP Stack/TCPIP.h"
60  
61 #if defined(STACK_USE_DNS)
62  
63 /****************************************************************************
64 Section:
65 Constants and Global Variables
66 ***************************************************************************/
67  
68 #define DNS_PORT 53u // Default port for DNS resolutions
69 #define DNS_TIMEOUT (TICK_SECOND*1) // Elapsed time after which a DNS resolution is considered to have timed out
70  
71 static UDP_SOCKET MySocket = INVALID_UDP_SOCKET; // UDP socket to use for DNS queries
72 static BYTE *DNSHostName; // Host name in RAM to look up
73 static ROM BYTE *DNSHostNameROM; // Host name in ROM to look up
74 static BYTE RecordType; // Record type being queried
75 static NODE_INFO ResolvedInfo; // Node information about the resolved node
76  
77 // Semaphore flags for the DNS module
78 static union
79 {
80 BYTE Val;
81 struct
82 {
83 unsigned char DNSInUse : 1; // Indicates the DNS module is in use
84 unsigned char AddressValid : 1; // Indicates that the address resolution is valid and complete
85 unsigned char filler : 6;
86 } bits;
87 } Flags = {0x00};
88  
89 // State machine for a DNS query
90 static enum
91 {
92 DNS_START = 0, // Initial state to reset client state variables
93 DNS_ARP_START_RESOLVE, // Send ARP resolution of DNS server or gateway MAC address
94 DNS_ARP_RESOLVE, // Wait for response to ARP request
95 DNS_OPEN_SOCKET, // Open UDP socket
96 DNS_QUERY, // Send DNS query to DNS server
97 DNS_GET_RESULT, // Wait for response from DNS server
98 DNS_FAIL, // ARP or DNS server not responding
99 DNS_DONE // DNS query is finished
100 } smDNS = DNS_DONE;
101  
102 // Structure for the DNS header
103 typedef struct
104 {
105 WORD_VAL TransactionID;
106 WORD_VAL Flags;
107 WORD_VAL Questions;
108 WORD_VAL Answers;
109 WORD_VAL AuthoritativeRecords;
110 WORD_VAL AdditionalRecords;
111 } DNS_HEADER;
112  
113 typedef struct
114 {
115 // Response name is first, but it is variable length and must be retrieved using the DNSDiscardName() function
116 WORD_VAL ResponseType;
117 WORD_VAL ResponseClass;
118 DWORD_VAL ResponseTTL;
119 WORD_VAL ResponseLen;
120 } DNS_ANSWER_HEADER;
121  
122  
123 /****************************************************************************
124 Section:
125 Function Prototypes
126 ***************************************************************************/
127  
128 static void DNSPutString(BYTE* String);
129 static void DNSDiscardName(void);
130  
131 #if defined(__18CXX)
132 static void DNSPutROMString(ROM BYTE* String);
133 #else
134 // Non-ROM alias for C30/C32
135 #define DNSPutROMString(a) DNSPutString((BYTE*)a)
136 #endif
137  
138  
139 /*****************************************************************************
140 Function:
141 BOOL DNSBeginUsage(void)
142  
143 Summary:
144 Claims access to the DNS module.
145  
146 Description:
147 This function acts as a semaphore to obtain usage of the DNS module.
148 Call this function and ensure that it returns TRUE before calling any
149 other DNS APIs. Call DNSEndUsage when this application no longer
150 needs the DNS module so that other applications may make use of it.
151  
152 Precondition:
153 Stack is initialized.
154  
155 Parameters:
156 None
157  
158 Return Values:
159 TRUE - No other DNS resolutions are in progress and the calling
160 application has sucessfully taken ownership of the DNS module
161 FALSE - The DNS module is currently in use. Yield to the stack and
162 attempt this call again later.
163  
164 Remarks:
165 Ensure that DNSEndUsage is always called once your application has
166 obtained control of the DNS module. If this is not done, the stack
167 will hang for all future applications requiring DNS access.
168 ***************************************************************************/
169 BOOL DNSBeginUsage(void)
170 {
171 if(Flags.bits.DNSInUse)
172 return FALSE;
173  
174 Flags.bits.DNSInUse = TRUE;
175 return TRUE;
176 }
177  
178  
179 /*****************************************************************************
180 Function:
181 BOOL DNSEndUsage(void)
182  
183 Summary:
184 Releases control of the DNS module.
185  
186 Description:
187 This function acts as a semaphore to obtain usage of the DNS module.
188 Call this function when this application no longer needs the DNS
189 module so that other applications may make use of it.
190  
191 Precondition:
192 DNSBeginUsage returned TRUE on a previous call.
193  
194 Parameters:
195 None
196  
197 Return Values:
198 TRUE - The address to the host name was successfully resolved.
199 FALSE - The DNS failed or the address does not exist.
200  
201 Remarks:
202 Ensure that DNSEndUsage is always called once your application has
203 obtained control of the DNS module. If this is not done, the stack
204 will hang for all future applications requiring DNS access.
205 ***************************************************************************/
206 BOOL DNSEndUsage(void)
207 {
208 if(MySocket != INVALID_UDP_SOCKET)
209 {
210 UDPClose(MySocket);
211 MySocket = INVALID_UDP_SOCKET;
212 }
213 smDNS = DNS_DONE;
214 Flags.bits.DNSInUse = FALSE;
215  
216 return Flags.bits.AddressValid;
217 }
218  
219  
220 /*****************************************************************************
221 Function:
222 void DNSResolve(BYTE* Hostname, BYTE Type)
223  
224 Summary:
225 Begins resolution of an address.
226  
227 Description:
228 This function attempts to resolve a host name to an IP address. When
229 called, it starts the DNS state machine. Call DNSIsResolved repeatedly
230 to determine if the resolution is complete.
231  
232 Only one DNS resoultion may be executed at a time. The Hostname must
233 not be modified in memory until the resolution is complete.
234  
235 Precondition:
236 DNSBeginUsage returned TRUE on a previous call.
237  
238 Parameters:
239 Hostname - A pointer to the null terminated string specifiying the
240 host for which to resolve an IP.
241 RecordType - DNS_TYPE_A or DNS_TYPE_MX depending on what type of
242 record resolution is desired.
243  
244 Returns:
245 None
246  
247 Remarks:
248 This function requires access to one UDP socket. If none are available,
249 MAX_UDP_SOCKETS may need to be increased.
250 ***************************************************************************/
251 void DNSResolve(BYTE* Hostname, BYTE Type)
252 {
253 if(StringToIPAddress(Hostname, &ResolvedInfo.IPAddr))
254 {
255 Flags.bits.AddressValid = TRUE;
256 smDNS = DNS_DONE;
257 }
258 else
259 {
260 DNSHostName = Hostname;
261 DNSHostNameROM = NULL;
262 smDNS = DNS_START;
263 RecordType = Type;
264 Flags.bits.AddressValid = FALSE;
265 }
266 }
267  
268  
269 /*****************************************************************************
270 Function:
271 void DNSResolveROM(ROM BYTE* Hostname, BYTE Type)
272  
273 Summary:
274 Begins resolution of an address.
275  
276 Description:
277 This function attempts to resolve a host name to an IP address. When
278 called, it starts the DNS state machine. Call DNSIsResolved repeatedly
279 to determine if the resolution is complete.
280  
281 Only one DNS resoultion may be executed at a time. The Hostname must
282 not be modified in memory until the resolution is complete.
283  
284 Precondition:
285 DNSBeginUsage returned TRUE on a previous call.
286  
287 Parameters:
288 Hostname - A pointer to the null terminated string specifiying the
289 host for which to resolve an IP.
290 RecordType - DNS_TYPE_A or DNS_TYPE_MX depending on what type of
291 record resolution is desired.
292  
293 Returns:
294 None
295  
296 Remarks:
297 This function requires access to one UDP socket. If none are available,
298 MAX_UDP_SOCKETS may need to be increased.
299  
300 This function is aliased to DNSResolve on non-PIC18 platforms.
301 ***************************************************************************/
302 #if defined(__18CXX)
303 void DNSResolveROM(ROM BYTE* Hostname, BYTE Type)
304 {
305 if(ROMStringToIPAddress(Hostname, &ResolvedInfo.IPAddr))
306 {
307 Flags.bits.AddressValid = TRUE;
308 smDNS = DNS_DONE;
309 }
310 else
311 {
312 DNSHostName = NULL;
313 DNSHostNameROM = Hostname;
314 smDNS = DNS_START;
315 RecordType = Type;
316 Flags.bits.AddressValid = FALSE;
317 }
318 }
319 #endif
320  
321  
322 /*****************************************************************************
323 Function:
324 BOOL DNSIsResolved(IP_ADDR* HostIP)
325  
326 Summary:
327 Determines if the DNS resolution is complete and provides the IP.
328  
329 Description:
330 Call this function to determine if the DNS resolution of an address has
331 been completed. If so, the resolved address will be provided in HostIP.
332  
333 Precondition:
334 DNSResolve or DNSResolveROM has been called.
335  
336 Parameters:
337 HostIP - A pointer to an IP_ADDR structure in which to store the
338 resolved IP address once resolution is complete.
339  
340 Return Values:
341 TRUE - The DNS client has obtained an IP, or the DNS process
342 has encountered an error. HostIP will be 0.0.0.0 on error. Possible
343 errors include server timeout (i.e. DNS server not available), hostname
344 not in the DNS, or DNS server errors.
345 FALSE - The resolution process is still in progress.
346 ***************************************************************************/
347 BOOL DNSIsResolved(IP_ADDR* HostIP)
348 {
349 static DWORD StartTime;
350 static WORD_VAL SentTransactionID __attribute__((persistent));
351 static BYTE vARPAttemptCount;
352 static BYTE vDNSAttemptCount;
353 BYTE i;
354 WORD_VAL w;
355 DNS_HEADER DNSHeader;
356 DNS_ANSWER_HEADER DNSAnswerHeader;
357  
358 switch(smDNS)
359 {
360 case DNS_START:
361 vARPAttemptCount = 0;
362 vDNSAttemptCount = 0;
363 // No break;
364  
365 case DNS_ARP_START_RESOLVE:
366 ARPResolve(&AppConfig.PrimaryDNSServer);
367 vARPAttemptCount++;
368 StartTime = TickGet();
369 smDNS = DNS_ARP_RESOLVE;
370 break;
371  
372 case DNS_ARP_RESOLVE:
373 if(!ARPIsResolved(&AppConfig.PrimaryDNSServer, &ResolvedInfo.MACAddr))
374 {
375 if(TickGet() - StartTime > DNS_TIMEOUT)
376 smDNS = (vARPAttemptCount >= 3u) ? DNS_FAIL : DNS_ARP_START_RESOLVE;
377 break;
378 }
379 ResolvedInfo.IPAddr.Val = AppConfig.PrimaryDNSServer.Val;
380 smDNS = DNS_OPEN_SOCKET;
381 // No break: DNS_OPEN_SOCKET is the correct next state
382  
383 case DNS_OPEN_SOCKET:
384 MySocket = UDPOpen(0, &ResolvedInfo, DNS_PORT);
385 if(MySocket == INVALID_UDP_SOCKET)
386 break;
387  
388 smDNS = DNS_QUERY;
389 // No need to break, we can immediately start resolution
390  
391 case DNS_QUERY:
392 if(!UDPIsPutReady(MySocket))
393 break;
394  
395 // Put DNS query here
396 SentTransactionID.Val++;
397 UDPPut(SentTransactionID.v[1]);// User chosen transaction ID
398 UDPPut(SentTransactionID.v[0]);
399 UDPPut(0x01); // Standard query with recursion
400 UDPPut(0x00);
401 UDPPut(0x00); // 0x0001 questions
402 UDPPut(0x01);
403 UDPPut(0x00); // 0x0000 answers
404 UDPPut(0x00);
405 UDPPut(0x00); // 0x0000 name server resource records
406 UDPPut(0x00);
407 UDPPut(0x00); // 0x0000 additional records
408 UDPPut(0x00);
409  
410 // Put hostname string to resolve
411 if(DNSHostName)
412 DNSPutString(DNSHostName);
413 else
414 DNSPutROMString(DNSHostNameROM);
415  
416 UDPPut(0x00); // Type: DNS_TYPE_A A (host address) or DNS_TYPE_MX for mail exchange
417 UDPPut(RecordType);
418 UDPPut(0x00); // Class: IN (Internet)
419 UDPPut(0x01);
420  
421 UDPFlush();
422 StartTime = TickGet();
423 smDNS = DNS_GET_RESULT;
424 break;
425  
426 case DNS_GET_RESULT:
427 if(!UDPIsGetReady(MySocket))
428 {
429 if(TickGet() - StartTime > DNS_TIMEOUT)
430 smDNS = DNS_FAIL;
431 break;
432 }
433  
434 // Retrieve the DNS header and de-big-endian it
435 UDPGet(&DNSHeader.TransactionID.v[1]);
436 UDPGet(&DNSHeader.TransactionID.v[0]);
437  
438 // Throw this packet away if it isn't in response to our last query
439 if(DNSHeader.TransactionID.Val != SentTransactionID.Val)
440 {
441 UDPDiscard();
442 break;
443 }
444  
445 UDPGet(&DNSHeader.Flags.v[1]);
446 UDPGet(&DNSHeader.Flags.v[0]);
447 UDPGet(&DNSHeader.Questions.v[1]);
448 UDPGet(&DNSHeader.Questions.v[0]);
449 UDPGet(&DNSHeader.Answers.v[1]);
450 UDPGet(&DNSHeader.Answers.v[0]);
451 UDPGet(&DNSHeader.AuthoritativeRecords.v[1]);
452 UDPGet(&DNSHeader.AuthoritativeRecords.v[0]);
453 UDPGet(&DNSHeader.AdditionalRecords.v[1]);
454 UDPGet(&DNSHeader.AdditionalRecords.v[0]);
455  
456 // Remove all questions (queries)
457 while(DNSHeader.Questions.Val--)
458 {
459 DNSDiscardName();
460 UDPGet(&w.v[1]); // Question type
461 UDPGet(&w.v[0]);
462 UDPGet(&w.v[1]); // Question class
463 UDPGet(&w.v[0]);
464 }
465  
466 // Scan through answers
467 while(DNSHeader.Answers.Val--)
468 {
469 DNSDiscardName(); // Throw away response name
470 UDPGet(&DNSAnswerHeader.ResponseType.v[1]); // Response type
471 UDPGet(&DNSAnswerHeader.ResponseType.v[0]);
472 UDPGet(&DNSAnswerHeader.ResponseClass.v[1]); // Response class
473 UDPGet(&DNSAnswerHeader.ResponseClass.v[0]);
474 UDPGet(&DNSAnswerHeader.ResponseTTL.v[3]); // Time to live
475 UDPGet(&DNSAnswerHeader.ResponseTTL.v[2]);
476 UDPGet(&DNSAnswerHeader.ResponseTTL.v[1]);
477 UDPGet(&DNSAnswerHeader.ResponseTTL.v[0]);
478 UDPGet(&DNSAnswerHeader.ResponseLen.v[1]); // Response length
479 UDPGet(&DNSAnswerHeader.ResponseLen.v[0]);
480  
481 // Make sure that this is a 4 byte IP address, response type A or MX, class 1
482 // Check if this is Type A or MX
483 if( DNSAnswerHeader.ResponseType.Val == 0x0001u &&
484 DNSAnswerHeader.ResponseClass.Val == 0x0001u && // Internet class
485 DNSAnswerHeader.ResponseLen.Val == 0x0004u)
486 {
487 Flags.bits.AddressValid = TRUE;
488 UDPGet(&ResolvedInfo.IPAddr.v[0]);
489 UDPGet(&ResolvedInfo.IPAddr.v[1]);
490 UDPGet(&ResolvedInfo.IPAddr.v[2]);
491 UDPGet(&ResolvedInfo.IPAddr.v[3]);
492 goto DoneSearchingRecords;
493 }
494 else
495 {
496 while(DNSAnswerHeader.ResponseLen.Val--)
497 {
498 UDPGet(&i);
499 }
500 }
501 }
502  
503 // Remove all Authoritative Records
504 while(DNSHeader.AuthoritativeRecords.Val--)
505 {
506 DNSDiscardName(); // Throw away response name
507 UDPGet(&DNSAnswerHeader.ResponseType.v[1]); // Response type
508 UDPGet(&DNSAnswerHeader.ResponseType.v[0]);
509 UDPGet(&DNSAnswerHeader.ResponseClass.v[1]); // Response class
510 UDPGet(&DNSAnswerHeader.ResponseClass.v[0]);
511 UDPGet(&DNSAnswerHeader.ResponseTTL.v[3]); // Time to live
512 UDPGet(&DNSAnswerHeader.ResponseTTL.v[2]);
513 UDPGet(&DNSAnswerHeader.ResponseTTL.v[1]);
514 UDPGet(&DNSAnswerHeader.ResponseTTL.v[0]);
515 UDPGet(&DNSAnswerHeader.ResponseLen.v[1]); // Response length
516 UDPGet(&DNSAnswerHeader.ResponseLen.v[0]);
517  
518 // Make sure that this is a 4 byte IP address, response type A or MX, class 1
519 // Check if this is Type A
520 if( DNSAnswerHeader.ResponseType.Val == 0x0001u &&
521 DNSAnswerHeader.ResponseClass.Val == 0x0001u && // Internet class
522 DNSAnswerHeader.ResponseLen.Val == 0x0004u)
523 {
524 Flags.bits.AddressValid = TRUE;
525 UDPGet(&ResolvedInfo.IPAddr.v[0]);
526 UDPGet(&ResolvedInfo.IPAddr.v[1]);
527 UDPGet(&ResolvedInfo.IPAddr.v[2]);
528 UDPGet(&ResolvedInfo.IPAddr.v[3]);
529 goto DoneSearchingRecords;
530 }
531 else
532 {
533 while(DNSAnswerHeader.ResponseLen.Val--)
534 {
535 UDPGet(&i);
536 }
537 }
538 }
539  
540 // Remove all Additional Records
541 while(DNSHeader.AdditionalRecords.Val--)
542 {
543 DNSDiscardName(); // Throw away response name
544 UDPGet(&DNSAnswerHeader.ResponseType.v[1]); // Response type
545 UDPGet(&DNSAnswerHeader.ResponseType.v[0]);
546 UDPGet(&DNSAnswerHeader.ResponseClass.v[1]); // Response class
547 UDPGet(&DNSAnswerHeader.ResponseClass.v[0]);
548 UDPGet(&DNSAnswerHeader.ResponseTTL.v[3]); // Time to live
549 UDPGet(&DNSAnswerHeader.ResponseTTL.v[2]);
550 UDPGet(&DNSAnswerHeader.ResponseTTL.v[1]);
551 UDPGet(&DNSAnswerHeader.ResponseTTL.v[0]);
552 UDPGet(&DNSAnswerHeader.ResponseLen.v[1]); // Response length
553 UDPGet(&DNSAnswerHeader.ResponseLen.v[0]);
554  
555 // Make sure that this is a 4 byte IP address, response type A or MX, class 1
556 // Check if this is Type A
557 if( DNSAnswerHeader.ResponseType.Val == 0x0001u &&
558 DNSAnswerHeader.ResponseClass.Val == 0x0001u && // Internet class
559 DNSAnswerHeader.ResponseLen.Val == 0x0004u)
560 {
561 Flags.bits.AddressValid = TRUE;
562 UDPGet(&ResolvedInfo.IPAddr.v[0]);
563 UDPGet(&ResolvedInfo.IPAddr.v[1]);
564 UDPGet(&ResolvedInfo.IPAddr.v[2]);
565 UDPGet(&ResolvedInfo.IPAddr.v[3]);
566 goto DoneSearchingRecords;
567 }
568 else
569 {
570 while(DNSAnswerHeader.ResponseLen.Val--)
571 {
572 UDPGet(&i);
573 }
574 }
575 }
576  
577 DoneSearchingRecords:
578  
579 UDPDiscard();
580 UDPClose(MySocket);
581 MySocket = INVALID_UDP_SOCKET;
582 smDNS = DNS_DONE;
583 // No break, DNS_DONE is the correct step
584  
585 case DNS_DONE:
586 // Return 0.0.0.0 if DNS resolution failed, otherwise return the
587 // resolved IP address
588 if(!Flags.bits.AddressValid)
589 ResolvedInfo.IPAddr.Val = 0;
590 HostIP->Val = ResolvedInfo.IPAddr.Val;
591 return TRUE;
592  
593 case DNS_FAIL:
594 // If 3 attempts or more, quit
595 if(vDNSAttemptCount >= 2u)
596 {
597 // Return an invalid IP address 0.0.0.0 if we can't finish ARP or DNS query step
598 HostIP->Val = 0x00000000;
599 return TRUE;
600 }
601 vDNSAttemptCount++;
602  
603 // Swap primary and secondary DNS servers if there is a secondary DNS server programmed
604 if(AppConfig.SecondaryDNSServer.Val)
605 {
606 AppConfig.PrimaryDNSServer.Val ^= AppConfig.SecondaryDNSServer.Val;
607 AppConfig.SecondaryDNSServer.Val ^= AppConfig.PrimaryDNSServer.Val;
608 AppConfig.PrimaryDNSServer.Val ^= AppConfig.SecondaryDNSServer.Val;
609  
610 // Start another ARP resolution for the secondary server (now primary)
611 vARPAttemptCount = 0;
612 if(MySocket != INVALID_UDP_SOCKET)
613 {
614 UDPClose(MySocket);
615 MySocket = INVALID_UDP_SOCKET;
616 }
617 smDNS = DNS_ARP_START_RESOLVE;
618 }
619  
620 break;
621  
622 }
623  
624 return FALSE;
625 }
626  
627 /*****************************************************************************
628 Function:
629 static void DNSPutString(BYTE* String)
630  
631 Summary:
632 Writes a string to the DNS socket.
633  
634 Description:
635 This function writes a string to the DNS socket, ensuring that it is
636 properly formatted.
637  
638 Precondition:
639 UDP socket is obtained and ready for writing.
640  
641 Parameters:
642 String - the string to write to the UDP socket.
643  
644 Returns:
645 None
646 ***************************************************************************/
647 static void DNSPutString(BYTE* String)
648 {
649 BYTE *RightPtr;
650 BYTE i;
651 BYTE Len;
652  
653 RightPtr = String;
654  
655 while(1)
656 {
657 do
658 {
659 i = *RightPtr++;
660 } while((i != 0x00u) && (i != '.') && (i != '/') && (i != ',') && (i != '>'));
661  
662 // Put the length and data
663 // Also, skip over the '.' in the input string
664 Len = (BYTE)(RightPtr-String-1);
665 UDPPut(Len);
666 String += UDPPutArray(String, Len) + 1;
667  
668 if(i == 0x00u || i == '/' || i == ',' || i == '>')
669 break;
670 }
671  
672 // Put the string null terminator character (zero length label)
673 UDPPut(0x00);
674 }
675  
676 /*****************************************************************************
677 Function:
678 static void DNSPutROMString(ROM BYTE* String)
679  
680 Summary:
681 Writes a ROM string to the DNS socket.
682  
683 Description:
684 This function writes a string to the DNS socket, ensuring that it is
685 properly formatted.
686  
687 Precondition:
688 UDP socket is obtained and ready for writing.
689  
690 Parameters:
691 String - the string to write to the UDP socket.
692  
693 Returns:
694 None
695  
696 Remarks:
697 This function is aliased to DNSPutString on non-PIC18 platforms.
698 ***************************************************************************/
699 #if defined(__18CXX)
700 static void DNSPutROMString(ROM BYTE* String)
701 {
702 ROM BYTE *RightPtr;
703 BYTE i;
704 BYTE Len;
705  
706 RightPtr = String;
707  
708 while(1)
709 {
710 do
711 {
712 i = *RightPtr++;
713 } while((i != 0x00u) && (i != '.') && (i != '/') && (i != ',') && (i != '>'));
714  
715 // Put the length and data
716 // Also, skip over the '.' in the input string
717 Len = (BYTE)(RightPtr-String-1);
718 UDPPut(Len);
719 String += UDPPutROMArray(String, Len) + 1;
720  
721 if(i == 0x00u || i == '/' || i == ',' || i == '>')
722 break;
723 }
724  
725 // Put the string terminator character (zero length label)
726 UDPPut(0x00);
727 }
728 #endif
729  
730  
731 /*****************************************************************************
732 Function:
733 static void DNSDiscardName(void)
734  
735 Summary:
736 Reads a name string or string pointer from the DNS socket and discards it.
737  
738 Description:
739 This function reads a name string from the DNS socket. Each string
740 consists of a series of labels. Each label consists of a length prefix
741 byte, followed by the label bytes. At the end of the string, a zero length
742 label is found as termination. If name compression is used, this function
743 will automatically detect the pointer and discard it.
744  
745 Precondition:
746 UDP socket is obtained and ready for reading a DNS name
747  
748 Parameters:
749 None
750  
751 Returns:
752 None
753 ***************************************************************************/
754 static void DNSDiscardName(void)
755 {
756 BYTE i;
757  
758 while(1)
759 {
760 // Get first byte which will tell us if this is a 16-bit pointer or the
761 // length of the first of a series of labels
762 if(!UDPGet(&i))
763 return;
764  
765 // Check if this is a pointer, if so, get the reminaing 8 bits and return
766 if((i & 0xC0u) == 0xC0u)
767 {
768 UDPGet(&i);
769 return;
770 }
771  
772 // Exit once we reach a zero length label
773 if(i == 0u)
774 return;
775  
776 // Discard complete label
777 UDPGetArray(NULL, i);
778 }
779 }
780  
781  
782 #endif //#if defined(STACK_USE_DNS)
{BLAME END}
{FOOTER START}

Powered by WebSVN v2.8.3