Пример #1
0
/*
 * i host = 0 mean INADDR_ANY only ipv4
 */
dlist *bnet_host2ipaddrs(const char *host, int family, const char **errstr)
{
   struct in_addr inaddr;
   IPADDR *addr = 0;
   const char *errmsg;
#ifdef HAVE_IPV6
   struct in6_addr inaddr6;
#endif

   dlist *addr_list = New(dlist(addr, &addr->link));
   if (!host || host[0] == '\0') {
      if (family != 0) {
         addr_list->append(add_any(family));
      } else {
         addr_list->append(add_any(AF_INET));
#ifdef HAVE_IPV6
         addr_list->append(add_any(AF_INET6));
#endif
      }
   } else if (inet_aton(host, &inaddr)) { /* MA Bug 4 */
      addr = New(IPADDR(AF_INET));
      addr->set_type(IPADDR::R_MULTIPLE);
      addr->set_addr4(&inaddr);
      addr_list->append(addr);
#ifdef HAVE_IPV6
   } else if (inet_pton(AF_INET6, host, &inaddr6) == 1) {
      addr = New(IPADDR(AF_INET6));
      addr->set_type(IPADDR::R_MULTIPLE);
      addr->set_addr6(&inaddr6);
      addr_list->append(addr);
#endif
   } else {
      if (family != 0) {
         errmsg = resolv_host(family, host, addr_list);
         if (errmsg) {
            *errstr = errmsg;
            free_addresses(addr_list);
            return 0;
         }
      } else {
#ifdef HAVE_IPV6
         /* We try to resolv host for ipv6 and ipv4, the connection procedure
          * will try to reach the host for each protocols. We report only "Host
          * not found" ipv4 message (no need to have ipv6 and ipv4 messages).
          */
         resolv_host(AF_INET6, host, addr_list);
#endif
         errmsg = resolv_host(AF_INET, host, addr_list);

         if (addr_list->size() == 0) {
            *errstr = errmsg;
            free_addresses(addr_list);
            return 0;
         }
      }
   }
   return addr_list;
}
Пример #2
0
const char *resolv_host(int family, const char *host, dlist *addr_list)
{
   int res;
   struct addrinfo hints;
   struct addrinfo *ai, *rp;
   IPADDR *addr;

   memset(&hints, 0, sizeof(struct addrinfo));
   hints.ai_family = family;
   hints.ai_socktype = SOCK_STREAM;
   hints.ai_protocol = IPPROTO_TCP;
   hints.ai_flags = 0;

   res = getaddrinfo(host, NULL, &hints, &ai);
   if (res != 0) {
      return gai_strerror(res);
   }

   for (rp = ai; rp != NULL; rp = rp->ai_next) {
      switch (rp->ai_addr->sa_family) {
      case AF_INET:
         addr = New(IPADDR(rp->ai_addr->sa_family));
         addr->set_type(IPADDR::R_MULTIPLE);
         /*
          * Some serious casting to get the struct in_addr *
          * rp->ai_addr == struct sockaddr
          * as this is AF_INET family we can cast that
          * to struct_sockaddr_in. Of that we need the
          * address of the sin_addr member which contains a
          * struct in_addr
          */
         addr->set_addr4(&(((struct sockaddr_in *)rp->ai_addr)->sin_addr));
         break;
#ifdef HAVE_IPV6
      case AF_INET6:
         addr = New(IPADDR(rp->ai_addr->sa_family));
         addr->set_type(IPADDR::R_MULTIPLE);
         /*
          * Some serious casting to get the struct in6_addr *
          * rp->ai_addr == struct sockaddr
          * as this is AF_INET6 family we can cast that
          * to struct_sockaddr_in6. Of that we need the
          * address of the sin6_addr member which contains a
          * struct in6_addr
          */
         addr->set_addr6(&(((struct sockaddr_in6 *)rp->ai_addr)->sin6_addr));
         break;
#endif
      default:
         continue;
      }
      addr_list->append(addr);
   }
   freeaddrinfo(ai);
   return NULL;
}
Пример #3
0
/*
 * Note: this is the old way of resolving a host
 *  that does not use the new getaddrinfo() above.
 */
static const char *resolv_host(int family, const char *host, dlist * addr_list)
{
   struct hostent *hp;
   const char *errmsg;

   P(ip_mutex);                       /* gethostbyname() is not thread safe */
#ifdef HAVE_GETHOSTBYNAME2
   if ((hp = gethostbyname2(host, family)) == NULL) {
#else
   if ((hp = gethostbyname(host)) == NULL) {
#endif
      /* may be the strerror give not the right result -:( */
      errmsg = gethost_strerror();
      V(ip_mutex);
      return errmsg;
   } else {
      char **p;
      for (p = hp->h_addr_list; *p != 0; p++) {
         IPADDR *addr =  New(IPADDR(hp->h_addrtype));
         addr->set_type(IPADDR::R_MULTIPLE);
         if (addr->get_family() == AF_INET) {
            addr->set_addr4((struct in_addr*)*p);
            addr_list->append(addr);
         }
#ifdef HAVE_IPV6
         else if (addr->get_family() == AF_INET6) {
            addr->set_addr6((struct in6_addr*)*p);
            addr_list->append(addr);
         }
#endif
      }
      V(ip_mutex);
   }
   return NULL;
}
#endif

static IPADDR *add_any(int family)
{
   IPADDR *addr = New(IPADDR(family));
   addr->set_type(IPADDR::R_MULTIPLE);
   addr->set_addr_any();
   return addr;
}