00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032
00033
00034
00035
00036
00037
00038
00039
00040
00041
00042
00043
00044
00045
00046
00047
00048
00049
00050
00051
00052
00053
00054
00055
00056
00057
00058
00059
00060
00061
00062
00063
00064 #include "net/tcpip.h"
00065 #include "net/resolv.h"
00066
00067 #include <string.h>
00068
00069 #ifndef NULL
00070 #define NULL (void *)0
00071 #endif
00072
00073
00074 #define MAX_RETRIES 8
00075
00076
00077 struct dns_hdr {
00078 u16_t id;
00079 u8_t flags1, flags2;
00080 #define DNS_FLAG1_RESPONSE 0x80
00081 #define DNS_FLAG1_OPCODE_STATUS 0x10
00082 #define DNS_FLAG1_OPCODE_INVERSE 0x08
00083 #define DNS_FLAG1_OPCODE_STANDARD 0x00
00084 #define DNS_FLAG1_AUTHORATIVE 0x04
00085 #define DNS_FLAG1_TRUNC 0x02
00086 #define DNS_FLAG1_RD 0x01
00087 #define DNS_FLAG2_RA 0x80
00088 #define DNS_FLAG2_ERR_MASK 0x0f
00089 #define DNS_FLAG2_ERR_NONE 0x00
00090 #define DNS_FLAG2_ERR_NAME 0x03
00091 u16_t numquestions;
00092 u16_t numanswers;
00093 u16_t numauthrr;
00094 u16_t numextrarr;
00095 };
00096
00097
00098 struct dns_answer {
00099
00100
00101 u16_t type;
00102 u16_t class;
00103 u16_t ttl[2];
00104 u16_t len;
00105 u16_t ipaddr[2];
00106 };
00107
00108 struct namemap {
00109 #define STATE_UNUSED 0
00110 #define STATE_NEW 1
00111 #define STATE_ASKING 2
00112 #define STATE_DONE 3
00113 #define STATE_ERROR 4
00114 u8_t state;
00115 u8_t tmr;
00116 u8_t retries;
00117 u8_t seqno;
00118 u8_t err;
00119 char name[32];
00120 u16_t ipaddr[2];
00121 };
00122
00123 #ifndef UIP_CONF_RESOLV_ENTRIES
00124 #define RESOLV_ENTRIES 4
00125 #else
00126 #define RESOLV_ENTRIES UIP_CONF_RESOLV_ENTRIES
00127 #endif
00128
00129
00130 static struct namemap names[RESOLV_ENTRIES];
00131
00132 static u8_t seqno;
00133
00134 static struct uip_udp_conn *resolv_conn = NULL;
00135
00136 process_event_t resolv_event_found;
00137
00138 PROCESS(resolv_process, "DNS resolver");
00139
00140 enum {
00141 EVENT_NEW_SERVER=0
00142 };
00143
00144
00145
00146
00147
00148
00149
00150
00151 static unsigned char *
00152 parse_name(unsigned char *query)
00153 {
00154 unsigned char n;
00155
00156 do {
00157 n = *query++;
00158
00159 while(n > 0) {
00160
00161 ++query;
00162 --n;
00163 };
00164
00165 } while(*query != 0);
00166
00167 return query + 1;
00168 }
00169
00170
00171
00172
00173
00174
00175 static void
00176 check_entries(void)
00177 {
00178 register struct dns_hdr *hdr;
00179 char *query, *nptr, *nameptr;
00180 static u8_t i;
00181 static u8_t n;
00182 register struct namemap *namemapptr;
00183
00184 for(i = 0; i < RESOLV_ENTRIES; ++i) {
00185 namemapptr = &names[i];
00186 if(namemapptr->state == STATE_NEW ||
00187 namemapptr->state == STATE_ASKING) {
00188 if(namemapptr->state == STATE_ASKING) {
00189 if(--namemapptr->tmr == 0) {
00190 if(++namemapptr->retries == MAX_RETRIES) {
00191 namemapptr->state = STATE_ERROR;
00192 resolv_found(namemapptr->name, NULL);
00193 continue;
00194 }
00195 namemapptr->tmr = namemapptr->retries;
00196 } else {
00197
00198
00199
00200 continue;
00201 }
00202 } else {
00203 namemapptr->state = STATE_ASKING;
00204 namemapptr->tmr = 1;
00205 namemapptr->retries = 0;
00206 }
00207 hdr = (struct dns_hdr *)uip_appdata;
00208 memset(hdr, 0, sizeof(struct dns_hdr));
00209 hdr->id = htons(i);
00210 hdr->flags1 = DNS_FLAG1_RD;
00211 hdr->numquestions = HTONS(1);
00212 query = (char *)uip_appdata + 12;
00213 nameptr = namemapptr->name;
00214 --nameptr;
00215
00216 do {
00217 ++nameptr;
00218 nptr = query;
00219 ++query;
00220 for(n = 0; *nameptr != '.' && *nameptr != 0; ++nameptr) {
00221 *query = *nameptr;
00222 ++query;
00223 ++n;
00224 }
00225 *nptr = n;
00226 } while(*nameptr != 0);
00227 {
00228 static unsigned char endquery[] =
00229 {0,0,1,0,1};
00230 memcpy(query, endquery, 5);
00231 }
00232 uip_udp_send((unsigned char)(query + 5 - (char *)uip_appdata));
00233 break;
00234 }
00235 }
00236 }
00237
00238
00239
00240
00241
00242 static void
00243 newdata(void)
00244 {
00245 char *nameptr;
00246 struct dns_answer *ans;
00247 struct dns_hdr *hdr;
00248 static u8_t nquestions, nanswers;
00249 static u8_t i;
00250 register struct namemap *namemapptr;
00251
00252 hdr = (struct dns_hdr *)uip_appdata;
00253
00254
00255
00256
00257
00258
00259
00260
00261
00262
00263
00264
00265 i = htons(hdr->id);
00266 namemapptr = &names[i];
00267 if(i < RESOLV_ENTRIES &&
00268 namemapptr->state == STATE_ASKING) {
00269
00270
00271 namemapptr->state = STATE_DONE;
00272 namemapptr->err = hdr->flags2 & DNS_FLAG2_ERR_MASK;
00273
00274
00275 if(namemapptr->err != 0) {
00276 namemapptr->state = STATE_ERROR;
00277 resolv_found(namemapptr->name, NULL);
00278 return;
00279 }
00280
00281
00282
00283 nquestions = htons(hdr->numquestions);
00284 nanswers = htons(hdr->numanswers);
00285
00286
00287
00288
00289 nameptr = parse_name((char *)uip_appdata + 12) + 4;
00290
00291 while(nanswers > 0) {
00292
00293
00294 if(*nameptr & 0xc0) {
00295
00296 nameptr +=2;
00297
00298 } else {
00299
00300 nameptr = parse_name((char *)nameptr);
00301 }
00302
00303 ans = (struct dns_answer *)nameptr;
00304
00305
00306
00307
00308
00309
00310 if(ans->type == HTONS(1) &&
00311 ans->class == HTONS(1) &&
00312 ans->len == HTONS(4)) {
00313
00314
00315
00316
00317
00318
00319
00320 namemapptr->ipaddr[0] = ans->ipaddr[0];
00321 namemapptr->ipaddr[1] = ans->ipaddr[1];
00322
00323 resolv_found(namemapptr->name, namemapptr->ipaddr);
00324 return;
00325 } else {
00326 nameptr = nameptr + 10 + htons(ans->len);
00327 }
00328 --nanswers;
00329 }
00330 }
00331
00332 }
00333
00334
00335
00336
00337
00338 PROCESS_THREAD(resolv_process, ev, data)
00339 {
00340 int i;
00341
00342 PROCESS_BEGIN();
00343
00344 for(i = 0; i < RESOLV_ENTRIES; ++i) {
00345 names[i].state = STATE_UNUSED;
00346 }
00347 resolv_conn = NULL;
00348 resolv_event_found = process_alloc_event();
00349
00350
00351 while(1) {
00352 PROCESS_WAIT_EVENT();
00353
00354 if(ev == EVENT_NEW_SERVER) {
00355 if(resolv_conn != NULL) {
00356 uip_udp_remove(resolv_conn);
00357 }
00358
00359 resolv_conn = udp_new((u16_t *)data, HTONS(53), NULL);
00360
00361 } else if(ev == tcpip_event) {
00362 if(uip_udp_conn->rport == HTONS(53)) {
00363 if(uip_poll()) {
00364 check_entries();
00365 }
00366 if(uip_newdata()) {
00367 newdata();
00368 }
00369 }
00370 }
00371 }
00372
00373 PROCESS_END();
00374 }
00375
00376
00377
00378
00379
00380
00381
00382 void
00383 resolv_query(char *name)
00384 {
00385 static u8_t i;
00386 static u8_t lseq, lseqi;
00387 register struct namemap *nameptr;
00388
00389 lseq = lseqi = 0;
00390
00391 for(i = 0; i < RESOLV_ENTRIES; ++i) {
00392 nameptr = &names[i];
00393 if(nameptr->state == STATE_UNUSED) {
00394 break;
00395 }
00396 if(seqno - nameptr->seqno > lseq) {
00397 lseq = seqno - nameptr->seqno;
00398 lseqi = i;
00399 }
00400 }
00401
00402 if(i == RESOLV_ENTRIES) {
00403 i = lseqi;
00404 nameptr = &names[i];
00405 }
00406
00407 strncpy(nameptr->name, name, sizeof(nameptr->name));
00408 nameptr->state = STATE_NEW;
00409 nameptr->seqno = seqno;
00410 ++seqno;
00411
00412 if(resolv_conn != NULL) {
00413 tcpip_poll_udp(resolv_conn);
00414 }
00415 }
00416
00417
00418
00419
00420
00421
00422
00423
00424
00425
00426
00427
00428
00429
00430 u16_t *
00431 resolv_lookup(char *name)
00432 {
00433 static u8_t i;
00434 struct namemap *nameptr;
00435
00436
00437
00438 for(i = 0; i < RESOLV_ENTRIES; ++i) {
00439 nameptr = &names[i];
00440 if(nameptr->state == STATE_DONE &&
00441 strcmp(name, nameptr->name) == 0) {
00442 return nameptr->ipaddr;
00443 }
00444 }
00445 return NULL;
00446 }
00447
00448
00449
00450
00451
00452
00453
00454
00455
00456 u16_t *
00457 resolv_getserver(void)
00458 {
00459 if(resolv_conn == NULL) {
00460 return NULL;
00461 }
00462 return resolv_conn->ripaddr;
00463 }
00464
00465
00466
00467
00468
00469
00470
00471
00472 void
00473 resolv_conf(u16_t *dnsserver)
00474 {
00475 static u16_t server[2];
00476 uip_ipaddr_copy(server, dnsserver);
00477 process_post(&resolv_process, EVENT_NEW_SERVER, server);
00478
00479
00480
00481
00482
00483
00484 }
00485
00486
00487
00488
00489
00490
00491 void
00492 resolv_found(char *name, u16_t *ipaddr)
00493 {
00494 process_post(PROCESS_BROADCAST, resolv_event_found, name);
00495 }
00496
00497
00498
00499