Exemplo n.º 1
0
int
linux32_sys_setsockopt(struct lwp *l, const struct linux32_sys_setsockopt_args *uap, register_t *retval)
{
	/* {
		syscallarg(int) s;
		syscallarg(int) level;
		syscallarg(int) optname;
		syscallarg(netbsd32_voidp) optval;
		syscallarg(int) optlen;
	} */
	struct linux_sys_setsockopt_args ua;

	NETBSD32TO64_UAP(s);
	NETBSD32TO64_UAP(level);
	NETBSD32TO64_UAP(optname);
	NETBSD32TOP_UAP(optval, void);
	NETBSD32TO64_UAP(optlen);

	return linux_sys_setsockopt(l, &ua, retval);
}
/*
 * Entry point to all Linux socket calls. Just check which call to
 * make and take appropriate action.
 */
int
linux_sys_socketcall(struct lwp *l, const struct linux_sys_socketcall_args *uap, register_t *retval)
{
	/* {
		syscallarg(int) what;
		syscallarg(void *) args;
	} */
	struct linux_socketcall_dummy_args lda;
	int error;

	if (SCARG(uap, what) < 0 || SCARG(uap, what) > LINUX_MAX_SOCKETCALL)
		return ENOSYS;

	if ((error = copyin(SCARG(uap, args), &lda,
	    linux_socketcall[SCARG(uap, what)].argsize))) {
		DPRINTF(("copyin for %s failed %d\n",
		linux_socketcall[SCARG(uap, what)].name, error));
		return error;
	}

	ktrkuser(linux_socketcall[SCARG(uap, what)].name, &lda,
	    linux_socketcall[SCARG(uap, what)].argsize);

#ifdef DEBUG_LINUX
	/* dump the passed argument data */
	{
        	DPRINTF(("linux_socketcall('%s'): ",
		    linux_socketcall[SCARG(uap, what)].name));

		if (SCARG(uap, what) == LINUX_SYS_SOCKET) {
			DPRINTF(("[dom %d type %d proto %d]\n",
				lda.dummy_ints[0],
				lda.dummy_ints[1],
				lda.dummy_ints[2]));
		} else {
			int i, sz;
			u_int8_t *data = (u_int8_t *)&lda.dummy_ints[1];

			sz = linux_socketcall[SCARG(uap, what)].argsize
			    - sizeof(lda.dummy_ints[0]);

			DPRINTF(("socket %d [", lda.dummy_ints[0]));
			for(i=0; i < sz; i++)
				DPRINTF(("%02x ", data[i]));
			DPRINTF(("]\n"));
		}
	}
#endif

	switch (SCARG(uap, what)) {
	case LINUX_SYS_SOCKET:
		error = linux_sys_socket(l, (void *)&lda, retval);
		break;
	case LINUX_SYS_BIND:
		error = linux_sys_bind(l, (void *)&lda, retval);
		break;
	case LINUX_SYS_CONNECT:
		error = linux_sys_connect(l, (void *)&lda, retval);
		break;
	case LINUX_SYS_LISTEN:
		error = sys_listen(l, (void *)&lda, retval);
		break;
	case LINUX_SYS_ACCEPT:
		error = linux_sys_accept(l, (void *)&lda, retval);
		break;
	case LINUX_SYS_GETSOCKNAME:
		error = linux_sys_getsockname(l, (void *)&lda, retval);
		break;
	case LINUX_SYS_GETPEERNAME:
		error = linux_sys_getpeername(l, (void *)&lda, retval);
		break;
	case LINUX_SYS_SOCKETPAIR:
		error = linux_sys_socketpair(l, (void *)&lda, retval);
		break;
	case LINUX_SYS_SEND:
		error = linux_sys_send(l, (void *)&lda, retval);
		break;
	case LINUX_SYS_RECV:
		error = linux_sys_recv(l, (void *)&lda, retval);
		break;
	case LINUX_SYS_SENDTO:
		error = linux_sys_sendto(l, (void *)&lda, retval);
		break;
	case LINUX_SYS_RECVFROM:
		error = linux_sys_recvfrom(l, (void *)&lda, retval);
		break;
	case LINUX_SYS_SHUTDOWN:
		error = sys_shutdown(l, (void *)&lda, retval);
		break;
	case LINUX_SYS_SETSOCKOPT:
		error = linux_sys_setsockopt(l, (void *)&lda, retval);
		break;
	case LINUX_SYS_GETSOCKOPT:
		error = linux_sys_getsockopt(l, (void *)&lda, retval);
		break;
	case LINUX_SYS_SENDMSG:
		error = linux_sys_sendmsg(l, (void *)&lda, retval);
		break;
	case LINUX_SYS_RECVMSG:
		error = linux_sys_recvmsg(l, (void *)&lda, retval);
		break;
	default:
		error = ENOSYS;
		break;
	}

	DPRINTF(("sys_%s() = %d\n", linux_socketcall[SCARG(uap, what)].name,
	    error));
	return error;
}