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

📄 dnsclnt.c

📁 在ARM7和UC/OSII的平台上实现了GPS自动报站的功能,涉及GPS模块LEA_4S的驱动,位置速寻算法,语音芯片ISD4004的录放音驱动,LED页面管理等等.从启动代码到操作系统的移植以及到业
💻 C
📖 第 1 页 / 共 3 页
字号:



/* FUNCTION: dns_lookup()
 *
 * dns_lookup() - check state of a DNS client request previously 
 * launched with dns_query(). Passed IP address is filled in (in net 
 * endian) if DNS query was resolved without error, else this clears 
 * passed Ip address and returns non-zero ENP_ code. 
 *
 * 
 * PARAM1: ip_addr * ip
 * PARAM2: char * name
 *
 * RETURNS: ENP_SEND_PENDING if request is still on the net, or ENP_TIMEOUT
 * if request timed out (or was never made), or 0 (SUCCESS) if passed IP 
 * is filled in and everything is peachy, or other ENP errors if 
 * detected. 
 */

int   
dns_lookup(ip_addr * ip, char * name)
{
   int   entry;
   int   e;

   *ip = 0L;
   e = dnc_lookup(name, &entry);
   if (e == 0)
      *ip = dns_qs[entry].ipaddr_list[0];    /* return IP address */
   return e;
}


/* FUNCTION: t_gethostbyname()
 *
 * does a DNS lookup of the host named in name and fills in the 
 * passed in p_hostent structure accordingly. its up to the caller to 
 * prepopulate the hostent structure with an array of pointers to 4 
 * byte buffers. see how gethostbyname() below calls 
 * t_gethostbyname() for an example of how to do this.
 *
 * 
 * PARAM1: char *name
 * PARAM2: struct hostent *p_hostent
 * PARAM3: char type    request type: A or SOA
 *
 * RETURNS:  0 if successful, ENP_SEND_PENDING if DNS lookup is in progress
 */

#ifdef DNS_CLIENT_UPDT
int t_gethostbyname(char *name, struct hostent *p_hostent, char type)
#else
int t_gethostbyname(char *name, struct hostent *p_hostent)
#endif /* DNS_CLIENT_UPDT */
{
   char *   cp;
   ip_addr address;
   unsigned int snbits;
   int   i;
   int   entry;   /* dns entry index */
   int   e;

   /* first see if the passed in name looks like a dot notation IP address */
   cp = parse_ipad(&address,&snbits,name);

   /* if it does look like an dot notation IP address,
      don't both with the DNS lookup */
   if (!cp)
   {
      /* fill in the hostent structure */
      p_hostent->h_name = name;
      p_hostent->h_aliases = NULL;  /* we don't do the aliases */
      p_hostent->h_addrtype = 2; /* AF_INET */
      p_hostent->h_length = 4;   /* length of IP address */

      /* if this is true it means the caller didn't set up the host_ent
         right, there's no place to store the IP address */
      if (!(p_hostent->h_addr_list) || !(p_hostent->h_addr_list[0]))
         return ENP_PARAM;
      else
      {
         /* copy the parsed IP address to the first h_addr_list buffer */
         MEMCPY(p_hostent->h_addr_list[0],&address,4);
         /* and zero out the rest */
         for (i = 1; i < MAXDNSADDRS; ++i)
         {
            p_hostent->h_addr_list[i] = 0;
         }
      }
      return 0;   /* success */
   }

   /* if no DNS servers are set up, the lookup will not work */
   if (!dns_servers[0])
      return ENP_LOGIC;

   /* see if we already have an entry for the host */
   e = dnc_lookup(name, &entry);

   /* if so, and it's a completed request... */
   if (e == 0)
   {
      /* fill in the hostent structure */
      p_hostent->h_name = name;
      p_hostent->h_aliases = NULL;  /* we don't do the aliases */
      p_hostent->h_addrtype = 2; /* AF_INET */
      p_hostent->h_length = 4;   /* length of IP address */

#ifdef DNS_CLIENT_UPDT
      p_hostent->h_rcode = dns_qs[entry].rcode;
#endif /* DNS_CLIENT_UPDT */
      /* if this is true it means the caller didn't set up the host_ent
         right, there's no place to store the IP address */
      if (!(p_hostent->h_addr_list))
         return ENP_PARAM;
      else
      {
         /* copy the IP addresses in the entry to the h_addr_list */
         for (i = 0; i < MAXDNSADDRS; ++i)
         {
            /* if no more addresses in entry, no more to copy */
            if (!dns_qs[entry].ipaddr_list[i])
            break;
            /* if caller didn't set up hostent right */
            if (!(p_hostent->h_addr_list[i]))
               return ENP_PARAM;

            /* copy the IP address to the h_addr_list */
            MEMCPY(p_hostent->h_addr_list[i],
             &dns_qs[entry].ipaddr_list[i],4);
         }
         /* zero out the unused h_addr_list entries */
         for ( ; i < MAXDNSADDRS; ++i)
            p_hostent->h_addr_list[i] = 0;
      }
      return 0;   /* success */
   }

   /* else, if dnc_lookup() found the entry, return its status */
   else if (e != ENP_PARAM)
   {
      return e;
   }

   /* there is no entry for the host so make sure we have a spare entry */

   /* try to make room if necessary */
   dnc_makeroom();

   /* look for an available entry */
   for (entry = 0; entry < MAXDNSENTRY; entry++)
      if (dns_qs[entry].id == 0)    /* found empty entry? */
   break;

   /* sanity check to make sure we really have a free entry */
   if (entry >= MAXDNSENTRY)
   {
      dtrap("dnsclnt 5\n"); /* may need to increase MAXDNSENTRY */
      return ENP_RESOURCE;
   }

   /* prepare entry for use and copy in name */
   MEMSET(&dns_qs[entry], 0, sizeof(dns_qs[entry]));     /* clear entry */
   strncpy(dns_qs[entry].dns_name, name, MAXDNSNAME-1);  /* copy in name */
   dns_qs[entry].id = dnsids++;  /* set ID for this transaction */

#ifdef DNS_CLIENT_UPDT
   dns_qs[entry].type = type;    /* set request type */
#endif /* DNS_CLIENT_UPDT */

   if (dnsids == 0)              /* don't allow ID of 0 */
      dnsids++;

#ifdef DNS_CLIENT_UPDT
   if (type == DNS_UPDT)       /* UPDATE packet */
   {
      strncpy(dns_qs[entry].h_z_name, p_hostent->h_z_name, MAXDNSNAME-1);
      dns_qs[entry].h_add_ipaddr = p_hostent->h_add_ipaddr;
      dns_qs[entry].h_ttl = p_hostent->h_ttl;
   }
#endif /* DNS_CLIENT_UPDT */

   /* get UDP port for packet, keep for ID */
   dns_qs[entry].lport = udp_socket();
   dnsc_active++;       /* maintain global dns pending count */
   dnsc_requests++;     /* count this request */

   e = dnc_sendreq(entry);
   if (e == 0) /* first packet sent OK */
      return ENP_SEND_PENDING;
   else  /* some kind of error */
      return e;
}


/* hostent structure returned by gethostbyname() */
static struct hostent gethostbyname_ent;

/* array of pointers addressed by hostent h_addr_list field */
static char *gethostbyname_ip_ptrs[MAXDNSADDRS];

/* buffers for IP addresses addressed by pointer array, a mess aint it */
static char gethostbyname_ip_addresses[MAXDNSADDRS][4];

/* FUNCTION: *gethostbyname()
 *
 * "standard" Unixey version of gethostbyname() that is not 
 * re-entrant. returns pointer to static hostent structure if 
 * successful, NULL if not successful. note that its not completely 
 * standard in that the list of aliases returned by the DNS lookup 
 * will not be in the hostent.
 *
 * 
 * PARAM1: char *name
 *
 * RETURNS:  pointer to static hostent structure if successful, NULL if not.
 */

#ifdef DNS_CLIENT_UPDT
struct hostent * gethostbyname(char *name, char type)
#else
struct hostent * gethostbyname(char *name)
#endif /* DNS_CLIENT_UPDT */
{
   int   i;
   int   rc =  0;
   unsigned long tmo;

   /* set up array of pointers to point to IP address buffers */
   /* t_gethostbyname() will set to NULL those pointers in this array
      that do not point to IP addresses once DNS lookup is done */
   for (i = 0; i < MAXDNSADDRS; ++i)
   {
      gethostbyname_ip_ptrs[i] = gethostbyname_ip_addresses[i];
   }

   /* set h_addr_list field to point to array of pointers */
   gethostbyname_ent.h_addr_list = gethostbyname_ip_ptrs;

   /* we will call t_gethostbyname() until it either succeeds, fails or
      we time out trying */
   tmo = cticks + (5 * TPS);

   while (tmo > cticks)
   {
      /* let t_gethostbyname() do the actual work */
#ifdef DNS_CLIENT_UPDT
      rc = t_gethostbyname(name,&gethostbyname_ent, type);
#else
      rc = t_gethostbyname(name,&gethostbyname_ent);
#endif
      /* if it succeeds, t_gethostbyname() returns 0. if it hard 
       * fails, t_gethostbyname() returns negative number, so 
       */
      if (rc <= 0)
      break;
      /* if it returns a positive number, a request is pending so
         yield and loop to try again until we time out */
      tk_yield();
   }

   /* rc != 0 implies we either failed or timed out trying so return 
    * NULL to indicate failure, else return address of static 
    * hostent. if you want to be able to retrieve the error code via 
    * whatever mechanism you are using to implement errno on your 
    * target system, 
    */
   return rc ? NULL : &gethostbyname_ent;
}

#ifdef DNS_CLIENT_UPDT

/* FUNCTION:  unsigned dns_update()
 *
 * dns_update- sends a DNS UPDATE packet to the authoritative server
 * of the specified domain name.  This routine uses the getsoa call
 * to get the authoritative server of the domain name.  It then sends
 * the UPDATE packet to the authoritative server.
 *
 * 
 * PARAM1: char *soa_mname     domain name
 * PARAM2: char *dname         host name
 * PARAM3: ip_addr ipaddress   ip address
 * PARAM4: unsigned long ttl   ttl value
 *
 * RETURNS:  NULL if successful, else returns one of the UPDATE errors.
 */

int
dns_update(char *soa_mname, char *dname, ip_addr ipaddr, unsigned long ttl,
           void * pio)
             
{
   struct hostent *  p;
   unsigned char * ucp;
   ip_addr save_dns_srvr;

   /* get authoritative name server for specified domain */

   p = getsoa(soa_mname); 

   /*
    * If we received a hostent structure, send the update packet to the
    * received IP address
    */

   if (p)
   {
      ucp = (unsigned char *) *(p->h_addr_list);
      MEMCPY(&save_dns_srvr, dns_servers, 4);
      MEMCPY(dns_servers, ucp, 4);
      ns_printf(pio," sending update packet to %d.%d.%d.%d\n",
            *ucp, *(ucp + 1), *(ucp + 2), *(ucp + 3));
      p->h_z_name = soa_mname;
      p->h_add_ipaddr = ipaddr;
      p->h_ttl = ttl;
      p = gethostbyname(dname, 5);
      MEMCPY(dns_servers, &save_dns_srvr, 4);
      if (p)
         return p->h_rcode; /* Return the output of UPDATE packet */
   }
   return -1; /* authoritative name server not found */
}


/* FUNCTION:  hostent * getsoa(soa_mname)
 *
 * PARAM1: char *soa_mname     zone name
 *
 * RETURNS:  Name of the authoritative name server for the zone.
 */
struct hostent * getsoa(char * soa_mname)
{
   struct hostent * p;
   p = gethostbyname(soa_mname, 2);
   return p;
}

#endif  /* DNS_CLIENT_UPDT */

#ifdef NET_STATS


/* FUNCTION: dns_state()
 * 
 * PARAM1: void * pio
 *
 * RETURNS: 
 */

int
dns_state(void * pio)
{
   int   i;

   ns_printf(pio,"DNS servers:");
   for (i = 0; i < MAXDNSSERVERS; i++)
      ns_printf(pio,"%u.%u.%u.%u ", PUSH_IPADDR(dns_servers[i]) );

   ns_printf(pio,"\nDNS cache:\n");
   for (i = 0; i < MAXDNSENTRY; i++)
   {
      ns_printf(pio,"name: %s, IP: %u.%u.%u.%u, ",
       dns_qs[i].dns_name, PUSH_IPADDR(dns_qs[i].ipaddr_list[0]) );
      ns_printf(pio,"retry:%d, ID:%d, rcode:%d, err:%d\n",
       dns_qs[i].tries, dns_qs[i].id, dns_qs[i].rcode, dns_qs[i].err);
   }
   ns_printf(pio,"protocol/implementation runtime errors:%lu\n", dnsc_errors);
   ns_printf(pio,"requests sent:%lu\n", dnsc_requests);
#ifdef DNS_CLIENT_UPDT
   ns_printf(pio, "Updates sent:%lu\n", dnsc_updates);
#endif /* DNS_CLIENT_UPDT */
   ns_printf(pio,"replies received:%lu\n", dnsc_replies);
   ns_printf(pio,"usable replies:%lu\n", dnsc_good);
   ns_printf(pio,"total retries:%lu\n", dnsc_retry);
   ns_printf(pio,"timeouts:%lu\n", dnsc_tmos);

   return 0;
}
#endif   /* NET_STATS */

#endif   /* DNS_CLIENT */
/* end of file dnsclnt.c */


⌨️ 快捷键说明

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