示例#1
0
static bool test_socket_wrapper_default_iface(struct torture_context *tctx)
{
	backup_env();
	unsetenv("SOCKET_WRAPPER_DEFAULT_IFACE");
	torture_assert_int_equal(tctx, socket_wrapper_default_iface(), 1, "unset");
	setenv("SOCKET_WRAPPER_DEFAULT_IFACE", "2", 1);
	torture_assert_int_equal(tctx, socket_wrapper_default_iface(), 2, "unset");
	setenv("SOCKET_WRAPPER_DEFAULT_IFACE", "bla", 1);
	torture_assert_int_equal(tctx, socket_wrapper_default_iface(), 1, "unset");
	restore_env();
	return true;
}
示例#2
0
static PyObject *py_socket_wrapper_default_interface(PyObject *self)
{
	unsigned int id;

	id = socket_wrapper_default_iface();

	return PyInt_FromLong(id);
}
示例#3
0
static int convert_in_un_alloc(struct socket_info *si, const struct sockaddr *inaddr, struct sockaddr_un *un,
			       int *bcast)
{
	char type = '\0';
	unsigned int prt;
	unsigned int iface;
	struct stat st;
	int is_bcast = 0;

	if (bcast) *bcast = 0;

	switch (si->family) {
	case AF_INET: {
		const struct sockaddr_in *in = 
		    (const struct sockaddr_in *)inaddr;
		unsigned int addr = ntohl(in->sin_addr.s_addr);
		char u_type = '\0';
		char d_type = '\0';
		char b_type = '\0';
		char a_type = '\0';

		prt = ntohs(in->sin_port);

		switch (si->type) {
		case SOCK_STREAM:
			u_type = SOCKET_TYPE_CHAR_TCP;
			d_type = SOCKET_TYPE_CHAR_TCP;
			break;
		case SOCK_DGRAM:
			u_type = SOCKET_TYPE_CHAR_UDP;
			d_type = SOCKET_TYPE_CHAR_UDP;
			a_type = SOCKET_TYPE_CHAR_UDP;
			b_type = SOCKET_TYPE_CHAR_UDP;
			break;
		}

		if (addr == 0) {
			/* 0.0.0.0 */
		 	is_bcast = 0;
			type = d_type;
			iface = socket_wrapper_default_iface();
		} else if (a_type && addr == 0xFFFFFFFF) {
			/* 255.255.255.255 only udp */
			is_bcast = 2;
			type = a_type;
			iface = socket_wrapper_default_iface();
		} else if (b_type && addr == 0x7FFFFFFF) {
			/* 127.255.255.255 only udp */
			is_bcast = 1;
			type = b_type;
			iface = socket_wrapper_default_iface();
		} else if ((addr & 0xFFFFFF00) == 0x7F000000) {
			/* 127.0.0.X */
			is_bcast = 0;
			type = u_type;
			iface = (addr & 0x000000FF);
		} else {
			errno = EADDRNOTAVAIL;
			return -1;
		}
		break;
	}
#ifdef HAVE_IPV6
	case AF_INET6: {
		const struct sockaddr_in6 *in = 
		    (const struct sockaddr_in6 *)inaddr;
		struct in6_addr cmp;

		switch (si->type) {
		case SOCK_STREAM:
			type = SOCKET_TYPE_CHAR_TCP_V6;
			break;
		case SOCK_DGRAM:
			type = SOCKET_TYPE_CHAR_UDP_V6;
			break;
		}

		/* XXX no multicast/broadcast */

		prt = ntohs(in->sin6_port);

		cmp = in->sin6_addr;
		cmp.s6_addr[15] = 0;
		if (IN6_IS_ADDR_UNSPECIFIED(&in->sin6_addr)) {
			iface = socket_wrapper_default_iface();
		} else if (IN6_ARE_ADDR_EQUAL(swrap_ipv6(), &cmp)) {
			iface = in->sin6_addr.s6_addr[15];
		} else {
			errno = EADDRNOTAVAIL;
			return -1;
		}

		break;
	}
#endif
	default:
		errno = EADDRNOTAVAIL;
		return -1;
	}


	if (bcast) *bcast = is_bcast;

	if (prt == 0) {
		/* handle auto-allocation of ephemeral ports */
		for (prt = 5001; prt < 10000; prt++) {
			snprintf(un->sun_path, sizeof(un->sun_path), "%s/"SOCKET_FORMAT, 
				 socket_wrapper_dir(), type, iface, prt);
			if (stat(un->sun_path, &st) == 0) continue;

			set_port(si->family, prt, si->myname);
			break;
		}
		if (prt == 10000) {
			errno = ENFILE;
			return -1;
		}
	}

	snprintf(un->sun_path, sizeof(un->sun_path), "%s/"SOCKET_FORMAT, 
		 socket_wrapper_dir(), type, iface, prt);
	return 0;
}
示例#4
0
static int convert_in_un_remote(struct socket_info *si, const struct sockaddr *inaddr, struct sockaddr_un *un,
				int *bcast)
{
	char type = '\0';
	unsigned int prt;
	unsigned int iface;
	int is_bcast = 0;

	if (bcast) *bcast = 0;

	switch (si->family) {
	case AF_INET: {
		const struct sockaddr_in *in = 
		    (const struct sockaddr_in *)inaddr;
		unsigned int addr = ntohl(in->sin_addr.s_addr);
		char u_type = '\0';
		char b_type = '\0';
		char a_type = '\0';

		switch (si->type) {
		case SOCK_STREAM:
			u_type = SOCKET_TYPE_CHAR_TCP;
			break;
		case SOCK_DGRAM:
			u_type = SOCKET_TYPE_CHAR_UDP;
			a_type = SOCKET_TYPE_CHAR_UDP;
			b_type = SOCKET_TYPE_CHAR_UDP;
			break;
		}

		prt = ntohs(in->sin_port);
		if (a_type && addr == 0xFFFFFFFF) {
			/* 255.255.255.255 only udp */
			is_bcast = 2;
			type = a_type;
			iface = socket_wrapper_default_iface();
		} else if (b_type && addr == 0x7FFFFFFF) {
			/* 127.255.255.255 only udp */
			is_bcast = 1;
			type = b_type;
			iface = socket_wrapper_default_iface();
		} else if ((addr & 0xFFFFFF00) == 0x7F000000) {
			/* 127.0.0.X */
			is_bcast = 0;
			type = u_type;
			iface = (addr & 0x000000FF);
		} else {
			errno = ENETUNREACH;
			return -1;
		}
		if (bcast) *bcast = is_bcast;
		break;
	}
#ifdef HAVE_IPV6
	case AF_INET6: {
		const struct sockaddr_in6 *in = 
		    (const struct sockaddr_in6 *)inaddr;
		struct in6_addr cmp;

		switch (si->type) {
		case SOCK_STREAM:
			type = SOCKET_TYPE_CHAR_TCP_V6;
			break;
		case SOCK_DGRAM:
			type = SOCKET_TYPE_CHAR_UDP_V6;
			break;
		}

		/* XXX no multicast/broadcast */

		prt = ntohs(in->sin6_port);

		cmp = in->sin6_addr;
		cmp.s6_addr[15] = 0;
		if (IN6_ARE_ADDR_EQUAL(swrap_ipv6(), &cmp)) {
			iface = in->sin6_addr.s6_addr[15];
		} else {
			errno = ENETUNREACH;
			return -1;
		}

		break;
	}
#endif
	default:
		errno = ENETUNREACH;
		return -1;
	}

	if (prt == 0) {
		errno = EINVAL;
		return -1;
	}

	if (is_bcast) {
		snprintf(un->sun_path, sizeof(un->sun_path), "%s/EINVAL", 
			 socket_wrapper_dir());
		/* the caller need to do more processing */
		return 0;
	}

	snprintf(un->sun_path, sizeof(un->sun_path), "%s/"SOCKET_FORMAT, 
		 socket_wrapper_dir(), type, iface, prt);

	return 0;
}
示例#5
0
/* using sendto() or connect() on an unbound socket would give the
   recipient no way to reply, as unlike UDP and TCP, a unix domain
   socket can't auto-assign emphemeral port numbers, so we need to
   assign it here.
   Note: this might change the family from ipv6 to ipv4
*/
static int swrap_auto_bind(struct socket_info *si, int family)
{
	struct sockaddr_un un_addr;
	int i;
	char type;
	int ret;
	int port;
	struct stat st;

	if (autobind_start_init != 1) {
		autobind_start_init = 1;
		autobind_start = getpid();
		autobind_start %= 50000;
		autobind_start += 10000;
	}

	un_addr.sun_family = AF_UNIX;

	switch (family) {
	case AF_INET: {
		struct sockaddr_in in;

		switch (si->type) {
		case SOCK_STREAM:
			type = SOCKET_TYPE_CHAR_TCP;
			break;
		case SOCK_DGRAM:
		    	type = SOCKET_TYPE_CHAR_UDP;
			break;
		default:
		    errno = ESOCKTNOSUPPORT;
		    return -1;
		}

		memset(&in, 0, sizeof(in));
		in.sin_family = AF_INET;
		in.sin_addr.s_addr = htonl(127<<24 | 
					   socket_wrapper_default_iface());

		si->myname_len = sizeof(in);
		si->myname = sockaddr_dup(&in, si->myname_len);
		break;
	}
#ifdef HAVE_IPV6
	case AF_INET6: {
		struct sockaddr_in6 in6;

		if (si->family != family) {
			errno = ENETUNREACH;
			return -1;
		}

		switch (si->type) {
		case SOCK_STREAM:
			type = SOCKET_TYPE_CHAR_TCP_V6;
			break;
		case SOCK_DGRAM:
		    	type = SOCKET_TYPE_CHAR_UDP_V6;
			break;
		default:
			errno = ESOCKTNOSUPPORT;
			return -1;
		}

		memset(&in6, 0, sizeof(in6));
		in6.sin6_family = AF_INET6;
		in6.sin6_addr = *swrap_ipv6();
		in6.sin6_addr.s6_addr[15] = socket_wrapper_default_iface();
		si->myname_len = sizeof(in6);
		si->myname = sockaddr_dup(&in6, si->myname_len);
		break;
	}
#endif
	default:
		errno = ESOCKTNOSUPPORT;
		return -1;
	}

	if (autobind_start > 60000) {
		autobind_start = 10000;
	}

	for (i=0;i<1000;i++) {
		port = autobind_start + i;
		snprintf(un_addr.sun_path, sizeof(un_addr.sun_path), 
			 "%s/"SOCKET_FORMAT, socket_wrapper_dir(),
			 type, socket_wrapper_default_iface(), port);
		if (stat(un_addr.sun_path, &st) == 0) continue;
		
		ret = real_bind(si->fd, (struct sockaddr *)&un_addr, sizeof(un_addr));
		if (ret == -1) return ret;

		si->tmp_path = strdup(un_addr.sun_path);
		si->bound = 1;
		autobind_start = port + 1;
		break;
	}
	if (i == 1000) {
		errno = ENFILE;
		return -1;
	}

	si->family = family;
	set_port(si->family, port, si->myname);

	return 0;
}
示例#6
0
static int convert_in_un_alloc(struct socket_info *si, const struct sockaddr_in *in, struct sockaddr_un *un,
			       int *bcast)
{
	char u_type = '\0';
	char d_type = '\0';
	char b_type = '\0';
	char a_type = '\0';
	char type = '\0';
	unsigned int addr= ntohl(in->sin_addr.s_addr);
	unsigned int prt = ntohs(in->sin_port);
	unsigned int iface;
	struct stat st;
	int is_bcast = 0;

	if (bcast) *bcast = 0;

	switch (si->type) {
	case SOCK_STREAM:
		u_type = SOCKET_TYPE_CHAR_TCP;
		d_type = SOCKET_TYPE_CHAR_TCP;
		break;
	case SOCK_DGRAM:
		u_type = SOCKET_TYPE_CHAR_UDP;
		d_type = SOCKET_TYPE_CHAR_UDP;
		a_type = SOCKET_TYPE_CHAR_UDP;
		b_type = SOCKET_TYPE_CHAR_UDP;
		break;
	}

	if (addr == 0) {
		/* 0.0.0.0 */
		is_bcast = 0;
		type = d_type;
		iface = socket_wrapper_default_iface();
	} else if (a_type && addr == 0xFFFFFFFF) {
		/* 255.255.255.255 only udp */
		is_bcast = 2;
		type = a_type;
		iface = socket_wrapper_default_iface();
	} else if (b_type && addr == 0x7FFFFFFF) {
		/* 127.255.255.255 only udp */
		is_bcast = 1;
		type = b_type;
		iface = socket_wrapper_default_iface();
	} else if ((addr & 0xFFFFFF00) == 0x7F000000) {
		/* 127.0.0.X */
		is_bcast = 0;
		type = u_type;
		iface = (addr & 0x000000FF);
	} else {
		errno = EADDRNOTAVAIL;
		return -1;
	}

	if (bcast) *bcast = is_bcast;

	if (prt == 0) {
		/* handle auto-allocation of ephemeral ports */
		for (prt = 5001; prt < 10000; prt++) {
			snprintf(un->sun_path, sizeof(un->sun_path), "%s/"SOCKET_FORMAT, 
				 socket_wrapper_dir(), type, iface, prt);
			if (stat(un->sun_path, &st) == 0) continue;

			((struct sockaddr_in *)si->myname)->sin_port = htons(prt);
			return 0;
		}
		errno = ENFILE;
		return -1;
	}

	snprintf(un->sun_path, sizeof(un->sun_path), "%s/"SOCKET_FORMAT, 
		 socket_wrapper_dir(), type, iface, prt);
	return 0;
}
示例#7
0
static int convert_in_un_remote(struct socket_info *si, const struct sockaddr_in *in, struct sockaddr_un *un,
				int *bcast)
{
	char u_type = '\0';
	char b_type = '\0';
	char a_type = '\0';
	char type = '\0';
	unsigned int addr= ntohl(in->sin_addr.s_addr);
	unsigned int prt = ntohs(in->sin_port);
	unsigned int iface;
	int is_bcast = 0;

	if (bcast) *bcast = 0;

	if (prt == 0) {
		errno = EINVAL;
		return -1;
	}

	switch (si->type) {
	case SOCK_STREAM:
		u_type = SOCKET_TYPE_CHAR_TCP;
		break;
	case SOCK_DGRAM:
		u_type = SOCKET_TYPE_CHAR_UDP;
		a_type = SOCKET_TYPE_CHAR_UDP;
		b_type = SOCKET_TYPE_CHAR_UDP;
		break;
	}

	if (a_type && addr == 0xFFFFFFFF) {
		/* 255.255.255.255 only udp */
		is_bcast = 2;
		type = a_type;
		iface = socket_wrapper_default_iface();
	} else if (b_type && addr == 0x7FFFFFFF) {
		/* 127.255.255.255 only udp */
		is_bcast = 1;
		type = b_type;
		iface = socket_wrapper_default_iface();
	} else if ((addr & 0xFFFFFF00) == 0x7F000000) {
		/* 127.0.0.X */
		is_bcast = 0;
		type = u_type;
		iface = (addr & 0x000000FF);
	} else {
		errno = ENETUNREACH;
		return -1;
	}

	if (bcast) *bcast = is_bcast;

	if (is_bcast) {
		snprintf(un->sun_path, sizeof(un->sun_path), "%s/EINVAL", 
			 socket_wrapper_dir());
		/* the caller need to do more processing */
		return 0;
	}

	snprintf(un->sun_path, sizeof(un->sun_path), "%s/"SOCKET_FORMAT, 
		 socket_wrapper_dir(), type, iface, prt);

	return 0;
}