Example #1
0
_PUBLIC_ ssize_t swrap_recvfrom(int s, void *buf, size_t len, int flags, struct sockaddr *from, socklen_t *fromlen)
{
	struct sockaddr_un un_addr;
	socklen_t un_addrlen = sizeof(un_addr);
	int ret;
	struct socket_info *si = find_socket_info(s);
	struct sockaddr_storage ss;
	socklen_t ss_len = sizeof(ss);

	if (!si) {
		return real_recvfrom(s, buf, len, flags, from, fromlen);
	}

	if (!from) {
		from = (struct sockaddr *)&ss;
		fromlen = &ss_len;
	}

	len = MIN(len, 1500);

	/* irix 6.4 forgets to null terminate the sun_path string :-( */
	memset(&un_addr, 0, sizeof(un_addr));
	ret = real_recvfrom(s, buf, len, flags, (struct sockaddr *)&un_addr, &un_addrlen);
	if (ret == -1) 
		return ret;

	if (sockaddr_convert_from_un(si, &un_addr, un_addrlen,
				     si->family, from, fromlen) == -1) {
		return -1;
	}

	swrap_dump_packet(si, from, SWRAP_RECVFROM, buf, ret);

	return ret;
}
Example #2
0
_PUBLIC_ int swrap_accept(int s, struct sockaddr *addr, socklen_t *addrlen)
{
	struct socket_info *parent_si, *child_si;
	int fd;
	struct sockaddr_un un_addr;
	socklen_t un_addrlen = sizeof(un_addr);
	struct sockaddr_un un_my_addr;
	socklen_t un_my_addrlen = sizeof(un_my_addr);
	struct sockaddr *my_addr;
	socklen_t my_addrlen, len;
	int ret;

	parent_si = find_socket_info(s);
	if (!parent_si) {
		return real_accept(s, addr, addrlen);
	}

	/* 
	 * assume out sockaddr have the same size as the in parent
	 * socket family
	 */
	my_addrlen = socket_length(parent_si->family);
	if (my_addrlen <= 0) {
		errno = EINVAL;
		return -1;
	}

	my_addr = (struct sockaddr *)malloc(my_addrlen);
	if (my_addr == NULL) {
		return -1;
	}

	memset(&un_addr, 0, sizeof(un_addr));
	memset(&un_my_addr, 0, sizeof(un_my_addr));

	ret = real_accept(s, (struct sockaddr *)&un_addr, &un_addrlen);
	if (ret == -1) {
		free(my_addr);
		return ret;
	}

	fd = ret;

	len = my_addrlen;
	ret = sockaddr_convert_from_un(parent_si, &un_addr, un_addrlen,
				       parent_si->family, my_addr, &len);
	if (ret == -1) {
		free(my_addr);
		close(fd);
		return ret;
	}

	child_si = (struct socket_info *)malloc(sizeof(struct socket_info));
	memset(child_si, 0, sizeof(*child_si));

	child_si->fd = fd;
	child_si->family = parent_si->family;
	child_si->type = parent_si->type;
	child_si->protocol = parent_si->protocol;
	child_si->bound = 1;
	child_si->is_server = 1;
	child_si->connected = 1;

	child_si->peername_len = len;
	child_si->peername = sockaddr_dup(my_addr, len);

	if (addr != NULL && addrlen != NULL) {
	    *addrlen = len;
	    if (*addrlen >= len)
		memcpy(addr, my_addr, len);
	    *addrlen = 0;
	}

	ret = real_getsockname(fd, (struct sockaddr *)&un_my_addr, &un_my_addrlen);
	if (ret == -1) {
		free(child_si);
		close(fd);
		return ret;
	}

	len = my_addrlen;
	ret = sockaddr_convert_from_un(child_si, &un_my_addr, un_my_addrlen,
				       child_si->family, my_addr, &len);
	if (ret == -1) {
		free(child_si);
		free(my_addr);
		close(fd);
		return ret;
	}

	child_si->myname_len = len;
	child_si->myname = sockaddr_dup(my_addr, len);
	free(my_addr);

	SWRAP_DLIST_ADD(sockets, child_si);

	swrap_dump_packet(child_si, addr, SWRAP_ACCEPT_SEND, NULL, 0);
	swrap_dump_packet(child_si, addr, SWRAP_ACCEPT_RECV, NULL, 0);
	swrap_dump_packet(child_si, addr, SWRAP_ACCEPT_ACK, NULL, 0);

	return fd;
}
Example #3
0
_PUBLIC_ int swrap_accept(int s, struct sockaddr *addr, socklen_t *addrlen)
{
	struct socket_info *parent_si, *child_si;
	int fd;
	struct sockaddr_un un_addr;
	socklen_t un_addrlen = sizeof(un_addr);
	struct sockaddr_un un_my_addr;
	socklen_t un_my_addrlen = sizeof(un_my_addr);
	struct sockaddr my_addr;
	socklen_t my_addrlen = sizeof(my_addr);
	int ret;

	parent_si = find_socket_info(s);
	if (!parent_si) {
		return real_accept(s, addr, addrlen);
	}

	memset(&un_addr, 0, sizeof(un_addr));
	memset(&un_my_addr, 0, sizeof(un_my_addr));
	memset(&my_addr, 0, sizeof(my_addr));

	ret = real_accept(s, (struct sockaddr *)&un_addr, &un_addrlen);
	if (ret == -1) return ret;

	fd = ret;

	ret = sockaddr_convert_from_un(parent_si, &un_addr, un_addrlen,
				       parent_si->family, addr, addrlen);
	if (ret == -1) {
		close(fd);
		return ret;
	}

	child_si = (struct socket_info *)malloc(sizeof(struct socket_info));
	memset(child_si, 0, sizeof(*child_si));

	child_si->fd = fd;
	child_si->family = parent_si->family;
	child_si->type = parent_si->type;
	child_si->protocol = parent_si->protocol;
	child_si->bound = 1;
	child_si->is_server = 1;

	ret = real_getsockname(fd, (struct sockaddr *)&un_my_addr, &un_my_addrlen);
	if (ret == -1) {
		free(child_si);
		close(fd);
		return ret;
	}

	ret = sockaddr_convert_from_un(child_si, &un_my_addr, un_my_addrlen,
				       child_si->family, &my_addr, &my_addrlen);
	if (ret == -1) {
		free(child_si);
		close(fd);
		return ret;
	}

	child_si->myname_len = my_addrlen;
	child_si->myname = sockaddr_dup(&my_addr, my_addrlen);

	child_si->peername_len = *addrlen;
	child_si->peername = sockaddr_dup(addr, *addrlen);

	SWRAP_DLIST_ADD(sockets, child_si);

	swrap_dump_packet(child_si, addr, SWRAP_ACCEPT_SEND, NULL, 0);
	swrap_dump_packet(child_si, addr, SWRAP_ACCEPT_RECV, NULL, 0);
	swrap_dump_packet(child_si, addr, SWRAP_ACCEPT_ACK, NULL, 0);

	return fd;
}