xref: /nrf52832-nimble/rt-thread/components/net/uip/apps/resolv/resolv.c (revision 104654410c56c573564690304ae786df310c91fc)
1*10465441SEvalZero /**
2*10465441SEvalZero  * \addtogroup apps
3*10465441SEvalZero  * @{
4*10465441SEvalZero  */
5*10465441SEvalZero 
6*10465441SEvalZero /**
7*10465441SEvalZero  * \defgroup resolv DNS resolver
8*10465441SEvalZero  * @{
9*10465441SEvalZero  *
10*10465441SEvalZero  * The uIP DNS resolver functions are used to lookup a hostname and
11*10465441SEvalZero  * map it to a numerical IP address. It maintains a list of resolved
12*10465441SEvalZero  * hostnames that can be queried with the resolv_lookup()
13*10465441SEvalZero  * function. New hostnames can be resolved using the resolv_query()
14*10465441SEvalZero  * function.
15*10465441SEvalZero  *
16*10465441SEvalZero  * When a hostname has been resolved (or found to be non-existant),
17*10465441SEvalZero  * the resolver code calls a callback function called resolv_found()
18*10465441SEvalZero  * that must be implemented by the module that uses the resolver.
19*10465441SEvalZero  */
20*10465441SEvalZero 
21*10465441SEvalZero /**
22*10465441SEvalZero  * \file
23*10465441SEvalZero  * DNS host name to IP address resolver.
24*10465441SEvalZero  * \author Adam Dunkels <[email protected]>
25*10465441SEvalZero  *
26*10465441SEvalZero  * This file implements a DNS host name to IP address resolver.
27*10465441SEvalZero  */
28*10465441SEvalZero 
29*10465441SEvalZero /*
30*10465441SEvalZero  * Copyright (c) 2002-2003, Adam Dunkels.
31*10465441SEvalZero  * All rights reserved.
32*10465441SEvalZero  *
33*10465441SEvalZero  * Redistribution and use in source and binary forms, with or without
34*10465441SEvalZero  * modification, are permitted provided that the following conditions
35*10465441SEvalZero  * are met:
36*10465441SEvalZero  * 1. Redistributions of source code must retain the above copyright
37*10465441SEvalZero  *    notice, this list of conditions and the following disclaimer.
38*10465441SEvalZero  * 2. Redistributions in binary form must reproduce the above copyright
39*10465441SEvalZero  *    notice, this list of conditions and the following disclaimer in the
40*10465441SEvalZero  *    documentation and/or other materials provided with the distribution.
41*10465441SEvalZero  * 3. The name of the author may not be used to endorse or promote
42*10465441SEvalZero  *    products derived from this software without specific prior
43*10465441SEvalZero  *    written permission.
44*10465441SEvalZero  *
45*10465441SEvalZero  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS
46*10465441SEvalZero  * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
47*10465441SEvalZero  * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
48*10465441SEvalZero  * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
49*10465441SEvalZero  * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
50*10465441SEvalZero  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
51*10465441SEvalZero  * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
52*10465441SEvalZero  * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
53*10465441SEvalZero  * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
54*10465441SEvalZero  * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
55*10465441SEvalZero  * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
56*10465441SEvalZero  *
57*10465441SEvalZero  * This file is part of the uIP TCP/IP stack.
58*10465441SEvalZero  *
59*10465441SEvalZero  * $Id: resolv.c,v 1.5 2006/06/11 21:46:37 adam Exp $
60*10465441SEvalZero  *
61*10465441SEvalZero  */
62*10465441SEvalZero 
63*10465441SEvalZero #include "resolv.h"
64*10465441SEvalZero #include "uip.h"
65*10465441SEvalZero 
66*10465441SEvalZero #include <string.h>
67*10465441SEvalZero 
68*10465441SEvalZero #ifndef NULL
69*10465441SEvalZero #define NULL (void *)0
70*10465441SEvalZero #endif /* NULL */
71*10465441SEvalZero 
72*10465441SEvalZero /** \internal The maximum number of retries when asking for a name. */
73*10465441SEvalZero #define MAX_RETRIES 8
74*10465441SEvalZero 
75*10465441SEvalZero /** \internal The DNS message header. */
76*10465441SEvalZero struct dns_hdr {
77*10465441SEvalZero   u16_t id;
78*10465441SEvalZero   u8_t flags1, flags2;
79*10465441SEvalZero #define DNS_FLAG1_RESPONSE        0x80
80*10465441SEvalZero #define DNS_FLAG1_OPCODE_STATUS   0x10
81*10465441SEvalZero #define DNS_FLAG1_OPCODE_INVERSE  0x08
82*10465441SEvalZero #define DNS_FLAG1_OPCODE_STANDARD 0x00
83*10465441SEvalZero #define DNS_FLAG1_AUTHORATIVE     0x04
84*10465441SEvalZero #define DNS_FLAG1_TRUNC           0x02
85*10465441SEvalZero #define DNS_FLAG1_RD              0x01
86*10465441SEvalZero #define DNS_FLAG2_RA              0x80
87*10465441SEvalZero #define DNS_FLAG2_ERR_MASK        0x0f
88*10465441SEvalZero #define DNS_FLAG2_ERR_NONE        0x00
89*10465441SEvalZero #define DNS_FLAG2_ERR_NAME        0x03
90*10465441SEvalZero   u16_t numquestions;
91*10465441SEvalZero   u16_t numanswers;
92*10465441SEvalZero   u16_t numauthrr;
93*10465441SEvalZero   u16_t numextrarr;
94*10465441SEvalZero };
95*10465441SEvalZero 
96*10465441SEvalZero /** \internal The DNS answer message structure. */
97*10465441SEvalZero struct dns_answer {
98*10465441SEvalZero   /* DNS answer record starts with either a domain name or a pointer
99*10465441SEvalZero      to a name already present somewhere in the packet. */
100*10465441SEvalZero   u16_t type;
101*10465441SEvalZero   u16_t class;
102*10465441SEvalZero   u16_t ttl[2];
103*10465441SEvalZero   u16_t len;
104*10465441SEvalZero   uip_ipaddr_t ipaddr;
105*10465441SEvalZero };
106*10465441SEvalZero 
107*10465441SEvalZero struct namemap {
108*10465441SEvalZero #define STATE_UNUSED 0
109*10465441SEvalZero #define STATE_NEW    1
110*10465441SEvalZero #define STATE_ASKING 2
111*10465441SEvalZero #define STATE_DONE   3
112*10465441SEvalZero #define STATE_ERROR  4
113*10465441SEvalZero   u8_t state;
114*10465441SEvalZero   u8_t tmr;
115*10465441SEvalZero   u8_t retries;
116*10465441SEvalZero   u8_t seqno;
117*10465441SEvalZero   u8_t err;
118*10465441SEvalZero   char name[32];
119*10465441SEvalZero   uip_ipaddr_t ipaddr;
120*10465441SEvalZero };
121*10465441SEvalZero 
122*10465441SEvalZero #ifndef UIP_CONF_RESOLV_ENTRIES
123*10465441SEvalZero #define RESOLV_ENTRIES 4
124*10465441SEvalZero #else /* UIP_CONF_RESOLV_ENTRIES */
125*10465441SEvalZero #define RESOLV_ENTRIES UIP_CONF_RESOLV_ENTRIES
126*10465441SEvalZero #endif /* UIP_CONF_RESOLV_ENTRIES */
127*10465441SEvalZero 
128*10465441SEvalZero 
129*10465441SEvalZero static struct namemap names[RESOLV_ENTRIES];
130*10465441SEvalZero 
131*10465441SEvalZero static u8_t seqno;
132*10465441SEvalZero 
133*10465441SEvalZero static struct uip_udp_conn *resolv_conn = NULL;
134*10465441SEvalZero 
135*10465441SEvalZero 
136*10465441SEvalZero /*---------------------------------------------------------------------------*/
137*10465441SEvalZero /** \internal
138*10465441SEvalZero  * Walk through a compact encoded DNS name and return the end of it.
139*10465441SEvalZero  *
140*10465441SEvalZero  * \return The end of the name.
141*10465441SEvalZero  */
142*10465441SEvalZero /*---------------------------------------------------------------------------*/
143*10465441SEvalZero static unsigned char *
parse_name(unsigned char * query)144*10465441SEvalZero parse_name(unsigned char *query)
145*10465441SEvalZero {
146*10465441SEvalZero   unsigned char n;
147*10465441SEvalZero 
148*10465441SEvalZero   do {
149*10465441SEvalZero     n = *query++;
150*10465441SEvalZero 
151*10465441SEvalZero     while(n > 0) {
152*10465441SEvalZero       /*      printf("%c", *query);*/
153*10465441SEvalZero       ++query;
154*10465441SEvalZero       --n;
155*10465441SEvalZero     };
156*10465441SEvalZero     /*    printf(".");*/
157*10465441SEvalZero   } while(*query != 0);
158*10465441SEvalZero   /*  printf("\n");*/
159*10465441SEvalZero   return query + 1;
160*10465441SEvalZero }
161*10465441SEvalZero /*---------------------------------------------------------------------------*/
162*10465441SEvalZero /** \internal
163*10465441SEvalZero  * Runs through the list of names to see if there are any that have
164*10465441SEvalZero  * not yet been queried and, if so, sends out a query.
165*10465441SEvalZero  */
166*10465441SEvalZero /*---------------------------------------------------------------------------*/
167*10465441SEvalZero static void
check_entries(void)168*10465441SEvalZero check_entries(void)
169*10465441SEvalZero {
170*10465441SEvalZero   register struct dns_hdr *hdr;
171*10465441SEvalZero   char *query, *nptr, *nameptr;
172*10465441SEvalZero   static u8_t i;
173*10465441SEvalZero   static u8_t n;
174*10465441SEvalZero   register struct namemap *namemapptr;
175*10465441SEvalZero 
176*10465441SEvalZero   for(i = 0; i < RESOLV_ENTRIES; ++i) {
177*10465441SEvalZero     namemapptr = &names[i];
178*10465441SEvalZero     if(namemapptr->state == STATE_NEW ||
179*10465441SEvalZero        namemapptr->state == STATE_ASKING) {
180*10465441SEvalZero       if(namemapptr->state == STATE_ASKING) {
181*10465441SEvalZero 	if(--namemapptr->tmr == 0) {
182*10465441SEvalZero 	  if(++namemapptr->retries == MAX_RETRIES) {
183*10465441SEvalZero 	    namemapptr->state = STATE_ERROR;
184*10465441SEvalZero 	    resolv_found(namemapptr->name, NULL);
185*10465441SEvalZero 	    continue;
186*10465441SEvalZero 	  }
187*10465441SEvalZero 	  namemapptr->tmr = namemapptr->retries;
188*10465441SEvalZero 	} else {
189*10465441SEvalZero 	  /*	  printf("Timer %d\n", namemapptr->tmr);*/
190*10465441SEvalZero 	  /* Its timer has not run out, so we move on to next
191*10465441SEvalZero 	     entry. */
192*10465441SEvalZero 	  continue;
193*10465441SEvalZero 	}
194*10465441SEvalZero       } else {
195*10465441SEvalZero 	namemapptr->state = STATE_ASKING;
196*10465441SEvalZero 	namemapptr->tmr = 1;
197*10465441SEvalZero 	namemapptr->retries = 0;
198*10465441SEvalZero       }
199*10465441SEvalZero       hdr = (struct dns_hdr *)uip_appdata;
200*10465441SEvalZero       memset(hdr, 0, sizeof(struct dns_hdr));
201*10465441SEvalZero       hdr->id = htons(i);
202*10465441SEvalZero       hdr->flags1 = DNS_FLAG1_RD;
203*10465441SEvalZero       hdr->numquestions = HTONS(1);
204*10465441SEvalZero       query = (char *)uip_appdata + 12;
205*10465441SEvalZero       nameptr = namemapptr->name;
206*10465441SEvalZero       --nameptr;
207*10465441SEvalZero       /* Convert hostname into suitable query format. */
208*10465441SEvalZero       do {
209*10465441SEvalZero 	++nameptr;
210*10465441SEvalZero 	nptr = query;
211*10465441SEvalZero 	++query;
212*10465441SEvalZero 	for(n = 0; *nameptr != '.' && *nameptr != 0; ++nameptr) {
213*10465441SEvalZero 	  *query = *nameptr;
214*10465441SEvalZero 	  ++query;
215*10465441SEvalZero 	  ++n;
216*10465441SEvalZero 	}
217*10465441SEvalZero 	*nptr = n;
218*10465441SEvalZero       } while(*nameptr != 0);
219*10465441SEvalZero       {
220*10465441SEvalZero 	static unsigned char endquery[] =
221*10465441SEvalZero 	  {0,0,1,0,1};
222*10465441SEvalZero 	memcpy(query, endquery, 5);
223*10465441SEvalZero       }
224*10465441SEvalZero       uip_udp_send((unsigned char)(query + 5 - (char *)uip_appdata));
225*10465441SEvalZero       break;
226*10465441SEvalZero     }
227*10465441SEvalZero   }
228*10465441SEvalZero }
229*10465441SEvalZero /*---------------------------------------------------------------------------*/
230*10465441SEvalZero /** \internal
231*10465441SEvalZero  * Called when new UDP data arrives.
232*10465441SEvalZero  */
233*10465441SEvalZero /*---------------------------------------------------------------------------*/
234*10465441SEvalZero static void
newdata(void)235*10465441SEvalZero newdata(void)
236*10465441SEvalZero {
237*10465441SEvalZero   char *nameptr;
238*10465441SEvalZero   struct dns_answer *ans;
239*10465441SEvalZero   struct dns_hdr *hdr;
240*10465441SEvalZero   static u8_t nquestions, nanswers;
241*10465441SEvalZero   static u8_t i;
242*10465441SEvalZero   register struct namemap *namemapptr;
243*10465441SEvalZero 
244*10465441SEvalZero   hdr = (struct dns_hdr *)uip_appdata;
245*10465441SEvalZero   /*  printf("ID %d\n", htons(hdr->id));
246*10465441SEvalZero       printf("Query %d\n", hdr->flags1 & DNS_FLAG1_RESPONSE);
247*10465441SEvalZero       printf("Error %d\n", hdr->flags2 & DNS_FLAG2_ERR_MASK);
248*10465441SEvalZero       printf("Num questions %d, answers %d, authrr %d, extrarr %d\n",
249*10465441SEvalZero       htons(hdr->numquestions),
250*10465441SEvalZero       htons(hdr->numanswers),
251*10465441SEvalZero       htons(hdr->numauthrr),
252*10465441SEvalZero       htons(hdr->numextrarr));
253*10465441SEvalZero   */
254*10465441SEvalZero 
255*10465441SEvalZero   /* The ID in the DNS header should be our entry into the name
256*10465441SEvalZero      table. */
257*10465441SEvalZero   i = htons(hdr->id);
258*10465441SEvalZero   namemapptr = &names[i];
259*10465441SEvalZero   if(i < RESOLV_ENTRIES &&
260*10465441SEvalZero      namemapptr->state == STATE_ASKING) {
261*10465441SEvalZero 
262*10465441SEvalZero     /* This entry is now finished. */
263*10465441SEvalZero     namemapptr->state = STATE_DONE;
264*10465441SEvalZero     namemapptr->err = hdr->flags2 & DNS_FLAG2_ERR_MASK;
265*10465441SEvalZero 
266*10465441SEvalZero     /* Check for error. If so, call callback to inform. */
267*10465441SEvalZero     if(namemapptr->err != 0) {
268*10465441SEvalZero       namemapptr->state = STATE_ERROR;
269*10465441SEvalZero       resolv_found(namemapptr->name, NULL);
270*10465441SEvalZero       return;
271*10465441SEvalZero     }
272*10465441SEvalZero 
273*10465441SEvalZero     /* We only care about the question(s) and the answers. The authrr
274*10465441SEvalZero        and the extrarr are simply discarded. */
275*10465441SEvalZero     nquestions = htons(hdr->numquestions);
276*10465441SEvalZero     nanswers = htons(hdr->numanswers);
277*10465441SEvalZero 
278*10465441SEvalZero     /* Skip the name in the question. XXX: This should really be
279*10465441SEvalZero        checked agains the name in the question, to be sure that they
280*10465441SEvalZero        match. */
281*10465441SEvalZero     nameptr = parse_name((char *)uip_appdata + 12) + 4;
282*10465441SEvalZero 
283*10465441SEvalZero     while(nanswers > 0) {
284*10465441SEvalZero       /* The first byte in the answer resource record determines if it
285*10465441SEvalZero 	 is a compressed record or a normal one. */
286*10465441SEvalZero       if(*nameptr & 0xc0) {
287*10465441SEvalZero 	/* Compressed name. */
288*10465441SEvalZero 	nameptr +=2;
289*10465441SEvalZero 	/*	printf("Compressed anwser\n");*/
290*10465441SEvalZero       } else {
291*10465441SEvalZero 	/* Not compressed name. */
292*10465441SEvalZero 	nameptr = parse_name((char *)nameptr);
293*10465441SEvalZero       }
294*10465441SEvalZero 
295*10465441SEvalZero       ans = (struct dns_answer *)nameptr;
296*10465441SEvalZero       /*      printf("Answer: type %x, class %x, ttl %x, length %x\n",
297*10465441SEvalZero 	     htons(ans->type), htons(ans->class), (htons(ans->ttl[0])
298*10465441SEvalZero 	     << 16) | htons(ans->ttl[1]), htons(ans->len));*/
299*10465441SEvalZero 
300*10465441SEvalZero       /* Check for IP address type and Internet class. Others are
301*10465441SEvalZero 	 discarded. */
302*10465441SEvalZero       if(ans->type == HTONS(1) &&
303*10465441SEvalZero 	 ans->class == HTONS(1) &&
304*10465441SEvalZero 	 ans->len == HTONS(4)) {
305*10465441SEvalZero 	/*	printf("IP address %d.%d.%d.%d\n",
306*10465441SEvalZero 	       htons(ans->ipaddr[0]) >> 8,
307*10465441SEvalZero 	       htons(ans->ipaddr[0]) & 0xff,
308*10465441SEvalZero 	       htons(ans->ipaddr[1]) >> 8,
309*10465441SEvalZero 	       htons(ans->ipaddr[1]) & 0xff);*/
310*10465441SEvalZero 	/* XXX: we should really check that this IP address is the one
311*10465441SEvalZero 	   we want. */
312*10465441SEvalZero 	namemapptr->ipaddr[0] = ans->ipaddr[0];
313*10465441SEvalZero 	namemapptr->ipaddr[1] = ans->ipaddr[1];
314*10465441SEvalZero 
315*10465441SEvalZero 	resolv_found(namemapptr->name, namemapptr->ipaddr);
316*10465441SEvalZero 	return;
317*10465441SEvalZero       } else {
318*10465441SEvalZero 	nameptr = nameptr + 10 + htons(ans->len);
319*10465441SEvalZero       }
320*10465441SEvalZero       --nanswers;
321*10465441SEvalZero     }
322*10465441SEvalZero   }
323*10465441SEvalZero 
324*10465441SEvalZero }
325*10465441SEvalZero /*---------------------------------------------------------------------------*/
326*10465441SEvalZero /** \internal
327*10465441SEvalZero  * The main UDP function.
328*10465441SEvalZero  */
329*10465441SEvalZero /*---------------------------------------------------------------------------*/
330*10465441SEvalZero void
resolv_appcall(void)331*10465441SEvalZero resolv_appcall(void)
332*10465441SEvalZero {
333*10465441SEvalZero   if(uip_udp_conn->rport == HTONS(53)) {
334*10465441SEvalZero     if(uip_poll()) {
335*10465441SEvalZero       check_entries();
336*10465441SEvalZero     }
337*10465441SEvalZero     if(uip_newdata()) {
338*10465441SEvalZero       newdata();
339*10465441SEvalZero     }
340*10465441SEvalZero   }
341*10465441SEvalZero }
342*10465441SEvalZero /*---------------------------------------------------------------------------*/
343*10465441SEvalZero /**
344*10465441SEvalZero  * Queues a name so that a question for the name will be sent out.
345*10465441SEvalZero  *
346*10465441SEvalZero  * \param name The hostname that is to be queried.
347*10465441SEvalZero  */
348*10465441SEvalZero /*---------------------------------------------------------------------------*/
349*10465441SEvalZero void
resolv_query(char * name)350*10465441SEvalZero resolv_query(char *name)
351*10465441SEvalZero {
352*10465441SEvalZero   static u8_t i;
353*10465441SEvalZero   static u8_t lseq, lseqi;
354*10465441SEvalZero   register struct namemap *nameptr;
355*10465441SEvalZero 
356*10465441SEvalZero   lseq = lseqi = 0;
357*10465441SEvalZero 
358*10465441SEvalZero   for(i = 0; i < RESOLV_ENTRIES; ++i) {
359*10465441SEvalZero     nameptr = &names[i];
360*10465441SEvalZero     if(nameptr->state == STATE_UNUSED) {
361*10465441SEvalZero       break;
362*10465441SEvalZero     }
363*10465441SEvalZero     if(seqno - nameptr->seqno > lseq) {
364*10465441SEvalZero       lseq = seqno - nameptr->seqno;
365*10465441SEvalZero       lseqi = i;
366*10465441SEvalZero     }
367*10465441SEvalZero   }
368*10465441SEvalZero 
369*10465441SEvalZero   if(i == RESOLV_ENTRIES) {
370*10465441SEvalZero     i = lseqi;
371*10465441SEvalZero     nameptr = &names[i];
372*10465441SEvalZero   }
373*10465441SEvalZero 
374*10465441SEvalZero   /*  printf("Using entry %d\n", i);*/
375*10465441SEvalZero 
376*10465441SEvalZero   strcpy(nameptr->name, name);
377*10465441SEvalZero   nameptr->state = STATE_NEW;
378*10465441SEvalZero   nameptr->seqno = seqno;
379*10465441SEvalZero   ++seqno;
380*10465441SEvalZero }
381*10465441SEvalZero /*---------------------------------------------------------------------------*/
382*10465441SEvalZero /**
383*10465441SEvalZero  * Look up a hostname in the array of known hostnames.
384*10465441SEvalZero  *
385*10465441SEvalZero  * \note This function only looks in the internal array of known
386*10465441SEvalZero  * hostnames, it does not send out a query for the hostname if none
387*10465441SEvalZero  * was found. The function resolv_query() can be used to send a query
388*10465441SEvalZero  * for a hostname.
389*10465441SEvalZero  *
390*10465441SEvalZero  * \return A pointer to a 4-byte representation of the hostname's IP
391*10465441SEvalZero  * address, or NULL if the hostname was not found in the array of
392*10465441SEvalZero  * hostnames.
393*10465441SEvalZero  */
394*10465441SEvalZero /*---------------------------------------------------------------------------*/
395*10465441SEvalZero u16_t *
resolv_lookup(char * name)396*10465441SEvalZero resolv_lookup(char *name)
397*10465441SEvalZero {
398*10465441SEvalZero   static u8_t i;
399*10465441SEvalZero   struct namemap *nameptr;
400*10465441SEvalZero 
401*10465441SEvalZero   /* Walk through the list to see if the name is in there. If it is
402*10465441SEvalZero      not, we return NULL. */
403*10465441SEvalZero   for(i = 0; i < RESOLV_ENTRIES; ++i) {
404*10465441SEvalZero     nameptr = &names[i];
405*10465441SEvalZero     if(nameptr->state == STATE_DONE &&
406*10465441SEvalZero        strcmp(name, nameptr->name) == 0) {
407*10465441SEvalZero       return nameptr->ipaddr;
408*10465441SEvalZero     }
409*10465441SEvalZero   }
410*10465441SEvalZero   return NULL;
411*10465441SEvalZero }
412*10465441SEvalZero /*---------------------------------------------------------------------------*/
413*10465441SEvalZero /**
414*10465441SEvalZero  * Obtain the currently configured DNS server.
415*10465441SEvalZero  *
416*10465441SEvalZero  * \return A pointer to a 4-byte representation of the IP address of
417*10465441SEvalZero  * the currently configured DNS server or NULL if no DNS server has
418*10465441SEvalZero  * been configured.
419*10465441SEvalZero  */
420*10465441SEvalZero /*---------------------------------------------------------------------------*/
421*10465441SEvalZero u16_t *
resolv_getserver(void)422*10465441SEvalZero resolv_getserver(void)
423*10465441SEvalZero {
424*10465441SEvalZero   if(resolv_conn == NULL) {
425*10465441SEvalZero     return NULL;
426*10465441SEvalZero   }
427*10465441SEvalZero   return resolv_conn->ripaddr;
428*10465441SEvalZero }
429*10465441SEvalZero /*---------------------------------------------------------------------------*/
430*10465441SEvalZero /**
431*10465441SEvalZero  * Configure which DNS server to use for queries.
432*10465441SEvalZero  *
433*10465441SEvalZero  * \param dnsserver A pointer to a 4-byte representation of the IP
434*10465441SEvalZero  * address of the DNS server to be configured.
435*10465441SEvalZero  */
436*10465441SEvalZero /*---------------------------------------------------------------------------*/
437*10465441SEvalZero void
resolv_conf(u16_t * dnsserver)438*10465441SEvalZero resolv_conf(u16_t *dnsserver)
439*10465441SEvalZero {
440*10465441SEvalZero   if(resolv_conn != NULL) {
441*10465441SEvalZero     uip_udp_remove(resolv_conn);
442*10465441SEvalZero   }
443*10465441SEvalZero 
444*10465441SEvalZero   resolv_conn = uip_udp_new(dnsserver, HTONS(53));
445*10465441SEvalZero }
446*10465441SEvalZero /*---------------------------------------------------------------------------*/
447*10465441SEvalZero /**
448*10465441SEvalZero  * Initalize the resolver.
449*10465441SEvalZero  */
450*10465441SEvalZero /*---------------------------------------------------------------------------*/
451*10465441SEvalZero void
resolv_init(void)452*10465441SEvalZero resolv_init(void)
453*10465441SEvalZero {
454*10465441SEvalZero   static u8_t i;
455*10465441SEvalZero 
456*10465441SEvalZero   for(i = 0; i < RESOLV_ENTRIES; ++i) {
457*10465441SEvalZero     names[i].state = STATE_DONE;
458*10465441SEvalZero   }
459*10465441SEvalZero 
460*10465441SEvalZero }
461*10465441SEvalZero /*---------------------------------------------------------------------------*/
462*10465441SEvalZero 
463*10465441SEvalZero /** @} */
464*10465441SEvalZero /** @} */
465