Exemple #1
0
int
main(int argc, char **argv) {
	struct hostent *he;
	int error;

	(void)argc;

	while (argv[1] != NULL) {
		he = gethostbyname(argv[1]);
		print_he(he, h_errno, "gethostbyname", argv[1]);

		he = getipnodebyname(argv[1], AF_INET6, AI_DEFAULT|AI_ALL,
				     &error);
		print_he(he, error, "getipnodebyname", argv[1]);
		if (he != NULL)
			freehostent(he);

		he = getipnodebyname(argv[1], AF_INET6, AI_DEFAULT,
				     &error);
		print_he(he, error, "getipnodebyname", argv[1]);
		if (he != NULL)
			freehostent(he);
		argv++;
	}
	return (0);
}
Exemple #2
0
static void
test_getipnodebyname(const char *name, const char *address, int af,
		     int v4map, int all)
{
	struct hostent *hp;
	unsigned char addrbuf[16];
	int len, ret;
	int error_num;
	int flags = 0;

	if (v4map)
		flags |= AI_V4MAPPED;
	if (all)
		flags |= AI_ALL;

	hp = getipnodebyname(name, af, flags, &error_num);
	if (hp == NULL) {
		if (address == NULL && error_num == HOST_NOT_FOUND)
			return;
		else if (error_num != HOST_NOT_FOUND) {
			printf("I:getipnodebyname(%s) failed: %d\n",
			       name, error_num);
			fails++;
			return;
		} else {
			printf("I:getipnodebyname(%s) returned not found\n",
			       name);
			fails++;
			return;
		}
	} else {
		if (af == AF_INET)
			len = 4;
		else
			len = 16;
		ret = inet_pton(af, address, addrbuf);
		assert(ret == 1);
		if (hp->h_addrtype != af) {
			printf("I:getipnodebyname(%s) returned wrong family\n",
			       name);
			freehostent(hp);
			fails++;
			return;
		}
		if (len != (int)hp->h_length ||
		    memcmp(hp->h_addr_list[0], addrbuf, hp->h_length) != 0)
		{
			char outbuf[16];
			(void)inet_ntop(af, hp->h_addr_list[0],
					outbuf, sizeof(outbuf));
			printf("I:getipnodebyname(%s) returned %s, "
			       "expected %s\n", name, outbuf, address);
			freehostent(hp);
			fails++;
			return;
		}
		freehostent(hp);
	}
}
struct hostent * ROKEN_LIB_FUNCTION
copyhostent (const struct hostent *h)
{
    struct hostent *res;
    char **p;
    int i, n;

    res = malloc (sizeof (*res));
    if (res == NULL)
	return NULL;
    res->h_name      = NULL;
    res->h_aliases   = NULL;
    res->h_addrtype  = h->h_addrtype;
    res->h_length    = h->h_length;
    res->h_addr_list = NULL;
    res->h_name = strdup (h->h_name);
    if (res->h_name == NULL) {
	freehostent (res);
	return NULL;
    }
    for (n = 0, p = h->h_aliases; *p != NULL; ++p)
	++n;
    res->h_aliases = malloc ((n + 1) * sizeof(*res->h_aliases));
    if (res->h_aliases == NULL) {
	freehostent (res);
	return NULL;
    }
    for (i = 0; i < n + 1; ++i)
	res->h_aliases[i] = NULL;
    for (i = 0; i < n; ++i) {
	res->h_aliases[i] = strdup (h->h_aliases[i]);
	if (res->h_aliases[i] == NULL) {
	    freehostent (res);
	    return NULL;
	}
    }

    for (n = 0, p = h->h_addr_list; *p != NULL; ++p)
	++n;
    res->h_addr_list = malloc ((n + 1) * sizeof(*res->h_addr_list));
    if (res->h_addr_list == NULL) {
	freehostent (res);
	return NULL;
    }
    for (i = 0; i < n + 1; ++i) {
	res->h_addr_list[i] = NULL;
    }
    for (i = 0; i < n; ++i) {
	res->h_addr_list[i] = malloc (h->h_length);
	if (res->h_addr_list[i] == NULL) {
	    freehostent (res);
	    return NULL;
	}
	memcpy (res->h_addr_list[i], h->h_addr_list[i], h->h_length);
    }
    return res;
}
Exemple #4
0
static char *
myGetHostByAddr (char *addr, int len, int type)
{
  struct hostent *hostEnt;
  char *result;

#if HAVE_GETIPNODEBYADDR
  int error;
  hostEnt = getipnodebyaddr (addr, len, type, &error);
#else
  hostEnt = gethostbyaddr (addr, len, type);
#endif

  if (hostEnt)
    {
      result = malloc (128);	/* out of a hat */
      strncpy (result, hostEnt->h_name, 128);
#if HAVE_GETIPNODEBYADDR
      freehostent (hostEnt);
#endif
    }
  else
    result = NULL;
  
  return (result);
}
Exemple #5
0
static void
__freehostent(struct hostent *he)
{
	/* NOTE: checking for he != NULL - just in case */
	if ((use_ipnode_functions != 0) && (he != NULL))
		freehostent(he);
}
static int
spoolss_getservername(char *name, size_t namelen)
{
	char		hostname[MAXHOSTNAMELEN];
	char		ipstr[INET6_ADDRSTRLEN];
	smb_inaddr_t	ipaddr;
	struct hostent	*h;
	const char	*p;
	int		error;

	if (smb_gethostname(hostname, MAXHOSTNAMELEN, 0) != 0) {
		smb_tracef("spoolss_s_GetPrinter: gethostname failed");
		return (-1);
	}

	if ((h = smb_gethostbyname(hostname, &error)) == NULL) {
		smb_tracef("spoolss_s_GetPrinter: gethostbyname failed: %d",
		    error);
		return (-1);
	}

	bcopy(h->h_addr, &ipaddr, h->h_length);
	ipaddr.a_family = h->h_addrtype;
	freehostent(h);

	p = smb_inet_ntop(&ipaddr, ipstr, SMB_IPSTRLEN(ipaddr.a_family));
	if (p == NULL) {
		smb_tracef("spoolss_s_GetPrinter: inet_ntop failed");
		return (-1);
	}

	(void) snprintf(name, namelen, "\\\\%s", ipstr);
	return (0);
}
Exemple #7
0
char *
SamrftGetHostByAddr(
	void *addr,
	int  af)
{
	struct hostent *host_ent;
	char *host_name = NULL;
	char buffer[32];
	int h_err = TRUE;
	int size;

	switch (af) {
	case AF_INET:
		size = sizeof (struct in_addr);
		break;
	case AF_INET6:
		size = sizeof (struct in6_addr);
		break;
	}
	host_ent = getipnodebyaddr((char *)addr, size, af, &h_err);
	if (host_ent != NULL) {
		SamStrdup(host_name, host_ent->h_name);
		freehostent(host_ent);
	} else {
		Trace(TR_ERR, "Samrft af %d address %s not found",
		    af, inet_ntop(af, (char *)addr, buffer, 32));
	}
	return (host_name);
}
Exemple #8
0
bool Util::safe_gethostbyname(const char *address, HostEnt &result) {
#if defined(__APPLE__)
  struct hostent *hp = gethostbyname(address);

  if (!hp) {
    return false;
  }

  result.hostbuf = *hp;
  freehostent(hp);
  return true;
#else
  struct hostent *hp;
  int res;

  size_t hstbuflen = 1024;
  result.tmphstbuf = (char*)malloc(hstbuflen);
  while ((res = gethostbyname_r(address, &result.hostbuf, result.tmphstbuf,
                                hstbuflen, &hp, &result.herr)) == ERANGE) {
    hstbuflen *= 2;
    result.tmphstbuf = (char*)realloc(result.tmphstbuf, hstbuflen);
  }
  return !res && hp;
#endif
}
Exemple #9
0
struct hostent *
tds_gethostbyaddr_r(const char *addr, int len, int type, struct hostent *result, char *buffer, int buflen, int *h_errnop)
{
#if defined(NETDB_REENTRANT)
    return gethostbyaddr(addr, len, type);

#elif defined(HAVE_GETIPNODEBYADDR)
    struct hostent *he = getipnodebyaddr(addr, len, type, h_errnop);

    if (!he)
        return NULL;
    if (tds_copy_hostent(he, result, buffer, buflen)) {
        errno = ENOMEM;
        if (h_errnop)
            *h_errnop = NETDB_INTERNAL;
        freehostent(he);
        return NULL;
    }
    freehostent(he);
    return result;

#elif defined(HAVE_FUNC_GETHOSTBYADDR_R_8)
    if (gethostbyaddr_r(addr, len, type, result, buffer, buflen, &result, h_errnop))
        return NULL;
    return result;

#elif defined(HAVE_FUNC_GETHOSTBYADDR_R_7)
    result = gethostbyaddr_r(addr, len, type, result, buffer, buflen, h_errnop);
    return result;

#elif defined(HAVE_FUNC_GETHOSTBYADDR_R_5)
	struct hostent_data *data = (struct hostent_data *) buffer;

	memset(buffer, 0, buflen);
	if (gethostbyaddr_r(addr, len, type, result, data)) {
		*h_errnop = 0;
		result = NULL;
	}
	return result;

#elif defined(TDS_NO_THREADSAFE)
	return gethostbyaddr(addr, len, type);

#else
#error gethostbyaddr_r style unknown
#endif
}
Exemple #10
0
struct hostent *
tds_gethostbyname_r(const char *servername, struct hostent *result, char *buffer, int buflen, int *h_errnop)
{
	struct hostent *he = getipnodebyname(servername, AF_INET, 0, h_errnop);

	if (!he)
		return NULL;
	if (tds_copy_hostent(he, result, buffer, buflen)) {
		errno = ENOMEM;
		if (h_errnop)
			*h_errnop = NETDB_INTERNAL;
		freehostent(he);
		return NULL;
	}
	freehostent(he);
	return result;
}
Exemple #11
0
void
free_ghbnctx (struct ghbnctx *ctx)
{
  assert (ctx != NULL);

  if (ctx->hostent != NULL)
    freehostent (ctx->hostent);
}
Exemple #12
0
static int
get_nodes (const char *nodename,
	   const struct addrinfo *hints,
	   int port, int protocol, int socktype,
	   struct addrinfo **res)
{
    struct addrinfo *first = NULL;
    struct addrinfo **current = &first;
    int family = PF_UNSPEC;
    int flags  = 0;
    int ret = EAI_NONAME;
    int error;

    if (hints != NULL) {
	family = hints->ai_family;
	flags  = hints->ai_flags;
    }

#ifdef HAVE_IPV6
    if (family == PF_INET6 || family == PF_UNSPEC) {
	struct hostent *he;

	he = getipnodebyname (nodename, PF_INET6, 0, &error);

	if (he != NULL) {
	    ret = add_hostent (port, protocol, socktype,
			       &current, const_v6, he, &flags);
	    freehostent (he);
	}
    }
#endif
    if (family == PF_INET || family == PF_UNSPEC) {
	struct hostent *he;

	he = getipnodebyname (nodename, PF_INET, 0, &error);

	if (he != NULL) {
	    ret = add_hostent (port, protocol, socktype,
			       &current, const_v4, he, &flags);
	    freehostent (he);
	}
    }
    *res = first;
    return ret;
}
Exemple #13
0
struct hostent *
tds_gethostbyname_r(const char *servername, struct hostent *result, char *buffer, int buflen, int *h_errnop)
{
#if defined(NETDB_REENTRANT)
    return gethostbyname(servername);

/* we have a better replacements */
#elif defined(HAVE_GETIPNODEBYNAME)
    struct hostent *he = getipnodebyname(servername, AF_INET, 0, h_errnop);

    if (!he)
        return NULL;
    if (tds_copy_hostent(he, result, buffer, buflen)) {
        errno = ENOMEM;
        if (h_errnop)
            *h_errnop = NETDB_INTERNAL;
        freehostent(he);
        return NULL;
    }
    freehostent(he);
    return result;

#elif defined(HAVE_FUNC_GETHOSTBYNAME_R_6)
    if (gethostbyname_r(servername, result, buffer, buflen, &result, h_errnop))
        return NULL;
    return result;

#elif defined(HAVE_FUNC_GETHOSTBYNAME_R_5)
    result = gethostbyname_r(servername, result, buffer, buflen, h_errnop);
    return result;

#elif defined(HAVE_FUNC_GETHOSTBYNAME_R_3)
    struct hostent_data *data = (struct hostent_data *) buffer;

    memset(buffer, 0, buflen);
    if (gethostbyname_r(servername, result, data)) {
        *h_errnop = 0;
        result = NULL;
    }
    return result;

#else
#error gethostbyname_r style unknown
#endif
}
Exemple #14
0
char *
one_addr(krb5_address *a)
{
    static char retstr[256];
    struct hostent *h;
    int no_resolve = 1;

    retstr[0] = '\0';

    if ((a->addrtype == ADDRTYPE_INET && a->length == 4)
#ifdef AF_INET6
        || (a->addrtype == ADDRTYPE_INET6 && a->length == 16)
#endif
        ) {
        int af = AF_INET;
#ifdef AF_INET6
        if (a->addrtype == ADDRTYPE_INET6)
            af = AF_INET6;
#endif
        if (!no_resolve) {
#ifdef HAVE_GETIPNODEBYADDR
            int err;
            h = getipnodebyaddr(a->contents, a->length, af, &err);
            if (h) {
                wsprintf(retstr, "%s", h->h_name);
                freehostent(h);
            }
#else
            h = gethostbyaddr(a->contents, a->length, af);
            if (h) {
                wsprintf(retstr,"%s", h->h_name);
            }
#endif
            if (h)
                return(retstr);
        }
        if (no_resolve || !h) {
#ifdef HAVE_INET_NTOP
            char buf[46];
            const char *name = inet_ntop(a->addrtype, a->contents, buf, sizeof(buf));
            if (name) {
                wsprintf(retstr,"%s", name);
                return;
            }
#else
            if (a->addrtype == ADDRTYPE_INET) {
                wsprintf(retstr,"%d.%d.%d.%d", a->contents[0], a->contents[1],
                       a->contents[2], a->contents[3]);
                return(retstr);
            }
#endif
        }
    }
    wsprintf(retstr,"unknown addr type %d", a->addrtype);
    return(retstr);
}
Exemple #15
0
static void
test_getipnodebyaddr(const char *address, int af, const char *name) {
	struct hostent *hp;
	char addrbuf[16];
	int len, ret;
	int error_num;

	if (af == AF_INET)
		len = 4;
	else
		len = 16;
	ret = inet_pton(af, address, addrbuf);
	assert(ret == 1);

	hp = getipnodebyaddr(addrbuf, len, af, &error_num);

	if (hp == NULL) {
		if (name == NULL && error_num == HOST_NOT_FOUND)
			return;
		else if (error_num != HOST_NOT_FOUND) {
			printf("I:getipnodebyaddr(%s) failed: %d\n",
			       address, error_num);
			fails++;
			return;
		} else {
			printf("I:getipnodebyaddr(%s) returned not found\n",
			       address);
			fails++;
			return;
		}
	} else {
		if (name != NULL && strcmp(hp->h_name, name) != 0) {
			printf("I:getipnodebyaddr(%s) returned %s, "
			       "expected %s\n", address, hp->h_name, name);
			freehostent(hp);
			fails++;
			return;
		}
		freehostent(hp);
	}
}
Exemple #16
0
/*
 * Frees host list - should be called while keeping auditd_mutex.
 */
static void
freehostlist(hostlist_t **hostlist_ptr)
{
	hostlist_t *h, *n;

	h = *hostlist_ptr;

	while (h != NULL)  {
		n = h->next_host;
		freehostent(h->host);
		free(h);
		h = n;
	}
	*hostlist_ptr = NULL;
}
Exemple #17
0
/*
 * vs_eng_connect
 * open socket connection to remote scan engine
 *
 * Returns: sockfd or -1 (error)
 */
static int
vs_eng_connect(char *host, int port)
{
	int rc, sockfd, opt_nodelay, opt_keepalive, opt_reuseaddr, err_num;
	struct sockaddr_in addr;
	struct hostent *hp;

	if ((sockfd = socket(AF_INET, SOCK_STREAM, 0)) == -1)
		return (-1);

	hp = getipnodebyname(host, AF_INET, 0, &err_num);
	if (hp == NULL) {
		(void) close(sockfd);
		return (-1);
	}

	(void) memset(&addr, 0, sizeof (addr));
	(void) memcpy(&addr.sin_addr, hp->h_addr, hp->h_length);
	addr.sin_port = htons(port);
	addr.sin_family = hp->h_addrtype;
	freehostent(hp);

#ifdef FIONBIO /* Use non-blocking mode for connect. */
	rc = nbio_connect(sockfd, (struct sockaddr *)&addr,
	    sizeof (struct sockaddr));
#else
	rc = connect(sockfd, (struct sockaddr *)&addr,
	    sizeof (struct sockaddr));
#endif

	opt_nodelay = 1;
	opt_keepalive = 1;
	opt_reuseaddr = 1;

	if ((rc < 0) ||
	    (setsockopt(sockfd, IPPROTO_TCP, TCP_NODELAY,
	    &opt_nodelay, sizeof (opt_nodelay)) < 0) ||
	    (setsockopt(sockfd, SOL_SOCKET, SO_KEEPALIVE,
	    &opt_keepalive, sizeof (opt_keepalive)) < 0) ||
	    (setsockopt(sockfd, SOL_SOCKET, SO_REUSEADDR,
	    &opt_reuseaddr, sizeof (opt_reuseaddr)) < 0)) {
		(void) close(sockfd);
		return (-1);
	}

	return (sockfd);
}
Exemple #18
0
static int
add_hostent (int port, int protocol, int socktype,
	     struct addrinfo ***current,
	     int (*func)(struct addrinfo *, void *data, int port),
	     struct hostent *he, int *flags)
{
    int ret;
    char *canonname = NULL;
    char **h;

    if (*flags & AI_CANONNAME) {
	struct hostent *he2 = NULL;
	const char *tmp_canon;

	tmp_canon = hostent_find_fqdn (he);
	if (strchr (tmp_canon, '.') == NULL) {
	    int error;

	    he2 = getipnodebyaddr (he->h_addr_list[0], he->h_length,
				   he->h_addrtype, &error);
	    if (he2 != NULL) {
		const char *tmp = hostent_find_fqdn (he2);

		if (strchr (tmp, '.') != NULL)
		    tmp_canon = tmp;
	    }
	}

	canonname = strdup (tmp_canon);
	if (he2 != NULL)
	    freehostent (he2);
	if (canonname == NULL)
	    return EAI_MEMORY;
    }

    for (h = he->h_addr_list; *h != NULL; ++h) {
	ret = add_one (port, protocol, socktype,
		       current, func, *h, canonname);
	if (ret)
	    return ret;
	if (*flags & AI_CANONNAME) {
	    *flags &= ~AI_CANONNAME;
	    canonname = NULL;
	}
    }
    return 0;
}
static struct hostent *
hostent_alloc(int family)
{
	struct hostent	*h;

	h = calloc(1, sizeof *h);
	if (h == NULL)
		return (NULL);

	h->h_aliases = calloc(MAXALIASES, sizeof *h->h_aliases);
	h->h_addr_list = calloc(MAXADDRS, sizeof *h->h_addr_list);
	if (h->h_aliases == NULL || h->h_addr_list == NULL) {
		freehostent(h);
		return (NULL);
	}
	h->h_addrtype = family;
	h->h_length = (family == AF_INET) ? 4 : 16;

	return (h);
}
Exemple #20
0
//-----------------------------------------------------------------------------
//	validate_ipstring
//-----------------------------------------------------------------------------
char* validate_ip_string(const char *inIPString, char *outIPString, size_t outSize)
{

    int		nErr ;
    char*	outIP;

    if (!inIPString)
            return 0;
    if (!*inIPString)
            return 0;
    if (outSize < 16)
            return 0;

    // First, ask the system to look up the given name.
    struct hostent	*hesp = getipnodebyname (inIPString, AF_INET, 0, &nErr);
    if (hesp == NULL)
        return 0;
    // Convert the returned info to dotted decimal string.
    outIP = (char*)inet_ntop(AF_INET, hesp->h_addr_list[0], outIPString, outSize);
    freehostent (hesp);
    return outIP;
}
Exemple #21
0
void printaddress (krb5_address address)
{
    int             af;
    char            buf[46];
    const char     *addr_string = NULL;
    
    
    switch (address.addrtype) {
        case ADDRTYPE_INET:
            af = AF_INET;
            break;
            
        case ADDRTYPE_INET6:
            af = AF_INET6;
            break;
            
        default:
             printmsg ("unknown address type %d", address.addrtype);
             return;
    }
    
    if (!no_reverse_resolve_addresses) {
        struct hostent *h = NULL;
        int err; 
        
        h = getipnodebyaddr (address.contents, address.length, af, &err);
        if (h != NULL) {
            printmsg ("%s", h->h_name);
            freehostent (h);
            return;
        }
    }
    
    /* either we aren't resolving addresses or we failed to do so */
    addr_string = inet_ntop(af, address.contents, buf, sizeof(buf));
    if (addr_string != NULL) {
        printmsg ("%s", addr_string);
    }
}
Exemple #22
0
int
main(int argc, char **argv) {
	struct hostent *he;
	int error;
	struct in_addr in_addr;
	struct in6_addr in6_addr;
	void *addr;
	int af;
	size_t len;

	(void)argc;

	while (argv[1] != NULL) {
		if (inet_pton(AF_INET, argv[1], &in_addr) == 1) {
			af = AF_INET;
			addr = &in_addr;
			len = sizeof(in_addr);
		} else if (inet_pton(AF_INET6, argv[1], &in6_addr) == 1) {
			af = AF_INET6;
			addr = &in6_addr;
			len = sizeof(in6_addr);
		} else {
			printf("unable to convert \"%s\" to an address\n",
			       argv[1]);
			argv++;
			continue;
		}
		he = gethostbyaddr(addr, len, af);
		print_he(he, h_errno, "gethostbyaddr", argv[1]);

		he = getipnodebyaddr(addr, len, af, &error);
		print_he(he, error, "getipnodebyaddr", argv[1]);
		if (he != NULL)
			freehostent(he);
		argv++;
	}
	return (0);
}
Exemple #23
0
/*
 * Get information about the Domain Controller in the joined resource domain.
 *
 * Returns NT status codes.
 */
uint32_t
smb_get_dcinfo(char *namebuf, uint32_t namebuflen, smb_inaddr_t *ipaddr)
{
    smb_string_t	dcname;
    struct hostent	*h;
    int		rc;

    assert((namebuf != NULL) && (namebuflen != 0));
    *namebuf = '\0';
    bzero(&dcname, sizeof (smb_string_t));

    rc = smb_door_call(SMB_DR_GET_DCINFO, NULL, NULL,
                       &dcname, smb_string_xdr);

    if (rc != 0) {
        syslog(LOG_DEBUG, "smb_get_dcinfo: %m");
        if (dcname.buf)
            xdr_free(smb_string_xdr, (char *)&dcname);
        return (NT_STATUS_INTERNAL_ERROR);
    }

    if (dcname.buf) {
        (void) strlcpy(namebuf, dcname.buf, namebuflen);

        if ((h = smb_gethostbyname(dcname.buf, &rc)) == NULL) {
            bzero(ipaddr, sizeof (smb_inaddr_t));
        } else {
            (void) memcpy(ipaddr, h->h_addr, h->h_length);
            ipaddr->a_family = h->h_addrtype;
            freehostent(h);
        }
        xdr_free(smb_string_xdr, (char *)&dcname);
    }

    return (NT_STATUS_SUCCESS);
}
/* getipnodebyname() internal routine for multiple query(PF_UNSPEC) support. */
struct hostent *
_getipnodebyname_multi(const char *name, int af, int flags, int *errp)
{
	struct hostent *hp;
	union inx_addr addrbuf;

	/* XXX: PF_UNSPEC is only supposed to be passed from getaddrinfo() */
	if (af != AF_INET
#ifdef INET6
	    && af != AF_INET6
#endif
	    && af != PF_UNSPEC
		)
	{
		*errp = NO_RECOVERY;
		return NULL;
	}

#ifdef INET6
	/* special case for literal address */
	if (inet_pton(AF_INET6, name, &addrbuf) == 1) {
		if (af != AF_INET6) {
			*errp = HOST_NOT_FOUND;
			return NULL;
		}
		return _hpaddr(af, name, &addrbuf, errp);
	}
#endif
	if (inet_aton(name, (struct in_addr *)&addrbuf) == 1) {
		if (af != AF_INET) {
			if (MAPADDRENABLED(flags)) {
				MAPADDR(&addrbuf, &addrbuf.in_addr);
			} else {
				*errp = HOST_NOT_FOUND;
				return NULL;
			}
		}
		return _hpaddr(af, name, &addrbuf, errp);
	}

	*errp = HOST_NOT_FOUND;
	hp = _ghbyname(name, af, flags, errp);

#ifdef INET6
	if (af == AF_INET6
	&&  ((flags & AI_ALL) || hp == NULL)
	&&  (MAPADDRENABLED(flags))) {
		struct hostent *hp2 = _ghbyname(name, AF_INET, flags, errp);
		if (hp == NULL)
			hp = _hpmapv6(hp2, errp);
		else {
			if (hp2 && strcmp(hp->h_name, hp2->h_name) != 0) {
				freehostent(hp2);
				hp2 = NULL;
			}
			hp = _hpmerge(hp, hp2, errp);
		}
	}
#endif
	return _hpsort(hp);
}
Exemple #25
0
int
main(int argc, char *argv[])
{
	int mib[4] = { CTL_NET, PF_INET6, IPPROTO_IPV6, IPV6CTL_DEFHLIM };
	char hbuf[NI_MAXHOST], src0[NI_MAXHOST], *ep;
	int ch, i, on = 1, seq, rcvcmsglen, error, minlen;
	struct addrinfo hints, *res;
	static u_char *rcvcmsgbuf;
	u_long probe, hops, lport;
	struct hostent *hp;
	size_t size;
	uid_t uid;

	/*
	 * Receive ICMP
	 */
	if ((rcvsock = socket(AF_INET6, SOCK_RAW, IPPROTO_ICMPV6)) < 0) {
		perror("socket(ICMPv6)");
		exit(5);
	}

	/* revoke privs */
	uid = getuid();
	if (setresuid(uid, uid, uid) == -1)
		err(1, "setresuid");

	size = sizeof(i);
	(void) sysctl(mib, sizeof(mib)/sizeof(mib[0]), &i, &size, NULL, 0);
	max_hops = i;

	/* specify to tell receiving interface */
	if (setsockopt(rcvsock, IPPROTO_IPV6, IPV6_RECVPKTINFO, &on,
	    sizeof(on)) < 0)
		err(1, "setsockopt(IPV6_RECVPKTINFO)");

	/* specify to tell value of hoplimit field of received IP6 hdr */
	if (setsockopt(rcvsock, IPPROTO_IPV6, IPV6_RECVHOPLIMIT, &on,
	    sizeof(on)) < 0)
		err(1, "setsockopt(IPV6_RECVHOPLIMIT)");

	seq = 0;

	while ((ch = getopt(argc, argv, "df:g:Ilm:np:q:rs:w:v")) != -1)
		switch (ch) {
		case 'd':
			options |= SO_DEBUG;
			break;
		case 'f':
			ep = NULL;
			errno = 0;
			first_hop = strtoul(optarg, &ep, 0);
			if (errno || !*optarg || *ep|| first_hop > 255) {
				fprintf(stderr,
				    "traceroute6: invalid min hoplimit.\n");
				exit(1);
			}
			break;
		case 'g':
			hp = getipnodebyname(optarg, AF_INET6, 0, &h_errno);
			if (hp == NULL) {
				fprintf(stderr,
				    "traceroute6: unknown host %s\n", optarg);
				exit(1);
			}
			if (rth == NULL) {
				/*
				 * XXX: We can't detect the number of
				 * intermediate nodes yet.
				 */
				if ((rth = inet6_rth_init((void *)rtbuf,
				    sizeof(rtbuf), IPV6_RTHDR_TYPE_0,
				    0)) == NULL) {
					fprintf(stderr,
					    "inet6_rth_init failed.\n");
					exit(1);
				}
			}
			if (inet6_rth_add((void *)rth,
			    (struct in6_addr *)hp->h_addr)) {
				fprintf(stderr,
				    "inet6_rth_add failed for %s\n",
				    optarg);
				exit(1);
			}
			freehostent(hp);
			break;
		case 'I':
			useicmp++;
			ident = htons(getpid() & 0xffff); /* same as ping6 */
			break;
		case 'l':
			lflag++;
			break;
		case 'm':
			ep = NULL;
			errno = 0;
			max_hops = strtoul(optarg, &ep, 0);
			if (errno || !*optarg || *ep || max_hops > 255) {
				fprintf(stderr,
				    "traceroute6: invalid max hoplimit.\n");
				exit(1);
			}
			break;
		case 'n':
			nflag++;
			break;
		case 'p':
			ep = NULL;
			errno = 0;
			lport = strtoul(optarg, &ep, 0);
			if (errno || !*optarg || *ep) {
				fprintf(stderr, "traceroute6: invalid port.\n");
				exit(1);
			}
			if (lport == 0 || lport != (lport & 0xffff)) {
				fprintf(stderr,
				    "traceroute6: port out of range.\n");
				exit(1);
			}
			port = lport & 0xffff;
			break;
		case 'q':
			ep = NULL;
			errno = 0;
			nprobes = strtoul(optarg, &ep, 0);
			if (errno || !*optarg || *ep) {
				fprintf(stderr,
				    "traceroute6: invalid nprobes.\n");
				exit(1);
			}
			if (nprobes < 1) {
				fprintf(stderr,
				    "traceroute6: nprobes must be >0.\n");
				exit(1);
			}
			break;
		case 'r':
			options |= SO_DONTROUTE;
			break;
		case 's':
			/*
			 * set the ip source address of the outbound
			 * probe (e.g., on a multi-homed host).
			 */
			source = optarg;
			break;
		case 'v':
			verbose++;
			break;
		case 'w':
			ep = NULL;
			errno = 0;
			waittime = strtoul(optarg, &ep, 0);
			if (errno || !*optarg || *ep) {
				fprintf(stderr,
				    "traceroute6: invalid wait time.\n");
				exit(1);
			}
			if (waittime <= 1) {
				fprintf(stderr,
				    "traceroute6: wait must be >1 sec.\n");
				exit(1);
			}
			break;
		default:
			usage();
		}
	argc -= optind;
	argv += optind;

	if (max_hops < first_hop) {
		fprintf(stderr,
		    "traceroute6: max hoplimit must be larger than first hoplimit.\n");
		exit(1);
	}

	if (argc < 1 || argc > 2)
		usage();

#if 1
	setvbuf(stdout, NULL, _IOLBF, BUFSIZ);
#else
	setlinebuf(stdout);
#endif

	memset(&hints, 0, sizeof(hints));
	hints.ai_family = PF_INET6;
	hints.ai_socktype = SOCK_RAW;
	hints.ai_protocol = IPPROTO_ICMPV6;
	hints.ai_flags = AI_CANONNAME;
	error = getaddrinfo(*argv, NULL, &hints, &res);
	if (error) {
		fprintf(stderr,
		    "traceroute6: %s\n", gai_strerror(error));
		exit(1);
	}
	if (res->ai_addrlen != sizeof(Dst)) {
		fprintf(stderr,
		    "traceroute6: size of sockaddr mismatch\n");
		exit(1);
	}
	memcpy(&Dst, res->ai_addr, res->ai_addrlen);
	hostname = res->ai_canonname ? strdup(res->ai_canonname) : *argv;
	if (!hostname) {
		fprintf(stderr, "traceroute6: not enough core\n");
		exit(1);
	}
	if (res->ai_next) {
		if (getnameinfo(res->ai_addr, res->ai_addrlen, hbuf,
		    sizeof(hbuf), NULL, 0, NI_NUMERICHOST) != 0)
			strlcpy(hbuf, "?", sizeof(hbuf));
		fprintf(stderr, "traceroute6: Warning: %s has multiple "
		    "addresses; using %s\n", hostname, hbuf);
	}

	if (*++argv) {
		ep = NULL;
		errno = 0;
		datalen = strtoul(*argv, &ep, 0);
		if (errno || !*argv || *ep) {
			fprintf(stderr,
			    "traceroute6: invalid packet length.\n");
			exit(1);
		}
	}
	if (useicmp)
		minlen = ICMP6ECHOLEN + sizeof(struct tv32);
	else
		minlen = sizeof(struct opacket);
	if (datalen < minlen)
		datalen = minlen;
	else if (datalen >= MAXPACKET) {
		fprintf(stderr,
		    "traceroute6: packet size must be %d <= s < %ld.\n",
		    minlen, (long)MAXPACKET);
		exit(1);
	}
	outpacket = (struct opacket *)malloc((unsigned)datalen);
	if (!outpacket) {
		perror("malloc");
		exit(1);
	}
	(void) bzero((char *)outpacket, datalen);

	/* initialize msghdr for receiving packets */
	rcviov[0].iov_base = (caddr_t)packet;
	rcviov[0].iov_len = sizeof(packet);
	rcvmhdr.msg_name = (caddr_t)&Rcv;
	rcvmhdr.msg_namelen = sizeof(Rcv);
	rcvmhdr.msg_iov = rcviov;
	rcvmhdr.msg_iovlen = 1;
	rcvcmsglen = CMSG_SPACE(sizeof(struct in6_pktinfo)) +
	    CMSG_SPACE(sizeof(int));
	
	if ((rcvcmsgbuf = malloc(rcvcmsglen)) == NULL) {
		fprintf(stderr, "traceroute6: malloc failed\n");
		exit(1);
	}
	rcvmhdr.msg_control = (caddr_t) rcvcmsgbuf;
	rcvmhdr.msg_controllen = rcvcmsglen;

	if (options & SO_DEBUG)
		(void) setsockopt(rcvsock, SOL_SOCKET, SO_DEBUG,
		    (char *)&on, sizeof(on));
	if (options & SO_DONTROUTE)
		(void) setsockopt(rcvsock, SOL_SOCKET, SO_DONTROUTE,
		    (char *)&on, sizeof(on));

	/*
	 * Send UDP or ICMP
	 */
	if (useicmp) {
		sndsock = rcvsock;
	} else {
		if ((sndsock = socket(AF_INET6, SOCK_DGRAM, 0)) < 0) {
			perror("socket(SOCK_DGRAM)");
			exit(5);
		}
	}
#ifdef SO_SNDBUF
	i = datalen;
	if (setsockopt(sndsock, SOL_SOCKET, SO_SNDBUF, (char *)&i,
	    sizeof(i)) < 0) {
		perror("setsockopt(SO_SNDBUF)");
		exit(6);
	}
#endif /* SO_SNDBUF */
	if (options & SO_DEBUG)
		(void) setsockopt(sndsock, SOL_SOCKET, SO_DEBUG,
		    (char *)&on, sizeof(on));
	if (options & SO_DONTROUTE)
		(void) setsockopt(sndsock, SOL_SOCKET, SO_DONTROUTE,
		    (char *)&on, sizeof(on));
	if (rth) {/* XXX: there is no library to finalize the header... */
		rth->ip6r_len = rth->ip6r_segleft * 2;
		if (setsockopt(sndsock, IPPROTO_IPV6, IPV6_RTHDR,
		    (void *)rth, (rth->ip6r_len + 1) << 3)) {
			fprintf(stderr, "setsockopt(IPV6_RTHDR): %s\n",
			    strerror(errno));
			exit(1);
		}
	}

	/*
	 * Source selection
	 */
	bzero(&Src, sizeof(Src));
	if (source) {
		struct addrinfo hints, *res;
		int error;

		memset(&hints, 0, sizeof(hints));
		hints.ai_family = AF_INET6;
		hints.ai_socktype = SOCK_DGRAM;	/*dummy*/
		hints.ai_flags = AI_NUMERICHOST;
		error = getaddrinfo(source, "0", &hints, &res);
		if (error) {
			printf("traceroute6: %s: %s\n", source,
			    gai_strerror(error));
			exit(1);
		}
		if (res->ai_addrlen > sizeof(Src)) {
			printf("traceroute6: %s: %s\n", source,
			    gai_strerror(error));
			exit(1);
		}
		memcpy(&Src, res->ai_addr, res->ai_addrlen);
		freeaddrinfo(res);
	} else {
		struct sockaddr_in6 Nxt;
		int dummy;
		socklen_t len;

		Nxt = Dst;
		Nxt.sin6_port = htons(DUMMY_PORT);
		if (cmsg != NULL)
			bcopy(inet6_rthdr_getaddr(cmsg, 1), &Nxt.sin6_addr,
			    sizeof(Nxt.sin6_addr));
		if ((dummy = socket(AF_INET6, SOCK_DGRAM, 0)) < 0) {
			perror("socket");
			exit(1);
		}
		if (connect(dummy, (struct sockaddr *)&Nxt, Nxt.sin6_len) < 0) {
			perror("connect");
			exit(1);
		}
		len = sizeof(Src);
		if (getsockname(dummy, (struct sockaddr *)&Src, &len) < 0) {
			perror("getsockname");
			exit(1);
		}
		if (getnameinfo((struct sockaddr *)&Src, Src.sin6_len,
		    src0, sizeof(src0), NULL, 0, NI_NUMERICHOST)) {
			fprintf(stderr, "getnameinfo failed for source\n");
			exit(1);
		}
		source = src0;
		close(dummy);
	}

	Src.sin6_port = htons(0);
	if (bind(sndsock, (struct sockaddr *)&Src, Src.sin6_len) < 0) {
		perror("bind");
		exit(1);
	}

	{
		socklen_t len;

		len = sizeof(Src);
		if (getsockname(sndsock, (struct sockaddr *)&Src, &len) < 0) {
			perror("getsockname");
			exit(1);
		}
		srcport = ntohs(Src.sin6_port);
	}

	/*
	 * Message to users
	 */
	if (getnameinfo((struct sockaddr *)&Dst, Dst.sin6_len, hbuf,
	    sizeof(hbuf), NULL, 0, NI_NUMERICHOST))
		strlcpy(hbuf, "(invalid)", sizeof(hbuf));
	fprintf(stderr, "traceroute6");
	fprintf(stderr, " to %s (%s)", hostname, hbuf);
	if (source)
		fprintf(stderr, " from %s", source);
	fprintf(stderr, ", %lu hops max, %lu byte packets\n",
	    max_hops, datalen);
	(void) fflush(stderr);

	if (first_hop > 1)
		printf("Skipping %lu intermediate hops\n", first_hop - 1);

	/*
	 * Main loop
	 */
	for (hops = first_hop; hops <= max_hops; ++hops) {
		struct in6_addr lastaddr;
		int got_there = 0;
		int unreachable = 0;

		printf("%2lu ", hops);
		bzero(&lastaddr, sizeof(lastaddr));
		for (probe = 0; probe < nprobes; ++probe) {
			int cc;
			struct timeval t1, t2;

			(void) gettimeofday(&t1, NULL);
			send_probe(++seq, hops);
			while ((cc = wait_for_reply(rcvsock, &rcvmhdr))) {
				(void) gettimeofday(&t2, NULL);
				if ((i = packet_ok(&rcvmhdr, cc, seq))) {
					if (!IN6_ARE_ADDR_EQUAL(&Rcv.sin6_addr,
					    &lastaddr)) {
						print(&rcvmhdr, cc);
						lastaddr = Rcv.sin6_addr;
					}
					printf("  %g ms", deltaT(&t1, &t2));
					switch (i - 1) {
					case ICMP6_DST_UNREACH_NOROUTE:
						++unreachable;
						printf(" !N");
						break;
					case ICMP6_DST_UNREACH_ADMIN:
						++unreachable;
						printf(" !P");
						break;
					case ICMP6_DST_UNREACH_NOTNEIGHBOR:
						++unreachable;
						printf(" !S");
						break;
					case ICMP6_DST_UNREACH_ADDR:
						++unreachable;
						printf(" !A");
						break;
					case ICMP6_DST_UNREACH_NOPORT:
						if (rcvhlim >= 0 &&
						    rcvhlim <= 1)
							printf(" !");
						++got_there;
						break;
					}
					break;
				}
			}
			if (cc == 0)
				printf(" *");
			(void) fflush(stdout);
		}
		putchar('\n');
		if (got_there ||
		    (unreachable > 0 && unreachable >= ((nprobes + 1) / 2))) {
			exit(0);
		}
	}

	exit(0);
}
static int
gethostnamadr_async_run(struct async *as, struct async_res *ar)
{
	struct hostent	*e;
	int	i, n, r, type;
	FILE	*f;
	char	*toks[MAXTOKEN], addr[16], dname[MAXDNAME], *data;

    next:
	switch(as->as_state) {

	case ASR_STATE_INIT:

		if (as->as.hostnamadr.family != AF_INET &&
		    as->as.hostnamadr.family != AF_INET6) {
			ar->ar_h_errno = NETDB_INTERNAL;
			ar->ar_errno = EAFNOSUPPORT;
			async_set_state(as, ASR_STATE_HALT);
			break;
		}

		if ((as->as.hostnamadr.family == AF_INET &&
		     as->as.hostnamadr.addrlen != INADDRSZ) ||
		    (as->as.hostnamadr.family == AF_INET6 &&
		     as->as.hostnamadr.addrlen != IN6ADDRSZ)) {
			ar->ar_h_errno = NETDB_INTERNAL;
			ar->ar_errno = EINVAL;
			async_set_state(as, ASR_STATE_HALT);
			break;
		}

		if (as->as_type == ASR_GETHOSTBYNAME)
			async_set_state(as, ASR_STATE_NEXT_DOMAIN);
		else
			async_set_state(as, ASR_STATE_NEXT_DB);
		break;

	case ASR_STATE_NEXT_DOMAIN:

		r = asr_iter_domain(as, as->as.hostnamadr.name, dname, sizeof(dname));
		if (r == -1) {
			async_set_state(as, ASR_STATE_NOT_FOUND);
			break;
		}

		if (as->as.hostnamadr.dname)
			free(as->as.hostnamadr.dname);
		if ((as->as.hostnamadr.dname = strdup(dname)) == NULL) {
			ar->ar_h_errno = NETDB_INTERNAL;
			ar->ar_errno = errno;
			async_set_state(as, ASR_STATE_HALT);
		}

		as->as_db_idx = 0;
		async_set_state(as, ASR_STATE_NEXT_DB);
		break;

	case ASR_STATE_NEXT_DB:

		if (asr_iter_db(as) == -1) {
			if (as->as_type == ASR_GETHOSTBYNAME)
				async_set_state(as, ASR_STATE_NEXT_DOMAIN);
			else
				async_set_state(as, ASR_STATE_NOT_FOUND);
			break;
		}

		switch(AS_DB(as)) {

		case ASR_DB_DNS:

			/* Create a subquery to do the DNS lookup */

			if (as->as_type == ASR_GETHOSTBYNAME) {
				type = (as->as.hostnamadr.family == AF_INET) ?
				    T_A : T_AAAA;
				as->as.hostnamadr.subq = res_query_async_ctx(
				    as->as.hostnamadr.dname,
				    C_IN, type, NULL, 0, as->as_ctx);
			} else {
				addr_as_fqdn(as->as.hostnamadr.addr,
				    as->as.hostnamadr.family,
				    dname, sizeof(dname));
				as->as.hostnamadr.subq = res_query_async_ctx(
				    dname, C_IN, T_PTR, NULL, 0, as->as_ctx);
			}

			if (as->as.hostnamadr.subq == NULL) {
				ar->ar_errno = errno;
				ar->ar_h_errno = NETDB_INTERNAL;
				async_set_state(as, ASR_STATE_HALT);
				break;
			}

			async_set_state(as, ASR_STATE_SUBQUERY);
			break;

		case ASR_DB_FILE:

			/* Try to find a match in the host file */

			if ((f = fopen(as->as_ctx->ac_hostfile, "r")) == NULL)
				break;

			if (as->as_type == ASR_GETHOSTBYNAME)
				data = as->as.hostnamadr.dname;
			else
				data = as->as.hostnamadr.addr;

			if (( n = hostent_file_match(f, as->as_type,
			    as->as.hostnamadr.family,
			    as->as.hostnamadr.addrlen, data, addr,
			    toks, MAXTOKEN)) == -1) {
				fclose(f);
				break;
			}
			e = hostent_alloc(as->as.hostnamadr.family);
			if (e == NULL) {
				ar->ar_errno = errno;
				ar->ar_h_errno = NETDB_INTERNAL;
				async_set_state(as, ASR_STATE_HALT);
				break;
			}
			hostent_set_cname(e, toks[1], 0);
			for (i = 2; i < n; i ++)
				hostent_add_alias(e, toks[i], 0);
			hostent_add_addr(e, addr, e->h_length);
			fclose(f);

			ar->ar_h_errno = NETDB_SUCCESS;
			ar->ar_hostent = e;
			async_set_state(as, ASR_STATE_HALT);
			break;
		}
		break;

	case ASR_STATE_SUBQUERY:

		/* Run the DNS subquery. */

		if ((r = async_run(as->as.hostnamadr.subq, ar)) == ASYNC_COND)
			return (ASYNC_COND);

		/* Done. */
		as->as.hostnamadr.subq = NULL;

		if (ar->ar_datalen == -1) {
			async_set_state(as, ASR_STATE_NEXT_DB);
			break;
		}

		/* If we got a packet but no anwser, use the next DB. */
		if (ar->ar_count == 0) {
			free(ar->ar_data);
			async_set_state(as, ASR_STATE_NEXT_DB);
			break;
		}

		/* Read the hostent from the packet. */
		if ((e = hostent_alloc(as->as.hostnamadr.family)) == NULL) {
			ar->ar_errno = errno;
			ar->ar_h_errno = NETDB_INTERNAL;
			free(ar->ar_data);
			async_set_state(as, ASR_STATE_HALT);
			break;
		}

		if (as->as_type == ASR_GETHOSTBYADDR) {
			e->h_addr_list[0] = malloc(as->as.hostnamadr.addrlen);
			if (e->h_addr_list[0])
				memmove(e->h_addr_list[0],
				    as->as.hostnamadr.addr,
				    as->as.hostnamadr.addrlen);
		}

		hostent_from_packet(e, as->as_type, ar->ar_data,
		    ar->ar_datalen);
		free(ar->ar_data);

		/*
		 * No address found in the dns packet. The blocking version
		 * reports this as an error.
		 */
		if (as->as_type == ASR_GETHOSTBYNAME &&
		    e->h_addr_list[0] == NULL) {
			freehostent(e);
			async_set_state(as, ASR_STATE_NEXT_DB);
			break;
		}

		ar->ar_h_errno = NETDB_SUCCESS;
		ar->ar_hostent = e;
		async_set_state(as, ASR_STATE_HALT);
		break;

	case ASR_STATE_NOT_FOUND:
		ar->ar_errno = 0;
		ar->ar_h_errno = HOST_NOT_FOUND;
		async_set_state(as, ASR_STATE_HALT);
		break;

	case ASR_STATE_HALT:
		if (ar->ar_h_errno)
			ar->ar_hostent = NULL;
		else
			ar->ar_errno = 0;
		return (ASYNC_DONE);

	default:
		ar->ar_errno = EOPNOTSUPP;
		ar->ar_h_errno = NETDB_INTERNAL;
		ar->ar_gai_errno = EAI_SYSTEM;
		async_set_state(as, ASR_STATE_HALT);
                break;
	}
	goto next;
}
Exemple #27
0
/*
 * NAME:	conn->init()
 * DESCRIPTION:	initialize connection handling
 */
bool conn_init(int maxusers, char **thosts, char **bhosts, 
	unsigned short *tports, unsigned short *bports, int ntports, 
	int nbports)
{
# ifdef INET6
    struct sockaddr_in6 sin6;
# endif
    struct sockaddr_in sin;
    struct hostent *host;
    int n;
    connection *conn;
    bool ipv6, ipv4;
    int err;

    if (!ipa_init(maxusers)) {
	return FALSE;
    }

#ifdef NETWORK_EXTENSIONS
    addrtype = PF_INET;
#endif

    nusers = 0;
    
    maxfd = 0;
    FD_ZERO(&infds);
    FD_ZERO(&outfds);
    FD_ZERO(&waitfds);
    FD_SET(in, &infds);
    npackets = 0;
    closed = 0;

#ifndef NETWORK_EXTENSIONS
    ntdescs = ntports;
    if (ntports != 0) {
	tdescs = ALLOC(portdesc, ntports);
	memset(tdescs, -1, ntports * sizeof(portdesc));
    }
    nbdescs = nbports;
    if (nbports != 0) {
	bdescs = ALLOC(portdesc, nbports);
	memset(bdescs, -1, nbports * sizeof(portdesc));
	udescs = ALLOC(portdesc, nbports);
	memset(udescs, -1, nbports * sizeof(portdesc));
    }
#endif

# ifdef INET6
    memset(&sin6, '\0', sizeof(sin6));
    sin6.sin6_family = AF_INET6;
# endif
    memset(&sin, '\0', sizeof(sin));
    sin.sin_family = AF_INET;

    for (n = 0; n < ntdescs; n++) {
	/* telnet ports */
	ipv6 = FALSE;
	ipv4 = FALSE;
	if (thosts[n] == (char *) NULL) {
# ifdef INET6
	    sin6.sin6_addr = in6addr_any;
	    ipv6 = TRUE;
# endif
	    sin.sin_addr.s_addr = INADDR_ANY;
	    ipv4 = TRUE;
	} else {
# ifdef INET6
	    if (inet_pton(AF_INET6, thosts[n], &sin6) > 0) {
		ipv6 = TRUE;
	    } else {
# ifdef AI_DEFAULT
		host = getipnodebyname(thosts[n], AF_INET6, 0, &err);
		if (host != (struct hostent *) NULL) {
		    memcpy(&sin6.sin6_addr, host->h_addr, host->h_length);
		    ipv6 = TRUE;
		    freehostent(host);
		}
# else
		host = gethostbyname2(thosts[n], AF_INET6);
		if (host != (struct hostent *) NULL) {
		    memcpy(&sin6.sin6_addr, host->h_addr, host->h_length);
		    ipv6 = TRUE;
		}
# endif
	    }
# endif
	    if ((sin.sin_addr.s_addr=inet_addr(thosts[n])) != INADDR_NONE) {
		ipv4 = TRUE;
	    } else {
		host = gethostbyname(thosts[n]);
		if (host != (struct hostent *) NULL) {
		    memcpy(&sin.sin_addr, host->h_addr, host->h_length);
		    ipv4 = TRUE;
		}
	    }
	}

	if (!ipv6 && !ipv4) {
	    message("unknown host %s\012", thosts[n]);	/* LF */
	    return FALSE;
	}

# ifdef INET6
	if (ipv6 && !conn_port6(&tdescs[n].in6, SOCK_STREAM, &sin6, tports[n]))
	{
	    return FALSE;
	}
# endif
	if (ipv4 && !conn_port(&tdescs[n].in4, SOCK_STREAM, &sin, tports[n])) {
	    return FALSE;
	}
    }

    for (n = 0; n < nbdescs; n++) {
	/* binary ports */
	ipv6 = FALSE;
	ipv4 = FALSE;
	if (bhosts[n] == (char *) NULL) {
# ifdef INET6
	    sin6.sin6_addr = in6addr_any;
	    ipv6 = TRUE;
# endif
	    sin.sin_addr.s_addr = INADDR_ANY;
	    ipv4 = TRUE;
	} else {
# ifdef INET6
	    if (inet_pton(AF_INET6, bhosts[n], &sin6) > 0) {
		ipv6 = TRUE;
	    } else {
# ifdef AI_DEFAULT
		host = getipnodebyname(bhosts[n], AF_INET6, 0, &err);
		if (host != (struct hostent *) NULL) {
		    memcpy(&sin6.sin6_addr, host->h_addr, host->h_length);
		    ipv6 = TRUE;
		    freehostent(host);
		}
# else
		host = gethostbyname2(bhosts[n], AF_INET6);
		if (host != (struct hostent *) NULL) {
		    memcpy(&sin6.sin6_addr, host->h_addr, host->h_length);
		    ipv6 = TRUE;
		}
# endif
	    }
# endif
	    if ((sin.sin_addr.s_addr=inet_addr(bhosts[n])) != INADDR_NONE) {
		ipv4 = TRUE;
	    } else {
		host = gethostbyname(bhosts[n]);
		if (host != (struct hostent *) NULL) {
		    memcpy(&sin.sin_addr, host->h_addr, host->h_length);
		    ipv4 = TRUE;
		}
	    }
	}

	if (!ipv6 && !ipv4) {
	    message("unknown host %s\012", bhosts[n]);	/* LF */
	    return FALSE;
	}

# ifdef INET6
	if (ipv6) {
	    if (!conn_port6(&bdescs[n].in6, SOCK_STREAM, &sin6, bports[n])) {
		return FALSE;
	    }
	    if (!conn_port6(&udescs[n].in6, SOCK_DGRAM, &sin6, bports[n])) {
		return FALSE;
	    }
	}
# endif
	if (ipv4) {
	    if (!conn_port(&bdescs[n].in4, SOCK_STREAM, &sin, bports[n])) {
		return FALSE;
	    }
	    if (!conn_port(&udescs[n].in4, SOCK_DGRAM, &sin, bports[n])) {
		return FALSE;
	    }
	}
    }

    flist = (connection *) NULL;
#ifndef NETWORK_EXTENSIONS
    connections = ALLOC(connection, nusers = maxusers);
#else
    connections = ALLOC(connection, nusers = maxusers+1);
#endif
    for (n = nusers, conn = connections; n > 0; --n, conn++) {
	conn->fd = -1;
	conn->chain.next = (hte *) flist;
	flist = conn;
    }

#ifndef NETWORK_EXTENSIONS
    udphtab = ALLOC(connection*, udphtabsz = maxusers);
    memset(udphtab, '\0', udphtabsz * sizeof(connection*));
    chtab = ht_new(maxusers, UDPHASHSZ, TRUE);
#endif

    return TRUE;
}
Exemple #28
0
/* the ultimate(?) socat resolver function
 node: the address to be resolved; supported forms:
   1.2.3.4 (IPv4 address)
   [::2]   (IPv6 address)
   hostname (hostname resolving to IPv4 or IPv6 address)
   hostname.domain (fq hostname resolving to IPv4 or IPv6 address)
 service: the port specification; may be numeric or symbolic
 family: PF_INET, PF_INET6, or PF_UNSPEC permitting both
 socktype: SOCK_STREAM, SOCK_DGRAM
 protocol: IPPROTO_UDP, IPPROTO_TCP
 sau: an uninitialized storage for the resulting socket address
 returns: STAT_OK, STAT_RETRYLATER
*/
int xiogetaddrinfo(const char *node, const char *service,
		   int family, int socktype, int protocol,
		   union sockaddr_union *sau, socklen_t *socklen,
		   unsigned long res_opts0, unsigned long res_opts1) {
   int port = -1;	/* port number in network byte order */
   char *numnode = NULL;
   size_t nodelen;
   unsigned long save_res_opts = 0;
#if HAVE_GETADDRINFO
   struct addrinfo hints = {0};
   struct addrinfo *res = NULL;
#else /* HAVE_GETIPNODEBYNAME || nothing */
   struct hostent *host;
#endif
   int error_num;

#if HAVE_RESOLV_H
   if (res_opts0 | res_opts1) {
      if (!(_res.options & RES_INIT)) {
         Res_init();	/*!!! returns -1 on error */
      }
      save_res_opts = _res.options;
      _res.options &= ~res_opts0;
      _res.options |= res_opts1;
      Debug2("changed _res.options from 0x%lx to 0x%lx",
	     save_res_opts, _res.options);
   }
#endif /* HAVE_RESOLV_H */
   memset(sau, 0, *socklen);
   sau->soa.sa_family = family;

   /* if service is numeric we don't want to have a lookup (might take long
      with NIS), so we handle this specially */
   if (service && isdigit(service[0]&0xff)) {
      char *extra;
      port = htons(strtoul(service, &extra, 0));
      if (*extra != '\0') {
	 Warn2("xiogetaddrinfo(, \"%s\", ...): extra trailing data \"%s\"",
	       service, extra);
      }
      service = NULL; 
   }

   /* the resolver functions might handle numeric forms of node names by
      reverse lookup, that's not what we want.
      So we detect these and handle them specially */
   if (node && isdigit(node[0]&0xff)) {
#if HAVE_GETADDRINFO
      hints.ai_flags |= AI_NUMERICHOST;
#endif /* HAVE_GETADDRINFO */
      if (family == PF_UNSPEC) {
	 family = PF_INET;
#if HAVE_GETADDRINFO
      } else if (family == PF_INET6) {
	 /* map "explicitely" into IPv6 address space; getipnodebyname() does
	    this with AI_V4MAPPED, but not getaddrinfo() */
	 if ((numnode = Malloc(strlen(node)+7+1)) == NULL) {
#if HAVE_RESOLV_H
	    if (res_opts0 | res_opts1) {
	       _res.options = (_res.options & (~res_opts0&~res_opts1) |
			       save_res_opts& ( res_opts0| res_opts1));
	    }
#endif
	    return STAT_NORETRY;
	 }
	 sprintf(numnode, "::ffff:%s", node);
	 node = numnode;
	 hints.ai_flags |= AI_NUMERICHOST;
#endif /* HAVE_GETADDRINFO */
      }
#if WITH_IP6
   } else if (node && node[0] == '[' && node[(nodelen=strlen(node))-1]==']') {
      if ((numnode = Malloc(nodelen-1)) == NULL) {
#if HAVE_RESOLV_H
	 if (res_opts0 | res_opts1) {
	    _res.options = (_res.options & (~res_opts0&~res_opts1) |
			    save_res_opts& ( res_opts0| res_opts1));
	 }
#endif
	 return STAT_NORETRY;
      }
      strncpy(numnode, node+1, nodelen-2);
      numnode[nodelen-2] = '\0';
      node = numnode;
#if HAVE_GETADDRINFO
      hints.ai_flags |= AI_NUMERICHOST;
#endif /* HAVE_GETADDRINFO */
      if (family == PF_UNSPEC)  family = PF_INET6;
#endif /* WITH_IP6 */
   }

#if HAVE_GETADDRINFO
   if (node != NULL || service != NULL) {
      struct addrinfo *record;

      if (socktype != SOCK_STREAM && socktype != SOCK_DGRAM) {
	 /* actual socket type value is not supported - fallback to a good one */
	 socktype = SOCK_DGRAM;
      }
      if (protocol != IPPROTO_TCP && protocol != IPPROTO_UDP) {
	 /* actual protocol value is not supported - fallback to a good one */
	 if (socktype == SOCK_DGRAM) {
	    protocol = IPPROTO_UDP;
	 } else {
	    protocol = IPPROTO_TCP;
	 }
      }
      hints.ai_flags |= AI_PASSIVE;
      hints.ai_family = family;
      hints.ai_socktype = socktype;
      hints.ai_protocol = protocol;
      hints.ai_addrlen = 0;
      hints.ai_addr = NULL;
      hints.ai_canonname = NULL;
      hints.ai_next = NULL;

      if ((error_num = Getaddrinfo(node, service, &hints, &res)) != 0) {
	 Error7("getaddrinfo(\"%s\", \"%s\", {%d,%d,%d,%d}, {}): %s",
		node, service, hints.ai_flags, hints.ai_family,
		hints.ai_socktype, hints.ai_protocol,
		(error_num == EAI_SYSTEM)?
		strerror(errno):gai_strerror(error_num));
	 if (res != NULL)  freeaddrinfo(res);
	 if (numnode)  free(numnode);

#if HAVE_RESOLV_H
	 if (res_opts0 | res_opts1) {
	    _res.options = (_res.options & (~res_opts0&~res_opts1) |
			    save_res_opts& ( res_opts0| res_opts1));
	 }
#endif
	 return STAT_RETRYLATER;
      }
      service = NULL;	/* do not resolve later again */

      record = res;
      if (family == PF_UNSPEC && xioopts.preferred_ip == '0') {
	 /* we just take the first result */
	 family = res[0].ai_addr->sa_family;
      }
      if (family == PF_UNSPEC) {
	 int trypf;
	 trypf = (xioopts.preferred_ip=='6'?PF_INET6:PF_INET);
	 /* we must look for a matching entry */
	 while (record != NULL) {
	    if (record->ai_family == trypf) {
	       family = trypf;
	       break;	/* family and record set accordingly */
	    }
	    record = record->ai_next;
	 }
	 if (record == NULL) {
	    /* we did not find a "preferred" entry, take the first */
	    record = res;
	    family = res[0].ai_addr->sa_family;
	 }
      }

      switch (family) {
#if WITH_IP4
      case PF_INET:
	 if (*socklen > record->ai_addrlen) {
	    *socklen = record->ai_addrlen;
	 }
	 memcpy(&sau->ip4, record->ai_addr, *socklen);
	 break;
#endif /* WITH_IP4 */
#if WITH_IP6
      case PF_INET6:
#if _AIX
	 /* older AIX versions pass wrong length, so we correct it */
	 record->ai_addr->sa_len = sizeof(struct sockaddr_in6);
#endif
	 if (*socklen > record->ai_addrlen) {
	    *socklen = record->ai_addrlen;
	 }
	 memcpy(&sau->ip6, record->ai_addr, *socklen);
	 break;
#endif /* WITH_IP6 */
      default:
	 Error1("address resolved to unknown protocol family %d",
		record->ai_addr->sa_family);
	 break;
      }
      freeaddrinfo(res);
   } else {
      switch (family) {
#if WITH_IP4
      case PF_INET:  *socklen = sizeof(sau->ip4); break;
#endif /* WITH_IP4 */
#if WITH_IP6
      case PF_INET6: *socklen = sizeof(sau->ip6); break;
#endif /* WITH_IP6 */
      }
   }

#elif HAVE_GETIPNODEBYNAME /* !HAVE_GETADDRINFO */

   if (node != NULL) {
      /* first fallback is getipnodebyname() */
      if (family == PF_UNSPEC) {
#if WITH_IP4 && WITH_IP6
	 family = xioopts.default_ip=='6'?PF_INET6:PF_INET;
#elif WITH_IP6
	 family = PF_INET6;
#else
	 family = PF_INET;
#endif
      }
      host = Getipnodebyname(node, family, AI_V4MAPPED, &error_num);
      if (host == NULL) {
	 const static char ai_host_not_found[] = "Host not found";
	 const static char ai_no_address[]     = "No address";
	 const static char ai_no_recovery[]    = "No recovery";
	 const static char ai_try_again[]      = "Try again";
	 const char *error_msg = "Unknown error";
	 switch (error_num) {
	 case HOST_NOT_FOUND: error_msg = ai_host_not_found; break;
	 case NO_ADDRESS:     error_msg = ai_no_address;
	 case NO_RECOVERY:    error_msg = ai_no_recovery;
	 case TRY_AGAIN:      error_msg = ai_try_again;
	 }
	 Error2("getipnodebyname(\"%s\", ...): %s", node, error_msg);
      } else {
	 switch (family) {
#if WITH_IP4
	 case PF_INET:
	    *socklen = sizeof(sau->ip4);
	    sau->soa.sa_family = PF_INET;
	    memcpy(&sau->ip4.sin_addr, host->h_addr_list[0], 4);
	    break;
#endif
#if WITH_IP6
	 case PF_INET6:
	    *socklen = sizeof(sau->ip6);
	    sau->soa.sa_family = PF_INET6;
	    memcpy(&sau->ip6.sin6_addr, host->h_addr_list[0], 16);
	    break;
#endif
	 }
      }
      freehostent(host);
   }

#else /* !HAVE_GETIPNODEBYNAME */

   if (node != NULL) {
      /* this is not a typical IP6 resolver function - but Linux
	 "man gethostbyname" says that the only supported address type with
	 this function is AF_INET _at present_, so maybe this fallback will
	 be useful somewhere sometimesin a future even for IP6 */
      if (family == PF_UNSPEC) {
#if WITH_IP4 && WITH_IP6
	 family = xioopts.default_ip=='6'?PF_INET6:PF_INET;
#elif WITH_IP6
	 family = PF_INET6;
#else
	 family = PF_INET;
#endif
      }
      /*!!! try gethostbyname2 for IP6 */
      if ((host = Gethostbyname(node)) == NULL) {
	 Error2("gethostbyname(\"%s\"): %s", node,
		h_errno == NETDB_INTERNAL ? strerror(errno) :
		hstrerror(h_errno));
#if HAVE_RESOLV_H
	 if (res_opts0 | res_opts1) {
	    _res.options = (_res.options & (~res_opts0&~res_opts1) |
			    save_res_opts& ( res_opts0| res_opts1));
	 }
#endif
	 return STAT_RETRYLATER;
      }
      if (host->h_addrtype != family) {
	 Error2("xioaddrinfo(): \"%s\" does not resolve to %s",
		node, family==PF_INET?"IP4":"IP6");
      } else {
	 switch (family) {
#if WITH_IP4
	 case PF_INET:
	    *socklen = sizeof(sau->ip4);
	    sau->soa.sa_family = PF_INET;
	    memcpy(&sau->ip4.sin_addr, host->h_addr_list[0], 4);
	    break;
#endif /* WITH_IP4 */
#if WITH_IP6
	 case PF_INET6:
	    *socklen = sizeof(sau->ip6);
	    sau->soa.sa_family = PF_INET6;
	    memcpy(&sau->ip6.sin6_addr, host->h_addr_list[0], 16);
	    break;
#endif /* WITH_IP6 */
	 }
      }
   }

#endif

#if WITH_TCP || WITH_UDP
   if (service) {
      port = parseport(service, protocol);
   }
   if (port >= 0) {
      switch (family) {
#if WITH_IP4
      case PF_INET:  sau->ip4.sin_port  = port; break;
#endif /* WITH_IP4 */
#if WITH_IP6
      case PF_INET6: sau->ip6.sin6_port = port; break;
#endif /* WITH_IP6 */
      }
   }      
#endif /* WITH_TCP || WITH_UDP */

   if (numnode)  free(numnode);

#if HAVE_RESOLV_H
   if (res_opts0 | res_opts1) {
      _res.options = (_res.options & (~res_opts0&~res_opts1) |
		      save_res_opts& ( res_opts0| res_opts1));
   }
#endif /* HAVE_RESOLV_H */
   return STAT_OK;
}
/*
 * _hpmerge: merge 2 hostent structure, arguments will be freed
 */
static struct hostent *
_hpmerge(struct hostent *hp1, struct hostent *hp2, int *errp)
{
	int i, j;
	int naddr, nalias;
	char **pp;
	struct hostent *hp, hpbuf;
	char *aliases[MAXALIASES + 1], *addrs[MAXADDRS + 1];
	union inx_addr addrbuf[MAXADDRS];

	if (hp1 == NULL)
		return hp2;
	if (hp2 == NULL)
		return hp1;

#define	HP(i)	(i == 1 ? hp1 : hp2)
	hp = &hpbuf;
	hp->h_name = (hp1->h_name != NULL ? hp1->h_name : hp2->h_name);
	hp->h_aliases = aliases;
	nalias = 0;
	for (i = 1; i <= 2; i++) {
		if ((pp = HP(i)->h_aliases) == NULL)
			continue;
		for (; nalias < MAXALIASES && *pp != NULL; pp++) {
			/* check duplicates */
			for (j = 0; j < nalias; j++)
				if (strcasecmp(*pp, aliases[j]) == 0)
					break;
			if (j == nalias)
				aliases[nalias++] = *pp;
		}
	}
	aliases[nalias] = NULL;
#ifdef INET6
	if (hp1->h_length != hp2->h_length) {
		hp->h_addrtype = AF_INET6;
		hp->h_length = sizeof(struct in6_addr);
	} else {
#endif
		hp->h_addrtype = hp1->h_addrtype;
		hp->h_length = hp1->h_length;
#ifdef INET6
	}
#endif
	hp->h_addr_list = addrs;
	naddr = 0;
	for (i = 1; i <= 2; i++) {
		if ((pp = HP(i)->h_addr_list) == NULL)
			continue;
		if (HP(i)->h_length == hp->h_length) {
			while (naddr < MAXADDRS && *pp != NULL)
				addrs[naddr++] = *pp++;
		} else {
			/* copy IPv4 addr as mapped IPv6 addr */
			while (naddr < MAXADDRS && *pp != NULL) {
				MAPADDR(&addrbuf[naddr], *pp++);
				addrs[naddr] = (char *)&addrbuf[naddr];
				naddr++;
			}
		}
	}
	addrs[naddr] = NULL;
	hp = _hpcopy(hp, errp);
	freehostent(hp1);
	freehostent(hp2);
	return hp;
}
Exemple #30
0
//-----------------------------------------------------------------------------
//	process_server_prefs
//-----------------------------------------------------------------------------
static int process_server_prefs(struct vpn_params *params)
{
    u_int32_t		lval, len;
    u_char            str[MAXPATHLEN];   
	int				err ;
	struct hostent	*hostent;
	
    get_int_option(params->serverRef, kRASEntServer, kRASPropServerMaximumSessions, &lval, 0);
    if (lval)
        params->max_sessions = lval;
	len = sizeof(str);
    get_str_option(params->serverRef, kRASEntServer, kRASPropServerLogfile, str, sizeof(str), &len, (u_char*)default_log_path);
    if (str[0])
        memcpy(params->log_path, str, len + 1);

    get_int_option(params->serverRef, kRASEntServer, kRASPropServerVerboseLogging, &lval, 0);
    if (lval)
        params->log_verbose = lval;

	// Load balancing parameters
	get_int_option(params->serverRef, kRASEntServer, kRASPropServerLoadBalancingEnabled, &lval, 0);
	if (lval) {
		params->lb_enable = 1;
		
		// will determine the interface from the cluster address
		//len = sizeof(str);
		//get_str_option(params->serverRef, kRASEntServer, kRASPropServerLoadBalancingInterface, str, sizeof(str), &len, "en1");
		//strncpy(params->lb_interface, str, sizeof(params->lb_interface));

		// is priority really useful ?
		//get_int_option(params->serverRef, kRASEntServer, kRASPropServerLoadBalancingPriority, &lval, 5);
		//if (lval < 1) lval = 1;
		//else if (lval > LB_MAX_PRIORITY) lval = LB_MAX_PRIORITY;
		//params->lb_priority = lval;
		
		get_int_option(params->serverRef, kRASEntServer, kRASPropServerLoadBalancingPort, &lval, LB_DEFAULT_PORT);
		params->lb_port = htons(lval);
		len = sizeof(str);
		get_str_option(params->serverRef, kRASEntServer, kRASPropServerLoadBalancingAddress, str, sizeof(str), &len, empty_str);
		// ask the system to look up the given name.
		hostent = getipnodebyname ((char*)str, AF_INET, 0, &err);
		if (!hostent) {
			vpnlog(LOG_ERR, "Incorrect Load Balancing address found '%s'\n", str);
			params->lb_enable = 0;
			
		}
		else {
			struct sockaddr_in src, dst;
			
			params->lb_cluster_address = *(struct in_addr *)hostent->h_addr_list[0];
			freehostent(hostent);
			
			bzero(&dst, sizeof(dst));
			dst.sin_family = PF_INET;
			dst.sin_len = sizeof(dst);
			dst.sin_addr = params->lb_cluster_address;
		
			// look for the interface and primary address of the cluster address			
			if (get_route_interface((struct sockaddr *)&src, (struct sockaddr *)&dst, params->lb_interface)) {
			
				vpnlog(LOG_ERR, "Cannot get load balancing redirect address and interface (errno = %d)\n", errno);
				params->lb_enable = 0;
			}

			params->lb_redirect_address = src.sin_addr;

			
		}
	}
	
    return 0;
}