⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 dns.c

📁 lwip-1.4.0
💻 C
📖 第 1 页 / 共 3 页
字号:
    LWIP_ASSERT("namelen <= DNS_LOCAL_HOSTLIST_MAX_NAMELEN", namelen <= DNS_LOCAL_HOSTLIST_MAX_NAMELEN);    entry = (struct local_hostlist_entry *)memp_malloc(MEMP_LOCALHOSTLIST);    LWIP_ASSERT("mem-error in dns_init_local", entry != NULL);    if (entry != NULL) {      entry->name = (char*)entry + sizeof(struct local_hostlist_entry);      MEMCPY((char*)entry->name, init_entry->name, namelen);      ((char*)entry->name)[namelen] = 0;      entry->addr = init_entry->addr;      entry->next = local_hostlist_dynamic;      local_hostlist_dynamic = entry;    }  }#endif /* DNS_LOCAL_HOSTLIST_IS_DYNAMIC && defined(DNS_LOCAL_HOSTLIST_INIT) */}/** * Scans the local host-list for a hostname. * * @param hostname Hostname to look for in the local host-list * @return The first IP address for the hostname in the local host-list or *         IPADDR_NONE if not found. */static u32_tdns_lookup_local(const char *hostname){#if DNS_LOCAL_HOSTLIST_IS_DYNAMIC  struct local_hostlist_entry *entry = local_hostlist_dynamic;  while(entry != NULL) {    if(strcmp(entry->name, hostname) == 0) {      return ip4_addr_get_u32(&entry->addr);    }    entry = entry->next;  }#else /* DNS_LOCAL_HOSTLIST_IS_DYNAMIC */  int i;  for (i = 0; i < sizeof(local_hostlist_static) / sizeof(struct local_hostlist_entry); i++) {    if(strcmp(local_hostlist_static[i].name, hostname) == 0) {      return ip4_addr_get_u32(&local_hostlist_static[i].addr);    }  }#endif /* DNS_LOCAL_HOSTLIST_IS_DYNAMIC */  return IPADDR_NONE;}#if DNS_LOCAL_HOSTLIST_IS_DYNAMIC/** Remove all entries from the local host-list for a specific hostname * and/or IP addess * * @param hostname hostname for which entries shall be removed from the local *                 host-list * @param addr address for which entries shall be removed from the local host-list * @return the number of removed entries */intdns_local_removehost(const char *hostname, const ip_addr_t *addr){  int removed = 0;  struct local_hostlist_entry *entry = local_hostlist_dynamic;  struct local_hostlist_entry *last_entry = NULL;  while (entry != NULL) {    if (((hostname == NULL) || !strcmp(entry->name, hostname)) &&        ((addr == NULL) || ip_addr_cmp(&entry->addr, addr))) {      struct local_hostlist_entry *free_entry;      if (last_entry != NULL) {        last_entry->next = entry->next;      } else {        local_hostlist_dynamic = entry->next;      }      free_entry = entry;      entry = entry->next;      memp_free(MEMP_LOCALHOSTLIST, free_entry);      removed++;    } else {      last_entry = entry;      entry = entry->next;    }  }  return removed;}/** * Add a hostname/IP address pair to the local host-list. * Duplicates are not checked. * * @param hostname hostname of the new entry * @param addr IP address of the new entry * @return ERR_OK if succeeded or ERR_MEM on memory error */err_tdns_local_addhost(const char *hostname, const ip_addr_t *addr){  struct local_hostlist_entry *entry;  size_t namelen;  LWIP_ASSERT("invalid host name (NULL)", hostname != NULL);  namelen = strlen(hostname);  LWIP_ASSERT("namelen <= DNS_LOCAL_HOSTLIST_MAX_NAMELEN", namelen <= DNS_LOCAL_HOSTLIST_MAX_NAMELEN);  entry = (struct local_hostlist_entry *)memp_malloc(MEMP_LOCALHOSTLIST);  if (entry == NULL) {    return ERR_MEM;  }  entry->name = (char*)entry + sizeof(struct local_hostlist_entry);  MEMCPY((char*)entry->name, hostname, namelen);  ((char*)entry->name)[namelen] = 0;  ip_addr_copy(entry->addr, *addr);  entry->next = local_hostlist_dynamic;  local_hostlist_dynamic = entry;  return ERR_OK;}#endif /* DNS_LOCAL_HOSTLIST_IS_DYNAMIC*/#endif /* DNS_LOCAL_HOSTLIST *//** * Look up a hostname in the array of known hostnames. * * @note This function only looks in the internal array of known * hostnames, it does not send out a query for the hostname if none * was found. The function dns_enqueue() can be used to send a query * for a hostname. * * @param name the hostname to look up * @return the hostname's IP address, as u32_t (instead of ip_addr_t to *         better check for failure: != IPADDR_NONE) or IPADDR_NONE if the hostname *         was not found in the cached dns_table. */static u32_tdns_lookup(const char *name){  u8_t i;#if DNS_LOCAL_HOSTLIST || defined(DNS_LOOKUP_LOCAL_EXTERN)  u32_t addr;#endif /* DNS_LOCAL_HOSTLIST || defined(DNS_LOOKUP_LOCAL_EXTERN) */#if DNS_LOCAL_HOSTLIST  if ((addr = dns_lookup_local(name)) != IPADDR_NONE) {    return addr;  }#endif /* DNS_LOCAL_HOSTLIST */#ifdef DNS_LOOKUP_LOCAL_EXTERN  if((addr = DNS_LOOKUP_LOCAL_EXTERN(name)) != IPADDR_NONE) {    return addr;  }#endif /* DNS_LOOKUP_LOCAL_EXTERN */  /* Walk through name list, return entry if found. If not, return NULL. */  for (i = 0; i < DNS_TABLE_SIZE; ++i) {    if ((dns_table[i].state == DNS_STATE_DONE) &&        (strcmp(name, dns_table[i].name) == 0)) {      LWIP_DEBUGF(DNS_DEBUG, ("dns_lookup: \"%s\": found = ", name));      ip_addr_debug_print(DNS_DEBUG, &(dns_table[i].ipaddr));      LWIP_DEBUGF(DNS_DEBUG, ("\n"));      return ip4_addr_get_u32(&dns_table[i].ipaddr);    }  }  return IPADDR_NONE;}#if DNS_DOES_NAME_CHECK/** * Compare the "dotted" name "query" with the encoded name "response" * to make sure an answer from the DNS server matches the current dns_table * entry (otherwise, answers might arrive late for hostname not on the list * any more). * * @param query hostname (not encoded) from the dns_table * @param response encoded hostname in the DNS response * @return 0: names equal; 1: names differ */static u8_tdns_compare_name(unsigned char *query, unsigned char *response){  unsigned char n;  do {    n = *response++;    /** @see RFC 1035 - 4.1.4. Message compression */    if ((n & 0xc0) == 0xc0) {      /* Compressed name */      break;    } else {      /* Not compressed name */      while (n > 0) {        if ((*query) != (*response)) {          return 1;        }        ++response;        ++query;        --n;      };      ++query;    }  } while (*response != 0);  return 0;}#endif /* DNS_DOES_NAME_CHECK *//** * Walk through a compact encoded DNS name and return the end of the name. * * @param query encoded DNS name in the DNS server response * @return end of the name */static unsigned char *dns_parse_name(unsigned char *query){  unsigned char n;  do {    n = *query++;    /** @see RFC 1035 - 4.1.4. Message compression */    if ((n & 0xc0) == 0xc0) {      /* Compressed name */      break;    } else {      /* Not compressed name */      while (n > 0) {        ++query;        --n;      };    }  } while (*query != 0);  return query + 1;}/** * Send a DNS query packet. * * @param numdns index of the DNS server in the dns_servers table * @param name hostname to query * @param id index of the hostname in dns_table, used as transaction ID in the *        DNS query packet * @return ERR_OK if packet is sent; an err_t indicating the problem otherwise */static err_tdns_send(u8_t numdns, const char* name, u8_t id){  err_t err;  struct dns_hdr *hdr;  struct dns_query qry;  struct pbuf *p;  char *query, *nptr;  const char *pHostname;  u8_t n;  LWIP_DEBUGF(DNS_DEBUG, ("dns_send: dns_servers[%"U16_F"] \"%s\": request\n",              (u16_t)(numdns), name));  LWIP_ASSERT("dns server out of array", numdns < DNS_MAX_SERVERS);  LWIP_ASSERT("dns server has no IP address set", !ip_addr_isany(&dns_servers[numdns]));  /* if here, we have either a new query or a retry on a previous query to process */  p = pbuf_alloc(PBUF_TRANSPORT, SIZEOF_DNS_HDR + DNS_MAX_NAME_LENGTH +                 SIZEOF_DNS_QUERY, PBUF_RAM);  if (p != NULL) {    LWIP_ASSERT("pbuf must be in one piece", p->next == NULL);    /* fill dns header */    hdr = (struct dns_hdr*)p->payload;    memset(hdr, 0, SIZEOF_DNS_HDR);    hdr->id = htons(id);    hdr->flags1 = DNS_FLAG1_RD;    hdr->numquestions = PP_HTONS(1);    query = (char*)hdr + SIZEOF_DNS_HDR;    pHostname = name;    --pHostname;    /* convert hostname into suitable query format. */    do {      ++pHostname;      nptr = query;      ++query;      for(n = 0; *pHostname != '.' && *pHostname != 0; ++pHostname) {        *query = *pHostname;        ++query;        ++n;      }      *nptr = n;    } while(*pHostname != 0);    *query++='\0';    /* fill dns query */    qry.type = PP_HTONS(DNS_RRTYPE_A);    qry.cls = PP_HTONS(DNS_RRCLASS_IN);    SMEMCPY(query, &qry, SIZEOF_DNS_QUERY);    /* resize pbuf to the exact dns query */    pbuf_realloc(p, (u16_t)((query + SIZEOF_DNS_QUERY) - ((char*)(p->payload))));    /* connect to the server for faster receiving */    udp_connect(dns_pcb, &dns_servers[numdns], DNS_SERVER_PORT);    /* send dns packet */    err = udp_sendto(dns_pcb, p, &dns_servers[numdns], DNS_SERVER_PORT);    /* free pbuf */    pbuf_free(p);  } else {    err = ERR_MEM;  }  return err;}/** * dns_check_entry() - see if pEntry has not yet been queried and, if so, sends out a query. * Check an entry in the dns_table: * - send out query for new entries * - retry old pending entries on timeout (also with different servers) * - remove completed entries from the table if their TTL has expired * * @param i index of the dns_table entry to check */static voiddns_check_entry(u8_t i){  err_t err;  struct dns_table_entry *pEntry = &dns_table[i];  LWIP_ASSERT("array index out of bounds", i < DNS_TABLE_SIZE);  switch(pEntry->state) {    case DNS_STATE_NEW: {      /* initialize new entry */      pEntry->state   = DNS_STATE_ASKING;      pEntry->numdns  = 0;

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -