68 #include "lib/random.h" 71 #define DEBUG CONTIKI_TARGET_COOJA 81 #define NULL (void *)0 84 #if !defined(__SDCC) && defined(SDCC_REVISION) 89 #define DEBUG_PRINTF(...) printf(__VA_ARGS__) 91 #define DEBUG_PRINTF(...) do { } while(0) 94 #if DEBUG || VERBOSE_DEBUG 95 #define PRINTF(...) printf(__VA_ARGS__) 97 #define PRINTF(...) do { } while(0) 102 strncasecmp(
const char *s1,
const char *s2,
size_t n)
105 return strncmp(s1, s2, n);
108 strcasecmp(
const char *s1,
const char *s2)
111 return strcmp(s1, s2);
115 #define UIP_UDP_BUF ((struct uip_udpip_hdr *)&uip_buf[UIP_LLH_LEN]) 121 #ifndef RESOLV_CONF_SUPPORTS_MDNS 122 #define RESOLV_CONF_SUPPORTS_MDNS 1 125 #ifndef RESOLV_CONF_MDNS_INCLUDE_GLOBAL_V6_ADDRS 126 #define RESOLV_CONF_MDNS_INCLUDE_GLOBAL_V6_ADDRS 0 130 #ifndef RESOLV_CONF_MAX_RETRIES 131 #define RESOLV_CONF_MAX_RETRIES 4 134 #ifndef RESOLV_CONF_MAX_MDNS_RETRIES 135 #define RESOLV_CONF_MAX_MDNS_RETRIES 3 138 #ifndef RESOLV_CONF_MAX_DOMAIN_NAME_SIZE 139 #define RESOLV_CONF_MAX_DOMAIN_NAME_SIZE 32 142 #ifdef RESOLV_CONF_AUTO_REMOVE_TRAILING_DOTS 143 #define RESOLV_AUTO_REMOVE_TRAILING_DOTS RESOLV_CONF_AUTO_REMOVE_TRAILING_DOTS 145 #define RESOLV_AUTO_REMOVE_TRAILING_DOTS RESOLV_CONF_SUPPORTS_MDNS 148 #ifdef RESOLV_CONF_VERIFY_ANSWER_NAMES 149 #define RESOLV_VERIFY_ANSWER_NAMES RESOLV_CONF_VERIFY_ANSWER_NAMES 151 #define RESOLV_VERIFY_ANSWER_NAMES RESOLV_CONF_SUPPORTS_MDNS 154 #ifdef RESOLV_CONF_SUPPORTS_RECORD_EXPIRATION 155 #define RESOLV_SUPPORTS_RECORD_EXPIRATION RESOLV_CONF_SUPPORTS_RECORD_EXPIRATION 157 #define RESOLV_SUPPORTS_RECORD_EXPIRATION 1 160 #if RESOLV_CONF_SUPPORTS_MDNS && !RESOLV_VERIFY_ANSWER_NAMES 161 #error RESOLV_CONF_SUPPORTS_MDNS cannot be set without RESOLV_CONF_VERIFY_ANSWER_NAMES 164 #if !defined(CONTIKI_TARGET_NAME) && defined(BOARD) 165 #define stringy2(x) #x 166 #define stringy(x) stringy2(x) 167 #define CONTIKI_TARGET_NAME stringy(BOARD) 170 #ifndef CONTIKI_CONF_DEFAULT_HOSTNAME 171 #ifdef CONTIKI_TARGET_NAME 172 #define CONTIKI_CONF_DEFAULT_HOSTNAME "contiki-"CONTIKI_TARGET_NAME 174 #define CONTIKI_CONF_DEFAULT_HOSTNAME "contiki" 179 #define DNS_TYPE_CNAME 5 180 #define DNS_TYPE_PTR 12 181 #define DNS_TYPE_MX 15 182 #define DNS_TYPE_TXT 16 183 #define DNS_TYPE_AAAA 28 184 #define DNS_TYPE_SRV 33 185 #define DNS_TYPE_ANY 255 186 #define DNS_TYPE_NSEC 47 189 #define NATIVE_DNS_TYPE DNS_TYPE_AAAA 191 #define NATIVE_DNS_TYPE DNS_TYPE_A 194 #define DNS_CLASS_IN 1 195 #define DNS_CLASS_ANY 255 202 #define MDNS_PORT 5353 206 #define LLMNR_PORT 5355 209 #ifndef MDNS_RESPONDER_PORT 210 #define MDNS_RESPONDER_PORT 5354 216 uint8_t flags1, flags2;
217 #define DNS_FLAG1_RESPONSE 0x80 218 #define DNS_FLAG1_OPCODE_STATUS 0x10 219 #define DNS_FLAG1_OPCODE_INVERSE 0x08 220 #define DNS_FLAG1_OPCODE_STANDARD 0x00 221 #define DNS_FLAG1_AUTHORATIVE 0x04 222 #define DNS_FLAG1_TRUNC 0x02 223 #define DNS_FLAG1_RD 0x01 224 #define DNS_FLAG2_RA 0x80 225 #define DNS_FLAG2_ERR_MASK 0x0f 226 #define DNS_FLAG2_ERR_NONE 0x00 227 #define DNS_FLAG2_ERR_NAME 0x03 228 uint16_t numquestions;
234 #define RESOLV_ENCODE_INDEX(i) (uip_htons(i+1)) 235 #define RESOLV_DECODE_INDEX(i) (unsigned char)(uip_ntohs(i-1)) 242 { { 0x20, 0x01, 0x48, 0x60, 0x48, 0x60, 0x00, 0x00,
243 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x88, 0x88 } };
264 #define STATE_UNUSED 0 265 #define STATE_ERROR 1 267 #define STATE_ASKING 3 273 #if RESOLV_SUPPORTS_RECORD_EXPIRATION 274 unsigned long expiration;
278 #if RESOLV_CONF_SUPPORTS_MDNS 279 int is_mdns:1, is_probe:1;
281 char name[RESOLV_CONF_MAX_DOMAIN_NAME_SIZE + 1];
284 #ifndef UIP_CONF_RESOLV_ENTRIES 285 #define RESOLV_ENTRIES 4 287 #define RESOLV_ENTRIES UIP_CONF_RESOLV_ENTRIES 290 static struct namemap names[RESOLV_ENTRIES];
292 static uint8_t seqno;
298 static struct etimer retry;
302 PROCESS(resolv_process,
"DNS resolver");
304 static void resolv_found(
char *name,
uip_ipaddr_t * ipaddr);
307 struct dns_question {
312 #if RESOLV_CONF_SUPPORTS_MDNS 313 static char resolv_hostname[RESOLV_CONF_MAX_DOMAIN_NAME_SIZE + 1];
316 MDNS_STATE_WAIT_BEFORE_PROBE,
321 static uint8_t mdns_state;
325 { { 0xff, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
326 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xfb } };
327 #include "net/uip-ds6.h" 329 { { 224, 0, 0, 251 } };
331 static int mdns_needs_host_announce;
333 PROCESS(mdns_probe_process,
"mDNS probe");
337 #if RESOLV_VERIFY_ANSWER_NAMES || VERBOSE_DEBUG 346 decode_name(
const unsigned char *query,
char *dest,
347 const unsigned char *packet)
349 int len = RESOLV_CONF_MAX_DOMAIN_NAME_SIZE;
351 unsigned char n = *query++;
357 const uint16_t offset = query[0] + ((n & ~0xC0) << 8);
360 query = packet + offset;
395 dns_name_isequal(
const unsigned char *queryptr,
const char *name,
396 const unsigned char *packet)
398 unsigned char n = *queryptr++;
405 queryptr = packet + queryptr[0] + ((n & ~0xC0) << 8);
414 if(tolower((uint8_t) *name++) != tolower((uint8_t) *queryptr++)) {
421 if((n != 0) && (*name++ !=
'.')) {
429 if (
uip_udp_conn == llmnr_conn && strcmp(name,
"local") == 0)
437 static unsigned char *
438 skip_name(
unsigned char *query)
442 DEBUG_PRINTF(
"resolver: skip name: ");
447 DEBUG_PRINTF(
"<skip-to-%d>", query[0] + ((n & ~0xC0) << 8));
455 DEBUG_PRINTF(
"%c", *query);
460 }
while(*query != 0);
467 static unsigned char *
468 encode_name(
unsigned char *query,
const char *nameptr)
471 const char *endptr = &nameptr[strlen(nameptr)];
473 if (nameptr + 6 <= endptr && memcmp(endptr - 6,
".local", 6) == 0)
483 nptr = (
char *)query;
485 for(n = 0; *nameptr !=
'.' && *nameptr != 0; ++nameptr) {
491 }
while(nameptr != endptr);
499 #if RESOLV_CONF_SUPPORTS_MDNS 503 mdns_announce_requested(
void)
505 mdns_needs_host_announce = 1;
511 start_name_collision_check(clock_time_t after)
519 static unsigned char *
520 mdns_write_announce_records(
unsigned char *queryptr, uint8_t *count)
522 struct dns_answer *ans;
527 for(i = 0; i < UIP_DS6_ADDR_NB; ++i) {
528 if(uip_ds6_if.addr_list[i].isused
529 #
if !RESOLV_CONF_MDNS_INCLUDE_GLOBAL_V6_ADDRS
530 && uip_is_addr_link_local(&uip_ds6_if.addr_list[i].ipaddr)
534 queryptr = encode_name(queryptr, resolv_hostname);
538 *queryptr++ =
sizeof(
struct dns_hdr);
540 ans = (
struct dns_answer *)queryptr;
542 *queryptr++ = (uint8_t) ((NATIVE_DNS_TYPE) >> 8);
543 *queryptr++ = (uint8_t) ((NATIVE_DNS_TYPE));
545 *queryptr++ = (uint8_t) ((DNS_CLASS_IN | 0x8000) >> 8);
546 *queryptr++ = (uint8_t) ((DNS_CLASS_IN | 0x8000));
562 queryptr = encode_name(queryptr, resolv_hostname);
563 ans = (
struct dns_answer *)queryptr;
572 queryptr = (
unsigned char *)ans +
sizeof(*ans);
582 mdns_prep_host_announce_packet(
void)
584 static const struct {
599 sizeof(
struct dns_hdr),
617 unsigned char *queryptr;
619 uint8_t total_answers = 0;
625 struct dns_hdr *hdr = (
struct dns_hdr *)
uip_appdata;
629 memset((
void *)hdr, 0,
sizeof(*hdr));
631 queryptr = (
unsigned char *)
uip_appdata +
sizeof(*hdr);
636 hdr->flags1 |= DNS_FLAG1_RESPONSE;
638 hdr->flags1 |= DNS_FLAG1_AUTHORATIVE;
640 queryptr = mdns_write_announce_records(queryptr, &total_answers);
646 queryptr = encode_name(queryptr, resolv_hostname);
650 *queryptr++ =
sizeof(*hdr);
654 memcpy((
void *)queryptr, (
void *)&nsec_record,
sizeof(nsec_record));
655 queryptr +=
sizeof(nsec_record);
656 ((uint8_t*)&hdr->numextrarr)[1] = 1;
661 ((uint8_t*)&hdr->numanswers)[1] = total_answers;
678 register struct dns_hdr *hdr;
680 register struct namemap *namemapptr;
682 for(i = 0; i < RESOLV_ENTRIES; ++i) {
683 namemapptr = &names[i];
684 if(namemapptr->state == STATE_NEW || namemapptr->state == STATE_ASKING) {
686 if(namemapptr->state == STATE_ASKING) {
687 if(--namemapptr->tmr == 0) {
688 #if RESOLV_CONF_SUPPORTS_MDNS 689 if(++namemapptr->retries ==
690 (namemapptr->is_mdns ? RESOLV_CONF_MAX_MDNS_RETRIES :
691 RESOLV_CONF_MAX_RETRIES))
693 if(++namemapptr->retries == RESOLV_CONF_MAX_RETRIES)
697 namemapptr->state = STATE_ERROR;
699 #if RESOLV_SUPPORTS_RECORD_EXPIRATION 704 resolv_found(namemapptr->name, NULL);
707 namemapptr->tmr = namemapptr->retries * namemapptr->retries * 3;
709 #if RESOLV_CONF_SUPPORTS_MDNS 710 if(namemapptr->is_probe) {
722 namemapptr->state = STATE_ASKING;
724 namemapptr->retries = 0;
727 memset(hdr, 0,
sizeof(
struct dns_hdr));
728 hdr->id = RESOLV_ENCODE_INDEX(i);
729 #if RESOLV_CONF_SUPPORTS_MDNS 730 if(!namemapptr->is_mdns || namemapptr->is_probe) {
731 hdr->flags1 = DNS_FLAG1_RD;
733 if(namemapptr->is_mdns) {
737 hdr->flags1 = DNS_FLAG1_RD;
740 query = (
unsigned char *)
uip_appdata +
sizeof(*hdr);
741 query = encode_name(query, namemapptr->name);
742 #if RESOLV_CONF_SUPPORTS_MDNS 743 if(namemapptr->is_probe) {
744 *query++ = (uint8_t) ((DNS_TYPE_ANY) >> 8);
745 *query++ = (uint8_t) ((DNS_TYPE_ANY));
749 *query++ = (uint8_t) ((NATIVE_DNS_TYPE) >> 8);
750 *query++ = (uint8_t) ((NATIVE_DNS_TYPE));
752 *query++ = (uint8_t) ((DNS_CLASS_IN) >> 8);
753 *query++ = (uint8_t) ((DNS_CLASS_IN));
754 #if RESOLV_CONF_SUPPORTS_MDNS 755 if(namemapptr->is_mdns) {
756 if(namemapptr->is_probe) {
764 query = mdns_write_announce_records(query, &count);
769 &resolv_mdns_addr,
UIP_HTONS(MDNS_PORT));
771 PRINTF(
"resolver: (i=%d) Sent MDNS %s for \"%s\".\n", i,
772 namemapptr->is_probe?
"probe":
"request",namemapptr->name);
776 &resolv_default_dns_server,
UIP_HTONS(DNS_PORT));
778 PRINTF(
"resolver: (i=%d) Sent DNS request for \"%s\".\n", i,
784 &resolv_default_dns_server,
UIP_HTONS(DNS_PORT));
785 PRINTF(
"resolver: (i=%d) Sent DNS request for \"%s\".\n", i,
799 static uint8_t nquestions, nanswers, nauthrr;
803 register struct namemap *namemapptr;
805 struct dns_answer *ans;
807 register struct dns_hdr const *hdr = (
struct dns_hdr *)
uip_appdata;
809 unsigned char *queryptr = (
unsigned char *)hdr +
sizeof(*hdr);
811 const uint8_t is_request = ((hdr->flags1 & ~1) == 0) && (hdr->flags2 == 0);
816 nquestions = (uint8_t) uip_ntohs(hdr->numquestions);
817 nanswers = (uint8_t) uip_ntohs(hdr->numanswers);
819 queryptr = (
unsigned char *)hdr +
sizeof(*hdr);
823 (
"resolver: flags1=0x%02X flags2=0x%02X nquestions=%d, nanswers=%d, nauthrr=%d, nextrarr=%d\n",
824 hdr->flags1, hdr->flags2, (uint8_t) nquestions, (uint8_t) nanswers,
825 (uint8_t) uip_ntohs(hdr->numauthrr),
826 (uint8_t) uip_ntohs(hdr->numextrarr));
828 if(is_request && (nquestions == 0)) {
830 DEBUG_PRINTF(
"resolver: Skipping request with no questions.\n");
836 for(; nquestions > 0;
837 queryptr = skip_name(queryptr) +
sizeof(
struct dns_question),
840 #if RESOLV_CONF_SUPPORTS_MDNS 850 struct dns_question *question = (
struct dns_question *)skip_name(queryptr);
852 #if !ARCH_DOESNT_NEED_ALIGNED_STRUCTS 853 static struct dns_question aligned;
854 memcpy(&aligned, question,
sizeof(aligned));
858 DEBUG_PRINTF(
"resolver: Question %d: type=%d class=%d\n", ++i,
861 if(((uip_ntohs(question->class) & 0x7FFF) != DNS_CLASS_IN) ||
862 ((question->type !=
UIP_HTONS(DNS_TYPE_ANY)) &&
863 (question->type !=
UIP_HTONS(NATIVE_DNS_TYPE)))) {
868 if(!dns_name_isequal(queryptr, resolv_hostname,
uip_appdata)) {
872 PRINTF(
"resolver: THIS IS A REQUEST FOR US!!!\n");
874 if(mdns_state == MDNS_STATE_READY) {
878 if(UIP_UDP_BUF->srcport ==
UIP_HTONS(MDNS_PORT)) {
879 mdns_announce_requested();
882 mdns_prep_host_announce_packet(),
883 &UIP_UDP_BUF->srcipaddr,
884 UIP_UDP_BUF->srcport);
888 PRINTF(
"resolver: But we are still probing. Waiting...\n");
893 nauthrr = (uint8_t)uip_ntohs(hdr->numauthrr);
915 #if RESOLV_CONF_SUPPORTS_MDNS 928 i = RESOLV_DECODE_INDEX(hdr->id);
930 namemapptr = &names[i];
932 if(i >= RESOLV_ENTRIES || i < 0 || namemapptr->state != STATE_ASKING) {
933 PRINTF(
"resolver: DNS response has bad ID (%04X) \n", uip_ntohs(hdr->id));
937 PRINTF(
"resolver: Incoming response for \"%s\".\n", namemapptr->name);
940 namemapptr->state = STATE_ERROR;
942 namemapptr->err = hdr->flags2 & DNS_FLAG2_ERR_MASK;
944 #if RESOLV_SUPPORTS_RECORD_EXPIRATION 950 if(namemapptr->err != 0) {
951 namemapptr->state = STATE_ERROR;
952 resolv_found(namemapptr->name, NULL);
960 while(nanswers > 0) {
961 ans = (
struct dns_answer *)skip_name(queryptr);
963 #if !ARCH_DOESNT_NEED_ALIGNED_STRUCTS 965 static struct dns_answer aligned;
966 memcpy(&aligned, ans,
sizeof(aligned));
972 static char debug_name[40];
974 DEBUG_PRINTF(
"resolver: Answer %d: \"%s\", type %d, class %d, ttl %d, length %d\n",
975 ++i, debug_name, uip_ntohs(ans->type),
976 uip_ntohs(ans->class) & 0x7FFF,
977 (
int)((uint32_t) uip_ntohs(ans->ttl[0]) << 16) | (uint32_t)
978 uip_ntohs(ans->ttl[1]), uip_ntohs(ans->len));
984 if(((uip_ntohs(ans->class) & 0x7FFF) != DNS_CLASS_IN) ||
986 goto skip_to_next_answer;
989 if(ans->type !=
UIP_HTONS(NATIVE_DNS_TYPE)) {
990 goto skip_to_next_answer;
993 #if RESOLV_CONF_SUPPORTS_MDNS 996 int8_t available_i = RESOLV_ENTRIES;
998 DEBUG_PRINTF(
"resolver: MDNS query.\n");
1003 for(i = 0; i < RESOLV_ENTRIES; ++i) {
1004 namemapptr = &names[i];
1005 if(dns_name_isequal(queryptr, namemapptr->name,
uip_appdata)) {
1008 if((namemapptr->state == STATE_UNUSED)
1009 #
if RESOLV_SUPPORTS_RECORD_EXPIRATION
1010 || (namemapptr->state == STATE_DONE &&
clock_seconds() > namemapptr->expiration)
1016 if(i == RESOLV_ENTRIES) {
1017 DEBUG_PRINTF(
"resolver: Unsolicited MDNS response.\n");
1019 namemapptr = &names[i];
1020 if(!decode_name(queryptr, namemapptr->name,
uip_appdata)) {
1021 DEBUG_PRINTF(
"resolver: MDNS name too big to cache.\n");
1023 goto skip_to_next_answer;
1026 if(i == RESOLV_ENTRIES) {
1028 (
"resolver: Not enough room to keep track of unsolicited MDNS answer.\n");
1030 if(dns_name_isequal(queryptr, resolv_hostname,
uip_appdata)) {
1032 resolv_found(resolv_hostname, (
uip_ipaddr_t *) ans->ipaddr);
1035 goto skip_to_next_answer;
1037 namemapptr = &names[i];
1055 DEBUG_PRINTF(
"resolver: Answer for \"%s\" is usable.\n", namemapptr->name);
1057 namemapptr->state = STATE_DONE;
1058 #if RESOLV_SUPPORTS_RECORD_EXPIRATION 1059 namemapptr->expiration = ans->ttl[1] + (ans->ttl[0] << 8);
1065 resolv_found(namemapptr->name, &namemapptr->ipaddr);
1067 skip_to_next_answer:
1068 queryptr = (
unsigned char *)skip_name(queryptr) + 10 +
uip_htons(ans->len);
1073 #if RESOLV_CONF_SUPPORTS_MDNS 1079 resolv_set_hostname(
const char *hostname)
1081 strncpy(resolv_hostname, hostname, RESOLV_CONF_MAX_DOMAIN_NAME_SIZE);
1084 if(strlen(resolv_hostname) < 7 ||
1085 strcasecmp(resolv_hostname + strlen(resolv_hostname) - 6,
".local") != 0) {
1086 strncat(resolv_hostname,
".local", RESOLV_CONF_MAX_DOMAIN_NAME_SIZE);
1089 PRINTF(
"resolver: hostname changed to \"%s\"\n", resolv_hostname);
1091 start_name_collision_check(0);
1099 resolv_get_hostname(
void)
1101 return resolv_hostname;
1109 static struct etimer delay;
1112 mdns_state = MDNS_STATE_WAIT_BEFORE_PROBE;
1114 PRINTF(
"mdns-probe: Process (re)started.\n");
1118 PRINTF(
"mdns-probe: Probing will begin in %ld clocks.\n",
1119 (
long)*(clock_time_t *)
data);
1130 mdns_state = MDNS_STATE_PROBING;
1131 resolv_query(resolv_hostname);
1135 }
while(strcasecmp(resolv_hostname,
data) != 0);
1137 mdns_state = MDNS_STATE_READY;
1138 mdns_announce_requested();
1140 PRINTF(
"mdns-probe: Finished probing.\n");
1143 #ifdef ECLIPSE_STUB_CODE_ANALYSE 1156 memset(names, 0,
sizeof(names));
1160 PRINTF(
"resolver: Process started.\n");
1162 resolv_conn =
udp_new(NULL, 0, NULL);
1164 #if RESOLV_CONF_SUPPORTS_MDNS 1165 PRINTF(
"resolver: Supports MDNS.\n");
1169 uip_ds6_maddr_add(&resolv_mdns_addr);
1174 llmnr_conn =
udp_new(NULL, 0, NULL);
1177 resolv_set_hostname(CONTIKI_CONF_DEFAULT_HOSTNAME);
1183 if(ev == PROCESS_EVENT_TIMER) {
1191 #if RESOLV_CONF_SUPPORTS_MDNS 1192 if(mdns_needs_host_announce) {
1195 PRINTF(
"resolver: Announcing that we are \"%s\".\n",
1200 len = mdns_prep_host_announce_packet();
1203 len, &resolv_mdns_addr,
UIP_HTONS(MDNS_PORT));
1205 mdns_needs_host_announce = 0;
1220 #if RESOLV_CONF_SUPPORTS_MDNS 1221 if(mdns_needs_host_announce) {
1228 #ifdef ECLIPSE_STUB_CODE_ANALYSE 1233 #if RESOLV_AUTO_REMOVE_TRAILING_DOTS 1235 remove_trailing_dots(
const char *name) {
1236 static char dns_name_without_dots[RESOLV_CONF_MAX_DOMAIN_NAME_SIZE + 1];
1237 size_t len = strlen(name);
1239 if(name[len - 1] ==
'.') {
1240 strncpy(dns_name_without_dots, name,
sizeof(dns_name_without_dots));
1241 while(len && (dns_name_without_dots[len - 1] ==
'.')) {
1242 dns_name_without_dots[--len] = 0;
1244 name = dns_name_without_dots;
1249 #define remove_trailing_dots(x) (x) 1258 resolv_query(
const char *name)
1262 static uint8_t lseq, lseqi;
1264 register struct namemap *nameptr = 0;
1269 name = remove_trailing_dots(name);
1271 for(i = 0; i < RESOLV_ENTRIES; ++i) {
1272 nameptr = &names[i];
1273 if(0 == strcasecmp(nameptr->name, name)) {
1276 if((nameptr->state == STATE_UNUSED)
1277 #
if RESOLV_SUPPORTS_RECORD_EXPIRATION
1278 || (nameptr->state == STATE_DONE &&
clock_seconds() > nameptr->expiration)
1283 }
else if(seqno - nameptr->seqno > lseq) {
1284 lseq = seqno - nameptr->seqno;
1289 if(i == RESOLV_ENTRIES) {
1291 nameptr = &names[i];
1294 PRINTF(
"resolver: Starting query for \"%s\".\n", name);
1296 memset(nameptr, 0,
sizeof(*nameptr));
1298 strncpy(nameptr->name, name,
sizeof(nameptr->name));
1299 nameptr->state = STATE_NEW;
1300 nameptr->seqno = seqno;
1303 #if RESOLV_CONF_SUPPORTS_MDNS 1305 size_t name_len = strlen(name);
1307 static const char local_suffix[] =
"local";
1309 if((name_len > (
sizeof(local_suffix) - 1)) &&
1310 (0 == strcasecmp(name + name_len - (
sizeof(local_suffix) - 1), local_suffix))) {
1311 PRINTF(
"resolver: Using MDNS to look up \"%s\".\n", name);
1312 nameptr->is_mdns = 1;
1314 nameptr->is_mdns = 0;
1317 nameptr->is_probe = (mdns_state == MDNS_STATE_PROBING) &&
1318 (0 == strcmp(nameptr->name, resolv_hostname));
1335 resolv_lookup(
const char *name,
uip_ipaddr_t ** ipaddr)
1341 struct namemap *nameptr;
1344 name = remove_trailing_dots(name);
1346 #if UIP_CONF_LOOPBACK_INTERFACE 1347 if(strcmp(name,
"localhost")) {
1350 { { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1351 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01 } };
1353 { { 127, 0, 0, 1 } };
1356 *ipaddr = &loopback;
1363 for(i = 0; i < RESOLV_ENTRIES; ++i) {
1364 nameptr = &names[i];
1366 if(strcasecmp(name, nameptr->name) == 0) {
1367 switch (nameptr->state) {
1370 #if RESOLV_SUPPORTS_RECORD_EXPIRATION 1383 #if RESOLV_SUPPORTS_RECORD_EXPIRATION 1392 *ipaddr = &nameptr->ipaddr;
1403 PRINTF(
"resolver: Found \"%s\" in cache.\n", name);
1407 (
"resolver: %02x%02x:%02x%02x:%02x%02x:%02x%02x:%02x%02x:%02x%02x:%02x%02x:%02x%02x \n",
1408 ((uint8_t *) addr)[0], ((uint8_t *) addr)[1], ((uint8_t *) addr)[2],
1409 ((uint8_t *) addr)[3], ((uint8_t *) addr)[4], ((uint8_t *) addr)[5],
1410 ((uint8_t *) addr)[6], ((uint8_t *) addr)[7], ((uint8_t *) addr)[8],
1411 ((uint8_t *) addr)[9], ((uint8_t *) addr)[10],
1412 ((uint8_t *) addr)[11], ((uint8_t *) addr)[12],
1413 ((uint8_t *) addr)[13], ((uint8_t *) addr)[14],
1414 ((uint8_t *) addr)[15]);
1418 DEBUG_PRINTF(
"resolver: \"%s\" is NOT cached.\n", name);
1434 resolv_getserver(
void)
1436 return &resolv_default_dns_server;
1458 #if RESOLV_CONF_SUPPORTS_MDNS 1459 if(strncasecmp(resolv_hostname, name, strlen(resolv_hostname)) == 0 &&
1462 && !uip_ds6_is_my_addr(ipaddr)
1464 && uip_ipaddr_cmp(&uip_hostaddr, ipaddr) != 0
1469 if(mdns_state == MDNS_STATE_PROBING) {
1473 PRINTF(
"resolver: Name collision detected for \"%s\".\n", name);
1476 resolv_hostname[strlen(resolv_hostname) - 6] = 0;
1479 for(i = 0; i < 3; ++i) {
1480 uint8_t val = uip_lladdr.addr[(UIP_LLADDR_LEN - 3) + i];
1482 char append_str[4] =
"-XX";
1484 append_str[2] = (((val & 0xF) > 9) ?
'a' :
'0') + (val & 0xF);
1486 append_str[1] = (((val & 0xF) > 9) ?
'a' :
'0') + (val & 0xF);
1487 strncat(resolv_hostname, append_str,
1488 sizeof(resolv_hostname) - strlen(resolv_hostname));
1492 strncat(resolv_hostname,
".local", RESOLV_CONF_MAX_DOMAIN_NAME_SIZE);
1495 }
else if(mdns_state == MDNS_STATE_READY) {
1500 PRINTF(
"resolver: Possible name collision, probing...\n");
1501 start_name_collision_check(0);
1510 PRINTF(
"resolver: Found address for \"%s\".\n", name);
1512 (
"resolver: %02x%02x:%02x%02x:%02x%02x:%02x%02x:%02x%02x:%02x%02x:%02x%02x:%02x%02x \n",
1513 ((uint8_t *) ipaddr)[0], ((uint8_t *) ipaddr)[1],
1514 ((uint8_t *) ipaddr)[2], ((uint8_t *) ipaddr)[3],
1515 ((uint8_t *) ipaddr)[4], ((uint8_t *) ipaddr)[5],
1516 ((uint8_t *) ipaddr)[6], ((uint8_t *) ipaddr)[7],
1517 ((uint8_t *) ipaddr)[8], ((uint8_t *) ipaddr)[9],
1518 ((uint8_t *) ipaddr)[10], ((uint8_t *) ipaddr)[11],
1519 ((uint8_t *) ipaddr)[12], ((uint8_t *) ipaddr)[13],
1520 ((uint8_t *) ipaddr)[14], ((uint8_t *) ipaddr)[15]);
1522 PRINTF(
"resolver: Found address for \"%s\": %d.%d.%d.%d\n", name,
1523 ipaddr->u8[0], ipaddr->u8[1], ipaddr->u8[2], ipaddr->u8[3]);
1524 #endif // UIP_CONF_IPV6 1526 PRINTF(
"resolver: Unable to retrieve address for \"%s\".\n", name);
#define PROCESS(name, strname)
void process_start(struct process *p, const char *arg)
#define uip_gethostaddr(addr)
#define PROCESS_WAIT_EVENT_UNTIL(c)
void process_exit(struct process *p)
Cause a process to exit.
#define PROCESS_WAIT_EVENT()
process_event_t process_alloc_event(void)
Allocate a global event number.
process_event_t tcpip_event
int process_post(struct process *p, process_event_t ev, process_data_t data)
#define uip_ipaddr_copy(dest, src)
CCIF struct uip_udp_conn * udp_new(const uip_ipaddr_t *ripaddr, uint16_t port, void *appstate)
uint8_t data[USBNET_RX_BUF_SIZE]
void etimer_set(struct etimer *et, clock_time_t interval)
Set an event timer.
#define PROCESS_THREAD(name, ev, data)
#define uip_udp_bind(conn, port)
CCIF process_event_t resolv_event_found
CCIF unsigned long clock_seconds(void)
uint16_t uip_htons(uint16_t val)
CCIF void tcpip_poll_udp(struct uip_udp_conn *conn)