-----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);
 

Reply via email to