Example #1
0
/* 30Dec2004, Replaces GOTO 'waitmsgtx' label */
static void waitmsgtx (int s)
{
   int index = 20;

	/* wait for I frame to be ACKed - K5JB/N5KNX */
	while (socklen (s,1) > 0 && index--)
		j2pause(500L);

	close_s(s);

	return;
}
Example #2
0
/*
 * NAME: inet_ntostr
 * USAGE: Convert a "sockaddr name" (SA) into a Hostname/p-addr
 * PLAIN ENGLISH: Convert getpeername() into "foo.bar.com"
 * ARGS: name - The socket address, possibly returned by getpeername().
 *       retval - A string to store the hostname/paddr (RETURN VALUE)
 *       size - The length of 'retval' in bytes
 * RETURN VALUE: "retval" is returned upon success
 *		 "empty_string" is returned for any error.
 *
 * NOTES: 'flags' should be set to NI_NAMEREQD if you don't want the remote
 *        host's p-addr if it does not have a DNS hostname.
 */
int	inet_ntostr (SA *name, char *host, int hsize, char *port, int psize, int flags)
{
	int	retval;
	socklen_t len;

	len = socklen(name);
	if ((retval = Getnameinfo(name, len, host, hsize, port, psize, flags | NI_NUMERICSERV))) {
		yell("Getnameinfo (sockaddr->p_addr): %s", gai_strerror(retval));
		return retval;
	}

	return 0;
}
Example #3
0
/*
 * NAME: inet_remotesockaddr
 * USAGE: Get a sockaddr of the specified host and port.
 * ARGS: family - The family whose sockaddr info is to be retrieved
 *       host - The host whose address shall be put in the sockaddr
 *       port - The port to put into the sockaddr -- MUST BE IN HOST ORDER!
 *       storage - Pointer to a sockaddr structure appropriate for family.
 */
static int	inet_remotesockaddr (int family, const char *host, const char *port, SS *storage, socklen_t *len)
{
	int	err;

	((SA *)storage)->sa_family = family;

	if ((err = inet_strton(host, port, (SA *)storage, 0)))
		return err;

	if ((*len = socklen((SA *)storage)) == 0)
		return -2;

	return 0;
}
Example #4
0
static int Connect (int fd, SA *addr)
{
	int	retval;

	set_non_blocking(fd);
	if ((retval = connect(fd, addr, socklen(addr))))
	{
	    if (errno != EINPROGRESS)
		syserr(-1, "Connect: connect(%d) failed: %s", fd, strerror(errno));
	    else
		retval = 0;
	}
	set_blocking(fd);
	return retval;
}
Example #5
0
void printaddr (struct sockaddr *sa)
    /*@modifies fileSystem@*/
{
    char buf[NI_MAXHOST];
    int err;

    printf ("%p ", (void *) sa);
    err = getnameinfo (sa, socklen (sa), buf, sizeof (buf), 0, 0,
		       NI_NUMERICHOST);
    if (err)
	printf ("<getnameinfo error %d: %s> family=%d",
		err, gai_strerror (err),
		sa->sa_family);
    else
	printf ("%s", buf);
}
Example #6
0
static const char *paddr (struct sockaddr *sa)
{
    static char buf[100];
    char portbuf[10];
    if (getnameinfo(sa, socklen(sa),
		    buf, sizeof(buf), portbuf, sizeof(portbuf),
		    NI_NUMERICHOST|NI_NUMERICSERV))
	strcpy(buf, "<unprintable>");
    else {
	unsigned int len = sizeof(buf) - strlen(buf);
	char *p = buf + strlen(buf);
	if (len > 2+strlen(portbuf)) {
	    *p++ = '.';
	    len--;
	    strncpy(p, portbuf, len);
	}
    }
    return buf;
}
Example #7
0
/*
 * NAME: inet_vhostsockaddr
 * USAGE: Get the sockaddr of the current virtual host, if one is in use.
 * ARGS: family - The family whose sockaddr info is to be retrieved
 *       storage - Pointer to a sockaddr structure appropriate for family.
 *       len - This will be set to the size of the sockaddr structure that
 *             was copied, or set to 0 if no virtual host is available in
 *             the given family.
 * NOTES: If "len" is set to 0, do not attempt to bind() 'storage'!
 */
int	inet_vhostsockaddr (int family, int port, SS *storage, socklen_t *len)
{
	char	p_port[12];
	char	*p = NULL;
	AI	hints, *res;
	int	err;

	/*
	 * If port == -1, then this is a client connection, so we punt
	 * if there is no virtual host name.  But if port is NOT zero, then
	 * the caller expects us to return a sockaddr they can bind() to, 
	 * so we need to use LocalHostName, even if it's NULL.  If you 
	 * return *len == 0 for port != -1, then /dcc breaks.
	 */
	if (family == AF_UNIX || (port == -1 && !LocalHostName))
	{
		*len = 0;
		return 0;		/* No vhost needed */
	}

	/*
	 * Can it really be this simple?
	 */
	memset(&hints, 0, sizeof(hints));
	hints.ai_family = family;
	hints.ai_socktype = SOCK_STREAM;
	if (port != -1) 
	{
		hints.ai_flags = AI_PASSIVE;
		snprintf(p_port, 12, "%u", port);
		p = p_port;
	}

	if ((err = Getaddrinfo(LocalHostName, p, &hints, &res)))
		return -10;
	memcpy(storage, res->ai_addr, res->ai_addrlen);
	*len = socklen((SA *)storage);
	return 0;
}
Example #8
0
/*
 * Bind a socket to a privileged IP port
 */
int
bindresvport_sa(int sd, struct sockaddr *sa)
{
	int res;
	static short port;
	struct sockaddr_storage myaddr;
	socklen_t salen;
	int i;

#define STARTPORT 600
#define ENDPORT (IPPORT_RESERVED - 1)
#define NPORTS	(ENDPORT - STARTPORT + 1)
	if (sa == NULL) {
		salen = sizeof(myaddr);
		sa = ss2sa(&myaddr);
		res = getsockname(sd, sa, &salen);
		if (res < 0)
			return (-1);
	}
	if (!sa_is_inet(sa)) {
		errno = EPFNOSUPPORT;
		return (-1);
	}
	if (port == 0) {
		port = (getpid() % NPORTS) + STARTPORT;
	}
	res = -1;
	errno = EADDRINUSE;
	for (i = 0; i < NPORTS && res < 0 && errno == EADDRINUSE; i++) {
		sa_setport(sa, htons(port++));
		if (port > ENDPORT) {
			port = STARTPORT;
		}
		res = bind(sd, sa, socklen(sa));
	}
	return (res);
}
Example #9
0
/*
 * NAME: inet_vhostsockaddr
 * USAGE: Get the sockaddr of the current virtual host, if one is in use.
 * ARGS: family - The family whose sockaddr info is to be retrieved
 *       storage - Pointer to a sockaddr structure appropriate for family.
 *       len - This will be set to the size of the sockaddr structure that
 *             was copied, or set to 0 if no virtual host is available in
 *             the given family.
 * NOTES: If "len" is set to 0, do not attempt to bind() 'storage'!
 */
int	inet_vhostsockaddr (int family, int port, const char *wanthost, SS *storage, socklen_t *len)
{
	char	p_port[12];
	char	*p = NULL;
	AI	hints, *res;
	int	err;
	const char *lhn;

	/*
	 * If port == -1, AND "wanthost" is NULL, then this is a client connection, 
	 * so we punt if there is no virtual host name.  But if port is NOT zero, 
	 * then the caller expects us to return a sockaddr they can bind() to, 
	 * so we need to use LocalIPv(4|6)HostName, even if it's NULL.  If you 
	 * return *len == 0 for port != -1, then /dcc breaks.
	 */
	if ((family == AF_UNIX) || 
            (family == AF_INET && port == -1 && empty(wanthost) && LocalIPv4HostName == NULL) 
#ifdef INET6
	 || (family == AF_INET6 && port == -1 && empty(wanthost) && LocalIPv6HostName == NULL)
#endif
									   )
	{
		*len = 0;
		return 0;		/* No vhost needed */
	}

	if (wanthost && *wanthost)
		lhn = wanthost;
	else if (family == AF_INET)
		lhn = LocalIPv4HostName;
#ifdef INET6
	else if (family == AF_INET6)
		lhn = LocalIPv6HostName;
#endif
	else
		lhn = NULL;

	/*
	 * Can it really be this simple?
	 */
	memset(&hints, 0, sizeof(hints));
	hints.ai_family = family;
	hints.ai_socktype = SOCK_STREAM;
	if (port != -1) 
	{
		hints.ai_flags = AI_PASSIVE;
		snprintf(p_port, 12, "%d", port);
		p = p_port;
	}

	if ((err = my_getaddrinfo(lhn, p, &hints, &res)))
	{
		syserr(-1, "inet_vhostsockaddr: my_getaddrinfo(%s,%s) failed: %s", 
				lhn, p, gai_strerror(err));
		return -1;
	}

	memcpy(storage, res->ai_addr, res->ai_addrlen);
	my_freeaddrinfo(res);
	*len = socklen((SA *)storage);
	return 0;
}
Example #10
0
long
pty_make_sane_hostname(const struct sockaddr *addr, int maxlen,
		       int strip_ldomain, int always_ipaddr, char **out)
{
    struct addrinfo *ai = 0;
    char addrbuf[NI_MAXHOST];
#ifdef HAVE_STRUCT_UTMP_UT_HOST
    struct utmp ut;
#else
    struct utmpx utx;
#endif
    char *cp, *domain;
    char lhost[MAXHOSTNAMELEN];
    size_t ut_host_len;

    /* Note that on some systems (e.g., AIX 4.3.3), we may get an IPv6
       address such as ::FFFF:18.18.1.71 when an IPv4 connection comes
       in.  That's okay; at least on AIX, getnameinfo will deal with
       that properly.  */

    *out = NULL;
    if (maxlen && maxlen < 16)
	/* assume they meant 16, otherwise IPv4 addr won't fit */
	maxlen = 16;
#ifdef HAVE_STRUCT_UTMP_UT_HOST
    ut_host_len = sizeof (ut.ut_host);
#else
    ut_host_len = sizeof (utx.ut_host);
#endif
    if (maxlen == 0)
	maxlen = ut_host_len;
    *out = malloc(ut_host_len);
    if (*out == NULL)
	return ENOMEM;

    if (always_ipaddr) {
    use_ipaddr:
	if (getnameinfo (addr, socklen (addr), addrbuf, sizeof (addrbuf),
			 (char *)0, 0, NI_NUMERICHOST) == 0)
	    strncpy(*out, addrbuf, ut_host_len);
	else
	    strncpy(*out, "??", ut_host_len);
	(*out)[ut_host_len - 1] = '\0';
	return 0;
    }

    /* If we didn't want to chop off the local domain, this would be
       much simpler -- just a single getnameinfo call and a strncpy.  */
    if (getnameinfo(addr, socklen (addr), addrbuf, sizeof (addrbuf),
		    (char *) NULL, 0, NI_NAMEREQD) != 0)
	goto use_ipaddr;
    downcase (addrbuf);
    if (strip_ldomain) {
	struct addrinfo hints;
	(void) gethostname(lhost, sizeof (lhost));
	memset (&hints, 0, sizeof (hints));
	hints.ai_family = PF_UNSPEC;
	hints.ai_flags = AI_CANONNAME;
	if (getaddrinfo(lhost, (char *)NULL, &hints, &ai) == 0
	    && ai != NULL) {
		if (ai->ai_canonname != NULL) {
			downcase (ai->ai_canonname);
			domain = strchr (ai->ai_canonname, '.');
			if (domain != NULL) {
				cp = strstr (addrbuf, domain);
				if (cp != NULL)
					*cp = '\0';
			}
		}
		freeaddrinfo (ai);
	}
    }
    strncpy(*out, addrbuf, ut_host_len);
    (*out)[ut_host_len - 1] = '\0';
    if (strlen(*out) >= maxlen)
	goto use_ipaddr;
    return 0;
}
Example #11
0
static int Connect (int fd, SA *addr)
{
	return connect(fd, addr, socklen(addr));
}
Example #12
0
/*
 * Solaris Kerberos
 * Same as krb5_sendto_kdc plus an extra arg to return the FQDN
 * of the KDC sent the request.
 * Caller (at top of stack) needs to free hostname_used.
 */
krb5_error_code
krb5_sendto_kdc2 (krb5_context context, const krb5_data *message,
		 const krb5_data *realm, krb5_data *reply,
		int *use_master, int tcp_only, char **hostname_used)
{
    krb5_error_code retval, retval2;
    struct addrlist addrs = ADDRLIST_INIT;	/* Solaris Kerberos */
    int socktype1 = 0, socktype2 = 0, addr_used;

    /*
     * find KDC location(s) for realm
     */

    /*
     * BUG: This code won't return "interesting" errors (e.g., out of mem,
     * bad config file) from locate_kdc.  KRB5_REALM_CANT_RESOLVE can be
     * ignored from one query of two, but if only one query is done, or
     * both return that error, it should be returned to the caller.  Also,
     * "interesting" errors (not KRB5_KDC_UNREACH) from sendto_{udp,tcp}
     * should probably be returned as well.
     */

    /*LINTED*/
    dprint("krb5_sendto_kdc(%d@%p, \"%D\", use_master=%d, tcp_only=%d)\n",
    /*LINTED*/
	   message->length, message->data, realm, *use_master, tcp_only);

    if (!tcp_only && context->udp_pref_limit < 0) {
	int tmp;
	retval = profile_get_integer(context->profile,
				     "libdefaults", "udp_preference_limit", 0,
				     DEFAULT_UDP_PREF_LIMIT, &tmp);
	if (retval)
	    return retval;
	if (tmp < 0)
	    tmp = DEFAULT_UDP_PREF_LIMIT;
	else if (tmp > HARD_UDP_LIMIT)
	    /* In the unlikely case that a *really* big value is
	       given, let 'em use as big as we think we can
	       support.  */
	    tmp = HARD_UDP_LIMIT;
	context->udp_pref_limit = tmp;
    }

    retval = (*use_master ? KRB5_KDC_UNREACH : KRB5_REALM_UNKNOWN);

    if (tcp_only)
	socktype1 = SOCK_STREAM, socktype2 = 0;
    else if (message->length <= context->udp_pref_limit)
	socktype1 = SOCK_DGRAM, socktype2 = SOCK_STREAM;
    else
	socktype1 = SOCK_STREAM, socktype2 = SOCK_DGRAM;

    retval = krb5_locate_kdc(context, realm, &addrs, *use_master, socktype1, 0);
    if (socktype2) {
	struct addrlist addrs2;

	retval2 = krb5_locate_kdc(context, realm, &addrs2, *use_master,
				  socktype2, 0);
#if 0
	if (retval2 == 0) {
	    (void) merge_addrlists(&addrs, &addrs2);
	    krb5int_free_addrlist(&addrs2);
	    retval = 0;
	} else if (retval == KRB5_REALM_CANT_RESOLVE) {
	    retval = retval2;
	}
#else
	retval = retval2;
	if (retval == 0) {
	    (void) merge_addrlists(&addrs, &addrs2);
	    krb5int_free_addrlist(&addrs2);
	}
#endif
    }

    if (addrs.naddrs > 0) {
	krb5_error_code err = 0;

        retval = krb5int_sendto (context, message, &addrs, 0, reply, 0, 0,
				 0, 0, &addr_used, check_for_svc_unavailable, &err);
	switch (retval) {
	case 0:
            /*
             * Set use_master to 1 if we ended up talking to a master when
             * we didn't explicitly request to
             */
            if (*use_master == 0) {
                struct addrlist addrs3;
                retval = krb5_locate_kdc(context, realm, &addrs3, 1, 
                                         addrs.addrs[addr_used].ai->ai_socktype,
                                         addrs.addrs[addr_used].ai->ai_family);
                if (retval == 0) {
		    if (in_addrlist(addrs.addrs[addr_used].ai, &addrs3))
			*use_master = 1;
                    krb5int_free_addrlist (&addrs3);
                }
            }

	    if (hostname_used) {
		struct sockaddr *sa;
		char buf[NI_MAXHOST];
		int err;

		*hostname_used = NULL;
		sa = addrs.addrs[addr_used].ai->ai_addr;
		err = getnameinfo (sa, socklen (sa), buf, sizeof (buf), 0, 0,
				AI_CANONNAME);
		if (err)
		    err = getnameinfo (sa, socklen (sa), buf,
				    sizeof (buf), 0, 0,
				    NI_NUMERICHOST);
		if (!err)
		    *hostname_used = strdup(buf);
	            /* don't sweat strdup fail */
	    }
            krb5int_free_addrlist (&addrs);
            return 0;
	default:
	    break;
	    /* Cases here are for constructing useful error messages.  */
	case KRB5_KDC_UNREACH:
	    if (err == KDC_ERR_SVC_UNAVAILABLE) {
		retval = KRB5KDC_ERR_SVC_UNAVAILABLE;
	    } else {
		krb5_set_error_message(context, retval,
				    dgettext(TEXT_DOMAIN,
				    "Cannot contact any KDC for realm '%.*s'"),
				    realm->length, realm->data);
	    }
	    break;
	}
        krb5int_free_addrlist (&addrs);
    }
    return retval;
}