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