patch-2.2.0-pre1 linux/net/ipx/af_ipx.c
Next file: linux/net/netrom/nr_dev.c
Previous file: linux/net/ipv6/af_inet6.c
Back to the patch index
Back to the overall index
- Lines: 162
- Date:
Mon Dec 28 11:06:44 1998
- Orig file:
v2.1.132/linux/net/ipx/af_ipx.c
- Orig date:
Thu Nov 19 09:56:29 1998
diff -u --recursive --new-file v2.1.132/linux/net/ipx/af_ipx.c linux/net/ipx/af_ipx.c
@@ -50,6 +50,9 @@
* Revision 0.39: SPX interfaces
* Revision 0.40: Tiny SIOCGSTAMP fix (chris@cybernet.co.nz)
* Revision 0.41: 802.2TR removed (p.norton@computer.org)
+ * Fixed connecting to primary net,
+ * Automatic binding on send & receive,
+ * Martijn van Oosterhout <kleptogimp@geocities.com>
*
* Protect the module by a MOD_INC_USE_COUNT/MOD_DEC_USE_COUNT
* pair. Also, now usage count is managed this way
@@ -450,7 +453,57 @@
struct sock *sock1 = NULL, *sock2 = NULL;
struct sk_buff *skb1 = NULL, *skb2 = NULL;
- sock1 = ipxitf_find_socket(intrfc, ipx->ipx_dest.sock);
+ if (intrfc == ipx_primary_net && ntohs(ipx->ipx_dest.sock) == 0x451)
+ {
+ /*
+ * The packet's target is a NCP connection handler. We want to
+ * hand it to the correct socket directly within the kernel,
+ * so that the mars_nwe packet distribution process
+ * does not have to do it. Here we only care about NCP and
+ * BURST packets.
+ * You might call this a hack, but believe me, you do not
+ * want a complete NCP layer in the kernel, and this is
+ * VERY fast as well.
+ */
+ int connection = 0;
+
+ if (*((char*)(ipx+1)) == 0x22 && *((char*)(ipx+1)+1) == 0x22)
+ {
+ /*
+ * The packet is a NCP request
+ */
+ connection = ( ((int) *((char*)(ipx+1)+5)) << 8 )
+ | (int) *((char*)(ipx+1)+3);
+ }
+ else if (*((char*)(ipx+1))== 0x77 && *((char*)(ipx+1)+1) == 0x77)
+ {
+ /*
+ * The packet is a BURST packet
+ */
+ connection = ( ((int) *((char*)(ipx+1)+9)) << 8 )
+ | (int) *((char*)(ipx+1)+8);
+ }
+
+ if (connection)
+ {
+ /*
+ * Now we have to look for a special NCP connection handling
+ * socket. Only these sockets have ipx_ncp_conn != 0, set
+ * by SIOCIPXNCPCONN.
+ */
+ for (sock1=intrfc->if_sklist;
+ (sock1 != NULL) &&
+ (sock1->protinfo.af_ipx.ipx_ncp_conn != connection);
+ sock1=sock1->next);
+ }
+ }
+ if (sock1 == NULL)
+ {
+ /* No special socket found, forward the packet the
+ * normal way.
+ */
+ sock1 = ipxitf_find_socket(intrfc, ipx->ipx_dest.sock);
+ }
/*
* We need to check if there is a primary net and if
@@ -1822,7 +1875,7 @@
}
/* protect IPX system stuff like routing/sap */
- if(ntohs(addr->sipx_port) < IPX_MIN_EPHEMERAL_SOCKET && !suser())
+ if(ntohs(addr->sipx_port) < IPX_MIN_EPHEMERAL_SOCKET && !capable(CAP_NET_ADMIN))
return (-EACCES);
sk->protinfo.af_ipx.port = addr->sipx_port;
@@ -1930,7 +1983,8 @@
return (ret);
}
- if(ipxrtr_lookup(addr->sipx_network) == NULL)
+ /* We can either connect to primary network or somewhere we can route to */
+ if( !(addr->sipx_network == 0 && ipx_primary_net != NULL) && ipxrtr_lookup(addr->sipx_network) == NULL)
return (-ENETUNREACH);
sk->protinfo.af_ipx.dest_addr.net = addr->sipx_network;
@@ -2061,8 +2115,9 @@
int retval;
int flags = msg->msg_flags;
- if(sk->zapped)
- return (-EIO); /* Socket not bound */
+ /* Socket gets bound below anyway */
+/* if(sk->zapped)
+ return (-EIO); */ /* Socket not bound */
if(flags & ~MSG_DONTWAIT)
return (-EINVAL);
@@ -2120,6 +2175,26 @@
struct sk_buff *skb;
int copied, err;
+ /* put the autobinding in */
+ if(sk->protinfo.af_ipx.port == 0)
+ {
+ struct sockaddr_ipx uaddr;
+ int ret;
+
+ uaddr.sipx_port = 0;
+ uaddr.sipx_network = 0;
+
+#ifdef CONFIG_IPX_INTERN
+ memcpy(uaddr.sipx_node, sk->protinfo.af_ipx.intrfc->if_node,
+ IPX_NODE_LEN);
+#endif /* CONFIG_IPX_INTERN */
+
+ ret = ipx_bind(sock, (struct sockaddr *)&uaddr,
+ sizeof(struct sockaddr_ipx));
+ if(ret != 0)
+ return (ret);
+ }
+
if(sk->zapped)
return (-ENOTCONN);
@@ -2191,14 +2266,14 @@
case SIOCADDRT:
case SIOCDELRT:
- if(!suser())
+ if(!capable(CAP_NET_ADMIN))
return (-EPERM);
return (ipxrtr_ioctl(cmd,(void *)arg));
case SIOCSIFADDR:
case SIOCAIPXITFCRT:
case SIOCAIPXPRISLT:
- if(!suser())
+ if(!capable(CAP_NET_ADMIN))
return (-EPERM);
case SIOCGIFADDR:
@@ -2206,6 +2281,17 @@
case SIOCIPXCFGDATA:
return (ipxcfg_get_config_data((void *)arg));
+
+ case SIOCIPXNCPCONN:
+ {
+ /*
+ * This socket wants to take care of the NCP connection
+ * handed to us in arg.
+ */
+ if (!capable(CAP_NET_ADMIN))
+ return(-EPERM);
+ return get_user(sk->protinfo.af_ipx.ipx_ncp_conn, (const unsigned short *)(arg));
+ }
case SIOCGSTAMP:
{
FUNET's LINUX-ADM group, linux-adm@nic.funet.fi
TCL-scripts by Sam Shen, slshen@lbl.gov