blob: 2af92f071880af4382813efa0f8a8fafe0ca3691 [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 *
adamdunkels0d7a19d2005-02-07 07:08:03 +000016 * The event resolv_event_found is posted when a hostname has been
17 * resolved. It is up to the receiving process to determine if the
adamdunkels1e45c6d2003-09-02 21:47:27 +000018 * correct hostname has been found by calling the resolv_lookup()
19 * function with the hostname.
20 */
21
adamdunkels0170b082003-10-01 11:25:37 +000022/**
23 * \file
24 * DNS host name to IP address resolver.
25 * \author Adam Dunkels <adam@dunkels.com>
26 *
27 * This file implements a DNS host name to IP address resolver.
28 */
29
adamdunkelsca9ddcb2003-03-19 14:13:31 +000030/*
adamdunkels1e45c6d2003-09-02 21:47:27 +000031 * Copyright (c) 2002-2003, Adam Dunkels.
adamdunkelsca9ddcb2003-03-19 14:13:31 +000032 * All rights reserved.
33 *
34 * Redistribution and use in source and binary forms, with or without
35 * modification, are permitted provided that the following conditions
36 * are met:
37 * 1. Redistributions of source code must retain the above copyright
38 * notice, this list of conditions and the following disclaimer.
39 * 2. Redistributions in binary form must reproduce the above copyright
40 * notice, this list of conditions and the following disclaimer in the
41 * documentation and/or other materials provided with the distribution.
adamdunkels1e45c6d2003-09-02 21:47:27 +000042 * 3. The name of the author may not be used to endorse or promote
adamdunkelsca9ddcb2003-03-19 14:13:31 +000043 * products derived from this software without specific prior
44 * written permission.
45 *
46 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS
47 * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
48 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
49 * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
50 * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
51 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
52 * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
53 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
54 * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
55 * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
56 * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
57 *
58 * This file is part of the uIP TCP/IP stack.
59 *
adamdunkels0d7a19d2005-02-07 07:08:03 +000060 * $Id: resolv.c,v 1.15 2005/02/07 07:08:03 adamdunkels Exp $
adamdunkelsca9ddcb2003-03-19 14:13:31 +000061 *
62 */
63
adamdunkelsae920f92004-07-04 16:52:30 +000064#include "ek.h"
65#include "tcpip.h"
adamdunkelsca9ddcb2003-03-19 14:13:31 +000066#include "resolv.h"
adamdunkelsae920f92004-07-04 16:52:30 +000067
68#include <string.h>
adamdunkelsca9ddcb2003-03-19 14:13:31 +000069
70#ifndef NULL
71#define NULL (void *)0
72#endif /* NULL */
73
adamdunkels1e45c6d2003-09-02 21:47:27 +000074/** \internal The maximum number of retries when asking for a name. */
adamdunkelsca9ddcb2003-03-19 14:13:31 +000075#define MAX_RETRIES 8
76
adamdunkels1e45c6d2003-09-02 21:47:27 +000077/** \internal The DNS message header. */
adamdunkelsca9ddcb2003-03-19 14:13:31 +000078struct dns_hdr {
79 u16_t id;
80 u8_t flags1, flags2;
81#define DNS_FLAG1_RESPONSE 0x80
82#define DNS_FLAG1_OPCODE_STATUS 0x10
83#define DNS_FLAG1_OPCODE_INVERSE 0x08
84#define DNS_FLAG1_OPCODE_STANDARD 0x00
85#define DNS_FLAG1_AUTHORATIVE 0x04
86#define DNS_FLAG1_TRUNC 0x02
87#define DNS_FLAG1_RD 0x01
88#define DNS_FLAG2_RA 0x80
89#define DNS_FLAG2_ERR_MASK 0x0f
90#define DNS_FLAG2_ERR_NONE 0x00
91#define DNS_FLAG2_ERR_NAME 0x03
92 u16_t numquestions;
93 u16_t numanswers;
94 u16_t numauthrr;
95 u16_t numextrarr;
96};
97
adamdunkels1e45c6d2003-09-02 21:47:27 +000098/** \internal The DNS answer message structure. */
adamdunkelsca9ddcb2003-03-19 14:13:31 +000099struct dns_answer {
100 /* DNS answer record starts with either a domain name or a pointer
101 to a name already present somewhere in the packet. */
102 u16_t type;
103 u16_t class;
104 u16_t ttl[2];
105 u16_t len;
106 u16_t ipaddr[2];
107};
108
adamdunkels1e45c6d2003-09-02 21:47:27 +0000109struct namemap {
adamdunkelsca9ddcb2003-03-19 14:13:31 +0000110#define STATE_UNUSED 0
111#define STATE_NEW 1
112#define STATE_ASKING 2
113#define STATE_DONE 3
114#define STATE_ERROR 4
adamdunkelsca9ddcb2003-03-19 14:13:31 +0000115 u8_t state;
116 u8_t tmr;
117 u8_t retries;
118 u8_t seqno;
119 u8_t err;
adamdunkels1d31c322003-08-24 22:40:32 +0000120 char name[32];
adamdunkelsca9ddcb2003-03-19 14:13:31 +0000121 u16_t ipaddr[2];
122};
123
adamdunkelsbb2e93c2003-09-04 19:38:46 +0000124#ifndef UIP_CONF_RESOLV_ENTRIES
adamdunkels99dcf452003-08-15 18:50:36 +0000125#define RESOLV_ENTRIES 4
adamdunkelsbb2e93c2003-09-04 19:38:46 +0000126#else /* UIP_CONF_RESOLV_ENTRIES */
127#define RESOLV_ENTRIES UIP_CONF_RESOLV_ENTRIES
128#endif /* UIP_CONF_RESOLV_ENTRIES */
129
adamdunkelsca9ddcb2003-03-19 14:13:31 +0000130
131static struct namemap names[RESOLV_ENTRIES];
132
133static u8_t seqno;
134
135static struct uip_udp_conn *resolv_conn = NULL;
136
adamdunkelsae920f92004-07-04 16:52:30 +0000137ek_event_t resolv_event_found;
adamdunkels0170b082003-10-01 11:25:37 +0000138
adamdunkelsae920f92004-07-04 16:52:30 +0000139/*static DISPATCHER_UIPCALL(udp_appcall, arg);
adamdunkels01385782003-11-27 15:53:48 +0000140static struct dispatcher_proc p =
adamdunkelsae920f92004-07-04 16:52:30 +0000141{DISPATCHER_PROC("DNS resolver", NULL, NULL, udp_appcall)};*/
142EK_EVENTHANDLER(resolv_eventhandler, ev, data);
143EK_PROCESS(p, "DNS resolver", EK_PRIO_NORMAL, resolv_eventhandler, NULL, NULL);
adamdunkels01385782003-11-27 15:53:48 +0000144static ek_id_t id = EK_ID_NONE;
145
adamdunkelsae920f92004-07-04 16:52:30 +0000146enum {
147 EVENT_NEW_SERVER=0
148};
adamdunkelsca9ddcb2003-03-19 14:13:31 +0000149
150/*-----------------------------------------------------------------------------------*/
adamdunkels1e45c6d2003-09-02 21:47:27 +0000151/** \internal
152 * Walk through a compact encoded DNS name and return the end of it.
adamdunkelsca9ddcb2003-03-19 14:13:31 +0000153 *
adamdunkels1e45c6d2003-09-02 21:47:27 +0000154 * \return The end of the name.
adamdunkelsca9ddcb2003-03-19 14:13:31 +0000155 */
adamdunkels1e45c6d2003-09-02 21:47:27 +0000156/*-----------------------------------------------------------------------------------*/
adamdunkelsca9ddcb2003-03-19 14:13:31 +0000157static unsigned char *
158parse_name(unsigned char *query)
159{
160 unsigned char n;
161
162 do {
163 n = *query++;
164
165 while(n > 0) {
166 /* printf("%c", *query);*/
167 ++query;
168 --n;
169 };
170 /* printf(".");*/
171 } while(*query != 0);
172 /* printf("\n");*/
173 return query + 1;
174}
175/*-----------------------------------------------------------------------------------*/
adamdunkels1e45c6d2003-09-02 21:47:27 +0000176/** \internal
adamdunkelsca9ddcb2003-03-19 14:13:31 +0000177 * Runs through the list of names to see if there are any that have
adamdunkels1e45c6d2003-09-02 21:47:27 +0000178 * not yet been queried and, if so, sends out a query.
adamdunkelsca9ddcb2003-03-19 14:13:31 +0000179 */
adamdunkels1e45c6d2003-09-02 21:47:27 +0000180/*-----------------------------------------------------------------------------------*/
adamdunkelsca9ddcb2003-03-19 14:13:31 +0000181static void
182check_entries(void)
183{
adamdunkels23664022003-08-05 13:51:50 +0000184 register struct dns_hdr *hdr;
adamdunkelsca9ddcb2003-03-19 14:13:31 +0000185 char *query, *nptr, *nameptr;
adamdunkels99dcf452003-08-15 18:50:36 +0000186 static u8_t i;
187 static u8_t n;
adamdunkels23664022003-08-05 13:51:50 +0000188 register struct namemap *namemapptr;
189
adamdunkels01385782003-11-27 15:53:48 +0000190 for(i = 0; i < RESOLV_ENTRIES; ++i) {
adamdunkels23664022003-08-05 13:51:50 +0000191 namemapptr = &names[i];
192 if(namemapptr->state == STATE_NEW ||
193 namemapptr->state == STATE_ASKING) {
194 if(namemapptr->state == STATE_ASKING) {
195 if(--namemapptr->tmr == 0) {
196 if(++namemapptr->retries == MAX_RETRIES) {
197 namemapptr->state = STATE_ERROR;
198 resolv_found(namemapptr->name, NULL);
adamdunkelsca9ddcb2003-03-19 14:13:31 +0000199 continue;
200 }
adamdunkels23664022003-08-05 13:51:50 +0000201 namemapptr->tmr = namemapptr->retries;
adamdunkelsca9ddcb2003-03-19 14:13:31 +0000202 } else {
adamdunkels23664022003-08-05 13:51:50 +0000203 /* printf("Timer %d\n", namemapptr->tmr);*/
adamdunkelsca9ddcb2003-03-19 14:13:31 +0000204 /* Its timer has not run out, so we move on to next
205 entry. */
206 continue;
207 }
208 } else {
adamdunkels23664022003-08-05 13:51:50 +0000209 namemapptr->state = STATE_ASKING;
210 namemapptr->tmr = 1;
211 namemapptr->retries = 0;
adamdunkelsca9ddcb2003-03-19 14:13:31 +0000212 }
213 hdr = (struct dns_hdr *)uip_appdata;
adamdunkels99dcf452003-08-15 18:50:36 +0000214 memset(hdr, 0, sizeof(struct dns_hdr));
adamdunkelsca9ddcb2003-03-19 14:13:31 +0000215 hdr->id = htons(i);
216 hdr->flags1 = DNS_FLAG1_RD;
adamdunkels47ec7fa2003-03-28 12:11:17 +0000217 hdr->numquestions = HTONS(1);
adamdunkelsca9ddcb2003-03-19 14:13:31 +0000218 query = (char *)uip_appdata + 12;
adamdunkels23664022003-08-05 13:51:50 +0000219 nameptr = namemapptr->name;
adamdunkelsca9ddcb2003-03-19 14:13:31 +0000220 --nameptr;
221 /* Convert hostname into suitable query format. */
222 do {
223 ++nameptr;
224 nptr = query;
225 ++query;
226 for(n = 0; *nameptr != '.' && *nameptr != 0; ++nameptr) {
227 *query = *nameptr;
228 ++query;
229 ++n;
230 }
231 *nptr = n;
232 } while(*nameptr != 0);
adamdunkels23664022003-08-05 13:51:50 +0000233 {
234 static unsigned char endquery[] =
235 {0,0,1,0,1};
236 memcpy(query, endquery, 5);
237 }
adamdunkels23664022003-08-05 13:51:50 +0000238 uip_udp_send((unsigned char)(query + 5 - (char *)uip_appdata));
adamdunkelsca9ddcb2003-03-19 14:13:31 +0000239 break;
240 }
241 }
242}
243/*-----------------------------------------------------------------------------------*/
adamdunkels1e45c6d2003-09-02 21:47:27 +0000244/** \internal
245 * Called when new UDP data arrives.
246 */
247/*-----------------------------------------------------------------------------------*/
adamdunkelsca9ddcb2003-03-19 14:13:31 +0000248static void
249newdata(void)
250{
251 char *nameptr;
252 struct dns_answer *ans;
253 struct dns_hdr *hdr;
adamdunkels99dcf452003-08-15 18:50:36 +0000254 static u8_t nquestions, nanswers;
255 static u8_t i;
adamdunkels23664022003-08-05 13:51:50 +0000256 register struct namemap *namemapptr;
adamdunkelsca9ddcb2003-03-19 14:13:31 +0000257
258 hdr = (struct dns_hdr *)uip_appdata;
259 /* printf("ID %d\n", htons(hdr->id));
260 printf("Query %d\n", hdr->flags1 & DNS_FLAG1_RESPONSE);
261 printf("Error %d\n", hdr->flags2 & DNS_FLAG2_ERR_MASK);
262 printf("Num questions %d, answers %d, authrr %d, extrarr %d\n",
263 htons(hdr->numquestions),
264 htons(hdr->numanswers),
265 htons(hdr->numauthrr),
266 htons(hdr->numextrarr));
267 */
268
269 /* The ID in the DNS header should be our entry into the name
270 table. */
adamdunkels23664022003-08-05 13:51:50 +0000271 i = htons(hdr->id);
272 namemapptr = &names[i];
adamdunkelsca9ddcb2003-03-19 14:13:31 +0000273 if(i < RESOLV_ENTRIES &&
adamdunkels23664022003-08-05 13:51:50 +0000274 namemapptr->state == STATE_ASKING) {
adamdunkelsca9ddcb2003-03-19 14:13:31 +0000275
276 /* This entry is now finished. */
adamdunkels23664022003-08-05 13:51:50 +0000277 namemapptr->state = STATE_DONE;
278 namemapptr->err = hdr->flags2 & DNS_FLAG2_ERR_MASK;
adamdunkelsca9ddcb2003-03-19 14:13:31 +0000279
280 /* Check for error. If so, call callback to inform. */
adamdunkels23664022003-08-05 13:51:50 +0000281 if(namemapptr->err != 0) {
282 namemapptr->state = STATE_ERROR;
283 resolv_found(namemapptr->name, NULL);
adamdunkelsca9ddcb2003-03-19 14:13:31 +0000284 return;
285 }
286
287 /* We only care about the question(s) and the answers. The authrr
288 and the extrarr are simply discarded. */
289 nquestions = htons(hdr->numquestions);
290 nanswers = htons(hdr->numanswers);
291
292 /* Skip the name in the question. XXX: This should really be
293 checked agains the name in the question, to be sure that they
294 match. */
295 nameptr = parse_name((char *)uip_appdata + 12) + 4;
296
297 while(nanswers > 0) {
298 /* The first byte in the answer resource record determines if it
299 is a compressed record or a normal one. */
300 if(*nameptr & 0xc0) {
301 /* Compressed name. */
302 nameptr +=2;
303 /* printf("Compressed anwser\n");*/
304 } else {
305 /* Not compressed name. */
306 nameptr = parse_name((char *)nameptr);
307 }
308
309 ans = (struct dns_answer *)nameptr;
310 /* printf("Answer: type %x, class %x, ttl %x, length %x\n",
adamdunkels99dcf452003-08-15 18:50:36 +0000311 htons(ans->type), htons(ans->class), (htons(ans->ttl[0])
312 << 16) | htons(ans->ttl[1]), htons(ans->len));*/
adamdunkelsca9ddcb2003-03-19 14:13:31 +0000313
314 /* Check for IP address type and Internet class. Others are
315 discarded. */
adamdunkels47ec7fa2003-03-28 12:11:17 +0000316 if(ans->type == HTONS(1) &&
317 ans->class == HTONS(1) &&
318 ans->len == HTONS(4)) {
adamdunkelsca9ddcb2003-03-19 14:13:31 +0000319 /* printf("IP address %d.%d.%d.%d\n",
320 htons(ans->ipaddr[0]) >> 8,
321 htons(ans->ipaddr[0]) & 0xff,
322 htons(ans->ipaddr[1]) >> 8,
323 htons(ans->ipaddr[1]) & 0xff);*/
324 /* XXX: we should really check that this IP address is the one
325 we want. */
adamdunkels23664022003-08-05 13:51:50 +0000326 namemapptr->ipaddr[0] = ans->ipaddr[0];
327 namemapptr->ipaddr[1] = ans->ipaddr[1];
adamdunkels99dcf452003-08-15 18:50:36 +0000328
adamdunkels23664022003-08-05 13:51:50 +0000329 resolv_found(namemapptr->name, namemapptr->ipaddr);
adamdunkelsca9ddcb2003-03-19 14:13:31 +0000330 return;
331 } else {
332 nameptr = nameptr + 10 + htons(ans->len);
333 }
334 --nanswers;
335 }
336 }
337
338}
339/*-----------------------------------------------------------------------------------*/
adamdunkels1e45c6d2003-09-02 21:47:27 +0000340/** \internal
adamdunkelsca9ddcb2003-03-19 14:13:31 +0000341 * The main UDP function.
342 */
adamdunkels1e45c6d2003-09-02 21:47:27 +0000343/*-----------------------------------------------------------------------------------*/
adamdunkelsae920f92004-07-04 16:52:30 +0000344EK_EVENTHANDLER(resolv_eventhandler, ev, data)
adamdunkelsca9ddcb2003-03-19 14:13:31 +0000345{
adamdunkelsae920f92004-07-04 16:52:30 +0000346 EK_EVENTHANDLER_ARGS(ev, data);
347 if(ev == EVENT_NEW_SERVER) {
348 if(resolv_conn != NULL) {
349 uip_udp_remove(resolv_conn);
adamdunkelsca9ddcb2003-03-19 14:13:31 +0000350 }
adamdunkelsae920f92004-07-04 16:52:30 +0000351
adamdunkelse3bf7472004-09-17 20:49:05 +0000352 resolv_conn = udp_new((u16_t *)data, HTONS(53), NULL);
adamdunkelsae920f92004-07-04 16:52:30 +0000353
354 } else if(ev == tcpip_event) {
355 if(uip_udp_conn->rport == HTONS(53)) {
356 if(uip_poll()) {
357 check_entries();
358 }
359 if(uip_newdata()) {
360 newdata();
361 }
362 }
363 }
adamdunkelsca9ddcb2003-03-19 14:13:31 +0000364}
365/*-----------------------------------------------------------------------------------*/
adamdunkels1e45c6d2003-09-02 21:47:27 +0000366/**
367 * Queues a name so that a question for the name will be sent out.
adamdunkelsca9ddcb2003-03-19 14:13:31 +0000368 *
adamdunkels1e45c6d2003-09-02 21:47:27 +0000369 * \param name The hostname that is to be queried.
adamdunkelsca9ddcb2003-03-19 14:13:31 +0000370 */
adamdunkels1e45c6d2003-09-02 21:47:27 +0000371/*-----------------------------------------------------------------------------------*/
adamdunkelsca9ddcb2003-03-19 14:13:31 +0000372void
373resolv_query(char *name)
374{
adamdunkels99dcf452003-08-15 18:50:36 +0000375 static u8_t i;
376 static u8_t lseq, lseqi;
adamdunkels23664022003-08-05 13:51:50 +0000377 register struct namemap *nameptr;
378
adamdunkelsca9ddcb2003-03-19 14:13:31 +0000379 lseq = lseqi = 0;
380
381 for(i = 0; i < RESOLV_ENTRIES; ++i) {
adamdunkels23664022003-08-05 13:51:50 +0000382 nameptr = &names[i];
383 if(nameptr->state == STATE_UNUSED) {
adamdunkelsca9ddcb2003-03-19 14:13:31 +0000384 break;
385 }
adamdunkels23664022003-08-05 13:51:50 +0000386 if(seqno - nameptr->seqno > lseq) {
387 lseq = seqno - nameptr->seqno;
adamdunkelsca9ddcb2003-03-19 14:13:31 +0000388 lseqi = i;
389 }
390 }
391
392 if(i == RESOLV_ENTRIES) {
393 i = lseqi;
adamdunkels23664022003-08-05 13:51:50 +0000394 nameptr = &names[i];
adamdunkelsca9ddcb2003-03-19 14:13:31 +0000395 }
396
adamdunkels01385782003-11-27 15:53:48 +0000397 strncpy(nameptr->name, name, sizeof(nameptr->name));
adamdunkels23664022003-08-05 13:51:50 +0000398 nameptr->state = STATE_NEW;
399 nameptr->seqno = seqno;
adamdunkelsca9ddcb2003-03-19 14:13:31 +0000400 ++seqno;
401
adamdunkels1e45c6d2003-09-02 21:47:27 +0000402 if(resolv_conn != NULL) {
adamdunkelsae920f92004-07-04 16:52:30 +0000403 tcpip_poll_udp(resolv_conn);
404 /*ek_post(EK_BROADCAST, uip_event_poll_udp, resolv_conn);*/
adamdunkels1e45c6d2003-09-02 21:47:27 +0000405 }
adamdunkelsca9ddcb2003-03-19 14:13:31 +0000406}
407/*-----------------------------------------------------------------------------------*/
adamdunkels1e45c6d2003-09-02 21:47:27 +0000408/**
409 * Look up a hostname in the array of known hostnames.
410 *
411 * \note This function only looks in the internal array of known
412 * hostnames, it does not send out a query for the hostname if none
413 * was found. The function resolv_query() can be used to send a query
414 * for a hostname.
415 *
416 * \return A pointer to a 4-byte representation of the hostname's IP
417 * address, or NULL if the hostname was not found in the array of
418 * hostnames.
419 */
420/*-----------------------------------------------------------------------------------*/
adamdunkelsca9ddcb2003-03-19 14:13:31 +0000421u16_t *
422resolv_lookup(char *name)
423{
adamdunkels99dcf452003-08-15 18:50:36 +0000424 static u8_t i;
adamdunkels23664022003-08-05 13:51:50 +0000425 struct namemap *nameptr;
426
adamdunkelsca9ddcb2003-03-19 14:13:31 +0000427 /* Walk through the list to see if the name is in there. If it is
428 not, we return NULL. */
429 for(i = 0; i < RESOLV_ENTRIES; ++i) {
adamdunkels23664022003-08-05 13:51:50 +0000430 nameptr = &names[i];
431 if(nameptr->state == STATE_DONE &&
adamdunkels99dcf452003-08-15 18:50:36 +0000432 strcmp(name, nameptr->name) == 0) {
adamdunkels23664022003-08-05 13:51:50 +0000433 return nameptr->ipaddr;
adamdunkelsca9ddcb2003-03-19 14:13:31 +0000434 }
435 }
436 return NULL;
437}
438/*-----------------------------------------------------------------------------------*/
adamdunkels1e45c6d2003-09-02 21:47:27 +0000439/**
440 * Obtain the currently configured DNS server.
441 *
442 * \return A pointer to a 4-byte representation of the IP address of
443 * the currently configured DNS server or NULL if no DNS server has
444 * been configured.
445 */
446/*-----------------------------------------------------------------------------------*/
adamdunkels66c6af62003-04-16 18:28:16 +0000447u16_t *
448resolv_getserver(void)
449{
450 if(resolv_conn == NULL) {
451 return NULL;
452 }
453 return resolv_conn->ripaddr;
454}
455/*-----------------------------------------------------------------------------------*/
adamdunkels1e45c6d2003-09-02 21:47:27 +0000456/**
457 * Configure a DNS server.
458 *
459 * \param dnsserver A pointer to a 4-byte representation of the IP
460 * address of the DNS server to be configured.
461 */
462/*-----------------------------------------------------------------------------------*/
adamdunkelsca9ddcb2003-03-19 14:13:31 +0000463void
464resolv_conf(u16_t *dnsserver)
465{
adamdunkels49432ec2004-08-09 20:46:32 +0000466 static u16_t server[2];
467 uip_ipaddr_copy(server, dnsserver);
468 ek_post(id, EVENT_NEW_SERVER, server);
adamdunkelsae920f92004-07-04 16:52:30 +0000469
470 /* if(resolv_conn != NULL) {
adamdunkelsca9ddcb2003-03-19 14:13:31 +0000471 uip_udp_remove(resolv_conn);
472 }
473
adamdunkelsae920f92004-07-04 16:52:30 +0000474 resolv_conn = udp_new(dnsserver, 53, NULL);*/
adamdunkelsca9ddcb2003-03-19 14:13:31 +0000475}
476/*-----------------------------------------------------------------------------------*/
adamdunkels1e45c6d2003-09-02 21:47:27 +0000477/**
478 * Initalize the resolver.
479 */
480/*-----------------------------------------------------------------------------------*/
adamdunkels981ae0d2004-02-24 09:54:52 +0000481/*LOADER_INIT_FUNC(resolv_init, arg)*/
482void
483resolv_init(char *arg)
adamdunkelsca9ddcb2003-03-19 14:13:31 +0000484{
adamdunkels49432ec2004-08-09 20:46:32 +0000485 static u8_t i;
486 arg_free(arg);
adamdunkels99dcf452003-08-15 18:50:36 +0000487
adamdunkels49432ec2004-08-09 20:46:32 +0000488 id = ek_start(&p);
489
490 for(i = 0; i < RESOLV_ENTRIES; ++i) {
491 names[i].state = STATE_UNUSED;
adamdunkelsca9ddcb2003-03-19 14:13:31 +0000492 }
adamdunkels49432ec2004-08-09 20:46:32 +0000493 resolv_conn = NULL;
494 resolv_event_found = ek_alloc_event();
adamdunkelsca9ddcb2003-03-19 14:13:31 +0000495}
496/*-----------------------------------------------------------------------------------*/
adamdunkels1e45c6d2003-09-02 21:47:27 +0000497/** \internal
498 * Callback function which is called when a hostname is found.
499 *
500 */
501/*-----------------------------------------------------------------------------------*/
adamdunkelsca9ddcb2003-03-19 14:13:31 +0000502void
503resolv_found(char *name, u16_t *ipaddr)
504{
adamdunkelsae920f92004-07-04 16:52:30 +0000505 ek_post(EK_BROADCAST, resolv_event_found, name);
adamdunkelsca9ddcb2003-03-19 14:13:31 +0000506}
adamdunkels66c6af62003-04-16 18:28:16 +0000507/*-----------------------------------------------------------------------------------*/
adamdunkels0170b082003-10-01 11:25:37 +0000508
509/** @} */
510/** @} */