[PATCH 2/2 - 2.6.15]net:32 bit (socket layer) ioctl emulation for 64 bit kernels

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



x25 module patch

diff -uprN -X dontdiff linux-2.6.15-vanilla/include/net/x25.h
linux-2.6.15/include/net/x25.h
--- linux-2.6.15-vanilla/include/net/x25.h	2006-01-03 14:21:10.000000000
+1100
+++ linux-2.6.15/include/net/x25.h	2006-01-10 16:15:16.000000000 +1100
@@ -223,6 +223,18 @@ extern struct x25_route *x25_get_route(s
 extern struct net_device *x25_dev_get(char *);
 extern void x25_route_device_down(struct net_device *dev);
 extern int  x25_route_ioctl(unsigned int, void __user *);
+
+#ifdef CONFIG_COMPAT
+#include <linux/compat.h>
+
+struct x25_route_struct32{
+	struct x25_address address;
+	compat_uint_t   sigdigits;
+	char    device[200];
+};
+extern int  compat_x25_route_ioctl(unsigned int, struct
x25_route_struct32 __user *);
+#endif
+
 extern void x25_route_free(void);
 
 static __inline__ void x25_route_hold(struct x25_route *rt)
diff -uprN -X dontdiff linux-2.6.15-vanilla/net/x25/af_x25.c
linux-2.6.15/net/x25/af_x25.c
--- linux-2.6.15-vanilla/net/x25/af_x25.c	2006-01-10 16:06:29.000000000
+1100
+++ linux-2.6.15/net/x25/af_x25.c	2006-01-10 16:15:16.000000000 +1100
@@ -475,6 +475,12 @@ out:
 
 void x25_init_timers(struct sock *sk);
 
+#ifdef CONFIG_COMPAT
+#include "x25_ioctl_compat.c"
+#else
+#define compat_x25_ioctl NULL
+#endif
+
 static int x25_create(struct socket *sock, int protocol)
 {
 	struct sock *sk;
@@ -1403,7 +1409,7 @@ static struct proto_ops SOCKOPS_WRAPPED(
 	.getname =	x25_getname,
 	.poll =		datagram_poll,
 	.ioctl =	x25_ioctl,
-	.compat_ioctl=  NULL,
+	.compat_ioctl=  compat_x25_ioctl,
 	.listen =	x25_listen,
 	.shutdown =	sock_no_shutdown,
 	.setsockopt =	x25_setsockopt,
diff -uprN -X dontdiff linux-2.6.15-vanilla/net/x25/x25_ioctl_compat.c
linux-2.6.15/net/x25/x25_ioctl_compat.c
--- linux-2.6.15-vanilla/net/x25/x25_ioctl_compat.c	1970-01-01
10:00:00.000000000 +1000
+++ linux-2.6.15/net/x25/x25_ioctl_compat.c	2006-01-10
16:15:16.000000000 +1100
@@ -0,0 +1,264 @@
+#include <linux/compat.h>
+
+struct x25_subscrip_struct32{
+	char device[200-sizeof(compat_ulong_t)];
+	compat_ulong_t global_facil_mask;
+	compat_uint_t extended;
+};
+
+struct x25_facilities32{
+	compat_uint_t	winzize_in, winsize_out;
+	compat_uint_t	pacsize_in, packsize_out;
+	compat_uint_t	throughput;
+	compat_uint_t   reverse;
+};
+
+struct x25_calluserdata32 {
+	compat_uint_t 	cudlength;
+	unsigned char   cuddata[128];
+};
+
+struct x25_subaddr32 {
+	compat_uint_t 	cudmatchlength;
+};
+
+static int compat_x25_subscr_ioctl(unsigned int cmd,
+		struct x25_subscrip_struct32 __user *x25_subscr32)
+{
+	struct x25_subscrip_struct x25_subscr;
+	struct x25_neigh *nb;
+	struct net_device *dev;
+	int rc = -EINVAL;
+
+	if (cmd != SIOCX25GSUBSCRIP && cmd != SIOCX25SSUBSCRIP)
+		goto out;
+
+	rc = -EFAULT;
+	if(copy_from_user(&x25_subscr, x25_subscr32, sizeof(*x25_subscr32)))
+		goto out;
+
+	rc = -EINVAL;
+	if ((dev = x25_dev_get(x25_subscr.device)) == NULL)
+		goto out;
+
+	if ((nb = x25_get_neigh(dev)) == NULL)
+		goto out_dev_put;
+
+	dev_put(dev);
+
+	if(cmd == SIOCX25GSUBSCRIP) {
+		x25_subscr.extended		= nb->extended;
+		x25_subscr.global_facil_mask	 = nb->global_facil_mask;
+		rc = copy_to_user(x25_subscr32, &x25_subscr,
+				sizeof(*x25_subscr32)) ? -EFAULT : 0;
+	} else {
+		rc = -EINVAL;
+		if (!(x25_subscr.extended && x25_subscr.extended != 1)) {
+			rc = 0;
+			nb->extended		= x25_subscr.extended;
+			nb->global_facil_mask 	= x25_subscr.global_facil_mask;
+		}
+	}
+	x25_neigh_put(nb);
+out:
+	return rc;
+out_dev_put:
+	dev_put(dev);
+	goto out;
+}
+
+static int compat_x25_facility_ioctl(struct socket *sock, struct
x25_facilities32 __user *facilities32)
+{
+	struct sock *sk = sock->sk;
+	struct x25_sock *x25 = x25_sk(sk);
+	struct x25_facilities 	facilities;
+	int rc;
+	rc = -EFAULT;
+	if(copy_from_user(&facilities, facilities32, sizeof(*facilities32)))
+	       goto out;
+	rc = -EINVAL;
+	if (sk->sk_state != TCP_LISTEN &&
+		sk->sk_state != TCP_CLOSE)
+		goto out;
+	if (facilities.pacsize_in < X25_PS16 ||
+		facilities.pacsize_in > X25_PS4096)
+	       	goto out;
+	if (facilities.pacsize_out < X25_PS16 ||
+		facilities.pacsize_out > X25_PS4096)
+	       	goto out;
+	if (facilities.winsize_in < 1 ||
+		facilities.winsize_in > 127)
+	       	goto out;
+	if (facilities.throughput < 0x03 ||
+		facilities.throughput > 0xDD)
+	       	goto out;
+	if (facilities.reverse &&
+		(facilities.reverse | 0x81)!= 0x81)
+	       	goto out;
+       	x25->facilities = facilities;
+	rc = 0;
+out :
+	return rc;
+}
+
+static int compat_x25_get_facility_ioctl(struct socket *sock, struct
x25_facilities32 __user *facility32)
+{
+	struct sock *sk = sock->sk;
+	struct x25_sock *x25 = x25_sk(sk);
+	struct x25_facilities fac = x25->facilities;
+	int rc;
+
+	rc = copy_to_user(facility32, &fac, sizeof(fac)) ? -EFAULT : 0;
+	return rc;
+}
+
+static int compat_x25_cud_ioctl(struct socket *sock, struct
x25_calluserdata32 __user *calluserdata32)
+{
+	struct sock *sk = sock->sk;
+	struct x25_sock *x25 = x25_sk(sk);
+	struct x25_calluserdata calluserdata;
+	int rc;
+
+	rc = -EFAULT;
+	if(copy_from_user(&calluserdata, calluserdata32, sizeof
(*calluserdata32)))
+		goto out;
+
+	rc = -EINVAL;
+	if (calluserdata.cudlength > X25_MAX_CUD_LEN)
+		goto out;
+
+	x25->calluserdata = calluserdata;
+	rc = 0;
+out:
+	return rc;
+}
+
+static int compat_x25_get_cud_ioctl(struct socket *sock, struct
x25_calluserdata32 __user *calluserdata32)
+{
+	struct sock *sk = sock->sk;
+	struct x25_sock *x25 = x25_sk(sk);
+	struct x25_calluserdata cud = x25->calluserdata;
+	int rc;
+
+	rc = copy_to_user(calluserdata32, &cud, sizeof(cud))? -EFAULT : 0;
+	return rc;
+}
+
+static int compat_x25_cud_match_ioctl(struct socket *sock, struct
x25_subaddr32 __user *sub_addr32)
+{
+	struct sock *sk = sock->sk;
+	struct x25_sock *x25 = x25_sk(sk);
+	struct x25_subaddr sub_addr;
+	int rc;
+
+	rc = -EINVAL;
+	if(sk->sk_state != TCP_CLOSE)
+		goto out;
+	rc = -EFAULT;
+	if(copy_from_user(&sub_addr, sub_addr32, sizeof(*sub_addr32)))
+		goto out;
+	rc = -EINVAL;
+	if(sub_addr.cudmatchlength > X25_MAX_CUD_LEN)
+		goto out;
+	x25->cudmatchlength = sub_addr.cudmatchlength;
+	rc = 0;
+out:
+	return rc;
+}
+
+static int compat_x25_accept_ctrl(struct socket *sock, unsigned int
cmd)
+{
+	struct sock *sk = sock->sk;
+	struct x25_sock *x25 = x25_sk(sk);
+	int rc = -EINVAL;
+
+	switch(cmd){
+
+		case SIOCX25CALLACCPTAPPRV: {
+	    		rc = -EINVAL;
+			if (sk->sk_state != TCP_CLOSE)
+			       	break;
+		       	x25->accptapprv = X25_ALLOW_ACCPT_APPRV;
+		       	rc = 0;
+		       	break;
+		}
+
+		case SIOCX25SENDCALLACCPT: {
+			rc = -EINVAL;
+			if (sk->sk_state != TCP_ESTABLISHED)
+				break;
+			if (x25->accptapprv)
+				break;
+			x25_write_internal(sk, X25_CALL_ACCEPTED);
+			x25->state = X25_STATE_3;
+			rc = 0;
+			break;
+		}
+	}
+	return rc;
+}
+
+static int compat_x25_ioctl(struct socket *sock, unsigned int cmd,
unsigned long arg)
+{
+	void __user *argp = compat_ptr(arg);
+	int rc = -ENOIOCTLCMD;
+
+	switch(cmd) {
+		case TIOCOUTQ:
+		case TIOCINQ:
+		case SIOCGSTAMP:
+		case SIOCGIFADDR:
+		case SIOCSIFADDR:
+		case SIOCGIFDSTADDR:
+		case SIOCSIFDSTADDR:
+		case SIOCGIFBRDADDR:
+		case SIOCSIFBRDADDR:
+		case SIOCGIFNETMASK:
+		case SIOCSIFNETMASK:
+		case SIOCGIFMETRIC:
+		case SIOCSIFMETRIC:
+		case SIOCADDRT:
+		case SIOCDELRT:
+			rc = -EPERM;
+			if (!capable(CAP_NET_ADMIN))
+				break;
+			rc = compat_x25_route_ioctl(cmd, argp);
+				break;
+		case SIOCX25GSUBSCRIP:
+			rc = compat_x25_subscr_ioctl(cmd, argp);
+			break;
+		case SIOCX25SSUBSCRIP:
+			rc = -EPERM;
+			if (!capable(CAP_NET_ADMIN))
+				break;
+			rc = compat_x25_subscr_ioctl(cmd, argp);
+			break;
+		case SIOCX25GFACILITIES:
+			rc = compat_x25_get_facility_ioctl(sock, argp);
+			break;
+		case SIOCX25SFACILITIES:
+			rc = compat_x25_facility_ioctl(sock, argp);
+			break;
+		case SIOCX25GCALLUSERDATA:
+			rc = compat_x25_get_cud_ioctl(sock, argp);
+			break;
+		case SIOCX25SCALLUSERDATA:
+			rc = compat_x25_cud_ioctl(sock, argp);
+			break;
+		case SIOCX25GCAUSEDIAG:
+		case SIOCX25SCUDMATCHLEN:
+			rc = compat_x25_cud_match_ioctl(sock,argp);
+			break;
+		case SIOCX25CALLACCPTAPPRV:
+			rc = compat_x25_accept_ctrl(sock,SIOCX25CALLACCPTAPPRV);
+				break;
+		case SIOCX25SENDCALLACCPT:
+			rc = compat_x25_accept_ctrl(sock,SIOCX25SENDCALLACCPT);
+				break;
+		default:
+			rc = -ENOIOCTLCMD;
+			break;
+	}
+
+	return rc;
+}
diff -uprN -X dontdiff linux-2.6.15-vanilla/net/x25/x25_route.c
linux-2.6.15/net/x25/x25_route.c
--- linux-2.6.15-vanilla/net/x25/x25_route.c	2006-01-03
14:21:10.000000000 +1100
+++ linux-2.6.15/net/x25/x25_route.c	2006-01-10 16:15:16.000000000 +1100
@@ -204,6 +204,36 @@ out:
 	return rc;
 }
 
+#ifdef CONFIG_COMPAT
+
+int compat_x25_route_ioctl(unsigned int cmd, struct x25_route_struct32
__user *rt32)
+{
+	struct x25_route_struct rt;
+	struct net_device *dev;
+       	int rc = -EINVAL;
+
+	if (cmd != SIOCADDRT && cmd != SIOCDELRT)
+	     	goto out;
+
+	rc = -EFAULT;
+       	if(copy_from_user(&rt, rt32, sizeof(*rt32)))
+	      	goto out;
+
+	dev = x25_dev_get(rt.device);
+	if (!dev)
+	     	goto out;
+
+	if (cmd == SIOCADDRT)
+	       	rc = x25_add_route(&rt.address, rt.sigdigits, dev);
+       	else
+	       	rc = x25_del_route(&rt.address, rt.sigdigits, dev);
+       	dev_put(dev);
+out:
+       	return rc;
+
+}
+#endif
+
 /*
  *	Release all memory associated with X.25 routing structures.
  */

-
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to [email protected]
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/

[Index of Archives]     [Kernel Newbies]     [Netfilter]     [Bugtraq]     [Photo]     [Stuff]     [Gimp]     [Yosemite News]     [MIPS Linux]     [ARM Linux]     [Linux Security]     [Linux RAID]     [Video 4 Linux]     [Linux for the blind]     [Linux Resources]
  Powered by Linux