blob: 365978730af48562db67d335da3991f382627e04 [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 *
adamdunkels981ae0d2004-02-24 09:54:52 +000061 * $Id: resolv.c,v 1.11 2004/02/24 09:54:52 adamdunkels Exp $
adamdunkelsca9ddcb2003-03-19 14:13:31 +000062 *
63 */
64
adamdunkels981ae0d2004-02-24 09:54:52 +000065#include <string.h>
66
adamdunkelsca9ddcb2003-03-19 14:13:31 +000067#include "resolv.h"
68#include "dispatcher.h"
adamdunkelsbb2e93c2003-09-04 19:38:46 +000069#include "uip-signal.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
adamdunkels0170b082003-10-01 11:25:37 +0000138ek_signal_t resolv_signal_found;
139
adamdunkels01385782003-11-27 15:53:48 +0000140static DISPATCHER_UIPCALL(udp_appcall, arg);
141static struct dispatcher_proc p =
142 {DISPATCHER_PROC("DNS resolver", NULL, NULL, udp_appcall)};
143static ek_id_t id = EK_ID_NONE;
144
adamdunkelsca9ddcb2003-03-19 14:13:31 +0000145
146/*-----------------------------------------------------------------------------------*/
adamdunkels1e45c6d2003-09-02 21:47:27 +0000147/** \internal
148 * Walk through a compact encoded DNS name and return the end of it.
adamdunkelsca9ddcb2003-03-19 14:13:31 +0000149 *
adamdunkels1e45c6d2003-09-02 21:47:27 +0000150 * \return The end of the name.
adamdunkelsca9ddcb2003-03-19 14:13:31 +0000151 */
adamdunkels1e45c6d2003-09-02 21:47:27 +0000152/*-----------------------------------------------------------------------------------*/
adamdunkelsca9ddcb2003-03-19 14:13:31 +0000153static unsigned char *
154parse_name(unsigned char *query)
155{
156 unsigned char n;
157
158 do {
159 n = *query++;
160
161 while(n > 0) {
162 /* printf("%c", *query);*/
163 ++query;
164 --n;
165 };
166 /* printf(".");*/
167 } while(*query != 0);
168 /* printf("\n");*/
169 return query + 1;
170}
171/*-----------------------------------------------------------------------------------*/
adamdunkels1e45c6d2003-09-02 21:47:27 +0000172/** \internal
adamdunkelsca9ddcb2003-03-19 14:13:31 +0000173 * Runs through the list of names to see if there are any that have
adamdunkels1e45c6d2003-09-02 21:47:27 +0000174 * not yet been queried and, if so, sends out a query.
adamdunkelsca9ddcb2003-03-19 14:13:31 +0000175 */
adamdunkels1e45c6d2003-09-02 21:47:27 +0000176/*-----------------------------------------------------------------------------------*/
adamdunkelsca9ddcb2003-03-19 14:13:31 +0000177static void
178check_entries(void)
179{
adamdunkels23664022003-08-05 13:51:50 +0000180 register struct dns_hdr *hdr;
adamdunkelsca9ddcb2003-03-19 14:13:31 +0000181 char *query, *nptr, *nameptr;
adamdunkels99dcf452003-08-15 18:50:36 +0000182 static u8_t i;
183 static u8_t n;
adamdunkels23664022003-08-05 13:51:50 +0000184 register struct namemap *namemapptr;
185
adamdunkels01385782003-11-27 15:53:48 +0000186 for(i = 0; i < RESOLV_ENTRIES; ++i) {
adamdunkels23664022003-08-05 13:51:50 +0000187 namemapptr = &names[i];
188 if(namemapptr->state == STATE_NEW ||
189 namemapptr->state == STATE_ASKING) {
190 if(namemapptr->state == STATE_ASKING) {
191 if(--namemapptr->tmr == 0) {
192 if(++namemapptr->retries == MAX_RETRIES) {
193 namemapptr->state = STATE_ERROR;
194 resolv_found(namemapptr->name, NULL);
adamdunkelsca9ddcb2003-03-19 14:13:31 +0000195 continue;
196 }
adamdunkels23664022003-08-05 13:51:50 +0000197 namemapptr->tmr = namemapptr->retries;
adamdunkelsca9ddcb2003-03-19 14:13:31 +0000198 } else {
adamdunkels23664022003-08-05 13:51:50 +0000199 /* printf("Timer %d\n", namemapptr->tmr);*/
adamdunkelsca9ddcb2003-03-19 14:13:31 +0000200 /* Its timer has not run out, so we move on to next
201 entry. */
202 continue;
203 }
204 } else {
adamdunkels23664022003-08-05 13:51:50 +0000205 namemapptr->state = STATE_ASKING;
206 namemapptr->tmr = 1;
207 namemapptr->retries = 0;
adamdunkelsca9ddcb2003-03-19 14:13:31 +0000208 }
209 hdr = (struct dns_hdr *)uip_appdata;
adamdunkels99dcf452003-08-15 18:50:36 +0000210 memset(hdr, 0, sizeof(struct dns_hdr));
adamdunkelsca9ddcb2003-03-19 14:13:31 +0000211 hdr->id = htons(i);
212 hdr->flags1 = DNS_FLAG1_RD;
adamdunkels47ec7fa2003-03-28 12:11:17 +0000213 hdr->numquestions = HTONS(1);
adamdunkelsca9ddcb2003-03-19 14:13:31 +0000214 query = (char *)uip_appdata + 12;
adamdunkels23664022003-08-05 13:51:50 +0000215 nameptr = namemapptr->name;
adamdunkelsca9ddcb2003-03-19 14:13:31 +0000216 --nameptr;
217 /* Convert hostname into suitable query format. */
218 do {
219 ++nameptr;
220 nptr = query;
221 ++query;
222 for(n = 0; *nameptr != '.' && *nameptr != 0; ++nameptr) {
223 *query = *nameptr;
224 ++query;
225 ++n;
226 }
227 *nptr = n;
228 } while(*nameptr != 0);
adamdunkels23664022003-08-05 13:51:50 +0000229 {
230 static unsigned char endquery[] =
231 {0,0,1,0,1};
232 memcpy(query, endquery, 5);
233 }
adamdunkels23664022003-08-05 13:51:50 +0000234 uip_udp_send((unsigned char)(query + 5 - (char *)uip_appdata));
adamdunkelsca9ddcb2003-03-19 14:13:31 +0000235 break;
236 }
237 }
238}
239/*-----------------------------------------------------------------------------------*/
adamdunkels1e45c6d2003-09-02 21:47:27 +0000240/** \internal
241 * Called when new UDP data arrives.
242 */
243/*-----------------------------------------------------------------------------------*/
adamdunkelsca9ddcb2003-03-19 14:13:31 +0000244static void
245newdata(void)
246{
247 char *nameptr;
248 struct dns_answer *ans;
249 struct dns_hdr *hdr;
adamdunkels99dcf452003-08-15 18:50:36 +0000250 static u8_t nquestions, nanswers;
251 static u8_t i;
adamdunkels23664022003-08-05 13:51:50 +0000252 register struct namemap *namemapptr;
adamdunkelsca9ddcb2003-03-19 14:13:31 +0000253
254 hdr = (struct dns_hdr *)uip_appdata;
255 /* printf("ID %d\n", htons(hdr->id));
256 printf("Query %d\n", hdr->flags1 & DNS_FLAG1_RESPONSE);
257 printf("Error %d\n", hdr->flags2 & DNS_FLAG2_ERR_MASK);
258 printf("Num questions %d, answers %d, authrr %d, extrarr %d\n",
259 htons(hdr->numquestions),
260 htons(hdr->numanswers),
261 htons(hdr->numauthrr),
262 htons(hdr->numextrarr));
263 */
264
265 /* The ID in the DNS header should be our entry into the name
266 table. */
adamdunkels23664022003-08-05 13:51:50 +0000267 i = htons(hdr->id);
268 namemapptr = &names[i];
adamdunkelsca9ddcb2003-03-19 14:13:31 +0000269 if(i < RESOLV_ENTRIES &&
adamdunkels23664022003-08-05 13:51:50 +0000270 namemapptr->state == STATE_ASKING) {
adamdunkelsca9ddcb2003-03-19 14:13:31 +0000271
272 /* This entry is now finished. */
adamdunkels23664022003-08-05 13:51:50 +0000273 namemapptr->state = STATE_DONE;
274 namemapptr->err = hdr->flags2 & DNS_FLAG2_ERR_MASK;
adamdunkelsca9ddcb2003-03-19 14:13:31 +0000275
276 /* Check for error. If so, call callback to inform. */
adamdunkels23664022003-08-05 13:51:50 +0000277 if(namemapptr->err != 0) {
278 namemapptr->state = STATE_ERROR;
279 resolv_found(namemapptr->name, NULL);
adamdunkelsca9ddcb2003-03-19 14:13:31 +0000280 return;
281 }
282
283 /* We only care about the question(s) and the answers. The authrr
284 and the extrarr are simply discarded. */
285 nquestions = htons(hdr->numquestions);
286 nanswers = htons(hdr->numanswers);
287
288 /* Skip the name in the question. XXX: This should really be
289 checked agains the name in the question, to be sure that they
290 match. */
291 nameptr = parse_name((char *)uip_appdata + 12) + 4;
292
293 while(nanswers > 0) {
294 /* The first byte in the answer resource record determines if it
295 is a compressed record or a normal one. */
296 if(*nameptr & 0xc0) {
297 /* Compressed name. */
298 nameptr +=2;
299 /* printf("Compressed anwser\n");*/
300 } else {
301 /* Not compressed name. */
302 nameptr = parse_name((char *)nameptr);
303 }
304
305 ans = (struct dns_answer *)nameptr;
306 /* printf("Answer: type %x, class %x, ttl %x, length %x\n",
adamdunkels99dcf452003-08-15 18:50:36 +0000307 htons(ans->type), htons(ans->class), (htons(ans->ttl[0])
308 << 16) | htons(ans->ttl[1]), htons(ans->len));*/
adamdunkelsca9ddcb2003-03-19 14:13:31 +0000309
310 /* Check for IP address type and Internet class. Others are
311 discarded. */
adamdunkels47ec7fa2003-03-28 12:11:17 +0000312 if(ans->type == HTONS(1) &&
313 ans->class == HTONS(1) &&
314 ans->len == HTONS(4)) {
adamdunkelsca9ddcb2003-03-19 14:13:31 +0000315 /* printf("IP address %d.%d.%d.%d\n",
316 htons(ans->ipaddr[0]) >> 8,
317 htons(ans->ipaddr[0]) & 0xff,
318 htons(ans->ipaddr[1]) >> 8,
319 htons(ans->ipaddr[1]) & 0xff);*/
320 /* XXX: we should really check that this IP address is the one
321 we want. */
adamdunkels23664022003-08-05 13:51:50 +0000322 namemapptr->ipaddr[0] = ans->ipaddr[0];
323 namemapptr->ipaddr[1] = ans->ipaddr[1];
adamdunkels99dcf452003-08-15 18:50:36 +0000324
adamdunkels23664022003-08-05 13:51:50 +0000325 resolv_found(namemapptr->name, namemapptr->ipaddr);
adamdunkelsca9ddcb2003-03-19 14:13:31 +0000326 return;
327 } else {
328 nameptr = nameptr + 10 + htons(ans->len);
329 }
330 --nanswers;
331 }
332 }
333
334}
335/*-----------------------------------------------------------------------------------*/
adamdunkels1e45c6d2003-09-02 21:47:27 +0000336/** \internal
adamdunkelsca9ddcb2003-03-19 14:13:31 +0000337 * The main UDP function.
338 */
adamdunkels1e45c6d2003-09-02 21:47:27 +0000339/*-----------------------------------------------------------------------------------*/
adamdunkels01385782003-11-27 15:53:48 +0000340static void
341udp_appcall(void *arg)
adamdunkelsca9ddcb2003-03-19 14:13:31 +0000342{
adamdunkels47ec7fa2003-03-28 12:11:17 +0000343 if(uip_udp_conn->rport == HTONS(53)) {
adamdunkelsca9ddcb2003-03-19 14:13:31 +0000344 if(uip_poll()) {
345 check_entries();
346 }
347 if(uip_newdata()) {
348 newdata();
349 }
350 }
351}
352/*-----------------------------------------------------------------------------------*/
adamdunkels1e45c6d2003-09-02 21:47:27 +0000353/**
354 * Queues a name so that a question for the name will be sent out.
adamdunkelsca9ddcb2003-03-19 14:13:31 +0000355 *
adamdunkels1e45c6d2003-09-02 21:47:27 +0000356 * \param name The hostname that is to be queried.
adamdunkelsca9ddcb2003-03-19 14:13:31 +0000357 */
adamdunkels1e45c6d2003-09-02 21:47:27 +0000358/*-----------------------------------------------------------------------------------*/
adamdunkelsca9ddcb2003-03-19 14:13:31 +0000359void
360resolv_query(char *name)
361{
adamdunkels99dcf452003-08-15 18:50:36 +0000362 static u8_t i;
363 static u8_t lseq, lseqi;
adamdunkels23664022003-08-05 13:51:50 +0000364 register struct namemap *nameptr;
365
adamdunkelsca9ddcb2003-03-19 14:13:31 +0000366 lseq = lseqi = 0;
367
368 for(i = 0; i < RESOLV_ENTRIES; ++i) {
adamdunkels23664022003-08-05 13:51:50 +0000369 nameptr = &names[i];
370 if(nameptr->state == STATE_UNUSED) {
adamdunkelsca9ddcb2003-03-19 14:13:31 +0000371 break;
372 }
adamdunkels23664022003-08-05 13:51:50 +0000373 if(seqno - nameptr->seqno > lseq) {
374 lseq = seqno - nameptr->seqno;
adamdunkelsca9ddcb2003-03-19 14:13:31 +0000375 lseqi = i;
376 }
377 }
378
379 if(i == RESOLV_ENTRIES) {
380 i = lseqi;
adamdunkels23664022003-08-05 13:51:50 +0000381 nameptr = &names[i];
adamdunkelsca9ddcb2003-03-19 14:13:31 +0000382 }
383
adamdunkels01385782003-11-27 15:53:48 +0000384 strncpy(nameptr->name, name, sizeof(nameptr->name));
adamdunkels23664022003-08-05 13:51:50 +0000385 nameptr->state = STATE_NEW;
386 nameptr->seqno = seqno;
adamdunkelsca9ddcb2003-03-19 14:13:31 +0000387 ++seqno;
388
adamdunkels1e45c6d2003-09-02 21:47:27 +0000389 if(resolv_conn != NULL) {
adamdunkelsbb2e93c2003-09-04 19:38:46 +0000390 dispatcher_emit(uip_signal_poll_udp, resolv_conn, DISPATCHER_BROADCAST);
adamdunkels1e45c6d2003-09-02 21:47:27 +0000391 }
adamdunkelsca9ddcb2003-03-19 14:13:31 +0000392}
393/*-----------------------------------------------------------------------------------*/
adamdunkels1e45c6d2003-09-02 21:47:27 +0000394/**
395 * Look up a hostname in the array of known hostnames.
396 *
397 * \note This function only looks in the internal array of known
398 * hostnames, it does not send out a query for the hostname if none
399 * was found. The function resolv_query() can be used to send a query
400 * for a hostname.
401 *
402 * \return A pointer to a 4-byte representation of the hostname's IP
403 * address, or NULL if the hostname was not found in the array of
404 * hostnames.
405 */
406/*-----------------------------------------------------------------------------------*/
adamdunkelsca9ddcb2003-03-19 14:13:31 +0000407u16_t *
408resolv_lookup(char *name)
409{
adamdunkels99dcf452003-08-15 18:50:36 +0000410 static u8_t i;
adamdunkels23664022003-08-05 13:51:50 +0000411 struct namemap *nameptr;
412
adamdunkelsca9ddcb2003-03-19 14:13:31 +0000413 /* Walk through the list to see if the name is in there. If it is
414 not, we return NULL. */
415 for(i = 0; i < RESOLV_ENTRIES; ++i) {
adamdunkels23664022003-08-05 13:51:50 +0000416 nameptr = &names[i];
417 if(nameptr->state == STATE_DONE &&
adamdunkels99dcf452003-08-15 18:50:36 +0000418 strcmp(name, nameptr->name) == 0) {
adamdunkels23664022003-08-05 13:51:50 +0000419 return nameptr->ipaddr;
adamdunkelsca9ddcb2003-03-19 14:13:31 +0000420 }
421 }
422 return NULL;
423}
424/*-----------------------------------------------------------------------------------*/
adamdunkels1e45c6d2003-09-02 21:47:27 +0000425/**
426 * Obtain the currently configured DNS server.
427 *
428 * \return A pointer to a 4-byte representation of the IP address of
429 * the currently configured DNS server or NULL if no DNS server has
430 * been configured.
431 */
432/*-----------------------------------------------------------------------------------*/
adamdunkels66c6af62003-04-16 18:28:16 +0000433u16_t *
434resolv_getserver(void)
435{
436 if(resolv_conn == NULL) {
437 return NULL;
438 }
439 return resolv_conn->ripaddr;
440}
441/*-----------------------------------------------------------------------------------*/
adamdunkels1e45c6d2003-09-02 21:47:27 +0000442/**
443 * Configure a DNS server.
444 *
445 * \param dnsserver A pointer to a 4-byte representation of the IP
446 * address of the DNS server to be configured.
447 */
448/*-----------------------------------------------------------------------------------*/
adamdunkelsca9ddcb2003-03-19 14:13:31 +0000449void
450resolv_conf(u16_t *dnsserver)
451{
452 if(resolv_conn != NULL) {
453 uip_udp_remove(resolv_conn);
454 }
455
adamdunkels01385782003-11-27 15:53:48 +0000456 resolv_conn = dispatcher_udp_new(dnsserver, 53, NULL);
adamdunkelsca9ddcb2003-03-19 14:13:31 +0000457}
458/*-----------------------------------------------------------------------------------*/
adamdunkels1e45c6d2003-09-02 21:47:27 +0000459/**
460 * Initalize the resolver.
461 */
462/*-----------------------------------------------------------------------------------*/
adamdunkels981ae0d2004-02-24 09:54:52 +0000463/*LOADER_INIT_FUNC(resolv_init, arg)*/
464void
465resolv_init(char *arg)
adamdunkelsca9ddcb2003-03-19 14:13:31 +0000466{
adamdunkels01385782003-11-27 15:53:48 +0000467 static u8_t i;
468 arg_free(arg);
adamdunkels99dcf452003-08-15 18:50:36 +0000469
adamdunkels01385782003-11-27 15:53:48 +0000470 if(id == EK_ID_NONE) {
471 id = dispatcher_start(&p);
472
473 for(i = 0; i < RESOLV_ENTRIES; ++i) {
474 names[i].state = STATE_UNUSED;
475 }
476
477 resolv_signal_found = dispatcher_sigalloc();
adamdunkelsca9ddcb2003-03-19 14:13:31 +0000478 }
adamdunkelsca9ddcb2003-03-19 14:13:31 +0000479}
480/*-----------------------------------------------------------------------------------*/
adamdunkels1e45c6d2003-09-02 21:47:27 +0000481/** \internal
482 * Callback function which is called when a hostname is found.
483 *
484 */
485/*-----------------------------------------------------------------------------------*/
adamdunkelsca9ddcb2003-03-19 14:13:31 +0000486void
487resolv_found(char *name, u16_t *ipaddr)
488{
489 dispatcher_emit(resolv_signal_found, name, DISPATCHER_BROADCAST);
490}
adamdunkels66c6af62003-04-16 18:28:16 +0000491/*-----------------------------------------------------------------------------------*/
adamdunkels0170b082003-10-01 11:25:37 +0000492
493/** @} */
494/** @} */