/*
 * 32bit Socket syscall emulation. Based on arch/sparc64/kernel/sys_sparc32.c.
 *
 * Copyright (C) 2000		VA Linux Co
 * Copyright (C) 2000		Don Dugger <n0ano@valinux.com>
 * Copyright (C) 1999 		Arun Sharma <arun.sharma@intel.com>
 * Copyright (C) 1997,1998 	Jakub Jelinek (jj@sunsite.mff.cuni.cz)
 * Copyright (C) 1997 		David S. Miller (davem@caip.rutgers.edu)
 * Copyright (C) 2000		Hewlett-Packard Co.
 * Copyright (C) 2000		David Mosberger-Tang <davidm@hpl.hp.com>
 * Copyright (C) 2000,2001	Andi Kleen, SuSE Labs
 */

#include <linux/kernel.h>
#include <linux/fs.h>
#include <linux/types.h>
#include <linux/file.h>
#include <linux/icmpv6.h>
#include <linux/socket.h>
#include <linux/syscalls.h>
#include <linux/filter.h>
#include <linux/compat.h>
#include <linux/netfilter_ipv4/ip_tables.h>
#include <linux/security.h>

#include <net/scm.h>
#include <net/sock.h>
#include <asm/uaccess.h>
#include <net/compat.h>

static inline int iov_from_user_compat_to_kern(struct iovec *kiov,
					  struct compat_iovec __user *uiov32,
					  int niov)
{
	int tot_len = 0;

	while (niov > 0) {
		compat_uptr_t buf;
		compat_size_t len;

		if (get_user(len, &uiov32->iov_len) ||
		   get_user(buf, &uiov32->iov_base)) {
			tot_len = -EFAULT;
			break;
		}
		tot_len += len;
		kiov->iov_base = compat_ptr(buf);
		kiov->iov_len = (__kernel_size_t) len;
		uiov32++;
		kiov++;
		niov--;
	}
	return tot_len;
}

int get_compat_msghdr(struct msghdr *kmsg, struct compat_msghdr __user *umsg)
{
	compat_uptr_t tmp1, tmp2, tmp3;

	if (!access_ok(VERIFY_READ, umsg, sizeof(*umsg)) ||
	    __get_user(tmp1, &umsg->msg_name) ||
	    __get_user(kmsg->msg_namelen, &umsg->msg_namelen) ||
	    __get_user(tmp2, &umsg->msg_iov) ||
	    __get_user(kmsg->msg_iovlen, &umsg->msg_iovlen) ||
	    __get_user(tmp3, &umsg->msg_control) ||
	    __get_user(kmsg->msg_controllen, &umsg->msg_controllen) ||
	    __get_user(kmsg->msg_flags, &umsg->msg_flags))
		return -EFAULT;
	kmsg->msg_name = compat_ptr(tmp1);
	kmsg->msg_iov = compat_ptr(tmp2);
	kmsg->msg_control = compat_ptr(tmp3);
	return 0;
}

/* I've named the args so it is easy to tell whose space the pointers are in. */
int verify_compat_iovec(struct msghdr *kern_msg, struct iovec *kern_iov,
		   char *kern_address, int mode)
{
	int tot_len;

	if (kern_msg->msg_namelen) {
		if (mode==VERIFY_READ) {
			int err = move_addr_to_kernel(kern_msg->msg_name,
						      kern_msg->msg_namelen,
						      kern_address);
			if (err < 0)
				return err;
		}
		kern_msg->msg_name = kern_address;
	} else
		kern_msg->msg_name = NULL;

	tot_len = iov_from_user_compat_to_kern(kern_iov,
					  (struct compat_iovec __user *)kern_msg->msg_iov,
					  kern_msg->msg_iovlen);
	if (tot_len >= 0)
		kern_msg->msg_iov = kern_iov;

	return tot_len;
}

/* Bleech... */
#define CMSG_COMPAT_ALIGN(len)	ALIGN((len), sizeof(s32))

#define CMSG_COMPAT_DATA(cmsg)				\
	((void __user *)((char __user *)(cmsg) + CMSG_COMPAT_ALIGN(sizeof(struct compat_cmsghdr))))
#define CMSG_COMPAT_SPACE(len)				\
	(CMSG_COMPAT_ALIGN(sizeof(struct compat_cmsghdr)) + CMSG_COMPAT_ALIGN(len))
#define CMSG_COMPAT_LEN(len)				\
	(CMSG_COMPAT_ALIGN(sizeof(struct compat_cmsghdr)) + (len))

#define CMSG_COMPAT_FIRSTHDR(msg)			\
	(((msg)->msg_controllen) >= sizeof(struct compat_cmsghdr) ?	\
	 (struct compat_cmsghdr __user *)((msg)->msg_control) :		\
	 (struct compat_cmsghdr __user *)NULL)

#define CMSG_COMPAT_OK(ucmlen, ucmsg, mhdr) \
	((ucmlen) >= sizeof(struct compat_cmsghdr) && \
	 (ucmlen) <= (unsigned long) \
	 ((mhdr)->msg_controllen - \
	  ((char *)(ucmsg) - (char *)(mhdr)->msg_control)))

static inline struct compat_cmsghdr __user *cmsg_compat_nxthdr(struct msghdr *msg,
		struct compat_cmsghdr __user *cmsg, int cmsg_len)
{
	char __user *ptr = (char __user *)cmsg + CMSG_COMPAT_ALIGN(cmsg_len);
	if ((unsigned long)(ptr + 1 - (char __user *)msg->msg_control) >
			msg->msg_controllen)
		return NULL;
	return (struct compat_cmsghdr __user *)ptr;
}

/* There is a lot of hair here because the alignment rules (and
 * thus placement) of cmsg headers and length are different for
 * 32-bit apps.  -DaveM
 */
int cmsghdr_from_user_compat_to_kern(struct msghdr *kmsg, struct sock *sk,
			       unsigned char *stackbuf, int stackbuf_size)
{
	struct compat_cmsghdr __user *ucmsg;
	struct cmsghdr *kcmsg, *kcmsg_base;
	compat_size_t ucmlen;
	__kernel_size_t kcmlen, tmp;
	int err = -EFAULT;

	kcmlen = 0;
	kcmsg_base = kcmsg = (struct cmsghdr *)stackbuf;
	ucmsg = CMSG_COMPAT_FIRSTHDR(kmsg);
	while (ucmsg != NULL) {
		if (get_user(ucmlen, &ucmsg->cmsg_len))
			return -EFAULT;

		/* Catch bogons. */
		if (!CMSG_COMPAT_OK(ucmlen, ucmsg, kmsg))
			return -EINVAL;

		tmp = ((ucmlen - CMSG_COMPAT_ALIGN(sizeof(*ucmsg))) +
		       CMSG_ALIGN(sizeof(struct cmsghdr)));
		tmp = CMSG_ALIGN(tmp);
		kcmlen += tmp;
		ucmsg = cmsg_compat_nxthdr(kmsg, ucmsg, ucmlen);
	}
	if (kcmlen == 0)
		return -EINVAL;

	/* The kcmlen holds the 64-bit version of the control length.
	 * It may not be modified as we do not stick it into the kmsg
	 * until we have successfully copied over all of the data
	 * from the user.
	 */
	if (kcmlen > stackbuf_size)
		kcmsg_base = kcmsg = sock_kmalloc(sk, kcmlen, GFP_KERNEL);
	if (kcmsg == NULL)
		return -ENOBUFS;

	/* Now copy them over neatly. */
	memset(kcmsg, 0, kcmlen);
	ucmsg = CMSG_COMPAT_FIRSTHDR(kmsg);
	while (ucmsg != NULL) {
		if (__get_user(ucmlen, &ucmsg->cmsg_len))
			goto Efault;
		if (!CMSG_COMPAT_OK(ucmlen, ucmsg, kmsg))
			goto Einval;
		tmp = ((ucmlen - CMSG_COMPAT_ALIGN(sizeof(*ucmsg))) +
		       CMSG_ALIGN(sizeof(struct cmsghdr)));
		if ((char *)kcmsg_base + kcmlen - (char *)kcmsg < CMSG_ALIGN(tmp))
			goto Einval;
		kcmsg->cmsg_len = tmp;
		tmp = CMSG_ALIGN(tmp);
		if (__get_user(kcmsg->cmsg_level, &ucmsg->cmsg_level) ||
		    __get_user(kcmsg->cmsg_type, &ucmsg->cmsg_type) ||
		    copy_from_user(CMSG_DATA(kcmsg),
				   CMSG_COMPAT_DATA(ucmsg),
				   (ucmlen - CMSG_COMPAT_ALIGN(sizeof(*ucmsg)))))
			goto Efault;

		/* Advance. */
		kcmsg = (struct cmsghdr *)((char *)kcmsg + tmp);
		ucmsg = cmsg_compat_nxthdr(kmsg, ucmsg, ucmlen);
	}

	/* Ok, looks like we made it.  Hook it up and return success. */
	kmsg->msg_control = kcmsg_base;
	kmsg->msg_controllen = kcmlen;
	return 0;

Einval:
	err = -EINVAL;
Efault:
	if (kcmsg_base != (struct cmsghdr *)stackbuf)
		sock_kfree_s(sk, kcmsg_base, kcmlen);
	return err;
}

int put_cmsg_compat(struct msghdr *kmsg, int level, int type, int len, void *data)
{
	struct compat_timeval ctv;
	struct compat_timespec cts;
	struct compat_cmsghdr __user *cm = (struct compat_cmsghdr __user *) kmsg->msg_control;
	struct compat_cmsghdr cmhdr;
	int cmlen;

	if (cm == NULL || kmsg->msg_controllen < sizeof(*cm)) {
		kmsg->msg_flags |= MSG_CTRUNC;
		return 0; /* XXX: return error? check spec. */
	}

	if (level == SOL_SOCKET && type == SO_TIMESTAMP) {
		struct timeval *tv = (struct timeval *)data;
		ctv.tv_sec = tv->tv_sec;
		ctv.tv_usec = tv->tv_usec;
		data = &ctv;
		len = sizeof(ctv);
	}
	if (level == SOL_SOCKET && type == SO_TIMESTAMPNS) {
		struct timespec *ts = (struct timespec *)data;
		cts.tv_sec = ts->tv_sec;
		cts.tv_nsec = ts->tv_nsec;
		data = &cts;
		len = sizeof(cts);
	}

	cmlen = CMSG_COMPAT_LEN(len);
	if (kmsg->msg_controllen < cmlen) {
		kmsg->msg_flags |= MSG_CTRUNC;
		cmlen = kmsg->msg_controllen;
	}
	cmhdr.cmsg_level = level;
	cmhdr.cmsg_type = type;
	cmhdr.cmsg_len = cmlen;

	if (copy_to_user(cm, &cmhdr, sizeof cmhdr))
		return -EFAULT;
	if (copy_to_user(CMSG_COMPAT_DATA(cm), data, cmlen - sizeof(struct compat_cmsghdr)))
		return -EFAULT;
	cmlen = CMSG_COMPAT_SPACE(len);
	if (kmsg->msg_controllen < cmlen)
		cmlen = kmsg->msg_controllen;
	kmsg->msg_control += cmlen;
	kmsg->msg_controllen -= cmlen;
	return 0;
}

void scm_detach_fds_compat(struct msghdr *kmsg, struct scm_cookie *scm)
{
	struct compat_cmsghdr __user *cm = (struct compat_cmsghdr __user *) kmsg->msg_control;
	int fdmax = (kmsg->msg_controllen - sizeof(struct compat_cmsghdr)) / sizeof(int);
	int fdnum = scm->fp->count;
	struct file **fp = scm->fp->fp;
	int __user *cmfptr;
	int err = 0, i;

	if (fdnum < fdmax)
		fdmax = fdnum;

	for (i = 0, cmfptr = (int __user *) CMSG_COMPAT_DATA(cm); i < fdmax; i++, cmfptr++) {
		int new_fd;
		err = security_file_receive(fp[i]);
		if (err)
			break;
		err = get_unused_fd_flags(MSG_CMSG_CLOEXEC & kmsg->msg_flags
					  ? O_CLOEXEC : 0);
		if (err < 0)
			break;
		new_fd = err;
		err = put_user(new_fd, cmfptr);
		if (err) {
			put_unused_fd(new_fd);
			break;
		}
		/* Bump the usage count and install the file. */
		get_file(fp[i]);
		fd_install(new_fd, fp[i]);
	}

	if (i > 0) {
		int cmlen = CMSG_COMPAT_LEN(i * sizeof(int));
		err = put_user(SOL_SOCKET, &cm->cmsg_level);
		if (!err)
			err = put_user(SCM_RIGHTS, &cm->cmsg_type);
		if (!err)
			err = put_user(cmlen, &cm->cmsg_len);
		if (!err) {
			cmlen = CMSG_COMPAT_SPACE(i * sizeof(int));
			kmsg->msg_control += cmlen;
			kmsg->msg_controllen -= cmlen;
		}
	}
	if (i < fdnum)
		kmsg->msg_flags |= MSG_CTRUNC;

	/*
	 * All of the files that fit in the message have had their
	 * usage counts incremented, so we just free the list.
	 */
	__scm_destroy(scm);
}

/*
 * For now, we assume that the compatibility and native version
 * of struct ipt_entry are the same - sfr.  FIXME
 */
struct compat_ipt_replace {
	char			name[IPT_TABLE_MAXNAMELEN];
	u32			valid_hooks;
	u32			num_entries;
	u32			size;
	u32			hook_entry[NF_IP_NUMHOOKS];
	u32			underflow[NF_IP_NUMHOOKS];
	u32			num_counters;
	compat_uptr_t		counters;	/* struct ipt_counters * */
	struct ipt_entry	entries[0];
};

static int do_netfilter_replace(int fd, int level, int optname,
				char __user *optval, int optlen)
{
	struct compat_ipt_replace __user *urepl;
	struct ipt_replace __user *repl_nat;
	char name[IPT_TABLE_MAXNAMELEN];
	u32 origsize, tmp32, num_counters;
	unsigned int repl_nat_size;
	int ret;
	int i;
	compat_uptr_t ucntrs;

	urepl = (struct compat_ipt_replace __user *)optval;
	if (get_user(origsize, &urepl->size))
		return -EFAULT;

	/* Hack: Causes ipchains to give correct error msg --RR */
	if (optlen != sizeof(*urepl) + origsize)
		return -ENOPROTOOPT;

	/* XXX Assumes that size of ipt_entry is the same both in
	 *     native and compat environments.
	 */
	repl_nat_size = sizeof(*repl_nat) + origsize;
	repl_nat = compat_alloc_user_space(repl_nat_size);

	ret = -EFAULT;
	if (put_user(origsize, &repl_nat->size))
		goto out;

	if (!access_ok(VERIFY_READ, urepl, optlen) ||
	    !access_ok(VERIFY_WRITE, repl_nat, optlen))
		goto out;

	if (__copy_from_user(name, urepl->name, sizeof(urepl->name)) ||
	    __copy_to_user(repl_nat->name, name, sizeof(repl_nat->name)))
		goto out;

	if (__get_user(tmp32, &urepl->valid_hooks) ||
	    __put_user(tmp32, &repl_nat->valid_hooks))
		goto out;

	if (__get_user(tmp32, &urepl->num_entries) ||
	    __put_user(tmp32, &repl_nat->num_entries))
		goto out;

	if (__get_user(num_counters, &urepl->num_counters) ||
	    __put_user(num_counters, &repl_nat->num_counters))
		goto out;

	if (__get_user(ucntrs, &urepl->counters) ||
	    __put_user(compat_ptr(ucntrs), &repl_nat->counters))
		goto out;

	if (__copy_in_user(&repl_nat->entries[0],
			   &urepl->entries[0],
			   origsize))
		goto out;

	for (i = 0; i < NF_IP_NUMHOOKS; i++) {
		if (__get_user(tmp32, &urepl->hook_entry[i]) ||
		    __put_user(tmp32, &repl_nat->hook_entry[i]) ||
		    __get_user(tmp32, &urepl->underflow[i]) ||
		    __put_user(tmp32, &repl_nat->underflow[i]))
			goto out;
	}

	/*
	 * Since struct ipt_counters just contains two u_int64_t members
	 * we can just do the access_ok check here and pass the (converted)
	 * pointer into the standard syscall.  We hope that the pointer is
	 * not misaligned ...
	 */
	if (!access_ok(VERIFY_WRITE, compat_ptr(ucntrs),
		       num_counters * sizeof(struct ipt_counters)))
		goto out;


	ret = sys_setsockopt(fd, level, optname,
			     (char __user *)repl_nat, repl_nat_size);

out:
	return ret;
}

/*
 * A struct sock_filter is architecture independent.
 */
struct compat_sock_fprog {
	u16		len;
	compat_uptr_t	filter;		/* struct sock_filter * */
};

static int do_set_attach_filter(struct socket *sock, int level, int optname,
				char __user *optval, int optlen)
{
	struct compat_sock_fprog __user *fprog32 = (struct compat_sock_fprog __user *)optval;
	struct sock_fprog __user *kfprog = compat_alloc_user_space(sizeof(struct sock_fprog));
	compat_uptr_t ptr;
	u16 len;

	if (!access_ok(VERIFY_READ, fprog32, sizeof(*fprog32)) ||
	    !access_ok(VERIFY_WRITE, kfprog, sizeof(struct sock_fprog)) ||
	    __get_user(len, &fprog32->len) ||
	    __get_user(ptr, &fprog32->filter) ||
	    __put_user(len, &kfprog->len) ||
	    __put_user(compat_ptr(ptr), &kfprog->filter))
		return -EFAULT;

	return sock_setsockopt(sock, level, optname, (char __user *)kfprog,
			      sizeof(struct sock_fprog));
}

static int do_set_sock_timeout(struct socket *sock, int level,
		int optname, char __user *optval, int optlen)
{
	struct compat_timeval __user *up = (struct compat_timeval __user *) optval;
	struct timeval ktime;
	mm_segment_t old_fs;
	int err;

	if (optlen < sizeof(*up))
		return -EINVAL;
	if (!access_ok(VERIFY_READ, up, sizeof(*up)) ||
	    __get_user(ktime.tv_sec, &up->tv_sec) ||
	    __get_user(ktime.tv_usec, &up->tv_usec))
		return -EFAULT;
	old_fs = get_fs();
	set_fs(KERNEL_DS);
	err = sock_setsockopt(sock, level, optname, (char *) &ktime, sizeof(ktime));
	set_fs(old_fs);

	return err;
}

static int compat_sock_setsockopt(struct socket *sock, int level, int optname,
				char __user *optval, int optlen)
{
	if (optname == SO_ATTACH_FILTER)
		return do_set_attach_filter(sock, level, optname,
					    optval, optlen);
	if (optname == SO_RCVTIMEO || optname == SO_SNDTIMEO)
		return do_set_sock_timeout(sock, level, optname, optval, optlen);

	return sock_setsockopt(sock, level, optname, optval, optlen);
}

asmlinkage long compat_sys_setsockopt(int fd, int level, int optname,
				char __user *optval, int optlen)
{
	int err;
	struct socket *sock;

	if (level == SOL_IPV6 && optname == IPT_SO_SET_REPLACE)
		return do_netfilter_replace(fd, level, optname,
					    optval, optlen);

	if (optlen < 0)
		return -EINVAL;

	if ((sock = sockfd_lookup(fd, &err))!=NULL)
	{
		err = security_socket_setsockopt(sock,level,optname);
		if (err) {
			sockfd_put(sock);
			return err;
		}

		if (level == SOL_SOCKET)
			err = compat_sock_setsockopt(sock, level,
					optname, optval, optlen);
		else if (sock->ops->compat_setsockopt)
			err = sock->ops->compat_setsockopt(sock, level,
					optname, optval, optlen);
		else
			err = sock->ops->setsockopt(sock, level,
					optname, optval, optlen);
		sockfd_put(sock);
	}
	return err;
}

static int do_get_sock_timeout(struct socket *sock, int level, int optname,
		char __user *optval, int __user *optlen)
{
	struct compat_timeval __user *up;
	struct timeval ktime;
	mm_segment_t old_fs;
	int len, err;

	up = (struct compat_timeval __user *) optval;
	if (get_user(len, optlen))
		return -EFAULT;
	if (len < sizeof(*up))
		return -EINVAL;
	len = sizeof(ktime);
	old_fs = get_fs();
	set_fs(KERNEL_DS);
	err = sock_getsockopt(sock, level, optname, (char *) &ktime, &len);
	set_fs(old_fs);

	if (!err) {
		if (put_user(sizeof(*up), optlen) ||
		    !access_ok(VERIFY_WRITE, up, sizeof(*up)) ||
		    __put_user(ktime.tv_sec, &up->tv_sec) ||
		    __put_user(ktime.tv_usec, &up->tv_usec))
			err = -EFAULT;
	}
	return err;
}

static int compat_sock_getsockopt(struct socket *sock, int level, int optname,
				char __user *optval, int __user *optlen)
{
	if (optname == SO_RCVTIMEO || optname == SO_SNDTIMEO)
		return do_get_sock_timeout(sock, level, optname, optval, optlen);
	return sock_getsockopt(sock, level, optname, optval, optlen);
}

int compat_sock_get_timestamp(struct sock *sk, struct timeval __user *userstamp)
{
	struct compat_timeval __user *ctv =
			(struct compat_timeval __user*) userstamp;
	int err = -ENOENT;
	struct timeval tv;

	if (!sock_flag(sk, SOCK_TIMESTAMP))
		sock_enable_timestamp(sk);
	tv = ktime_to_timeval(sk->sk_stamp);
	if (tv.tv_sec == -1)
		return err;
	if (tv.tv_sec == 0) {
		sk->sk_stamp = ktime_get_real();
		tv = ktime_to_timeval(sk->sk_stamp);
	}
	err = 0;
	if (put_user(tv.tv_sec, &ctv->tv_sec) ||
			put_user(tv.tv_usec, &ctv->tv_usec))
		err = -EFAULT;
	return err;
}
EXPORT_SYMBOL(compat_sock_get_timestamp);

int compat_sock_get_timestampns(struct sock *sk, struct timespec __user *userstamp)
{
	struct compat_timespec __user *ctv =
			(struct compat_timespec __user*) userstamp;
	int err = -ENOENT;
	struct timespec ts;

	if (!sock_flag(sk, SOCK_TIMESTAMP))
		sock_enable_timestamp(sk);
	ts = ktime_to_timespec(sk->sk_stamp);
	if (ts.tv_sec == -1)
		return err;
	if (ts.tv_sec == 0) {
		sk->sk_stamp = ktime_get_real();
		ts = ktime_to_timespec(sk->sk_stamp);
	}
	err = 0;
	if (put_user(ts.tv_sec, &ctv->tv_sec) ||
			put_user(ts.tv_nsec, &ctv->tv_nsec))
		err = -EFAULT;
	return err;
}
EXPORT_SYMBOL(compat_sock_get_timestampns);

asmlinkage long compat_sys_getsockopt(int fd, int level, int optname,
				char __user *optval, int __user *optlen)
{
	int err;
	struct socket *sock;

	if ((sock = sockfd_lookup(fd, &err))!=NULL)
	{
		err = security_socket_getsockopt(sock, level,
							   optname);
		if (err) {
			sockfd_put(sock);
			return err;
		}

		if (level == SOL_SOCKET)
			err = compat_sock_getsockopt(sock, level,
					optname, optval, optlen);
		else if (sock->ops->compat_getsockopt)
			err = sock->ops->compat_getsockopt(sock, level,
					optname, optval, optlen);
		else
			err = sock->ops->getsockopt(sock, level,
					optname, optval, optlen);
		sockfd_put(sock);
	}
	return err;
}
/* Argument list sizes for compat_sys_socketcall */
#define AL(x) ((x) * sizeof(u32))
static unsigned char nas[18]={AL(0),AL(3),AL(3),AL(3),AL(2),AL(3),
				AL(3),AL(3),AL(4),AL(4),AL(4),AL(6),
				AL(6),AL(2),AL(5),AL(5),AL(3),AL(3)};
#undef AL

asmlinkage long compat_sys_sendmsg(int fd, struct compat_msghdr __user *msg, unsigned flags)
{
	return sys_sendmsg(fd, (struct msghdr __user *)msg, flags | MSG_CMSG_COMPAT);
}

asmlinkage long compat_sys_recvmsg(int fd, struct compat_msghdr __user *msg, unsigned int flags)
{
	return sys_recvmsg(fd, (struct msghdr __user *)msg, flags | MSG_CMSG_COMPAT);
}

asmlinkage long compat_sys_socketcall(int call, u32 __user *args)
{
	int ret;
	u32 a[6];
	u32 a0, a1;

	if (call < SYS_SOCKET || call > SYS_RECVMSG)
		return -EINVAL;
	if (copy_from_user(a, args, nas[call]))
		return -EFAULT;
	a0 = a[0];
	a1 = a[1];

	switch (call) {
	case SYS_SOCKET:
		ret = sys_socket(a0, a1, a[2]);
		break;
	case SYS_BIND:
		ret = sys_bind(a0, compat_ptr(a1), a[2]);
		break;
	case SYS_CONNECT:
		ret = sys_connect(a0, compat_ptr(a1), a[2]);
		break;
	case SYS_LISTEN:
		ret = sys_listen(a0, a1);
		break;
	case SYS_ACCEPT:
		ret = sys_accept(a0, compat_ptr(a1), compat_ptr(a[2]));
		break;
	case SYS_GETSOCKNAME:
		ret = sys_getsockname(a0, compat_ptr(a1), compat_ptr(a[2]));
		break;
	case SYS_GETPEERNAME:
		ret = sys_getpeername(a0, compat_ptr(a1), compat_ptr(a[2]));
		break;
	case SYS_SOCKETPAIR:
		ret = sys_socketpair(a0, a1, a[2], compat_ptr(a[3]));
		break;
	case SYS_SEND:
		ret = sys_send(a0, compat_ptr(a1), a[2], a[3]);
		break;
	case SYS_SENDTO:
		ret = sys_sendto(a0, compat_ptr(a1), a[2], a[3], compat_ptr(a[4]), a[5]);
		break;
	case SYS_RECV:
		ret = sys_recv(a0, compat_ptr(a1), a[2], a[3]);
		break;
	case SYS_RECVFROM:
		ret = sys_recvfrom(a0, compat_ptr(a1), a[2], a[3], compat_ptr(a[4]), compat_ptr(a[5]));
		break;
	case SYS_SHUTDOWN:
		ret = sys_shutdown(a0,a1);
		break;
	case SYS_SETSOCKOPT:
		ret = compat_sys_setsockopt(a0, a1, a[2],
				compat_ptr(a[3]), a[4]);
		break;
	case SYS_GETSOCKOPT:
		ret = compat_sys_getsockopt(a0, a1, a[2],
				compat_ptr(a[3]), compat_ptr(a[4]));
		break;
	case SYS_SENDMSG:
		ret = compat_sys_sendmsg(a0, compat_ptr(a1), a[2]);
		break;
	case SYS_RECVMSG:
		ret = compat_sys_recvmsg(a0, compat_ptr(a1), a[2]);
		break;
	default:
		ret = -EINVAL;
		break;
	}
	return ret;
}
