-----BEGIN PGP SIGNED MESSAGE-----
Hash: SHA1
Trying to send this to [EMAIL PROTECTED], listed in the kernel
source as the maintainer of the IPX code, got me a bounce, so I'll try posting
here.
I've taken it upon myself to get IPX networking up and running in Wine (the
Windows Emulator) for Linux. In the process, I have found that some games,
such as Descent 2, use a special broadcast destination network (0xffffffff)
which is not currently supported in the Linux kernel IPX code. Packet
analysis shows that the expected behavior is to direct a copy of the packet to
each network that a route is available for, setting the destination network
appropriately in the header.
The attached patch, taken against a 2.1.126 tree, implements this
functionality in what appears to me so far to be a safe and correct fashion.
I don't know what the chances are of this getting into the 2.1 tree still, but
here it is regardless. If it's judged an inappropriate addition to the
kernel, then I suppose I'll have to look for some other way to get the desired
results out of the userspace Wine code... :)
-Steve Langasek
- -doink-
-----BEGIN PGP SIGNATURE-----
Version: PGPfreeware 5.0i for non-commercial use
Charset: noconv
iQA/AwUBNkLx/7iSFNRrVpG8EQKuAQCgo99kAcs+VzQ+5Mk7URoj9aeAKcsAn3SB
rQquni+Z5N4aBYbZJViaJ3tP
=97yT
-----END PGP SIGNATURE-----
--- linux.old/net/ipx/af_ipx.c Tue Nov 3 21:53:46 1998
+++ linux/net/ipx/af_ipx.c Thu Nov 5 22:50:25 1998
@@ -2058,7 +2058,8 @@
struct sock *sk = sock->sk;
struct sockaddr_ipx *usipx=(struct sockaddr_ipx *)msg->msg_name;
struct sockaddr_ipx local_sipx;
- int retval;
+ ipx_route *rt = NULL;
+ int retval = -EINVAL;
int flags = msg->msg_flags;
if(sk->zapped)
@@ -2103,7 +2104,31 @@
memcpy(usipx->sipx_node,sk->protinfo.af_ipx.dest_addr.node,IPX_NODE_LEN);
}
- retval = ipxrtr_route_packet(sk, usipx, msg->msg_iov, len,
flags&MSG_DONTWAIT);
+ /* Handle the special case of the broadcast network number */
+ if (usipx->sipx_network == 0xFFFFFFFF) {
+ int tmp;
+ void *base;
+ __kernel_size_t iovlen;
+
+ if(ipx_routes == NULL)
+ return (-ENETUNREACH);
+
+ iovlen = msg->msg_iov->iov_len;
+ base = msg->msg_iov->iov_base;
+
+ for(rt = ipx_routes; rt; rt = rt->ir_next) {
+ msg->msg_iov->iov_len = iovlen;
+ msg->msg_iov->iov_base = base;
+
+ usipx->sipx_network = rt->ir_net;
+ tmp = ipxrtr_route_packet(sk, usipx, msg->msg_iov,
+ len, flags&MSG_DONTWAIT);
+ if(retval != 0)
+ retval = tmp;
+ }
+ } else
+ retval = ipxrtr_route_packet(sk, usipx, msg->msg_iov, len,
+ flags&MSG_DONTWAIT);
if(retval < 0)
return (retval);