68 #include "lib/random.h" 74 #define LOG_MODULE "Resolv" 75 #define LOG_LEVEL LOG_LEVEL_NONE 81 int strcasecmp(
const char *s1,
const char *s2);
82 int strncasecmp(
const char *s1,
const char *s2,
size_t n);
88 #ifndef RESOLV_CONF_SUPPORTS_MDNS 89 #define RESOLV_CONF_SUPPORTS_MDNS 1 92 #ifndef RESOLV_CONF_MDNS_INCLUDE_GLOBAL_V6_ADDRS 93 #define RESOLV_CONF_MDNS_INCLUDE_GLOBAL_V6_ADDRS 0 97 #ifndef RESOLV_CONF_MAX_RETRIES 98 #define RESOLV_CONF_MAX_RETRIES 4 101 #ifndef RESOLV_CONF_MAX_MDNS_RETRIES 102 #define RESOLV_CONF_MAX_MDNS_RETRIES 3 105 #ifndef RESOLV_CONF_MAX_DOMAIN_NAME_SIZE 106 #define RESOLV_CONF_MAX_DOMAIN_NAME_SIZE 32 109 #ifdef RESOLV_CONF_AUTO_REMOVE_TRAILING_DOTS 110 #define RESOLV_AUTO_REMOVE_TRAILING_DOTS RESOLV_CONF_AUTO_REMOVE_TRAILING_DOTS 112 #define RESOLV_AUTO_REMOVE_TRAILING_DOTS RESOLV_CONF_SUPPORTS_MDNS 115 #ifdef RESOLV_CONF_VERIFY_ANSWER_NAMES 116 #define RESOLV_VERIFY_ANSWER_NAMES RESOLV_CONF_VERIFY_ANSWER_NAMES 118 #define RESOLV_VERIFY_ANSWER_NAMES RESOLV_CONF_SUPPORTS_MDNS 121 #ifdef RESOLV_CONF_SUPPORTS_RECORD_EXPIRATION 122 #define RESOLV_SUPPORTS_RECORD_EXPIRATION RESOLV_CONF_SUPPORTS_RECORD_EXPIRATION 124 #define RESOLV_SUPPORTS_RECORD_EXPIRATION 1 127 #if RESOLV_CONF_SUPPORTS_MDNS && !RESOLV_VERIFY_ANSWER_NAMES 128 #error RESOLV_CONF_SUPPORTS_MDNS cannot be set without RESOLV_CONF_VERIFY_ANSWER_NAMES 131 #if !defined(CONTIKI_TARGET_NAME) && defined(BOARD) 132 #define stringy2(x) #x 133 #define stringy(x) stringy2(x) 134 #define CONTIKI_TARGET_NAME stringy(BOARD) 137 #ifndef CONTIKI_CONF_DEFAULT_HOSTNAME 138 #ifdef CONTIKI_TARGET_NAME 139 #define CONTIKI_CONF_DEFAULT_HOSTNAME "contiki-"CONTIKI_TARGET_NAME 141 #define CONTIKI_CONF_DEFAULT_HOSTNAME "contiki" 146 #define DNS_TYPE_CNAME 5 147 #define DNS_TYPE_PTR 12 148 #define DNS_TYPE_MX 15 149 #define DNS_TYPE_TXT 16 150 #define DNS_TYPE_AAAA 28 151 #define DNS_TYPE_SRV 33 152 #define DNS_TYPE_ANY 255 153 #define DNS_TYPE_NSEC 47 155 #define NATIVE_DNS_TYPE DNS_TYPE_AAAA 157 #define DNS_CLASS_IN 1 158 #define DNS_CLASS_ANY 255 165 #define MDNS_PORT 5353 168 #ifndef MDNS_RESPONDER_PORT 169 #define MDNS_RESPONDER_PORT 5354 175 uint8_t flags1, flags2;
176 #define DNS_FLAG1_RESPONSE 0x80 177 #define DNS_FLAG1_OPCODE_STATUS 0x10 178 #define DNS_FLAG1_OPCODE_INVERSE 0x08 179 #define DNS_FLAG1_OPCODE_STANDARD 0x00 180 #define DNS_FLAG1_AUTHORATIVE 0x04 181 #define DNS_FLAG1_TRUNC 0x02 182 #define DNS_FLAG1_RD 0x01 183 #define DNS_FLAG2_RA 0x80 184 #define DNS_FLAG2_ERR_MASK 0x0f 185 #define DNS_FLAG2_ERR_NONE 0x00 186 #define DNS_FLAG2_ERR_NAME 0x03 187 uint16_t numquestions;
205 #define STATE_UNUSED 0 206 #define STATE_ERROR 1 208 #define STATE_ASKING 3 215 #if RESOLV_SUPPORTS_RECORD_EXPIRATION 216 unsigned long expiration;
221 #if RESOLV_CONF_SUPPORTS_MDNS 222 int is_mdns:1, is_probe:1;
224 char name[RESOLV_CONF_MAX_DOMAIN_NAME_SIZE + 1];
227 #ifndef UIP_CONF_RESOLV_ENTRIES 228 #define RESOLV_ENTRIES 4 230 #define RESOLV_ENTRIES UIP_CONF_RESOLV_ENTRIES 233 static struct namemap names[RESOLV_ENTRIES];
235 static uint8_t seqno;
239 static struct etimer retry;
243 PROCESS(resolv_process,
"DNS resolver");
245 static void resolv_found(
char *name, uip_ipaddr_t *
ipaddr);
248 struct dns_question {
253 #if RESOLV_CONF_SUPPORTS_MDNS 254 static char resolv_hostname[RESOLV_CONF_MAX_DOMAIN_NAME_SIZE + 1];
257 MDNS_STATE_WAIT_BEFORE_PROBE,
262 static uint8_t mdns_state;
264 static const uip_ipaddr_t resolv_mdns_addr =
265 { { 0xff, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
266 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xfb } };
269 static int mdns_needs_host_announce;
271 PROCESS(mdns_probe_process,
"mDNS probe");
275 #if RESOLV_VERIFY_ANSWER_NAMES || VERBOSE_DEBUG 284 decode_name(
const unsigned char *query,
char *dest,
285 const unsigned char *packet)
287 int len = RESOLV_CONF_MAX_DOMAIN_NAME_SIZE;
289 unsigned char n = *query++;
291 LOG_DBG(
"decoding name: \"");
295 const uint16_t offset = query[0] + ((n & ~0xC0) << 8);
297 LOG_DBG(
"<skip-to-%d>",offset);
298 query = packet + offset;
306 LOG_DBG(
"%c",*query);
333 dns_name_isequal(
const unsigned char *queryptr,
const char *name,
334 const unsigned char *packet)
336 unsigned char n = *queryptr++;
343 queryptr = packet + queryptr[0] + ((n & ~0xC0) << 8);
352 if(tolower((
unsigned int)*name++) != tolower((
unsigned int)*queryptr++)) {
359 if((n != 0) && (*name++ !=
'.')) {
373 static unsigned char *
374 skip_name(
unsigned char *query)
378 LOG_DBG(
"skip name: ");
383 LOG_DBG(
"<skip-to-%d>", query[0] + ((n & ~0xC0) << 8));
391 LOG_DBG_(
"%c", *query);
396 }
while(*query != 0);
403 static unsigned char *
404 encode_name(
unsigned char *query,
const char *nameptr)
414 nptr = (
char *)query;
416 for(n = 0; *nameptr !=
'.' && *nameptr != 0; ++nameptr) {
422 }
while(*nameptr != 0);
430 #if RESOLV_CONF_SUPPORTS_MDNS 434 mdns_announce_requested(
void)
436 mdns_needs_host_announce = 1;
442 start_name_collision_check(clock_time_t after)
450 static unsigned char *
451 mdns_write_announce_records(
unsigned char *queryptr, uint8_t *count)
455 for(i = 0; i < UIP_DS6_ADDR_NB; ++i) {
457 #
if !RESOLV_CONF_MDNS_INCLUDE_GLOBAL_V6_ADDRS
462 queryptr = encode_name(queryptr, resolv_hostname);
466 *queryptr++ =
sizeof(
struct dns_hdr);
469 *queryptr++ = (uint8_t) ((NATIVE_DNS_TYPE) >> 8);
470 *queryptr++ = (uint8_t) ((NATIVE_DNS_TYPE));
472 *queryptr++ = (uint8_t) ((DNS_CLASS_IN | 0x8000) >> 8);
473 *queryptr++ = (uint8_t) ((DNS_CLASS_IN | 0x8000));
481 *queryptr++ =
sizeof(uip_ipaddr_t);
484 queryptr +=
sizeof(uip_ipaddr_t);
495 mdns_prep_host_announce_packet(
void)
497 static const struct {
512 sizeof(
struct dns_hdr),
523 unsigned char *queryptr;
525 uint8_t total_answers = 0;
529 struct dns_hdr *hdr = (
struct dns_hdr *)
uip_appdata;
532 memset((
void *)hdr, 0,
sizeof(*hdr));
534 hdr->flags1 |= DNS_FLAG1_RESPONSE | DNS_FLAG1_AUTHORATIVE;
536 queryptr = (
unsigned char *)
uip_appdata +
sizeof(*hdr);
538 queryptr = mdns_write_announce_records(queryptr, &total_answers);
544 queryptr = encode_name(queryptr, resolv_hostname);
548 *queryptr++ =
sizeof(*hdr);
551 memcpy((
void *)queryptr, (
void *)&nsec_record,
sizeof(nsec_record));
553 queryptr +=
sizeof(nsec_record);
557 ((uint8_t*)&hdr->numanswers)[1] = total_answers;
558 ((uint8_t*)&hdr->numextrarr)[1] = 1;
565 try_next_server(
struct namemap *namemapptr)
568 printf(
"server %d\n", namemapptr->server);
570 namemapptr->server++;
572 namemapptr->retries = 0;
575 namemapptr->server = 0;
590 register struct dns_hdr *hdr;
592 register struct namemap *namemapptr;
594 for(i = 0; i < RESOLV_ENTRIES; ++i) {
595 namemapptr = &names[i];
596 if(namemapptr->state == STATE_NEW || namemapptr->state == STATE_ASKING) {
598 if(namemapptr->state == STATE_ASKING) {
599 if(--namemapptr->tmr == 0) {
600 #if RESOLV_CONF_SUPPORTS_MDNS 601 if(++namemapptr->retries ==
602 (namemapptr->is_mdns ? RESOLV_CONF_MAX_MDNS_RETRIES :
605 if(++namemapptr->retries == RESOLV_CONF_MAX_RETRIES)
610 if(try_next_server(namemapptr) == 0) {
612 namemapptr->state = STATE_ERROR;
614 #if RESOLV_SUPPORTS_RECORD_EXPIRATION 619 resolv_found(namemapptr->name, NULL);
623 namemapptr->tmr = namemapptr->retries * namemapptr->retries * 3;
625 #if RESOLV_CONF_SUPPORTS_MDNS 626 if(namemapptr->is_probe) {
638 namemapptr->state = STATE_ASKING;
640 namemapptr->retries = 0;
643 memset(hdr, 0,
sizeof(
struct dns_hdr));
645 namemapptr->id = hdr->id;
646 #if RESOLV_CONF_SUPPORTS_MDNS 647 if(!namemapptr->is_mdns || namemapptr->is_probe) {
648 hdr->flags1 = DNS_FLAG1_RD;
650 if(namemapptr->is_mdns) {
654 hdr->flags1 = DNS_FLAG1_RD;
657 query = (
unsigned char *)
uip_appdata +
sizeof(*hdr);
658 query = encode_name(query, namemapptr->name);
659 #if RESOLV_CONF_SUPPORTS_MDNS 660 if(namemapptr->is_probe) {
661 *query++ = (uint8_t) ((DNS_TYPE_ANY) >> 8);
662 *query++ = (uint8_t) ((DNS_TYPE_ANY));
666 *query++ = (uint8_t) ((NATIVE_DNS_TYPE) >> 8);
667 *query++ = (uint8_t) ((NATIVE_DNS_TYPE));
669 *query++ = (uint8_t) ((DNS_CLASS_IN) >> 8);
670 *query++ = (uint8_t) ((DNS_CLASS_IN));
671 #if RESOLV_CONF_SUPPORTS_MDNS 672 if(namemapptr->is_mdns) {
673 if(namemapptr->is_probe) {
681 query = mdns_write_announce_records(query, &count);
686 &resolv_mdns_addr,
UIP_HTONS(MDNS_PORT));
688 LOG_DBG(
"(i=%d) Sent MDNS %s for \"%s\".\n", i,
689 namemapptr->is_probe?
"probe":
"request",namemapptr->name);
693 (
const uip_ipaddr_t *)
697 LOG_DBG(
"(i=%d) Sent DNS request for \"%s\".\n", i,
701 uip_udp_packet_sendto(resolv_conn, uip_appdata,
702 (query - (uint8_t *) uip_appdata),
705 LOG_DBG(
"(i=%d) Sent DNS request for \"%s\".\n", i,
719 uint8_t nquestions, nanswers;
723 register struct namemap *namemapptr = NULL;
725 struct dns_answer *ans;
727 register struct dns_hdr const *hdr = (
struct dns_hdr *)uip_appdata;
729 unsigned char *queryptr = (
unsigned char *)hdr +
sizeof(*hdr);
731 const uint8_t is_request = ((hdr->flags1 & ~1) == 0) && (hdr->flags2 == 0);
736 nquestions = (uint8_t) uip_ntohs(hdr->numquestions);
737 nanswers = (uint8_t) uip_ntohs(hdr->numanswers);
739 queryptr = (
unsigned char *)hdr +
sizeof(*hdr);
742 LOG_DBG(
"flags1=0x%02X flags2=0x%02X nquestions=%d, nanswers=%d, nauthrr=%d, nextrarr=%d\n",
743 hdr->flags1, hdr->flags2, (uint8_t) nquestions, (uint8_t) nanswers,
744 (uint8_t) uip_ntohs(hdr->numauthrr),
745 (uint8_t) uip_ntohs(hdr->numextrarr));
747 if(is_request && (nquestions == 0)) {
749 LOG_DBG(
"Skipping request with no questions.\n");
755 for(; nquestions > 0;
756 queryptr = skip_name(queryptr) +
sizeof(
struct dns_question),
759 #if RESOLV_CONF_SUPPORTS_MDNS 769 struct dns_question *question = (
struct dns_question *)skip_name(queryptr);
771 #if !ARCH_DOESNT_NEED_ALIGNED_STRUCTS 772 static struct dns_question aligned;
773 memcpy(&aligned, question,
sizeof(aligned));
777 LOG_DBG(
"Question %d: type=%d class=%d\n", ++i,
780 if(((uip_ntohs(question->class) & 0x7FFF) != DNS_CLASS_IN) ||
781 ((question->type !=
UIP_HTONS(DNS_TYPE_ANY)) &&
782 (question->type !=
UIP_HTONS(NATIVE_DNS_TYPE)))) {
787 if(!dns_name_isequal(queryptr, resolv_hostname, uip_appdata)) {
791 LOG_DBG(
"THIS IS A REQUEST FOR US!!!\n");
793 if(mdns_state == MDNS_STATE_READY) {
797 if(UIP_UDP_BUF->srcport ==
UIP_HTONS(MDNS_PORT)) {
798 mdns_announce_requested();
800 uip_udp_packet_sendto(resolv_conn, uip_appdata,
801 mdns_prep_host_announce_packet(),
803 UIP_UDP_BUF->srcport);
808 LOG_DBG(
"But we are still probing. Waiting...\n");
813 nauthrr = (uint8_t)uip_ntohs(hdr->numauthrr);
835 #if RESOLV_CONF_SUPPORTS_MDNS 836 if(UIP_UDP_BUF->srcport ==
UIP_HTONS(MDNS_PORT) &&
847 for(i = 0; i < RESOLV_ENTRIES; ++i) {
848 namemapptr = &names[i];
849 if(namemapptr->state == STATE_ASKING &&
850 namemapptr->id == hdr->id) {
855 if(i >= RESOLV_ENTRIES || i < 0 || namemapptr->state != STATE_ASKING) {
856 LOG_DBG(
"DNS response has bad ID (%04X) \n", uip_ntohs(hdr->id));
860 LOG_DBG(
"Incoming response for \"%s\".\n", namemapptr->name);
863 namemapptr->state = STATE_ERROR;
865 namemapptr->err = hdr->flags2 & DNS_FLAG2_ERR_MASK;
867 #if RESOLV_SUPPORTS_RECORD_EXPIRATION 873 if(namemapptr->err != 0) {
874 namemapptr->state = STATE_ERROR;
875 resolv_found(namemapptr->name, NULL);
883 while(nanswers > 0) {
884 ans = (
struct dns_answer *)skip_name(queryptr);
886 #if !ARCH_DOESNT_NEED_ALIGNED_STRUCTS 888 static struct dns_answer aligned;
889 memcpy(&aligned, ans,
sizeof(aligned));
896 decode_name(queryptr, debug_name, uip_appdata);
897 LOG_DBG(
"Answer %d: \"%s\", type %d, class %d, ttl %d, length %d\n",
898 ++i, debug_name, uip_ntohs(ans->type),
899 uip_ntohs(ans->class) & 0x7FFF,
900 (
int)((uint32_t) uip_ntohs(ans->ttl[0]) << 16) | (uint32_t)
901 uip_ntohs(ans->ttl[1]), uip_ntohs(ans->len));
907 if(((uip_ntohs(ans->class) & 0x7FFF) != DNS_CLASS_IN) ||
908 (ans->len !=
UIP_HTONS(
sizeof(uip_ipaddr_t)))) {
909 goto skip_to_next_answer;
912 if(ans->type !=
UIP_HTONS(NATIVE_DNS_TYPE)) {
913 goto skip_to_next_answer;
916 #if RESOLV_CONF_SUPPORTS_MDNS 917 if(UIP_UDP_BUF->srcport ==
UIP_HTONS(MDNS_PORT) &&
919 int8_t available_i = RESOLV_ENTRIES;
921 LOG_DBG(
"MDNS query.\n");
926 for(i = 0; i < RESOLV_ENTRIES; ++i) {
927 namemapptr = &names[i];
928 if(dns_name_isequal(queryptr, namemapptr->name, uip_appdata)) {
931 if((namemapptr->state == STATE_UNUSED)
932 #
if RESOLV_SUPPORTS_RECORD_EXPIRATION
933 || (namemapptr->state == STATE_DONE &&
clock_seconds() > namemapptr->expiration)
939 if(i == RESOLV_ENTRIES) {
940 LOG_DBG(
"Unsolicited MDNS response.\n");
942 namemapptr = &names[i];
943 if(!decode_name(queryptr, namemapptr->name, uip_appdata)) {
944 LOG_DBG(
"MDNS name too big to cache.\n");
946 goto skip_to_next_answer;
949 if(i == RESOLV_ENTRIES) {
951 (
"Not enough room to keep track of unsolicited MDNS answer.\n");
953 if(dns_name_isequal(queryptr, resolv_hostname, uip_appdata)) {
955 resolv_found(resolv_hostname, (uip_ipaddr_t *) ans->ipaddr);
958 goto skip_to_next_answer;
960 namemapptr = &names[i];
978 LOG_DBG(
"Answer for \"%s\" is usable.\n", namemapptr->name);
980 namemapptr->state = STATE_DONE;
981 #if RESOLV_SUPPORTS_RECORD_EXPIRATION 982 namemapptr->expiration = (uint32_t) uip_ntohs(ans->ttl[0]) << 16 |
983 (uint32_t) uip_ntohs(ans->ttl[1]);
984 LOG_DBG(
"Expires in %lu seconds\n", namemapptr->expiration);
991 resolv_found(namemapptr->name, &namemapptr->ipaddr);
995 queryptr = (
unsigned char *)skip_name(queryptr) + 10 +
uip_htons(ans->len);
1001 #if RESOLV_CONF_SUPPORTS_MDNS 1002 if(nanswers == 0 && UIP_UDP_BUF->srcport !=
UIP_HTONS(MDNS_PORT)
1008 if(try_next_server(namemapptr)) {
1009 namemapptr->state = STATE_ASKING;
1010 process_post(&resolv_process, PROCESS_EVENT_TIMER, NULL);
1016 #if RESOLV_CONF_SUPPORTS_MDNS 1024 strncpy(resolv_hostname, hostname, RESOLV_CONF_MAX_DOMAIN_NAME_SIZE);
1027 if(strlen(resolv_hostname) < 7 ||
1028 strcasecmp(resolv_hostname + strlen(resolv_hostname) - 6,
".local") != 0) {
1029 strncat(resolv_hostname,
".local", RESOLV_CONF_MAX_DOMAIN_NAME_SIZE - strlen(resolv_hostname));
1032 LOG_DBG(
"hostname changed to \"%s\"\n", resolv_hostname);
1034 start_name_collision_check(0);
1044 return resolv_hostname;
1052 static struct etimer delay;
1055 mdns_state = MDNS_STATE_WAIT_BEFORE_PROBE;
1057 LOG_DBG(
"mdns-probe: Process (re)started.\n");
1061 LOG_DBG(
"mdns-probe: Probing will begin in %ld clocks.\n",
1062 (
long)*(clock_time_t *) data);
1073 mdns_state = MDNS_STATE_PROBING;
1078 }
while(strcasecmp(resolv_hostname, data) != 0);
1080 mdns_state = MDNS_STATE_READY;
1081 mdns_announce_requested();
1083 LOG_DBG(
"mdns-probe: Finished probing.\n");
1096 memset(names, 0,
sizeof(names));
1100 LOG_DBG(
"Process started.\n");
1102 resolv_conn =
udp_new(NULL, 0, NULL);
1104 #if RESOLV_CONF_SUPPORTS_MDNS 1105 LOG_DBG(
"Supports MDNS.\n");
1108 uip_ds6_maddr_add(&resolv_mdns_addr);
1116 if(ev == PROCESS_EVENT_TIMER) {
1124 #if RESOLV_CONF_SUPPORTS_MDNS 1125 if(mdns_needs_host_announce) {
1128 LOG_DBG(
"Announcing that we are \"%s\".\n",
1131 memset(uip_appdata, 0,
sizeof(
struct dns_hdr));
1133 len = mdns_prep_host_announce_packet();
1135 uip_udp_packet_sendto(resolv_conn, uip_appdata,
1136 len, &resolv_mdns_addr,
UIP_HTONS(MDNS_PORT));
1138 mdns_needs_host_announce = 0;
1153 #if RESOLV_CONF_SUPPORTS_MDNS 1154 if(mdns_needs_host_announce) {
1166 static uint8_t initialized = 0;
1173 #if RESOLV_AUTO_REMOVE_TRAILING_DOTS 1175 remove_trailing_dots(
const char *name) {
1176 static char dns_name_without_dots[RESOLV_CONF_MAX_DOMAIN_NAME_SIZE + 1];
1177 size_t len = strlen(name);
1179 if(len && name[len - 1] ==
'.') {
1180 strncpy(dns_name_without_dots, name, RESOLV_CONF_MAX_DOMAIN_NAME_SIZE);
1181 while(len && (dns_name_without_dots[len - 1] ==
'.')) {
1182 dns_name_without_dots[--len] = 0;
1184 name = dns_name_without_dots;
1189 #define remove_trailing_dots(x) (x) 1202 uint8_t lseq, lseqi;
1204 register struct namemap *nameptr = 0;
1211 name = remove_trailing_dots(name);
1213 for(i = 0; i < RESOLV_ENTRIES; ++i) {
1214 nameptr = &names[i];
1215 if(0 == strcasecmp(nameptr->name, name)) {
1218 if((nameptr->state == STATE_UNUSED)
1219 #
if RESOLV_SUPPORTS_RECORD_EXPIRATION
1220 || (nameptr->state == STATE_DONE &&
clock_seconds() > nameptr->expiration)
1225 }
else if(seqno - nameptr->seqno > lseq) {
1226 lseq = seqno - nameptr->seqno;
1231 if(i == RESOLV_ENTRIES) {
1233 nameptr = &names[i];
1236 LOG_DBG(
"Starting query for \"%s\".\n", name);
1238 memset(nameptr, 0,
sizeof(*nameptr));
1240 strncpy(nameptr->name, name,
sizeof(nameptr->name) - 1);
1241 nameptr->state = STATE_NEW;
1242 nameptr->seqno = seqno;
1245 #if RESOLV_CONF_SUPPORTS_MDNS 1247 size_t name_len = strlen(name);
1249 const char local_suffix[] =
"local";
1251 if((name_len > (
sizeof(local_suffix) - 1)) &&
1252 (0 == strcasecmp(name + name_len - (
sizeof(local_suffix) - 1), local_suffix))) {
1253 LOG_DBG(
"Using MDNS to look up \"%s\".\n", name);
1254 nameptr->is_mdns = 1;
1256 nameptr->is_mdns = 0;
1259 nameptr->is_probe = (mdns_state == MDNS_STATE_PROBING) &&
1260 (0 == strcmp(nameptr->name, resolv_hostname));
1283 struct namemap *nameptr;
1286 name = remove_trailing_dots(name);
1288 #if UIP_CONF_LOOPBACK_INTERFACE 1289 if(strcmp(name,
"localhost")) {
1290 static uip_ipaddr_t loopback =
1291 { { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1292 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01 } };
1294 *ipaddr = &loopback;
1301 for(i = 0; i < RESOLV_ENTRIES; ++i) {
1302 nameptr = &names[i];
1304 if(strcasecmp(name, nameptr->name) == 0) {
1305 switch (nameptr->state) {
1308 #if RESOLV_SUPPORTS_RECORD_EXPIRATION 1321 #if RESOLV_SUPPORTS_RECORD_EXPIRATION 1330 *ipaddr = &nameptr->ipaddr;
1338 #if LOG_LEVEL == LOG_LEVEL_DBG 1342 LOG_DBG(
"Found \"%s\" in cache. => ", name);
1344 LOG_DBG_6ADDR(addr);
1349 LOG_DBG(
"\"%s\" is NOT cached.\n", name);
1362 resolv_found(
char *name, uip_ipaddr_t *
ipaddr)
1364 #if RESOLV_CONF_SUPPORTS_MDNS 1365 if(strncasecmp(resolv_hostname, name, strlen(resolv_hostname)) == 0 &&
1367 && !uip_ds6_is_my_addr(ipaddr)
1371 if(mdns_state == MDNS_STATE_PROBING) {
1375 LOG_DBG(
"Name collision detected for \"%s\".\n", name);
1378 resolv_hostname[strlen(resolv_hostname) - 6] = 0;
1381 for(i = 0; i < 3; ++i) {
1384 char append_str[4] =
"-XX";
1386 append_str[2] = (((val & 0xF) > 9) ?
'a' :
'0') + (val & 0xF);
1388 append_str[1] = (((val & 0xF) > 9) ?
'a' :
'0') + (val & 0xF);
1389 strncat(resolv_hostname, append_str,
1390 sizeof(resolv_hostname) - strlen(resolv_hostname) - 1);
1394 strncat(resolv_hostname,
".local", RESOLV_CONF_MAX_DOMAIN_NAME_SIZE - strlen(resolv_hostname));
1397 }
else if(mdns_state == MDNS_STATE_READY) {
1402 LOG_DBG(
"Possible name collision, probing...\n");
1403 start_name_collision_check(0);
1409 LOG_DBG(
"Found address for \"%s\" => ", name);
1410 LOG_DBG_6ADDR(ipaddr);
1413 LOG_DBG(
"Unable to retrieve address for \"%s\".\n", name);
process_event_t resolv_event_found
Event that is broadcasted when a DNS name has been resolved.
static uip_ipaddr_t ipaddr
Pointer to prefix information option in uip_buf.
#define UIP_IP_BUF
Direct access to IPv6 header.
uip_lladdr_t uip_lladdr
Host L2 address.
Header for the Contiki/uIP interface.
#define PROCESS(name, strname)
Declare a process.
void tcpip_poll_udp(struct uip_udp_conn *conn)
Cause a specified UDP connection to be polled.
#define PROCESS_WAIT_EVENT()
Wait for an event to be posted to the process.
static uip_ds6_addr_t * addr
Pointer to a nbr cache entry.
uIP DNS resolver code header file.
#define PROCESS_BEGIN()
Define the beginning of a process.
#define PROCESS_END()
Define the end of a process.
process_event_t tcpip_event
The uIP event.
#define PROCESS_WAIT_EVENT_UNTIL(c)
Wait for an event to be posted to the process, with an extra condition.
Hostname was not found in the cache.
static void newdata(void)
unsigned long clock_seconds(void)
Get the current value of the platform seconds.
Header file for module for sending UDP packets through uIP.
#define RESOLV_CONF_MAX_RETRIES
The maximum number of retries when asking for a name.
uint16_t uip_htons(uint16_t val)
Convert a 16-bit quantity from host byte order to network byte order.
Header file for IPv6-related data structures.
void process_exit(struct process *p)
Cause a process to exit.
#define UIP_LLADDR_LEN
802.15.4 address
void resolv_set_hostname(const char *hostname)
Changes the local hostname advertised by MDNS.
#define CLOCK_SECOND
A second, measured in system clock time.
resolv_status_t resolv_lookup(const char *name, uip_ipaddr_t **ipaddr)
Look up a hostname in the array of known hostnames.
#define uip_newdata()
Is new incoming data available?
struct uip_udp_conn * udp_new(const uip_ipaddr_t *ripaddr, uint16_t port, void *appstate)
Create a new UDP connection.
uIP Name Server interface
Hostname is fresh and usable.
#define uip_ipaddr_copy(dest, src)
Copy an IP address from one place to another.
This hostname is in the process of being resolved.
process_event_t process_alloc_event(void)
Allocate a global event number.
Hostname was found, but it's status has expired.
#define UIP_HTONS(n)
Convert 16-bit quantity from host byte order to network byte order.
uip_ds6_netif_t uip_ds6_if
The single interface.
int process_post(struct process *p, process_event_t ev, process_data_t data)
Post an asynchronous event.
const char * resolv_get_hostname(void)
Returns the local hostname being advertised via MDNS.
#define uip_udp_bind(conn, port)
Bind a UDP connection to a local port.
#define uip_poll()
Is the connection being polled by uIP?
PROCESS_THREAD(cc2538_rf_process, ev, data)
Implementation of the cc2538 RF driver process.
unsigned short random_rand(void)
Generates a new random number using the cc2538 RNG.
#define uip_is_addr_linklocal(a)
is addr (a) a link local unicast address, see RFC 4291 i.e.
The server has returned a not-found response for this domain name.
Header file for the logging system
void resolv_query(const char *name)
Queues a name so that a question for the name will be sent out.
uip_ipaddr_t * uip_nameserver_get(uint8_t num)
Get a Nameserver ip address given in RA.
void etimer_set(struct etimer *et, clock_time_t interval)
Set an event timer.
void * uip_appdata
Pointer to the application data in the packet buffer.
void process_start(struct process *p, process_data_t data)
Start a process.
Representation of a uIP UDP connection.