71 #define NULL (void *)0
83 PROCESS(resolv_process,
"DNS resolver");
100 #define MAX_RETRIES 8
106 #define DNS_FLAG1_RESPONSE 0x80
107 #define DNS_FLAG1_OPCODE_STATUS 0x10
108 #define DNS_FLAG1_OPCODE_INVERSE 0x08
109 #define DNS_FLAG1_OPCODE_STANDARD 0x00
110 #define DNS_FLAG1_AUTHORATIVE 0x04
111 #define DNS_FLAG1_TRUNC 0x02
112 #define DNS_FLAG1_RD 0x01
113 #define DNS_FLAG2_RA 0x80
114 #define DNS_FLAG2_ERR_MASK 0x0f
115 #define DNS_FLAG2_ERR_NONE 0x00
116 #define DNS_FLAG2_ERR_NAME 0x03
135 #define STATE_UNUSED 0
137 #define STATE_ASKING 2
139 #define STATE_ERROR 4
149 #ifndef UIP_CONF_RESOLV_ENTRIES
150 #define RESOLV_ENTRIES 4
152 #define RESOLV_ENTRIES UIP_CONF_RESOLV_ENTRIES
156 static struct namemap names[RESOLV_ENTRIES];
162 static struct etimer retry;
166 PROCESS(resolv_process,
"DNS resolver");
168 static void resolv_found(
char *name,
uip_ipaddr_t *ipaddr);
181 static unsigned char *
182 parse_name(
unsigned char *query)
195 }
while(*query != 0);
208 register struct dns_hdr *hdr;
209 char *query, *nptr, *nameptr;
212 register struct namemap *namemapptr;
214 for(i = 0; i < RESOLV_ENTRIES; ++i) {
215 namemapptr = &names[i];
216 if(namemapptr->state == STATE_NEW ||
217 namemapptr->state == STATE_ASKING) {
219 if(namemapptr->state == STATE_ASKING) {
220 if(--namemapptr->tmr == 0) {
221 if(++namemapptr->retries == MAX_RETRIES) {
222 namemapptr->state = STATE_ERROR;
223 resolv_found(namemapptr->name,
NULL);
226 namemapptr->tmr = namemapptr->retries;
234 namemapptr->state = STATE_ASKING;
236 namemapptr->retries = 0;
239 memset(hdr, 0,
sizeof(
struct dns_hdr));
241 hdr->flags1 = DNS_FLAG1_RD;
244 nameptr = namemapptr->name;
251 for(n = 0; *nameptr !=
'.' && *nameptr != 0; ++nameptr) {
257 }
while(*nameptr != 0);
259 static unsigned char endquery[] =
261 memcpy(query, endquery, 5);
276 unsigned char *nameptr;
277 struct dns_answer *ans;
279 static u8_t nquestions, nanswers;
281 register struct namemap *namemapptr;
297 namemapptr = &names[i];
298 if(i < RESOLV_ENTRIES &&
299 namemapptr->state == STATE_ASKING) {
302 namemapptr->state = STATE_DONE;
303 namemapptr->err = hdr->flags2 & DNS_FLAG2_ERR_MASK;
306 if(namemapptr->err != 0) {
307 namemapptr->state = STATE_ERROR;
308 resolv_found(namemapptr->name,
NULL);
320 nameptr = parse_name((uint8_t *)
uip_appdata + 12) + 4;
322 while(nanswers > 0) {
325 if(*nameptr & 0xc0) {
331 nameptr = parse_name((uint8_t *)nameptr);
334 ans = (
struct dns_answer *)nameptr;
351 for(i = 0; i < 4; i++) {
352 namemapptr->ipaddr.u8[i] = ans->ipaddr[i];
355 resolv_found(namemapptr->name, &namemapptr->ipaddr);
358 nameptr = nameptr + 10 +
uip_htons(ans->len);
375 for(i = 0; i < RESOLV_ENTRIES; ++i) {
376 names[i].state = STATE_UNUSED;
385 if(ev == PROCESS_EVENT_TIMER) {
386 if(resolv_conn !=
NULL) {
390 }
else if(ev == EVENT_NEW_SERVER) {
391 if(resolv_conn !=
NULL) {
421 static u8_t lseq, lseqi;
422 register struct namemap *nameptr;
427 for(i = 0; i < RESOLV_ENTRIES; ++i) {
429 if(nameptr->state == STATE_UNUSED) {
432 if(seqno - nameptr->seqno > lseq) {
433 lseq = seqno - nameptr->seqno;
438 if(i == RESOLV_ENTRIES) {
443 strncpy(nameptr->name, name,
sizeof(nameptr->name));
444 nameptr->state = STATE_NEW;
445 nameptr->seqno = seqno;
448 if(resolv_conn !=
NULL) {
470 struct namemap *nameptr;
474 for(i = 0; i < RESOLV_ENTRIES; ++i) {
476 if(nameptr->state == STATE_DONE &&
477 strcmp(name, nameptr->name) == 0) {
478 return &nameptr->ipaddr;
495 if(resolv_conn ==
NULL) {
513 process_post(&resolv_process, EVENT_NEW_SERVER, &server);