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)