blob: 571170527163ea74e2f9d0d15c6ccd561c2a2a31 [file] [log] [blame]
adamdunkels1e45c6d2003-09-02 21:47:27 +00001/**
adamdunkels0170b082003-10-01 11:25:37 +00002 * \addtogroup uip
3 * @{
4 */
5
6/**
7 * \defgroup uipdns uIP hostname resolver functions
8 * @{
9 *
10 * The uIP DNS resolver functions are used to lookup a hostname and
11 * map it to a numerical IP address. It maintains a list of resolved
12 * hostnames that can be queried with the resolv_lookup()
13 * function. New hostnames can be resolved using the resolv_query()
14 * function.
adamdunkels1e45c6d2003-09-02 21:47:27 +000015 *
16 * The signal resolv_signal_found is emitted when a hostname has been
17 * resolved. The signal is emitted to all processes listening for the
18 * signal, and it is up to the receiving process to determine if the
19 * correct hostname has been found by calling the resolv_lookup()
20 * function with the hostname.
21 */
22
adamdunkels0170b082003-10-01 11:25:37 +000023/**
24 * \file
25 * DNS host name to IP address resolver.
26 * \author Adam Dunkels <adam@dunkels.com>
27 *
28 * This file implements a DNS host name to IP address resolver.
29 */
30
adamdunkelsca9ddcb2003-03-19 14:13:31 +000031/*
adamdunkels1e45c6d2003-09-02 21:47:27 +000032 * Copyright (c) 2002-2003, Adam Dunkels.
adamdunkelsca9ddcb2003-03-19 14:13:31 +000033 * All rights reserved.
34 *
35 * Redistribution and use in source and binary forms, with or without
36 * modification, are permitted provided that the following conditions
37 * are met:
38 * 1. Redistributions of source code must retain the above copyright
39 * notice, this list of conditions and the following disclaimer.
40 * 2. Redistributions in binary form must reproduce the above copyright
41 * notice, this list of conditions and the following disclaimer in the
42 * documentation and/or other materials provided with the distribution.
adamdunkels1e45c6d2003-09-02 21:47:27 +000043 * 3. The name of the author may not be used to endorse or promote
adamdunkelsca9ddcb2003-03-19 14:13:31 +000044 * products derived from this software without specific prior
45 * written permission.
46 *
47 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS
48 * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
49 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
50 * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
51 * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
52 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
53 * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
54 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
55 * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
56 * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
57 * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
58 *
59 * This file is part of the uIP TCP/IP stack.
60 *
adamdunkels49432ec2004-08-09 20:46:32 +000061 * $Id: resolv.c,v 1.13 2004/08/09 20:46:32 adamdunkels Exp $
adamdunkelsca9ddcb2003-03-19 14:13:31 +000062 *
63 */
64
adamdunkelsae920f92004-07-04 16:52:30 +000065#include "ek.h"
66#include "tcpip.h"
adamdunkelsca9ddcb2003-03-19 14:13:31 +000067#include "resolv.h"
adamdunkelsae920f92004-07-04 16:52:30 +000068
69#include <string.h>
adamdunkelsca9ddcb2003-03-19 14:13:31 +000070
71#ifndef NULL
72#define NULL (void *)0
73#endif /* NULL */
74
adamdunkels1e45c6d2003-09-02 21:47:27 +000075/** \internal The maximum number of retries when asking for a name. */
adamdunkelsca9ddcb2003-03-19 14:13:31 +000076#define MAX_RETRIES 8
77
adamdunkels1e45c6d2003-09-02 21:47:27 +000078/** \internal The DNS message header. */
adamdunkelsca9ddcb2003-03-19 14:13:31 +000079struct dns_hdr {
80 u16_t id;
81 u8_t flags1, flags2;
82#define DNS_FLAG1_RESPONSE 0x80
83#define DNS_FLAG1_OPCODE_STATUS 0x10
84#define DNS_FLAG1_OPCODE_INVERSE 0x08
85#define DNS_FLAG1_OPCODE_STANDARD 0x00
86#define DNS_FLAG1_AUTHORATIVE 0x04
87#define DNS_FLAG1_TRUNC 0x02
88#define DNS_FLAG1_RD 0x01
89#define DNS_FLAG2_RA 0x80
90#define DNS_FLAG2_ERR_MASK 0x0f
91#define DNS_FLAG2_ERR_NONE 0x00
92#define DNS_FLAG2_ERR_NAME 0x03
93 u16_t numquestions;
94 u16_t numanswers;
95 u16_t numauthrr;
96 u16_t numextrarr;
97};
98
adamdunkels1e45c6d2003-09-02 21:47:27 +000099/** \internal The DNS answer message structure. */
adamdunkelsca9ddcb2003-03-19 14:13:31 +0000100struct dns_answer {
101 /* DNS answer record starts with either a domain name or a pointer
102 to a name already present somewhere in the packet. */
103 u16_t type;
104 u16_t class;
105 u16_t ttl[2];
106 u16_t len;
107 u16_t ipaddr[2];
108};
109
adamdunkels1e45c6d2003-09-02 21:47:27 +0000110struct namemap {
adamdunkelsca9ddcb2003-03-19 14:13:31 +0000111#define STATE_UNUSED 0
112#define STATE_NEW 1
113#define STATE_ASKING 2
114#define STATE_DONE 3
115#define STATE_ERROR 4
adamdunkelsca9ddcb2003-03-19 14:13:31 +0000116 u8_t state;
117 u8_t tmr;
118 u8_t retries;
119 u8_t seqno;
120 u8_t err;
adamdunkels1d31c322003-08-24 22:40:32 +0000121 char name[32];
adamdunkelsca9ddcb2003-03-19 14:13:31 +0000122 u16_t ipaddr[2];
123};
124
adamdunkelsbb2e93c2003-09-04 19:38:46 +0000125#ifndef UIP_CONF_RESOLV_ENTRIES
adamdunkels99dcf452003-08-15 18:50:36 +0000126#define RESOLV_ENTRIES 4
adamdunkelsbb2e93c2003-09-04 19:38:46 +0000127#else /* UIP_CONF_RESOLV_ENTRIES */
128#define RESOLV_ENTRIES UIP_CONF_RESOLV_ENTRIES
129#endif /* UIP_CONF_RESOLV_ENTRIES */
130
adamdunkelsca9ddcb2003-03-19 14:13:31 +0000131
132static struct namemap names[RESOLV_ENTRIES];
133
134static u8_t seqno;
135
136static struct uip_udp_conn *resolv_conn = NULL;
137
adamdunkelsae920f92004-07-04 16:52:30 +0000138ek_event_t resolv_event_found;
adamdunkels0170b082003-10-01 11:25:37 +0000139
adamdunkelsae920f92004-07-04 16:52:30 +0000140/*static DISPATCHER_UIPCALL(udp_appcall, arg);
adamdunkels01385782003-11-27 15:53:48 +0000141static struct dispatcher_proc p =
adamdunkelsae920f92004-07-04 16:52:30 +0000142{DISPATCHER_PROC("DNS resolver", NULL, NULL, udp_appcall)};*/
143EK_EVENTHANDLER(resolv_eventhandler, ev, data);
144EK_PROCESS(p, "DNS resolver", EK_PRIO_NORMAL, resolv_eventhandler, NULL, NULL);
adamdunkels01385782003-11-27 15:53:48 +0000145static ek_id_t id = EK_ID_NONE;
146
adamdunkelsae920f92004-07-04 16:52:30 +0000147enum {
148 EVENT_NEW_SERVER=0
149};
adamdunkelsca9ddcb2003-03-19 14:13:31 +0000150
151/*-----------------------------------------------------------------------------------*/
adamdunkels1e45c6d2003-09-02 21:47:27 +0000152/** \internal
153 * Walk through a compact encoded DNS name and return the end of it.
adamdunkelsca9ddcb2003-03-19 14:13:31 +0000154 *
adamdunkels1e45c6d2003-09-02 21:47:27 +0000155 * \return The end of the name.
adamdunkelsca9ddcb2003-03-19 14:13:31 +0000156 */
adamdunkels1e45c6d2003-09-02 21:47:27 +0000157/*-----------------------------------------------------------------------------------*/
adamdunkelsca9ddcb2003-03-19 14:13:31 +0000158static unsigned char *
159parse_name(unsigned char *query)
160{
161 unsigned char n;
162
163 do {
164 n = *query++;
165
166 while(n > 0) {
167 /* printf("%c", *query);*/
168 ++query;
169 --n;
170 };
171 /* printf(".");*/
172 } while(*query != 0);
173 /* printf("\n");*/
174 return query + 1;
175}
176/*-----------------------------------------------------------------------------------*/
adamdunkels1e45c6d2003-09-02 21:47:27 +0000177/** \internal
adamdunkelsca9ddcb2003-03-19 14:13:31 +0000178 * Runs through the list of names to see if there are any that have
adamdunkels1e45c6d2003-09-02 21:47:27 +0000179 * not yet been queried and, if so, sends out a query.
adamdunkelsca9ddcb2003-03-19 14:13:31 +0000180 */
adamdunkels1e45c6d2003-09-02 21:47:27 +0000181/*-----------------------------------------------------------------------------------*/
adamdunkelsca9ddcb2003-03-19 14:13:31 +0000182static void
183check_entries(void)
184{
adamdunkels23664022003-08-05 13:51:50 +0000185 register struct dns_hdr *hdr;
adamdunkelsca9ddcb2003-03-19 14:13:31 +0000186 char *query, *nptr, *nameptr;
adamdunkels99dcf452003-08-15 18:50:36 +0000187 static u8_t i;
188 static u8_t n;
adamdunkels23664022003-08-05 13:51:50 +0000189 register struct namemap *namemapptr;
190
adamdunkels01385782003-11-27 15:53:48 +0000191 for(i = 0; i < RESOLV_ENTRIES; ++i) {
adamdunkels23664022003-08-05 13:51:50 +0000192 namemapptr = &names[i];
193 if(namemapptr->state == STATE_NEW ||
194 namemapptr->state == STATE_ASKING) {
195 if(namemapptr->state == STATE_ASKING) {
196 if(--namemapptr->tmr == 0) {
197 if(++namemapptr->retries == MAX_RETRIES) {
198 namemapptr->state = STATE_ERROR;
199 resolv_found(namemapptr->name, NULL);
adamdunkelsca9ddcb2003-03-19 14:13:31 +0000200 continue;
201 }
adamdunkels23664022003-08-05 13:51:50 +0000202 namemapptr->tmr = namemapptr->retries;
adamdunkelsca9ddcb2003-03-19 14:13:31 +0000203 } else {
adamdunkels23664022003-08-05 13:51:50 +0000204 /* printf("Timer %d\n", namemapptr->tmr);*/
adamdunkelsca9ddcb2003-03-19 14:13:31 +0000205 /* Its timer has not run out, so we move on to next
206 entry. */
207 continue;
208 }
209 } else {
adamdunkels23664022003-08-05 13:51:50 +0000210 namemapptr->state = STATE_ASKING;
211 namemapptr->tmr = 1;
212 namemapptr->retries = 0;
adamdunkelsca9ddcb2003-03-19 14:13:31 +0000213 }
214 hdr = (struct dns_hdr *)uip_appdata;
adamdunkels99dcf452003-08-15 18:50:36 +0000215 memset(hdr, 0, sizeof(struct dns_hdr));
adamdunkelsca9ddcb2003-03-19 14:13:31 +0000216 hdr->id = htons(i);
217 hdr->flags1 = DNS_FLAG1_RD;
adamdunkels47ec7fa2003-03-28 12:11:17 +0000218 hdr->numquestions = HTONS(1);
adamdunkelsca9ddcb2003-03-19 14:13:31 +0000219 query = (char *)uip_appdata + 12;
adamdunkels23664022003-08-05 13:51:50 +0000220 nameptr = namemapptr->name;
adamdunkelsca9ddcb2003-03-19 14:13:31 +0000221 --nameptr;
222 /* Convert hostname into suitable query format. */
223 do {
224 ++nameptr;
225 nptr = query;
226 ++query;
227 for(n = 0; *nameptr != '.' && *nameptr != 0; ++nameptr) {
228 *query = *nameptr;
229 ++query;
230 ++n;
231 }
232 *nptr = n;
233 } while(*nameptr != 0);
adamdunkels23664022003-08-05 13:51:50 +0000234 {
235 static unsigned char endquery[] =
236 {0,0,1,0,1};
237 memcpy(query, endquery, 5);
238 }
adamdunkels23664022003-08-05 13:51:50 +0000239 uip_udp_send((unsigned char)(query + 5 - (char *)uip_appdata));
adamdunkelsca9ddcb2003-03-19 14:13:31 +0000240 break;
241 }
242 }
243}
244/*-----------------------------------------------------------------------------------*/
adamdunkels1e45c6d2003-09-02 21:47:27 +0000245/** \internal
246 * Called when new UDP data arrives.
247 */
248/*-----------------------------------------------------------------------------------*/
adamdunkelsca9ddcb2003-03-19 14:13:31 +0000249static void
250newdata(void)
251{
252 char *nameptr;
253 struct dns_answer *ans;
254 struct dns_hdr *hdr;
adamdunkels99dcf452003-08-15 18:50:36 +0000255 static u8_t nquestions, nanswers;
256 static u8_t i;
adamdunkels23664022003-08-05 13:51:50 +0000257 register struct namemap *namemapptr;
adamdunkelsca9ddcb2003-03-19 14:13:31 +0000258
259 hdr = (struct dns_hdr *)uip_appdata;
260 /* printf("ID %d\n", htons(hdr->id));
261 printf("Query %d\n", hdr->flags1 & DNS_FLAG1_RESPONSE);
262 printf("Error %d\n", hdr->flags2 & DNS_FLAG2_ERR_MASK);
263 printf("Num questions %d, answers %d, authrr %d, extrarr %d\n",
264 htons(hdr->numquestions),
265 htons(hdr->numanswers),
266 htons(hdr->numauthrr),
267 htons(hdr->numextrarr));
268 */
269
270 /* The ID in the DNS header should be our entry into the name
271 table. */
adamdunkels23664022003-08-05 13:51:50 +0000272 i = htons(hdr->id);
273 namemapptr = &names[i];
adamdunkelsca9ddcb2003-03-19 14:13:31 +0000274 if(i < RESOLV_ENTRIES &&
adamdunkels23664022003-08-05 13:51:50 +0000275 namemapptr->state == STATE_ASKING) {
adamdunkelsca9ddcb2003-03-19 14:13:31 +0000276
277 /* This entry is now finished. */
adamdunkels23664022003-08-05 13:51:50 +0000278 namemapptr->state = STATE_DONE;
279 namemapptr->err = hdr->flags2 & DNS_FLAG2_ERR_MASK;
adamdunkelsca9ddcb2003-03-19 14:13:31 +0000280
281 /* Check for error. If so, call callback to inform. */
adamdunkels23664022003-08-05 13:51:50 +0000282 if(namemapptr->err != 0) {
283 namemapptr->state = STATE_ERROR;
284 resolv_found(namemapptr->name, NULL);
adamdunkelsca9ddcb2003-03-19 14:13:31 +0000285 return;
286 }
287
288 /* We only care about the question(s) and the answers. The authrr
289 and the extrarr are simply discarded. */
290 nquestions = htons(hdr->numquestions);
291 nanswers = htons(hdr->numanswers);
292
293 /* Skip the name in the question. XXX: This should really be
294 checked agains the name in the question, to be sure that they
295 match. */
296 nameptr = parse_name((char *)uip_appdata + 12) + 4;
297
298 while(nanswers > 0) {
299 /* The first byte in the answer resource record determines if it
300 is a compressed record or a normal one. */
301 if(*nameptr & 0xc0) {
302 /* Compressed name. */
303 nameptr +=2;
304 /* printf("Compressed anwser\n");*/
305 } else {
306 /* Not compressed name. */
307 nameptr = parse_name((char *)nameptr);
308 }
309
310 ans = (struct dns_answer *)nameptr;
311 /* printf("Answer: type %x, class %x, ttl %x, length %x\n",
adamdunkels99dcf452003-08-15 18:50:36 +0000312 htons(ans->type), htons(ans->class), (htons(ans->ttl[0])
313 << 16) | htons(ans->ttl[1]), htons(ans->len));*/
adamdunkelsca9ddcb2003-03-19 14:13:31 +0000314
315 /* Check for IP address type and Internet class. Others are
316 discarded. */
adamdunkels47ec7fa2003-03-28 12:11:17 +0000317 if(ans->type == HTONS(1) &&
318 ans->class == HTONS(1) &&
319 ans->len == HTONS(4)) {
adamdunkelsca9ddcb2003-03-19 14:13:31 +0000320 /* printf("IP address %d.%d.%d.%d\n",
321 htons(ans->ipaddr[0]) >> 8,
322 htons(ans->ipaddr[0]) & 0xff,
323 htons(ans->ipaddr[1]) >> 8,
324 htons(ans->ipaddr[1]) & 0xff);*/
325 /* XXX: we should really check that this IP address is the one
326 we want. */
adamdunkels23664022003-08-05 13:51:50 +0000327 namemapptr->ipaddr[0] = ans->ipaddr[0];
328 namemapptr->ipaddr[1] = ans->ipaddr[1];
adamdunkels99dcf452003-08-15 18:50:36 +0000329
adamdunkels23664022003-08-05 13:51:50 +0000330 resolv_found(namemapptr->name, namemapptr->ipaddr);
adamdunkelsca9ddcb2003-03-19 14:13:31 +0000331 return;
332 } else {
333 nameptr = nameptr + 10 + htons(ans->len);
334 }
335 --nanswers;
336 }
337 }
338
339}
340/*-----------------------------------------------------------------------------------*/
adamdunkels1e45c6d2003-09-02 21:47:27 +0000341/** \internal
adamdunkelsca9ddcb2003-03-19 14:13:31 +0000342 * The main UDP function.
343 */
adamdunkels1e45c6d2003-09-02 21:47:27 +0000344/*-----------------------------------------------------------------------------------*/
adamdunkelsae920f92004-07-04 16:52:30 +0000345EK_EVENTHANDLER(resolv_eventhandler, ev, data)
adamdunkelsca9ddcb2003-03-19 14:13:31 +0000346{
adamdunkelsae920f92004-07-04 16:52:30 +0000347 EK_EVENTHANDLER_ARGS(ev, data);
348 if(ev == EVENT_NEW_SERVER) {
349 if(resolv_conn != NULL) {
350 uip_udp_remove(resolv_conn);
adamdunkelsca9ddcb2003-03-19 14:13:31 +0000351 }
adamdunkelsae920f92004-07-04 16:52:30 +0000352
353 resolv_conn = udp_new((u16_t *)data, 53, NULL);
354
355 } else if(ev == tcpip_event) {
356 if(uip_udp_conn->rport == HTONS(53)) {
357 if(uip_poll()) {
358 check_entries();
359 }
360 if(uip_newdata()) {
361 newdata();
362 }
363 }
364 }
adamdunkelsca9ddcb2003-03-19 14:13:31 +0000365}
366/*-----------------------------------------------------------------------------------*/
adamdunkels1e45c6d2003-09-02 21:47:27 +0000367/**
368 * Queues a name so that a question for the name will be sent out.
adamdunkelsca9ddcb2003-03-19 14:13:31 +0000369 *
adamdunkels1e45c6d2003-09-02 21:47:27 +0000370 * \param name The hostname that is to be queried.
adamdunkelsca9ddcb2003-03-19 14:13:31 +0000371 */
adamdunkels1e45c6d2003-09-02 21:47:27 +0000372/*-----------------------------------------------------------------------------------*/
adamdunkelsca9ddcb2003-03-19 14:13:31 +0000373void
374resolv_query(char *name)
375{
adamdunkels99dcf452003-08-15 18:50:36 +0000376 static u8_t i;
377 static u8_t lseq, lseqi;
adamdunkels23664022003-08-05 13:51:50 +0000378 register struct namemap *nameptr;
379
adamdunkelsca9ddcb2003-03-19 14:13:31 +0000380 lseq = lseqi = 0;
381
382 for(i = 0; i < RESOLV_ENTRIES; ++i) {
adamdunkels23664022003-08-05 13:51:50 +0000383 nameptr = &names[i];
384 if(nameptr->state == STATE_UNUSED) {
adamdunkelsca9ddcb2003-03-19 14:13:31 +0000385 break;
386 }
adamdunkels23664022003-08-05 13:51:50 +0000387 if(seqno - nameptr->seqno > lseq) {
388 lseq = seqno - nameptr->seqno;
adamdunkelsca9ddcb2003-03-19 14:13:31 +0000389 lseqi = i;
390 }
391 }
392
393 if(i == RESOLV_ENTRIES) {
394 i = lseqi;
adamdunkels23664022003-08-05 13:51:50 +0000395 nameptr = &names[i];
adamdunkelsca9ddcb2003-03-19 14:13:31 +0000396 }
397
adamdunkels01385782003-11-27 15:53:48 +0000398 strncpy(nameptr->name, name, sizeof(nameptr->name));
adamdunkels23664022003-08-05 13:51:50 +0000399 nameptr->state = STATE_NEW;
400 nameptr->seqno = seqno;
adamdunkelsca9ddcb2003-03-19 14:13:31 +0000401 ++seqno;
402
adamdunkels1e45c6d2003-09-02 21:47:27 +0000403 if(resolv_conn != NULL) {
adamdunkelsae920f92004-07-04 16:52:30 +0000404 tcpip_poll_udp(resolv_conn);
405 /*ek_post(EK_BROADCAST, uip_event_poll_udp, resolv_conn);*/
adamdunkels1e45c6d2003-09-02 21:47:27 +0000406 }
adamdunkelsca9ddcb2003-03-19 14:13:31 +0000407}
408/*-----------------------------------------------------------------------------------*/
adamdunkels1e45c6d2003-09-02 21:47:27 +0000409/**
410 * Look up a hostname in the array of known hostnames.
411 *
412 * \note This function only looks in the internal array of known
413 * hostnames, it does not send out a query for the hostname if none
414 * was found. The function resolv_query() can be used to send a query
415 * for a hostname.
416 *
417 * \return A pointer to a 4-byte representation of the hostname's IP
418 * address, or NULL if the hostname was not found in the array of
419 * hostnames.
420 */
421/*-----------------------------------------------------------------------------------*/
adamdunkelsca9ddcb2003-03-19 14:13:31 +0000422u16_t *
423resolv_lookup(char *name)
424{
adamdunkels99dcf452003-08-15 18:50:36 +0000425 static u8_t i;
adamdunkels23664022003-08-05 13:51:50 +0000426 struct namemap *nameptr;
427
adamdunkelsca9ddcb2003-03-19 14:13:31 +0000428 /* Walk through the list to see if the name is in there. If it is
429 not, we return NULL. */
430 for(i = 0; i < RESOLV_ENTRIES; ++i) {
adamdunkels23664022003-08-05 13:51:50 +0000431 nameptr = &names[i];
432 if(nameptr->state == STATE_DONE &&
adamdunkels99dcf452003-08-15 18:50:36 +0000433 strcmp(name, nameptr->name) == 0) {
adamdunkels23664022003-08-05 13:51:50 +0000434 return nameptr->ipaddr;
adamdunkelsca9ddcb2003-03-19 14:13:31 +0000435 }
436 }
437 return NULL;
438}
439/*-----------------------------------------------------------------------------------*/
adamdunkels1e45c6d2003-09-02 21:47:27 +0000440/**
441 * Obtain the currently configured DNS server.
442 *
443 * \return A pointer to a 4-byte representation of the IP address of
444 * the currently configured DNS server or NULL if no DNS server has
445 * been configured.
446 */
447/*-----------------------------------------------------------------------------------*/
adamdunkels66c6af62003-04-16 18:28:16 +0000448u16_t *
449resolv_getserver(void)
450{
451 if(resolv_conn == NULL) {
452 return NULL;
453 }
454 return resolv_conn->ripaddr;
455}
456/*-----------------------------------------------------------------------------------*/
adamdunkels1e45c6d2003-09-02 21:47:27 +0000457/**
458 * Configure a DNS server.
459 *
460 * \param dnsserver A pointer to a 4-byte representation of the IP
461 * address of the DNS server to be configured.
462 */
463/*-----------------------------------------------------------------------------------*/
adamdunkelsca9ddcb2003-03-19 14:13:31 +0000464void
465resolv_conf(u16_t *dnsserver)
466{
adamdunkels49432ec2004-08-09 20:46:32 +0000467 static u16_t server[2];
468 uip_ipaddr_copy(server, dnsserver);
469 ek_post(id, EVENT_NEW_SERVER, server);
adamdunkelsae920f92004-07-04 16:52:30 +0000470
471 /* if(resolv_conn != NULL) {
adamdunkelsca9ddcb2003-03-19 14:13:31 +0000472 uip_udp_remove(resolv_conn);
473 }
474
adamdunkelsae920f92004-07-04 16:52:30 +0000475 resolv_conn = udp_new(dnsserver, 53, NULL);*/
adamdunkelsca9ddcb2003-03-19 14:13:31 +0000476}
477/*-----------------------------------------------------------------------------------*/
adamdunkels1e45c6d2003-09-02 21:47:27 +0000478/**
479 * Initalize the resolver.
480 */
481/*-----------------------------------------------------------------------------------*/
adamdunkels981ae0d2004-02-24 09:54:52 +0000482/*LOADER_INIT_FUNC(resolv_init, arg)*/
483void
484resolv_init(char *arg)
adamdunkelsca9ddcb2003-03-19 14:13:31 +0000485{
adamdunkels49432ec2004-08-09 20:46:32 +0000486 static u8_t i;
487 arg_free(arg);
adamdunkels99dcf452003-08-15 18:50:36 +0000488
adamdunkels49432ec2004-08-09 20:46:32 +0000489 id = ek_start(&p);
490
491 for(i = 0; i < RESOLV_ENTRIES; ++i) {
492 names[i].state = STATE_UNUSED;
adamdunkelsca9ddcb2003-03-19 14:13:31 +0000493 }
adamdunkels49432ec2004-08-09 20:46:32 +0000494 resolv_conn = NULL;
495 resolv_event_found = ek_alloc_event();
adamdunkelsca9ddcb2003-03-19 14:13:31 +0000496}
497/*-----------------------------------------------------------------------------------*/
adamdunkels1e45c6d2003-09-02 21:47:27 +0000498/** \internal
499 * Callback function which is called when a hostname is found.
500 *
501 */
502/*-----------------------------------------------------------------------------------*/
adamdunkelsca9ddcb2003-03-19 14:13:31 +0000503void
504resolv_found(char *name, u16_t *ipaddr)
505{
adamdunkelsae920f92004-07-04 16:52:30 +0000506 ek_post(EK_BROADCAST, resolv_event_found, name);
adamdunkelsca9ddcb2003-03-19 14:13:31 +0000507}
adamdunkels66c6af62003-04-16 18:28:16 +0000508/*-----------------------------------------------------------------------------------*/
adamdunkels0170b082003-10-01 11:25:37 +0000509
510/** @} */
511/** @} */