diff options
author | Ralf Baechle <ralf@linux-mips.org> | 1998-08-25 09:12:35 +0000 |
---|---|---|
committer | Ralf Baechle <ralf@linux-mips.org> | 1998-08-25 09:12:35 +0000 |
commit | c7fc24dc4420057f103afe8fc64524ebc25c5d37 (patch) | |
tree | 3682407a599b8f9f03fc096298134cafba1c9b2f /net/ipx | |
parent | 1d793fade8b063fde3cf275bf1a5c2d381292cd9 (diff) |
o Merge with Linux 2.1.116.
o New Newport console code.
o New G364 console code.
Diffstat (limited to 'net/ipx')
-rw-r--r-- | net/ipx/af_ipx.c | 1911 | ||||
-rw-r--r-- | net/ipx/af_spx.c | 163 |
2 files changed, 1039 insertions, 1035 deletions
diff --git a/net/ipx/af_ipx.c b/net/ipx/af_ipx.c index f035e8c62..85aaaa7b8 100644 --- a/net/ipx/af_ipx.c +++ b/net/ipx/af_ipx.c @@ -11,32 +11,32 @@ * work I am currently employed to do there. * * All the material in this file is subject to the Gnu license version 2. - * Neither Alan Cox nor the Swansea University Computer Society admit liability - * nor provide warranty for any of this software. This material is provided - * as is and at no charge. + * Neither Alan Cox nor the Swansea University Computer Society admit + * liability nor provide warranty for any of this software. This material + * is provided as is and at no charge. * * Revision 0.21: Uses the new generic socket option code. * Revision 0.22: Gcc clean ups and drop out device registration. Use the * new multi-protocol edition of hard_header - * Revision 0.23: IPX /proc by Mark Evans. - * Adding a route will overwrite any existing route to the same - * network. + * Revision 0.23: IPX /proc by Mark Evans. Adding a route will + * will overwrite any existing route to the same network. * Revision 0.24: Supports new /proc with no 4K limit * Revision 0.25: Add ephemeral sockets, passive local network * identification, support for local net 0 and * multiple datalinks <Greg Page> - * Revision 0.26: Device drop kills IPX routes via it. (needed for modules) + * Revision 0.26: Device drop kills IPX routes via it. (needed for module) * Revision 0.27: Autobind <Mark Evans> * Revision 0.28: Small fix for multiple local networks <Thomas Winder> * Revision 0.29: Assorted major errors removed <Mark Evans> * Small correction to promisc mode error fix <Alan Cox> - * Asynchronous I/O support. - * Changed to use notifiers and the newer packet_type stuff. - * Assorted major fixes <Alejandro Liu> + * Asynchronous I/O support. Changed to use notifiers + * and the newer packet_type stuff. Assorted major + * fixes <Alejandro Liu> * Revision 0.30: Moved to net/ipx/... <Alan Cox> * Don't set address length on recvfrom that errors. * Incorrect verify_area. - * Revision 0.31: New sk_buffs. This still needs a lot of testing. <Alan Cox> + * Revision 0.31: New sk_buffs. This still needs a lot of + * testing. <Alan Cox> * Revision 0.32: Using sock_alloc_send_skb, firewall hooks. <Alan Cox> * Supports sendmsg/recvmsg * Revision 0.33: Internal network support, routing changes, uses a @@ -47,8 +47,9 @@ * Revision 0.36: Internal bump up for 2.1 * Revision 0.37: Began adding POSIXisms. * Revision 0.38: Asynchronous socket stuff made current. - * Revision 0.39: SPX interfaces - * Revision 0.40: Tiny SIOCGSTAMP fix (chris@cybernet.co.nz) + * 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) * * Protect the module by a MOD_INC_USE_COUNT/MOD_DEC_USE_COUNT * pair. Also, now usage count is managed this way @@ -65,6 +66,7 @@ */ #include <linux/config.h> +#if defined (CONFIG_IPX) || defined (CONFIG_IPX_MODULE) #include <linux/module.h> #include <linux/errno.h> #include <linux/types.h> @@ -88,12 +90,12 @@ #include <linux/termios.h> /* For TIOCOUTQ/INQ */ #include <linux/interrupt.h> #include <net/p8022.h> -#include <net/p8022tr.h> #include <net/psnap.h> #include <linux/proc_fs.h> #include <linux/stat.h> #include <linux/firewall.h> #include <linux/init.h> +#include <linux/if_arp.h> #ifdef MODULE static void ipx_proto_finito(void); @@ -105,44 +107,42 @@ static char ipxcfg_auto_select_primary = 0; static char ipxcfg_auto_create_interfaces = 0; /* Global Variables */ -static struct datalink_proto *p8022_datalink = NULL; -static struct datalink_proto *p8022tr_datalink = NULL; -static struct datalink_proto *pEII_datalink = NULL; -static struct datalink_proto *p8023_datalink = NULL; -static struct datalink_proto *pSNAP_datalink = NULL; +static struct datalink_proto *p8022_datalink = NULL; +static struct datalink_proto *pEII_datalink = NULL; +static struct datalink_proto *p8023_datalink = NULL; +static struct datalink_proto *pSNAP_datalink = NULL; static struct proto_ops ipx_dgram_ops; static struct net_proto_family *spx_family_ops; -static ipx_route *ipx_routes = NULL; -static ipx_interface *ipx_interfaces = NULL; -static ipx_interface *ipx_primary_net = NULL; -static ipx_interface *ipx_internal_net = NULL; +static ipx_route *ipx_routes = NULL; +static ipx_interface *ipx_interfaces = NULL; +static ipx_interface *ipx_primary_net = NULL; +static ipx_interface *ipx_internal_net = NULL; static int ipxcfg_set_auto_create(char val) { - if (ipxcfg_auto_create_interfaces != val) + if(ipxcfg_auto_create_interfaces != val) { - if (val) - { + if(val) MOD_INC_USE_COUNT; - } else - { MOD_DEC_USE_COUNT; - } + ipxcfg_auto_create_interfaces = val; } - return 0; + + return (0); } static int ipxcfg_set_auto_select(char val) { ipxcfg_auto_select_primary = val; - if (val && (ipx_primary_net == NULL)) + if(val && (ipx_primary_net == NULL)) ipx_primary_net = ipx_interfaces; - return 0; + + return (0); } static int ipxcfg_get_config_data(ipx_config_data *arg) @@ -151,84 +151,86 @@ static int ipxcfg_get_config_data(ipx_config_data *arg) vals.ipxcfg_auto_create_interfaces = ipxcfg_auto_create_interfaces; vals.ipxcfg_auto_select_primary = ipxcfg_auto_select_primary; - return copy_to_user(arg, &vals, sizeof(vals)) ? -EFAULT : 0; -} + return (copy_to_user(arg, &vals, sizeof(vals)) ? -EFAULT : 0); +} -/***********************************************************************************************************************\ -* * -* Handlers for the socket list. * -* * -\***********************************************************************************************************************/ +/**************************************************************************\ +* * +* Handlers for the socket list. * +* * +\**************************************************************************/ /* - * Note: Sockets may not be removed _during_ an interrupt or inet_bh - * handler using this technique. They can be added although we do not - * use this facility. + * Note: Sockets may not be removed _during_ an interrupt or inet_bh + * handler using this technique. They can be added although we do not + * use this facility. */ void ipx_remove_socket(struct sock *sk) { - struct sock *s; - ipx_interface *intrfc; - unsigned long flags; + struct sock *s; + ipx_interface *intrfc; + unsigned long flags; save_flags(flags); cli(); /* Determine interface with which socket is associated */ intrfc = sk->protinfo.af_ipx.intrfc; - if (intrfc == NULL) { + if(intrfc == NULL) + { restore_flags(flags); return; } - s=intrfc->if_sklist; - if(s==sk) { - intrfc->if_sklist=s->next; + s = intrfc->if_sklist; + if(s == sk) + { + intrfc->if_sklist = s->next; restore_flags(flags); return; } - while(s && s->next) { - if(s->next==sk) { - s->next=sk->next; + while(s && s->next) + { + if(s->next == sk) + { + s->next = sk->next; restore_flags(flags); return; } - s=s->next; + s = s->next; } restore_flags(flags); } /* - * This is only called from user mode. Thus it protects itself against - * interrupt users but doesn't worry about being called during work. - * Once it is removed from the queue no interrupt or bottom half will - * touch it and we are (fairly 8-) ) safe. + * This is only called from user mode. Thus it protects itself against + * interrupt users but doesn't worry about being called during work. + * Once it is removed from the queue no interrupt or bottom half will + * touch it and we are (fairly 8-) ) safe. */ - static void ipx_destroy_socket(struct sock *sk) { struct sk_buff *skb; ipx_remove_socket(sk); - while((skb=skb_dequeue(&sk->receive_queue))!=NULL) { + while((skb = skb_dequeue(&sk->receive_queue)) != NULL) kfree_skb(skb); - } sk_free(sk); } -/* The following code is used to support IPX Interfaces (IPXITF). An +/* + * The following code is used to support IPX Interfaces (IPXITF). An * IPX interface is defined by a physical device and a frame type. */ - static ipx_route * ipxrtr_lookup(__u32); static void ipxitf_clear_primary_net(void) { - if (ipxcfg_auto_select_primary && (ipx_interfaces != NULL)) + if(ipxcfg_auto_select_primary && (ipx_interfaces != NULL)) ipx_primary_net = ipx_interfaces; else ipx_primary_net = NULL; @@ -238,36 +240,38 @@ static ipx_interface *ipxitf_find_using_phys(struct device *dev, unsigned short { ipx_interface *i; - for (i=ipx_interfaces; - i && ((i->if_dev!=dev) || (i->if_dlink_type!=datalink)); - i=i->if_next) + for(i = ipx_interfaces; + i && ((i->if_dev != dev) || (i->if_dlink_type != datalink)); + i = i->if_next) ; - return i; + + return (i); } static ipx_interface *ipxitf_find_using_net(__u32 net) { ipx_interface *i; - if (!net) - return ipx_primary_net; + if(!net) + return (ipx_primary_net); - for (i=ipx_interfaces; i && (i->if_netnum!=net); i=i->if_next) + for(i = ipx_interfaces; i && (i->if_netnum != net); i = i->if_next) ; - return i; + return (i); } /* Sockets are bound to a particular IPX interface. */ static void ipxitf_insert_socket(ipx_interface *intrfc, struct sock *sk) { - struct sock *s; + struct sock *s; sk->protinfo.af_ipx.intrfc = intrfc; sk->next = NULL; - if (intrfc->if_sklist == NULL) { + if(intrfc->if_sklist == NULL) intrfc->if_sklist = sk; - } else { + else + { for (s = intrfc->if_sklist; s->next != NULL; s = s->next) ; s->next = sk; @@ -276,14 +280,14 @@ static void ipxitf_insert_socket(ipx_interface *intrfc, struct sock *sk) static struct sock *ipxitf_find_socket(ipx_interface *intrfc, unsigned short port) { - struct sock *s; + struct sock *s; - for (s=intrfc->if_sklist; + for(s = intrfc->if_sklist; (s != NULL) && (s->protinfo.af_ipx.port != port); - s=s->next) + s = s->next) ; - return s; + return (s); } #ifdef CONFIG_IPX_INTERN @@ -293,16 +297,17 @@ static struct sock *ipxitf_find_internal_socket(ipx_interface *intrfc, { struct sock *s = intrfc->if_sklist; - while (s != NULL) + while(s != NULL) { - if ( (s->protinfo.af_ipx.port == port) + if((s->protinfo.af_ipx.port == port) && (memcmp(node, s->protinfo.af_ipx.node, IPX_NODE_LEN) == 0)) { break; } s = s->next; } - return s; + + return (s); } #endif @@ -310,14 +315,15 @@ static void ipxrtr_del_routes(ipx_interface *); static void ipxitf_down(ipx_interface *intrfc) { - ipx_interface *i; - struct sock *s, *t; + ipx_interface *i; + struct sock *s, *t; /* Delete all routes associated with this interface */ ipxrtr_del_routes(intrfc); /* error sockets */ - for (s = intrfc->if_sklist; s != NULL; ) { + for(s = intrfc->if_sklist; s != NULL; ) + { s->err = ENOLINK; s->error_report(s); s->protinfo.af_ipx.intrfc = NULL; @@ -330,28 +336,27 @@ static void ipxitf_down(ipx_interface *intrfc) intrfc->if_sklist = NULL; /* remove this interface from list */ - if (intrfc == ipx_interfaces) { + if(intrfc == ipx_interfaces) ipx_interfaces = intrfc->if_next; - } else { - for (i = ipx_interfaces; + else + { + for(i = ipx_interfaces; (i != NULL) && (i->if_next != intrfc); i = i->if_next) ; - if ((i != NULL) && (i->if_next == intrfc)) + if((i != NULL) && (i->if_next == intrfc)) i->if_next = intrfc->if_next; } /* remove this interface from *special* networks */ - if (intrfc == ipx_primary_net) + if(intrfc == ipx_primary_net) ipxitf_clear_primary_net(); - if (intrfc == ipx_internal_net) + if(intrfc == ipx_internal_net) ipx_internal_net = NULL; kfree_s(intrfc, sizeof(*intrfc)); - /* sockets still dangling - * - must be closed from user space - */ MOD_DEC_USE_COUNT; + return; } @@ -360,30 +365,29 @@ static int ipxitf_device_event(struct notifier_block *notifier, unsigned long ev struct device *dev = ptr; ipx_interface *i, *tmp; - if(event!=NETDEV_DOWN) + if(event != NETDEV_DOWN) return NOTIFY_DONE; - for (i = ipx_interfaces; i != NULL; ) { - + for(i = ipx_interfaces; i != NULL;) + { tmp = i->if_next; - if (i->if_dev == dev) + if(i->if_dev == dev) ipxitf_down(i); i = tmp; } - return NOTIFY_DONE; + return (NOTIFY_DONE); } static int ipxitf_def_skb_handler(struct sock *sock, struct sk_buff *skb) { - int retval; + int retval; - if((retval = sock_queue_rcv_skb(sock, skb))<0) - { + if((retval = sock_queue_rcv_skb(sock, skb)) < 0) kfree_skb(skb); - } - return retval; + + return (retval); } /* @@ -393,25 +397,25 @@ static int ipxitf_def_skb_handler(struct sock *sock, struct sk_buff *skb) #ifdef CONFIG_IPX_INTERN static int ipxitf_demux_socket(ipx_interface *intrfc, struct sk_buff *skb, int copy) { - struct ipxhdr *ipx = skb->nh.ipxh; - struct sock *s; + struct ipxhdr *ipx = skb->nh.ipxh; + struct sock *s; int is_broadcast = (memcmp(ipx->ipx_dest.node, ipx_broadcast_node, IPX_NODE_LEN) == 0); s = intrfc->if_sklist; - while (s != NULL) + while(s != NULL) { - if ( (s->protinfo.af_ipx.port == ipx->ipx_dest.sock) - && ( is_broadcast + if((s->protinfo.af_ipx.port == ipx->ipx_dest.sock) + && (is_broadcast || (memcmp(ipx->ipx_dest.node, s->protinfo.af_ipx.node, IPX_NODE_LEN) == 0))) { /* We found a socket to which to send */ struct sk_buff *skb1; - if (copy != 0) + if(copy != 0) { skb1 = skb_clone(skb, GFP_ATOMIC); if (skb1 == NULL) @@ -424,57 +428,50 @@ static int ipxitf_demux_socket(ipx_interface *intrfc, struct sk_buff *skb, int c } ipxitf_def_skb_handler(s, skb1); - if (intrfc != ipx_internal_net) - { - /* on an external interface, at most - * one socket can listen. - */ + /* On an external interface, one socket can listen */ + if(intrfc != ipx_internal_net) break; - } } s = s->next; } - if (copy == 0) - { - /* skb was solely for us, and we did not make a copy, - * so free it. - */ + /* skb was solely for us, and we did not make a copy, so free it. */ + if(copy == 0) kfree_skb(skb); - } - return 0; + + return (0); } #else static int ipxitf_demux_socket(ipx_interface *intrfc, struct sk_buff *skb, int copy) { - struct ipxhdr *ipx = skb->nh.ipxh; - struct sock *sock1 = NULL, *sock2 = NULL; - struct sk_buff *skb1 = NULL, *skb2 = NULL; + struct ipxhdr *ipx = skb->nh.ipxh; + struct sock *sock1 = NULL, *sock2 = NULL; + struct sk_buff *skb1 = NULL, *skb2 = NULL; sock1 = ipxitf_find_socket(intrfc, ipx->ipx_dest.sock); /* - * We need to check if there is a primary net and if - * this is addressed to one of the *SPECIAL* sockets because - * these need to be propagated to the primary net. - * The *SPECIAL* socket list contains: 0x452(SAP), 0x453(RIP) and - * 0x456(Diagnostic). + * We need to check if there is a primary net and if + * this is addressed to one of the *SPECIAL* sockets because + * these need to be propagated to the primary net. + * The *SPECIAL* socket list contains: 0x452(SAP), 0x453(RIP) and + * 0x456(Diagnostic). */ - if (ipx_primary_net && (intrfc != ipx_primary_net)) + if(ipx_primary_net && (intrfc != ipx_primary_net)) { - switch (ntohs(ipx->ipx_dest.sock)) + switch(ntohs(ipx->ipx_dest.sock)) { case 0x452: case 0x453: case 0x456: /* - * The appropriate thing to do here is to - * dup the packet and route to the primary net - * interface via ipxitf_send; however, we'll cheat - * and just demux it here. + * The appropriate thing to do here is to + * dup the packet and route to the primary net + * interface via ipxitf_send; however, we'll + * cheat and just demux it here. */ sock2 = ipxitf_find_socket(ipx_primary_net, ipx->ipx_dest.sock); @@ -485,15 +482,13 @@ static int ipxitf_demux_socket(ipx_interface *intrfc, struct sk_buff *skb, int c } /* - * if there is nothing to do, return. The kfree will - * cancel any charging. + * If there is nothing to do return. The kfree will cancel any charging. */ - - if (sock1 == NULL && sock2 == NULL) + if(sock1 == NULL && sock2 == NULL) { - if (!copy) + if(!copy) kfree_skb(skb); - return 0; + return (0); } /* @@ -504,191 +499,162 @@ static int ipxitf_demux_socket(ipx_interface *intrfc, struct sk_buff *skb, int c * copies, we do as much as is possible. */ - if (copy) - { + if(copy) skb1 = skb_clone(skb, GFP_ATOMIC); - } else - { skb1 = skb; - } - if (skb1 == NULL) - return -ENOMEM; - - /* - * Do we need 2 SKBs? - */ + if(skb1 == NULL) + return (-ENOMEM); - if (sock1 && sock2) - { + /* Do we need 2 SKBs? */ + if(sock1 && sock2) skb2 = skb_clone(skb1, GFP_ATOMIC); - } else skb2 = skb1; - if (sock1) + if(sock1) (void) ipxitf_def_skb_handler(sock1, skb1); - if (skb2 == NULL) - return -ENOMEM; + if(skb2 == NULL) + return (-ENOMEM); - if (sock2) + if(sock2) (void) ipxitf_def_skb_handler(sock2, skb2); - return 0; + return (0); } -#endif +#endif /* CONFIG_IPX_INTERN */ static struct sk_buff *ipxitf_adjust_skbuff(ipx_interface *intrfc, struct sk_buff *skb) { - struct sk_buff *skb2; - int in_offset = skb->h.raw - skb->head; - int out_offset = intrfc->if_ipx_offset; - int len; + struct sk_buff *skb2; + int in_offset = skb->h.raw - skb->head; + int out_offset = intrfc->if_ipx_offset; + int len; /* Hopefully, most cases */ - if (in_offset >= out_offset) { - return skb; - } + if(in_offset >= out_offset) + return (skb); /* Need new SKB */ - len = skb->len + out_offset; + len = skb->len + out_offset; skb2 = alloc_skb(len, GFP_ATOMIC); - if (skb2 != NULL) { - skb_reserve(skb2,out_offset); - skb2->nh.raw= - skb2->h.raw=skb_put(skb2,skb->len); + if(skb2 != NULL) + { + skb_reserve(skb2, out_offset); + skb2->nh.raw = + skb2->h.raw = skb_put(skb2,skb->len); memcpy(skb2->h.raw, skb->h.raw, skb->len); } kfree_skb(skb); - return NULL; + + return (NULL); } static int ipxitf_send(ipx_interface *intrfc, struct sk_buff *skb, char *node) { - struct ipxhdr *ipx = skb->nh.ipxh; - struct device *dev = intrfc->if_dev; - struct datalink_proto *dl = intrfc->if_dlink; - char dest_node[IPX_NODE_LEN]; - int send_to_wire = 1; - int addr_len; + struct ipxhdr *ipx = skb->nh.ipxh; + struct device *dev = intrfc->if_dev; + struct datalink_proto *dl = intrfc->if_dlink; + char dest_node[IPX_NODE_LEN]; + int send_to_wire = 1; + int addr_len; /* - * We need to know how many skbuffs it will take to send out this - * packet to avoid unnecessary copies. + * We need to know how many skbuffs it will take to send out this + * packet to avoid unnecessary copies. */ - if ((dl == NULL) || (dev == NULL) || (dev->flags & IFF_LOOPBACK)) + if((dl == NULL) || (dev == NULL) || (dev->flags & IFF_LOOPBACK)) send_to_wire = 0; /* No non looped */ /* - * See if this should be demuxed to sockets on this interface + * See if this should be demuxed to sockets on this interface * - * We want to ensure the original was eaten or that we only use - * up clones. + * We want to ensure the original was eaten or that we only use + * up clones. */ - if (ipx->ipx_dest.net == intrfc->if_netnum) + if(ipx->ipx_dest.net == intrfc->if_netnum) { /* - * To our own node, loop and free the original. - * The internal net will receive on all node address. + * To our own node, loop and free the original. + * The internal net will receive on all node address. */ - if ((intrfc == ipx_internal_net) + if((intrfc == ipx_internal_net) || memcmp(intrfc->if_node, node, IPX_NODE_LEN) == 0) { - /* - * Don't charge sender - */ + /* Don't charge sender */ skb_orphan(skb); - /* - * Will charge receiver - */ - return ipxitf_demux_socket(intrfc, skb, 0); + + /* Will charge receiver */ + return (ipxitf_demux_socket(intrfc, skb, 0)); } - /* - * Broadcast, loop and possibly keep to send on. - */ - if (memcmp(ipx_broadcast_node, node, IPX_NODE_LEN) == 0) + + /* Broadcast, loop and possibly keep to send on. */ + if(memcmp(ipx_broadcast_node, node, IPX_NODE_LEN) == 0) { - if (!send_to_wire) + if(!send_to_wire) skb_orphan(skb); ipxitf_demux_socket(intrfc, skb, send_to_wire); - if (!send_to_wire) - return 0; + if(!send_to_wire) + return (0); } } /* - * If the originating net is not equal to our net; this is routed - * We are still charging the sender. Which is right - the driver - * free will handle this fairly. + * If the originating net is not equal to our net; this is routed + * We are still charging the sender. Which is right - the driver + * free will handle this fairly. */ - - if (ipx->ipx_source.net != intrfc->if_netnum) + if(ipx->ipx_source.net != intrfc->if_netnum) { /* - * Unshare the buffer before modifying the count in - * case its a flood or tcpdump + * Unshare the buffer before modifying the count in + * case its a flood or tcpdump */ - skb=skb_unshare(skb, GFP_ATOMIC); + skb = skb_unshare(skb, GFP_ATOMIC); if(!skb) - return 0; - ipx = skb->nh.ipxh; - if (++(ipx->ipx_tctrl) > ipxcfg_max_hops) + return (0); + if(++(ipx->ipx_tctrl) > ipxcfg_max_hops) send_to_wire = 0; } - if (!send_to_wire) + if(!send_to_wire) { kfree_skb(skb); - return 0; + return (0); } - /* - * Determine the appropriate hardware address - */ - + /* Determine the appropriate hardware address */ addr_len = dev->addr_len; - if (memcmp(ipx_broadcast_node, node, IPX_NODE_LEN) == 0) + if(memcmp(ipx_broadcast_node, node, IPX_NODE_LEN) == 0) memcpy(dest_node, dev->broadcast, addr_len); else memcpy(dest_node, &(node[IPX_NODE_LEN-addr_len]), addr_len); - /* - * Make any compensation for differing physical/data link size - */ - + /* Make any compensation for differing physical/data link size */ skb = ipxitf_adjust_skbuff(intrfc, skb); - if (skb == NULL) - return 0; + if(skb == NULL) + return (0); /* set up data link and physical headers */ skb->dev = dev; skb->protocol = htons(ETH_P_IPX); dl->datalink_header(dl, skb, dest_node); -#if 0 - /* - * Now log the packet just before transmission - */ - - dump_pkt("IPX snd:", skb->nh.ipxh); - dump_data("ETH hdr:", skb->mac.raw, skb->nh.raw - skb->mac.raw); -#endif - /* - * Send it out - */ + /* Send it out */ dev_queue_xmit(skb); - return 0; + + return (0); } static int ipxrtr_add_route(__u32, ipx_interface *, unsigned char *); static int ipxitf_add_local_route(ipx_interface *intrfc) { - return ipxrtr_add_route(intrfc->if_netnum, intrfc, NULL); + return (ipxrtr_add_route(intrfc->if_netnum, intrfc, NULL)); } static const char * ipx_frame_name(unsigned short); @@ -699,26 +665,23 @@ static int ipxitf_rcv(ipx_interface *intrfc, struct sk_buff *skb) struct ipxhdr *ipx = skb->nh.ipxh; ipx_interface *i; - /* - * We firewall first, ask questions later. - */ - + /* We firewall first, ask questions later. */ if (call_in_firewall(PF_IPX, skb->dev, ipx, NULL, &skb)!=FW_ACCEPT) { kfree_skb(skb); - return 0; + return (0); } /* See if we should update our network number */ - if ( !intrfc->if_netnum && /* net number of intrfc not known yet (== 0) */ - (ipx->ipx_source.net == ipx->ipx_dest.net) && /* intra-net packet */ - ipx->ipx_source.net) /* source net number of packet != 0 */ + if(!intrfc->if_netnum /* net number of intrfc not known yet (== 0) */ + && (ipx->ipx_source.net == ipx->ipx_dest.net) /* intra packet */ + && ipx->ipx_source.net) /* source net number of packet != 0 */ { /* NB: NetWare servers lie about their hop count so we * dropped the test based on it. This is the best way * to determine this is a 0 hop count packet. */ - if ((i=ipxitf_find_using_net(ipx->ipx_source.net))==NULL) + if((i=ipxitf_find_using_net(ipx->ipx_source.net)) == NULL) { intrfc->if_netnum = ipx->ipx_source.net; (void) ipxitf_add_local_route(intrfc); @@ -734,7 +697,9 @@ static int ipxitf_rcv(ipx_interface *intrfc, struct sk_buff *skb) } } - if( ipx->ipx_type == IPX_TYPE_PPROP && ipx->ipx_tctrl < 8 && skb->pkt_type != PACKET_OTHERHOST ) + if(ipx->ipx_type == IPX_TYPE_PPROP + && ipx->ipx_tctrl < 8 + && skb->pkt_type != PACKET_OTHERHOST) { int i; ipx_interface *ifcs; @@ -743,235 +708,247 @@ static int ipxitf_rcv(ipx_interface *intrfc, struct sk_buff *skb) char *c; c = (char *) skb->data; - c += sizeof( struct ipxhdr ); + c += sizeof(struct ipxhdr); l = (__u32 *) c; i = 0; - /* - * Dump packet if too many hops or already seen this net - */ - if( ipx->ipx_tctrl < 8 ) - for( ; i < ipx->ipx_tctrl ; i++ ) - if( *l++ == intrfc->if_netnum ) - break; - if( i == ipx->ipx_tctrl ) + /* Dump packet if too many hops or already seen this net */ + if(ipx->ipx_tctrl < 8) + for( ; i < ipx->ipx_tctrl; i++) + if(*l++ == intrfc->if_netnum) + break; + + if(i == ipx->ipx_tctrl) { /* < 8 hops && input itfc not in list */ *l = intrfc->if_netnum; /* insert recvd netnum into list */ /* xmit on all other interfaces... */ - for ( ifcs = ipx_interfaces; ifcs != NULL ; ifcs = ifcs->if_next) + for(ifcs = ipx_interfaces; ifcs != NULL; ifcs = ifcs->if_next) { /* That aren't in the list */ l = (__u32 *) c; - for( i = 0 ; i <= ipx->ipx_tctrl ; i++ ) - if( ifcs->if_netnum == *l++ ) + for(i = 0; i <= ipx->ipx_tctrl; i++) + if(ifcs->if_netnum == *l++) break; - if( i - 1 == ipx->ipx_tctrl ) + if(i - 1 == ipx->ipx_tctrl) { ipx->ipx_dest.net = ifcs->if_netnum; /* See if we are allowed to firewall forward */ - if (call_fw_firewall(PF_IPX, skb->dev, ipx, NULL, &skb)==FW_ACCEPT) + if(call_fw_firewall(PF_IPX, skb->dev, ipx, NULL, &skb) == FW_ACCEPT) { - skb2 = skb_clone(skb, GFP_ATOMIC); + skb2=skb_clone(skb, GFP_ATOMIC); ipxrtr_route_skb(skb2); } } } - /* - * Reset network number in packet - */ + + /* Reset network number in packet */ ipx->ipx_dest.net = intrfc->if_netnum; } - } - if (!ipx->ipx_dest.net) + if(!ipx->ipx_dest.net) ipx->ipx_dest.net = intrfc->if_netnum; - if (!ipx->ipx_source.net) + if(!ipx->ipx_source.net) ipx->ipx_source.net = intrfc->if_netnum; - if (intrfc->if_netnum != ipx->ipx_dest.net) + if(intrfc->if_netnum != ipx->ipx_dest.net) { - /* - * See if we are allowed to firewall forward - */ - if (call_fw_firewall(PF_IPX, skb->dev, ipx, NULL, &skb)!=FW_ACCEPT) + /* See if we are allowed to firewall forward */ + if(call_fw_firewall(PF_IPX, skb->dev, ipx, NULL, &skb) != FW_ACCEPT) { kfree_skb(skb); - return 0; + return (0); } /* We only route point-to-point packets. */ - if (skb->pkt_type == PACKET_HOST) + if(skb->pkt_type == PACKET_HOST) { skb=skb_unshare(skb, GFP_ATOMIC); if(skb) - return ipxrtr_route_skb(skb); + return (ipxrtr_route_skb(skb)); else - return 0; + return (0); } + kfree_skb(skb); - return 0; + return (0); } /* see if we should keep it */ - if ((memcmp(ipx_broadcast_node, ipx->ipx_dest.node, IPX_NODE_LEN) == 0) + if((memcmp(ipx_broadcast_node, ipx->ipx_dest.node, IPX_NODE_LEN) == 0) || (memcmp(intrfc->if_node, ipx->ipx_dest.node, IPX_NODE_LEN) == 0)) { - return ipxitf_demux_socket(intrfc, skb, 0); + return (ipxitf_demux_socket(intrfc, skb, 0)); } /* we couldn't pawn it off so unload it */ kfree_skb(skb); - return 0; + return (0); } static void ipxitf_insert(ipx_interface *intrfc) { - ipx_interface *i; + ipx_interface *i; intrfc->if_next = NULL; - if (ipx_interfaces == NULL) { + if(ipx_interfaces == NULL) ipx_interfaces = intrfc; - } else { - for (i = ipx_interfaces; i->if_next != NULL; i = i->if_next) + else + { + for(i = ipx_interfaces; i->if_next != NULL; i = i->if_next) ; i->if_next = intrfc; } - if (ipxcfg_auto_select_primary && (ipx_primary_net == NULL)) + if(ipxcfg_auto_select_primary && (ipx_primary_net == NULL)) ipx_primary_net = intrfc; + MOD_INC_USE_COUNT; + return; } static int ipxitf_create_internal(ipx_interface_definition *idef) { - ipx_interface *intrfc; + ipx_interface *intrfc; /* Only one primary network allowed */ - if (ipx_primary_net != NULL) - return -EEXIST; + if(ipx_primary_net != NULL) + return (-EEXIST); /* Must have a valid network number */ - if (!idef->ipx_network) - return -EADDRNOTAVAIL; - if (ipxitf_find_using_net(idef->ipx_network) != NULL) - return -EADDRINUSE; - - intrfc=(ipx_interface *)kmalloc(sizeof(ipx_interface),GFP_ATOMIC); - if (intrfc==NULL) - return -EAGAIN; - intrfc->if_dev=NULL; - intrfc->if_netnum=idef->ipx_network; - intrfc->if_dlink_type = 0; - intrfc->if_dlink = NULL; - intrfc->if_sklist = NULL; - intrfc->if_internal = 1; - intrfc->if_ipx_offset = 0; - intrfc->if_sknum = IPX_MIN_EPHEMERAL_SOCKET; + if(!idef->ipx_network) + return (-EADDRNOTAVAIL); + if(ipxitf_find_using_net(idef->ipx_network) != NULL) + return (-EADDRINUSE); + + intrfc = (ipx_interface *)kmalloc(sizeof(ipx_interface),GFP_ATOMIC); + if(intrfc == NULL) + return (-EAGAIN); + intrfc->if_dev = NULL; + intrfc->if_netnum = idef->ipx_network; + intrfc->if_dlink_type = 0; + intrfc->if_dlink = NULL; + intrfc->if_sklist = NULL; + intrfc->if_internal = 1; + intrfc->if_ipx_offset = 0; + intrfc->if_sknum = IPX_MIN_EPHEMERAL_SOCKET; memcpy((char *)&(intrfc->if_node), idef->ipx_node, IPX_NODE_LEN); - ipx_internal_net = intrfc; - ipx_primary_net = intrfc; + ipx_internal_net = intrfc; + ipx_primary_net = intrfc; ipxitf_insert(intrfc); - return ipxitf_add_local_route(intrfc); + + return (ipxitf_add_local_route(intrfc)); } static int ipx_map_frame_type(unsigned char type) { - switch (type) + switch(type) { case IPX_FRAME_ETHERII: - return htons(ETH_P_IPX); + return (htons(ETH_P_IPX)); + case IPX_FRAME_8022: - return htons(ETH_P_802_2); - case IPX_FRAME_TR_8022: - return htons(ETH_P_TR_802_2); + return (htons(ETH_P_802_2)); + case IPX_FRAME_SNAP: - return htons(ETH_P_SNAP); + return (htons(ETH_P_SNAP)); + case IPX_FRAME_8023: - return htons(ETH_P_802_3); + return (htons(ETH_P_802_3)); } - return 0; + + return (0); } static int ipxitf_create(ipx_interface_definition *idef) { - struct device *dev; - unsigned short dlink_type = 0; - struct datalink_proto *datalink = NULL; - ipx_interface *intrfc; + struct device *dev; + unsigned short dlink_type = 0; + struct datalink_proto *datalink = NULL; + ipx_interface *intrfc; + + if(idef->ipx_special == IPX_INTERNAL) + return (ipxitf_create_internal(idef)); - if (idef->ipx_special == IPX_INTERNAL) - return ipxitf_create_internal(idef); + if((idef->ipx_special == IPX_PRIMARY) && (ipx_primary_net != NULL)) + return (-EEXIST); - if ((idef->ipx_special == IPX_PRIMARY) && (ipx_primary_net != NULL)) - return -EEXIST; + if(idef->ipx_network + && (ipxitf_find_using_net(idef->ipx_network) != NULL)) + return (-EADDRINUSE); - if (idef->ipx_network && - (ipxitf_find_using_net(idef->ipx_network) != NULL)) - return -EADDRINUSE; + dev = dev_get(idef->ipx_device); + if(dev == NULL) + return (-ENODEV); - switch (idef->ipx_dlink_type) + switch(idef->ipx_dlink_type) { - case IPX_FRAME_ETHERII: - dlink_type = htons(ETH_P_IPX); - datalink = pEII_datalink; - break; case IPX_FRAME_TR_8022: - dlink_type = htons(ETH_P_TR_802_2); - datalink = p8022tr_datalink; - break; + printk("IPX frame type 802.2TR is obsolete. Use 802.2 instead.\n"); + /* fall through */ + case IPX_FRAME_8022: - dlink_type = htons(ETH_P_802_2); - datalink = p8022_datalink; + dlink_type = htons(ETH_P_802_2); + datalink = p8022_datalink; break; + + case IPX_FRAME_ETHERII: + if (dev->type != ARPHRD_IEEE802) + { + dlink_type = htons(ETH_P_IPX); + datalink = pEII_datalink; + break; + } + else + printk("IPX frame type EtherII over token-ring is obsolete. Use SNAP instead.\n"); + /* fall through */ + case IPX_FRAME_SNAP: - dlink_type = htons(ETH_P_SNAP); - datalink = pSNAP_datalink; + dlink_type = htons(ETH_P_SNAP); + datalink = pSNAP_datalink; break; + case IPX_FRAME_8023: - dlink_type = htons(ETH_P_802_3); - datalink = p8023_datalink; + dlink_type = htons(ETH_P_802_3); + datalink = p8023_datalink; break; + case IPX_FRAME_NONE: default: break; } - if (datalink == NULL) - return -EPROTONOSUPPORT; - - dev=dev_get(idef->ipx_device); - if (dev==NULL) - return -ENODEV; - - if (!(dev->flags & IFF_UP)) - return -ENETDOWN; + if(!(dev->flags & IFF_UP)) + return (-ENETDOWN); /* Check addresses are suitable */ - if(dev->addr_len>IPX_NODE_LEN) - return -EINVAL; + if(dev->addr_len > IPX_NODE_LEN) + return (-EINVAL); + + if(datalink == NULL) + return (-EPROTONOSUPPORT); - if ((intrfc = ipxitf_find_using_phys(dev, dlink_type)) == NULL) + if((intrfc = ipxitf_find_using_phys(dev, dlink_type)) == NULL) { /* Ok now create */ - intrfc=(ipx_interface *)kmalloc(sizeof(ipx_interface),GFP_ATOMIC); - if (intrfc==NULL) - return -EAGAIN; - intrfc->if_dev=dev; - intrfc->if_netnum=idef->ipx_network; - intrfc->if_dlink_type = dlink_type; - intrfc->if_dlink = datalink; - intrfc->if_sklist = NULL; - intrfc->if_sknum = IPX_MIN_EPHEMERAL_SOCKET; + intrfc = (ipx_interface *)kmalloc(sizeof(ipx_interface),GFP_ATOMIC); + if(intrfc == NULL) + return (-EAGAIN); + intrfc->if_dev = dev; + intrfc->if_netnum = idef->ipx_network; + intrfc->if_dlink_type = dlink_type; + intrfc->if_dlink = datalink; + intrfc->if_sklist = NULL; + intrfc->if_sknum = IPX_MIN_EPHEMERAL_SOCKET; /* Setup primary if necessary */ - if ((idef->ipx_special == IPX_PRIMARY)) + if((idef->ipx_special == IPX_PRIMARY)) ipx_primary_net = intrfc; - intrfc->if_internal = 0; - intrfc->if_ipx_offset = dev->hard_header_len + datalink->header_length; - if(memcmp(idef->ipx_node, "\000\000\000\000\000\000", IPX_NODE_LEN)==0) + intrfc->if_internal = 0; + intrfc->if_ipx_offset = dev->hard_header_len + datalink->header_length; + if(memcmp(idef->ipx_node, "\000\000\000\000\000\000", IPX_NODE_LEN) == 0) { memset(intrfc->if_node, 0, IPX_NODE_LEN); memcpy((char *)&(intrfc->if_node[IPX_NODE_LEN-dev->addr_len]), @@ -983,234 +960,246 @@ static int ipxitf_create(ipx_interface_definition *idef) } /* If the network number is known, add a route */ - if (!intrfc->if_netnum) - return 0; + if(!intrfc->if_netnum) + return (0); - return ipxitf_add_local_route(intrfc); + return (ipxitf_add_local_route(intrfc)); } static int ipxitf_delete(ipx_interface_definition *idef) { - struct device *dev = NULL; - unsigned short dlink_type = 0; - ipx_interface *intrfc; + struct device *dev = NULL; + unsigned short dlink_type = 0; + ipx_interface *intrfc; - if (idef->ipx_special == IPX_INTERNAL) + if(idef->ipx_special == IPX_INTERNAL) { - if (ipx_internal_net != NULL) + if(ipx_internal_net != NULL) { ipxitf_down(ipx_internal_net); - return 0; + return (0); } - return -ENOENT; + return (-ENOENT); } dlink_type = ipx_map_frame_type(idef->ipx_dlink_type); - if (dlink_type == 0) - return -EPROTONOSUPPORT; + if(dlink_type == 0) + return (-EPROTONOSUPPORT); - dev=dev_get(idef->ipx_device); - if (dev==NULL) - return -ENODEV; + dev = dev_get(idef->ipx_device); + if(dev == NULL) + return (-ENODEV); intrfc = ipxitf_find_using_phys(dev, dlink_type); - if (intrfc != NULL) { + if(intrfc != NULL) + { ipxitf_down(intrfc); - return 0; + return (0); } - return -EINVAL; + + return (-EINVAL); } static ipx_interface *ipxitf_auto_create(struct device *dev, unsigned short dlink_type) { struct datalink_proto *datalink = NULL; - ipx_interface *intrfc; + ipx_interface *intrfc; - switch (htons(dlink_type)) + switch(htons(dlink_type)) { case ETH_P_IPX: datalink = pEII_datalink; break; + case ETH_P_802_2: datalink = p8022_datalink; break; - case ETH_P_TR_802_2: - datalink = p8022tr_datalink; - break; + case ETH_P_SNAP: datalink = pSNAP_datalink; break; + case ETH_P_802_3: datalink = p8023_datalink; break; + default: - return NULL; + return (NULL); } - if (dev == NULL) - return NULL; + if(dev == NULL) + return (NULL); /* Check addresses are suitable */ - if(dev->addr_len>IPX_NODE_LEN) return NULL; - - intrfc=(ipx_interface *)kmalloc(sizeof(ipx_interface),GFP_ATOMIC); - if (intrfc!=NULL) - { - intrfc->if_dev=dev; - intrfc->if_netnum=0; - intrfc->if_dlink_type = dlink_type; - intrfc->if_dlink = datalink; - intrfc->if_sklist = NULL; - intrfc->if_internal = 0; - intrfc->if_sknum = IPX_MIN_EPHEMERAL_SOCKET; - intrfc->if_ipx_offset = dev->hard_header_len + - datalink->header_length; + if(dev->addr_len>IPX_NODE_LEN) + return (NULL); + + intrfc = (ipx_interface *)kmalloc(sizeof(ipx_interface),GFP_ATOMIC); + if(intrfc != NULL) + { + intrfc->if_dev = dev; + intrfc->if_netnum = 0; + intrfc->if_dlink_type = dlink_type; + intrfc->if_dlink = datalink; + intrfc->if_sklist = NULL; + intrfc->if_internal = 0; + intrfc->if_sknum = IPX_MIN_EPHEMERAL_SOCKET; + intrfc->if_ipx_offset = dev->hard_header_len + + datalink->header_length; memset(intrfc->if_node, 0, IPX_NODE_LEN); memcpy((char *)&(intrfc->if_node[IPX_NODE_LEN-dev->addr_len]), dev->dev_addr, dev->addr_len); ipxitf_insert(intrfc); } - return intrfc; + return (intrfc); } -static int ipxitf_ioctl_real(unsigned int cmd, void *arg) +static int ipxitf_ioctl(unsigned int cmd, void *arg) { + struct ifreq ifr; + int err, val; + switch(cmd) { case SIOCSIFADDR: { - struct ifreq ifr; struct sockaddr_ipx *sipx; ipx_interface_definition f; - if (copy_from_user(&ifr,arg,sizeof(ifr))) - return -EFAULT; - sipx=(struct sockaddr_ipx *)&ifr.ifr_addr; - if(sipx->sipx_family!=AF_IPX) - return -EINVAL; - f.ipx_network=sipx->sipx_network; - memcpy(f.ipx_device, ifr.ifr_name, sizeof(f.ipx_device)); + if(copy_from_user(&ifr, arg, sizeof(ifr))) + return (-EFAULT); + + sipx = (struct sockaddr_ipx *)&ifr.ifr_addr; + if(sipx->sipx_family != AF_IPX) + return (-EINVAL); + + f.ipx_network = sipx->sipx_network; + memcpy(f.ipx_device,ifr.ifr_name,sizeof(f.ipx_device)); memcpy(f.ipx_node, sipx->sipx_node, IPX_NODE_LEN); - f.ipx_dlink_type=sipx->sipx_type; - f.ipx_special=sipx->sipx_special; - if(sipx->sipx_action==IPX_DLTITF) - return ipxitf_delete(&f); + f.ipx_dlink_type = sipx->sipx_type; + f.ipx_special = sipx->sipx_special; + + if(sipx->sipx_action == IPX_DLTITF) + return (ipxitf_delete(&f)); else - return ipxitf_create(&f); + return (ipxitf_create(&f)); } + case SIOCGIFADDR: { - struct ifreq ifr; struct sockaddr_ipx *sipx; ipx_interface *ipxif; struct device *dev; - int err; - if (copy_from_user(&ifr,arg,sizeof(ifr))) - return -EFAULT; - sipx=(struct sockaddr_ipx *)&ifr.ifr_addr; - dev=dev_get(ifr.ifr_name); + if(copy_from_user(&ifr, arg, sizeof(ifr))) + return (-EFAULT); + + sipx = (struct sockaddr_ipx *)&ifr.ifr_addr; + dev = dev_get(ifr.ifr_name); if(!dev) - return -ENODEV; - ipxif=ipxitf_find_using_phys(dev, ipx_map_frame_type(sipx->sipx_type)); - if(ipxif==NULL) - return -EADDRNOTAVAIL; - sipx->sipx_family=AF_IPX; - sipx->sipx_network=ipxif->if_netnum; + return (-ENODEV); + + ipxif = ipxitf_find_using_phys(dev, ipx_map_frame_type(sipx->sipx_type)); + if(ipxif == NULL) + return (-EADDRNOTAVAIL); + + sipx->sipx_family = AF_IPX; + sipx->sipx_network = ipxif->if_netnum; memcpy(sipx->sipx_node, ipxif->if_node, sizeof(sipx->sipx_node)); err = -EFAULT; - if (!copy_to_user(arg, &ifr, sizeof(ifr))) + if(!copy_to_user(arg, &ifr, sizeof(ifr))) err = 0; - return err; + + return (err); } + case SIOCAIPXITFCRT: { - int err, val; err = get_user(val, (unsigned char *) arg); - if (err) - return err; - return ipxcfg_set_auto_create(val); + if(err) + return (err); + + return (ipxcfg_set_auto_create(val)); } + case SIOCAIPXPRISLT: { - int err, val; err = get_user(val, (unsigned char *) arg); - if (err) - return err; - return ipxcfg_set_auto_select(val); + if(err) + return (err); + + return (ipxcfg_set_auto_select(val)); } + default: - return -EINVAL; + return (-EINVAL); } } -static int ipxitf_ioctl(unsigned int cmd, void *arg) -{ - int ret; - MOD_INC_USE_COUNT; - ret = ipxitf_ioctl_real (cmd,arg); - MOD_DEC_USE_COUNT; - return ret; -} - -/*******************************************************************************************************************\ -* * -* Routing tables for the IPX socket layer * -* * -\*******************************************************************************************************************/ +/**************************************************************************\ +* * +* Routing tables for the IPX socket layer. * +* * +\**************************************************************************/ static ipx_route *ipxrtr_lookup(__u32 net) { ipx_route *r; - for (r=ipx_routes; (r!=NULL) && (r->ir_net!=net); r=r->ir_next) + for(r = ipx_routes; (r != NULL) && (r->ir_net != net); r = r->ir_next) ; - return r; + return (r); } static int ipxrtr_add_route(__u32 network, ipx_interface *intrfc, unsigned char *node) { - ipx_route *rt; + ipx_route *rt; /* Get a route structure; either existing or create */ rt = ipxrtr_lookup(network); - if (rt==NULL) + if(rt == NULL) + { + rt = (ipx_route *)kmalloc(sizeof(ipx_route),GFP_ATOMIC); + if(rt == NULL) + return (-EAGAIN); + rt->ir_next = ipx_routes; + ipx_routes = rt; + } + else if(intrfc == ipx_internal_net) + return (-EEXIST); + + rt->ir_net = network; + rt->ir_intrfc = intrfc; + if(node == NULL) { - rt=(ipx_route *)kmalloc(sizeof(ipx_route),GFP_ATOMIC); - if(rt==NULL) - return -EAGAIN; - rt->ir_next=ipx_routes; - ipx_routes=rt; - } - else if (intrfc == ipx_internal_net) - return(-EEXIST); - - rt->ir_net = network; - rt->ir_intrfc = intrfc; - if (node == NULL) { memset(rt->ir_router_node, '\0', IPX_NODE_LEN); rt->ir_routed = 0; - } else { + } + else + { memcpy(rt->ir_router_node, node, IPX_NODE_LEN); - rt->ir_routed=1; + rt->ir_routed = 1; } - return 0; + + return (0); } static void ipxrtr_del_routes(ipx_interface *intrfc) { - ipx_route **r, *tmp; + ipx_route **r, *tmp; - for (r = &ipx_routes; (tmp = *r) != NULL; ) { - if (tmp->ir_intrfc == intrfc) { + for(r = &ipx_routes; (tmp = *r) != NULL;) + { + if(tmp->ir_intrfc == intrfc) + { *r = tmp->ir_next; kfree_s(tmp, sizeof(ipx_route)); - } else { - r = &(tmp->ir_next); } + else + r = &(tmp->ir_next); } } @@ -1220,33 +1209,34 @@ static int ipxrtr_create(ipx_route_definition *rd) /* Find the appropriate interface */ intrfc = ipxitf_find_using_net(rd->ipx_router_network); - if (intrfc == NULL) - return -ENETUNREACH; + if(intrfc == NULL) + return (-ENETUNREACH); - return ipxrtr_add_route(rd->ipx_network, intrfc, rd->ipx_router_node); + return (ipxrtr_add_route(rd->ipx_network, intrfc, rd->ipx_router_node)); } - static int ipxrtr_delete(long net) { - ipx_route **r; - ipx_route *tmp; + ipx_route **r; + ipx_route *tmp; - for (r = &ipx_routes; (tmp = *r) != NULL; ) + for(r = &ipx_routes; (tmp = *r) != NULL;) { - if (tmp->ir_net == net) + if(tmp->ir_net == net) { - if (!(tmp->ir_routed)) - /* Directly connected; can't lose route */ - return -EPERM; + /* Directly connected; can't lose route */ + if(!(tmp->ir_routed)) + return (-EPERM); + *r = tmp->ir_next; kfree_s(tmp, sizeof(ipx_route)); - return 0; + return (0); } + r = &(tmp->ir_next); } - return -ENOENT; + return (-ENOENT); } /* @@ -1263,59 +1253,41 @@ static __u16 ipx_set_checksum(struct ipxhdr *packet,int length) * don't know of a machine that isn't.) */ - __u32 sum=0; + __u32 sum = 0; - /* - * Pointer to second word - We skip the checksum field - */ + /* Pointer to second word - We skip the checksum field */ + __u16 *p = (__u16 *)&packet->ipx_pktsize; - __u16 *p=(__u16 *)&packet->ipx_pktsize; + /* Number of complete words */ + __u32 i = length >> 1; + char hops = packet->ipx_tctrl; - /* - * Number of complete words - */ - - __u32 i=length>>1; - char hops = packet->ipx_tctrl; - - packet->ipx_tctrl = 0; /* hop count excluded from checksum calc */ - - /* - * Loop through all complete words except the checksum field - */ + /* Hop count excluded from checksum calc */ + packet->ipx_tctrl = 0; + /* Loop through all complete words except the checksum field */ while(--i) - sum+=*p++; + sum += *p++; - /* - * Add on the last part word if it exists - */ - - if(packet->ipx_pktsize&htons(1)) - sum+=ntohs(0xff00)&*p; + /* Add on the last part word if it exists */ + if(packet->ipx_pktsize & htons(1)) + sum += ntohs(0xff00) & *p; packet->ipx_tctrl = hops; - /* - * Do final fixup - */ - sum=(sum&0xffff)+(sum>>16); + /* Do final fixup */ + sum = (sum & 0xffff) + (sum >> 16); - /* - * It's a pity there's no concept of carry in C - */ - - if(sum>=0x10000) + /* It's a pity there's no concept of carry in C */ + if(sum >= 0x10000) sum++; - return ~sum; -}; - + return (~sum); +} /* - * Route an outgoing frame from a socket. + * Route an outgoing frame from a socket. */ - static int ipxrtr_route_packet(struct sock *sk, struct sockaddr_ipx *usipx, struct iovec *iov, int len, int noblock) { struct sk_buff *skb; @@ -1327,7 +1299,7 @@ static int ipxrtr_route_packet(struct sock *sk, struct sockaddr_ipx *usipx, stru int err; /* Find the appropriate interface on which to send packet */ - if (!usipx->sipx_network && (ipx_primary_net != NULL)) + if(!usipx->sipx_network && (ipx_primary_net != NULL)) { usipx->sipx_network = ipx_primary_net->if_netnum; intrfc = ipx_primary_net; @@ -1335,35 +1307,36 @@ static int ipxrtr_route_packet(struct sock *sk, struct sockaddr_ipx *usipx, stru else { rt = ipxrtr_lookup(usipx->sipx_network); - if (rt==NULL) - return -ENETUNREACH; + if(rt == NULL) + return (-ENETUNREACH); intrfc = rt->ir_intrfc; } ipx_offset = intrfc->if_ipx_offset; - size=sizeof(struct ipxhdr)+len; - size += ipx_offset; + size = sizeof(struct ipxhdr) + len; + size += ipx_offset; - skb=sock_alloc_send_skb(sk, size, 0, noblock, &err); - if(skb==NULL) - return err; + skb = sock_alloc_send_skb(sk, size, 0, noblock, &err); + if(skb == NULL) + return (err); skb_reserve(skb,ipx_offset); - skb->sk=sk; + skb->sk = sk; /* Fill in IPX header */ - ipx=(struct ipxhdr *)skb_put(skb,sizeof(struct ipxhdr)); - ipx->ipx_pktsize=htons(len+sizeof(struct ipxhdr)); - ipx->ipx_tctrl=0; - ipx->ipx_type=usipx->sipx_type; - skb->h.raw = (void *)skb->nh.ipxh = ipx; + ipx = (struct ipxhdr *)skb_put(skb, sizeof(struct ipxhdr)); + ipx->ipx_pktsize= htons(len + sizeof(struct ipxhdr)); + ipx->ipx_tctrl = 0; + ipx->ipx_type = usipx->sipx_type; + skb->h.raw = (void *)skb->nh.ipxh = ipx; ipx->ipx_source.net = sk->protinfo.af_ipx.intrfc->if_netnum; + #ifdef CONFIG_IPX_INTERN memcpy(ipx->ipx_source.node, sk->protinfo.af_ipx.node, IPX_NODE_LEN); #else - if ((err = ntohs(sk->protinfo.af_ipx.port)) == 0x453 || err == 0x452) + if((err = ntohs(sk->protinfo.af_ipx.port)) == 0x453 || err == 0x452) { /* RIP/SAP special handling for mars_nwe */ ipx->ipx_source.net = intrfc->if_netnum; @@ -1374,114 +1347,119 @@ static int ipxrtr_route_packet(struct sock *sk, struct sockaddr_ipx *usipx, stru ipx->ipx_source.net = sk->protinfo.af_ipx.intrfc->if_netnum; memcpy(ipx->ipx_source.node, sk->protinfo.af_ipx.intrfc->if_node, IPX_NODE_LEN); } -#endif - ipx->ipx_source.sock = sk->protinfo.af_ipx.port; - ipx->ipx_dest.net=usipx->sipx_network; +#endif /* CONFIG_IPX_INTERN */ + + ipx->ipx_source.sock = sk->protinfo.af_ipx.port; + ipx->ipx_dest.net = usipx->sipx_network; memcpy(ipx->ipx_dest.node,usipx->sipx_node,IPX_NODE_LEN); - ipx->ipx_dest.sock=usipx->sipx_port; + ipx->ipx_dest.sock = usipx->sipx_port; err = memcpy_fromiovec(skb_put(skb,len),iov,len); - if (err) + if(err) { kfree_skb(skb); - return -EFAULT; + return (-EFAULT); } - /* - * Apply checksum. Not allowed on 802.3 links. - */ - - if(sk->no_check || intrfc->if_dlink_type==IPX_FRAME_8023) + /* Apply checksum. Not allowed on 802.3 links. */ + if(sk->no_check || intrfc->if_dlink_type == IPX_FRAME_8023) ipx->ipx_checksum=0xFFFF; else - ipx->ipx_checksum=ipx_set_checksum(ipx, len+sizeof(struct ipxhdr)); + ipx->ipx_checksum = ipx_set_checksum(ipx, len + sizeof(struct ipxhdr)); - if(call_out_firewall(PF_IPX, skb->dev, ipx, NULL, &skb)!=FW_ACCEPT) + if(call_out_firewall(PF_IPX, skb->dev, ipx, NULL, &skb) != FW_ACCEPT) { kfree_skb(skb); - return -EPERM; + return (-EPERM); } - return ipxitf_send(intrfc, skb, (rt && rt->ir_routed) ? - rt->ir_router_node : ipx->ipx_dest.node); + return (ipxitf_send(intrfc, skb, (rt && rt->ir_routed) ? + rt->ir_router_node : ipx->ipx_dest.node)); } int ipxrtr_route_skb(struct sk_buff *skb) { - struct ipxhdr *ipx = skb->nh.ipxh; - ipx_route *r; - ipx_interface *i; + struct ipxhdr *ipx = skb->nh.ipxh; + ipx_interface *i; + ipx_route *r; r = ipxrtr_lookup(ipx->ipx_dest.net); - if (r == NULL) + if(r == NULL) /* no known route */ { - /* no known route */ kfree_skb(skb); - return 0; + return (0); } + i = r->ir_intrfc; (void)ipxitf_send(i, skb, (r->ir_routed) ? r->ir_router_node : ipx->ipx_dest.node); - return 0; + + return (0); } /* - * We use a normal struct rtentry for route handling + * We use a normal struct rtentry for route handling */ - static int ipxrtr_ioctl(unsigned int cmd, void *arg) { - int err; struct rtentry rt; /* Use these to behave like 'other' stacks */ struct sockaddr_ipx *sg,*st; + int err; err = copy_from_user(&rt,arg,sizeof(rt)); - if (err) - return -EFAULT; + if(err) + return (-EFAULT); - sg=(struct sockaddr_ipx *)&rt.rt_gateway; - st=(struct sockaddr_ipx *)&rt.rt_dst; + sg = (struct sockaddr_ipx *)&rt.rt_gateway; + st = (struct sockaddr_ipx *)&rt.rt_dst; - if(!(rt.rt_flags&RTF_GATEWAY)) - return -EINVAL; /* Direct routes are fixed */ - if(sg->sipx_family!=AF_IPX) - return -EINVAL; - if(st->sipx_family!=AF_IPX) - return -EINVAL; + if(!(rt.rt_flags & RTF_GATEWAY)) + return (-EINVAL); /* Direct routes are fixed */ + if(sg->sipx_family != AF_IPX) + return (-EINVAL); + if(st->sipx_family != AF_IPX) + return (-EINVAL); switch(cmd) { case SIOCDELRT: - return ipxrtr_delete(st->sipx_network); + return (ipxrtr_delete(st->sipx_network)); + case SIOCADDRT: { struct ipx_route_definition f; f.ipx_network=st->sipx_network; f.ipx_router_network=sg->sipx_network; memcpy(f.ipx_router_node, sg->sipx_node, IPX_NODE_LEN); - return ipxrtr_create(&f); + return (ipxrtr_create(&f)); } + default: - return -EINVAL; + return (-EINVAL); } } static const char *ipx_frame_name(unsigned short frame) { - switch (ntohs(frame)) + switch(ntohs(frame)) { case ETH_P_IPX: - return "EtherII"; + return ("EtherII"); + case ETH_P_802_2: - return "802.2"; + return ("802.2"); + case ETH_P_SNAP: - return "SNAP"; + return ("SNAP"); + case ETH_P_802_3: - return "802.3"; + return ("802.3"); + case ETH_P_TR_802_2: - return "802.2TR"; + return ("802.2TR"); + default: - return "None"; + return ("None"); } } @@ -1496,43 +1474,44 @@ static int ipx_interface_get_info(char *buffer, char **start, off_t offset, int length, int dummy) { ipx_interface *i; - int len=0; - off_t pos=0; - off_t begin=0; + off_t begin = 0, pos = 0; + int len = 0; /* Theory.. Keep printing in the same place until we pass offset */ - len += sprintf (buffer,"%-11s%-15s%-9s%-11s%s\n", "Network", + len += sprintf(buffer,"%-11s%-15s%-9s%-11s%s\n", "Network", "Node_Address", "Primary", "Device", "Frame_Type"); - for (i = ipx_interfaces; i != NULL; i = i->if_next) { + for(i = ipx_interfaces; i != NULL; i = i->if_next) + { len += sprintf(buffer+len, "%08lX ", (long unsigned int)ntohl(i->if_netnum)); - len += sprintf (buffer+len,"%02X%02X%02X%02X%02X%02X ", + len += sprintf(buffer+len,"%02X%02X%02X%02X%02X%02X ", i->if_node[0], i->if_node[1], i->if_node[2], i->if_node[3], i->if_node[4], i->if_node[5]); len += sprintf(buffer+len, "%-9s", (i == ipx_primary_net) ? "Yes" : "No"); - len += sprintf (buffer+len, "%-11s", ipx_device_name(i)); - len += sprintf (buffer+len, "%s\n", + len += sprintf(buffer+len, "%-11s", ipx_device_name(i)); + len += sprintf(buffer+len, "%s\n", ipx_frame_name(i->if_dlink_type)); /* Are we still dumping unwanted data then discard the record */ - pos=begin+len; + pos = begin + len; - if(pos<offset) { - len=0; /* Keep dumping into the buffer start */ - begin=pos; + if(pos < offset) + { + len = 0; /* Keep dumping into the buffer start */ + begin = pos; } - if(pos>offset+length) /* We have dumped enough */ + if(pos > offset + length) /* We have dumped enough */ break; } /* The data in question runs from begin to begin+len */ - *start=buffer+(offset-begin); /* Start of wanted data */ - len-=(offset-begin); /* Remove unwanted header data from length */ - if(len>length) - len=length; /* Remove unwanted tail data from length */ + *start = buffer + (offset - begin); /* Start of wanted data */ + len -= (offset - begin); /* Remove unwanted header data from length */ + if(len > length) + len = length; /* Remove unwanted tail data from length */ - return len; + return (len); } static int ipx_get_info(char *buffer, char **start, off_t offset, @@ -1540,21 +1519,23 @@ static int ipx_get_info(char *buffer, char **start, off_t offset, { struct sock *s; ipx_interface *i; - int len=0; - off_t pos=0; - off_t begin=0; + off_t begin = 0, pos = 0; + int len = 0; /* Theory.. Keep printing in the same place until we pass offset */ #ifdef CONFIG_IPX_INTERN - len += sprintf (buffer,"%-28s%-28s%-10s%-10s%-7s%s\n", "Local_Address", + len += sprintf(buffer,"%-28s%-28s%-10s%-10s%-7s%s\n", "Local_Address", #else - len += sprintf (buffer,"%-15s%-28s%-10s%-10s%-7s%s\n", "Local_Address", -#endif + len += sprintf(buffer,"%-15s%-28s%-10s%-10s%-7s%s\n", "Local_Address", +#endif /* CONFIG_IPX_INTERN */ "Remote_Address", "Tx_Queue", "Rx_Queue", "State", "Uid"); - for (i = ipx_interfaces; i != NULL; i = i->if_next) { - for (s = i->if_sklist; s != NULL; s = s->next) { + + for(i = ipx_interfaces; i != NULL; i = i->if_next) + { + for(s = i->if_sklist; s != NULL; s = s->next) + { #ifdef CONFIG_IPX_INTERN len += sprintf(buffer+len, "%08lX:%02X%02X%02X%02X%02X%02X:%04X ", @@ -1570,11 +1551,13 @@ static int ipx_get_info(char *buffer, char **start, off_t offset, len += sprintf(buffer+len,"%08lX:%04X ", htonl(i->if_netnum), htons(s->protinfo.af_ipx.port)); -#endif - if (s->state!=TCP_ESTABLISHED) { +#endif /* CONFIG_IPX_INTERN */ + + if(s->state != TCP_ESTABLISHED) len += sprintf(buffer+len, "%-28s", "Not_Connected"); - } else { - len += sprintf (buffer+len, + else + { + len += sprintf(buffer+len, "%08lX:%02X%02X%02X%02X%02X%02X:%04X ", (long unsigned int) htonl(s->protinfo.af_ipx.dest_addr.net), s->protinfo.af_ipx.dest_addr.node[0], @@ -1585,92 +1568,99 @@ static int ipx_get_info(char *buffer, char **start, off_t offset, s->protinfo.af_ipx.dest_addr.node[5], htons(s->protinfo.af_ipx.dest_addr.sock)); } - len += sprintf (buffer+len,"%08X %08X ", + + len += sprintf(buffer+len,"%08X %08X ", atomic_read(&s->wmem_alloc), - atomic_read(&s->rmem_alloc)); - len += sprintf (buffer+len,"%02X %03d\n", + atomic_read(&s->rmem_alloc)); + len += sprintf(buffer+len,"%02X %03d\n", s->state, SOCK_INODE(s->socket)->i_uid); - /* Are we still dumping unwanted data then discard the record */ - pos=begin+len; - - if(pos<offset) + pos = begin + len; + if(pos < offset) { - len=0; /* Keep dumping into the buffer start */ - begin=pos; + len = 0; + begin = pos; } - if(pos>offset+length) /* We have dumped enough */ + + if(pos > offset + length) /* We have dumped enough */ break; } } /* The data in question runs from begin to begin+len */ - *start=buffer+(offset-begin); /* Start of wanted data */ - len-=(offset-begin); /* Remove unwanted header data from length */ - if(len>length) - len=length; /* Remove unwanted tail data from length */ + *start = buffer + (offset-begin); + len -= (offset - begin); + if(len > length) + len = length; - return len; + return (len); } static int ipx_rt_get_info(char *buffer, char **start, off_t offset, int length, int dummy) { ipx_route *rt; - int len=0; - off_t pos=0; - off_t begin=0; + off_t begin = 0, pos = 0; + int len = 0; - len += sprintf (buffer,"%-11s%-13s%s\n", + len += sprintf(buffer,"%-11s%-13s%s\n", "Network", "Router_Net", "Router_Node"); - for (rt = ipx_routes; rt != NULL; rt = rt->ir_next) + for(rt = ipx_routes; rt != NULL; rt = rt->ir_next) { - len += sprintf (buffer+len,"%08lX ", (long unsigned int) ntohl(rt->ir_net)); - if (rt->ir_routed) { - len += sprintf (buffer+len,"%08lX %02X%02X%02X%02X%02X%02X\n", + len += sprintf(buffer+len,"%08lX ", (long unsigned int) ntohl(rt->ir_net)); + if(rt->ir_routed) + { + len += sprintf(buffer+len,"%08lX %02X%02X%02X%02X%02X%02X\n", (long unsigned int) ntohl(rt->ir_intrfc->if_netnum), rt->ir_router_node[0], rt->ir_router_node[1], rt->ir_router_node[2], rt->ir_router_node[3], rt->ir_router_node[4], rt->ir_router_node[5]); - } else { - len += sprintf (buffer+len, "%-13s%s\n", + } + else + { + len += sprintf(buffer+len, "%-13s%s\n", "Directly", "Connected"); } - pos=begin+len; - if(pos<offset) + + pos = begin + len; + if(pos < offset) { - len=0; - begin=pos; + len = 0; + begin = pos; } - if(pos>offset+length) + + if(pos > offset + length) break; } - *start=buffer+(offset-begin); - len-=(offset-begin); - if(len>length) - len=length; - return len; + + *start = buffer + (offset - begin); + len -= (offset - begin); + if(len > length) + len = length; + + return (len); } -/*******************************************************************************************************************\ -* * -* Handling for system calls applied via the various interfaces to an IPX socket object * -* * -\*******************************************************************************************************************/ +/**************************************************************************\ +* * +* Handling for system calls applied via the various interfaces to an * +* IPX socket object. * +* * +\**************************************************************************/ static int ipx_setsockopt(struct socket *sock, int level, int optname, char *optval, int optlen) { struct sock *sk; - int err,opt; + int err, opt; - sk=sock->sk; + sk = sock->sk; - if (optlen!=sizeof(int)) - return(-EINVAL); + if(optlen != sizeof(int)) + return (-EINVAL); err = get_user(opt, (unsigned int *)optval); - if (err) - return err; + if(err) + return (err); switch(level) { @@ -1678,15 +1668,16 @@ static int ipx_setsockopt(struct socket *sock, int level, int optname, char *opt switch(optname) { case IPX_TYPE: - sk->protinfo.af_ipx.type=opt; - return 0; + sk->protinfo.af_ipx.type = opt; + return (0); + default: - return -ENOPROTOOPT; + return (-ENOPROTOOPT); } break; default: - return -ENOPROTOOPT; + return (-ENOPROTOOPT); } } @@ -1697,142 +1688,157 @@ static int ipx_getsockopt(struct socket *sock, int level, int optname, int val=0; int len; - sk=sock->sk; + sk = sock->sk; switch(level) { - case SOL_IPX: switch(optname) { case IPX_TYPE: - val=sk->protinfo.af_ipx.type; + val = sk->protinfo.af_ipx.type; break; + default: - return -ENOPROTOOPT; + return (-ENOPROTOOPT); } break; default: - return -ENOPROTOOPT; + return (-ENOPROTOOPT); } - if(get_user(len,optlen)) - return -EFAULT; - len=min(len,sizeof(int)); + + if(get_user(len, optlen)) + return (-EFAULT); + + len = min(len, sizeof(int)); if(put_user(len, optlen)) - return -EFAULT; - if(copy_to_user(optval,&val,len)) - return -EFAULT; - return 0; + return (-EFAULT); + + if(copy_to_user(optval, &val, len)) + return (-EFAULT); + + return (0); } static int ipx_create(struct socket *sock, int protocol) { struct sock *sk; + switch(sock->type) { case SOCK_DGRAM: - sk=sk_alloc(AF_IPX, GFP_KERNEL, 1); - if(sk==NULL) - return(-ENOMEM); + sk = sk_alloc(PF_IPX, GFP_KERNEL, 1); + if(sk == NULL) + return (-ENOMEM); sock->ops = &ipx_dgram_ops; break; + case SOCK_SEQPACKET: /* - * From this point on SPX sockets are handled - * by af_spx.c and the methods replaced. + * From this point on SPX sockets are handled + * by af_spx.c and the methods replaced. */ if(spx_family_ops) - return spx_family_ops->create(sock,protocol); - /* Fall through if SPX is not loaded */ - case SOCK_STREAM: /* Allow higher levels to piggyback */ + return (spx_family_ops->create(sock,protocol)); + /* Fall through if SPX is not loaded */ + case SOCK_STREAM: /* Allow higher levels to piggyback */ default: - return(-ESOCKTNOSUPPORT); + return (-ESOCKTNOSUPPORT); } - sock_init_data(sock,sk); - sk->destruct=NULL; - sk->mtu=IPX_MTU; - sk->no_check = 1; /* Checksum off by default */ + + sock_init_data(sock, sk); + sk->destruct = NULL; + sk->mtu = IPX_MTU; + sk->no_check = 1; /* Checksum off by default */ + MOD_INC_USE_COUNT; - return 0; + + return (0); } static int ipx_release(struct socket *sock, struct socket *peer) { - struct sock *sk=sock->sk; - if(sk==NULL) - return(0); + struct sock *sk = sock->sk; + + if(sk == NULL) + return (0); + if(!sk->dead) sk->state_change(sk); - sk->dead=1; - sock->sk=NULL; + + sk->dead = 1; + sock->sk = NULL; ipx_destroy_socket(sk); - if ( sock->type == SOCK_DGRAM ) { + + if(sock->type == SOCK_DGRAM) MOD_DEC_USE_COUNT; - } - return(0); + + return (0); } static unsigned short ipx_first_free_socketnum(ipx_interface *intrfc) { - unsigned short socketNum = intrfc->if_sknum; + unsigned short socketNum = intrfc->if_sknum; - if (socketNum < IPX_MIN_EPHEMERAL_SOCKET) + if(socketNum < IPX_MIN_EPHEMERAL_SOCKET) socketNum = IPX_MIN_EPHEMERAL_SOCKET; - while (ipxitf_find_socket(intrfc, ntohs(socketNum)) != NULL) - if (socketNum > IPX_MAX_EPHEMERAL_SOCKET) + while(ipxitf_find_socket(intrfc, ntohs(socketNum)) != NULL) + { + if(socketNum > IPX_MAX_EPHEMERAL_SOCKET) socketNum = IPX_MIN_EPHEMERAL_SOCKET; else socketNum++; + } intrfc->if_sknum = socketNum; - return ntohs(socketNum); + + return (ntohs(socketNum)); } static int ipx_bind(struct socket *sock, struct sockaddr *uaddr, int addr_len) { struct sock *sk; ipx_interface *intrfc; - struct sockaddr_ipx *addr=(struct sockaddr_ipx *)uaddr; + struct sockaddr_ipx *addr = (struct sockaddr_ipx *)uaddr; - sk=sock->sk; + sk = sock->sk; - if(sk->zapped==0) - return -EINVAL; + if(sk->zapped == 0) + return (-EINVAL); - if(addr_len!=sizeof(struct sockaddr_ipx)) - return -EINVAL; + if(addr_len != sizeof(struct sockaddr_ipx)) + return (-EINVAL); intrfc = ipxitf_find_using_net(addr->sipx_network); - if (intrfc == NULL) - return -EADDRNOTAVAIL; + if(intrfc == NULL) + return (-EADDRNOTAVAIL); - if (addr->sipx_port == 0) { + if(addr->sipx_port == 0) + { addr->sipx_port = ipx_first_free_socketnum(intrfc); - if (addr->sipx_port == 0) - return -EINVAL; + if(addr->sipx_port == 0) + return (-EINVAL); } - if(ntohs(addr->sipx_port)<IPX_MIN_EPHEMERAL_SOCKET && !suser()) - return -EACCES; /* protect IPX system stuff like routing/sap */ + /* protect IPX system stuff like routing/sap */ + if(ntohs(addr->sipx_port) < IPX_MIN_EPHEMERAL_SOCKET && !suser()) + return (-EACCES); - sk->protinfo.af_ipx.port=addr->sipx_port; + sk->protinfo.af_ipx.port = addr->sipx_port; #ifdef CONFIG_IPX_INTERN - if (intrfc == ipx_internal_net) + if(intrfc == ipx_internal_net) { /* The source address is to be set explicitly if the * socket is to be bound on the internal network. If a * node number 0 was specified, the default is used. */ - if (memcmp(addr->sipx_node, ipx_broadcast_node, - IPX_NODE_LEN) == 0) - { - return -EINVAL; - } - if (memcmp(addr->sipx_node, ipx_this_node, IPX_NODE_LEN) == 0) + if(memcmp(addr->sipx_node,ipx_broadcast_node,IPX_NODE_LEN) == 0) + return (-EINVAL); + if(memcmp(addr->sipx_node, ipx_this_node, IPX_NODE_LEN) == 0) { memcpy(sk->protinfo.af_ipx.node, intrfc->if_node, IPX_NODE_LEN); @@ -1841,14 +1847,15 @@ static int ipx_bind(struct socket *sock, struct sockaddr *uaddr, int addr_len) { memcpy(sk->protinfo.af_ipx.node, addr->sipx_node, IPX_NODE_LEN); } - if (ipxitf_find_internal_socket(intrfc, + + if(ipxitf_find_internal_socket(intrfc, sk->protinfo.af_ipx.node, sk->protinfo.af_ipx.port) != NULL) { SOCK_DEBUG(sk, "IPX: bind failed because port %X in use.\n", ntohs((int)addr->sipx_port)); - return -EADDRINUSE; + return (-EADDRINUSE); } } else @@ -1861,85 +1868,96 @@ static int ipx_bind(struct socket *sock, struct sockaddr *uaddr, int addr_len) memcpy(sk->protinfo.af_ipx.node, intrfc->if_node, IPX_NODE_LEN); - if(ipxitf_find_socket(intrfc, addr->sipx_port)!=NULL) { + if(ipxitf_find_socket(intrfc, addr->sipx_port) != NULL) + { SOCK_DEBUG(sk, "IPX: bind failed because port %X in use.\n", ntohs((int)addr->sipx_port)); - return -EADDRINUSE; + return (-EADDRINUSE); } } -#else +#else /* !def CONFIG_IPX_INTERN */ /* Source addresses are easy. It must be our network:node pair for an interface routed to IPX with the ipx routing ioctl() */ - if(ipxitf_find_socket(intrfc, addr->sipx_port)!=NULL) { + if(ipxitf_find_socket(intrfc, addr->sipx_port) != NULL) + { SOCK_DEBUG(sk, "IPX: bind failed because port %X in use.\n", ntohs((int)addr->sipx_port)); - return -EADDRINUSE; + return (-EADDRINUSE); } -#endif +#endif /* CONFIG_IPX_INTERN */ ipxitf_insert_socket(intrfc, sk); - sk->zapped=0; + sk->zapped = 0; SOCK_DEBUG(sk, "IPX: bound socket 0x%04X.\n", ntohs(addr->sipx_port) ); - return 0; + return (0); } static int ipx_connect(struct socket *sock, struct sockaddr *uaddr, int addr_len, int flags) { - struct sock *sk=sock->sk; + struct sock *sk = sock->sk; struct sockaddr_ipx *addr; - sk->state = TCP_CLOSE; - sock->state = SS_UNCONNECTED; + sk->state = TCP_CLOSE; + sock->state = SS_UNCONNECTED; - if(addr_len!=sizeof(*addr)) - return(-EINVAL); - addr=(struct sockaddr_ipx *)uaddr; + if(addr_len != sizeof(*addr)) + return (-EINVAL); + addr = (struct sockaddr_ipx *)uaddr; - if(sk->protinfo.af_ipx.port==0) /* 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; + 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 - ret = ipx_bind (sock, (struct sockaddr *)&uaddr, +#endif /* CONFIG_IPX_INTERN */ + + ret = ipx_bind(sock, (struct sockaddr *)&uaddr, sizeof(struct sockaddr_ipx)); - if (ret != 0) return (ret); + if(ret != 0) + return (ret); } - if(ipxrtr_lookup(addr->sipx_network)==NULL) - return -ENETUNREACH; - sk->protinfo.af_ipx.dest_addr.net=addr->sipx_network; - sk->protinfo.af_ipx.dest_addr.sock=addr->sipx_port; + if(ipxrtr_lookup(addr->sipx_network) == NULL) + return (-ENETUNREACH); + + sk->protinfo.af_ipx.dest_addr.net = addr->sipx_network; + sk->protinfo.af_ipx.dest_addr.sock = addr->sipx_port; memcpy(sk->protinfo.af_ipx.dest_addr.node, addr->sipx_node,IPX_NODE_LEN); - sk->protinfo.af_ipx.type=addr->sipx_type; - if(sock->type == SOCK_DGRAM ) { - sock->state = SS_CONNECTED; - sk->state=TCP_ESTABLISHED; + sk->protinfo.af_ipx.type = addr->sipx_type; + + if(sock->type == SOCK_DGRAM ) + { + sock->state = SS_CONNECTED; + sk->state = TCP_ESTABLISHED; } - return 0; + + return (0); } static int ipx_accept(struct socket *sock, struct socket *newsock, int flags) { - if(newsock->sk) { + if(newsock->sk) + { sk_free(newsock->sk); MOD_DEC_USE_COUNT; } - return -EOPNOTSUPP; + + return (-EOPNOTSUPP); } static int ipx_getname(struct socket *sock, struct sockaddr *uaddr, @@ -1949,163 +1967,105 @@ static int ipx_getname(struct socket *sock, struct sockaddr *uaddr, struct sockaddr_ipx sipx; struct sock *sk; - sk=sock->sk; + sk = sock->sk; *uaddr_len = sizeof(struct sockaddr_ipx); - if(peer) { - if(sk->state!=TCP_ESTABLISHED) - return -ENOTCONN; - addr=&sk->protinfo.af_ipx.dest_addr; + if(peer) + { + if(sk->state != TCP_ESTABLISHED) + return (-ENOTCONN); + + addr = &sk->protinfo.af_ipx.dest_addr; sipx.sipx_network = addr->net; memcpy(sipx.sipx_node,addr->node,IPX_NODE_LEN); sipx.sipx_port = addr->sock; - } else { - if (sk->protinfo.af_ipx.intrfc != NULL) { - sipx.sipx_network = sk->protinfo.af_ipx.intrfc->if_netnum; + } + else + { + if(sk->protinfo.af_ipx.intrfc != NULL) + { + sipx.sipx_network=sk->protinfo.af_ipx.intrfc->if_netnum; #ifdef CONFIG_IPX_INTERN memcpy(sipx.sipx_node, sk->protinfo.af_ipx.node, IPX_NODE_LEN); #else - memcpy(sipx.sipx_node, - sk->protinfo.af_ipx.intrfc->if_node, IPX_NODE_LEN); -#endif + memcpy(sipx.sipx_node, sk->protinfo.af_ipx.intrfc->if_node, IPX_NODE_LEN); +#endif /* CONFIG_IPX_INTERN */ - } else { + } + else + { sipx.sipx_network = 0; memset(sipx.sipx_node, '\0', IPX_NODE_LEN); } + sipx.sipx_port = sk->protinfo.af_ipx.port; } sipx.sipx_family = AF_IPX; - sipx.sipx_type = sk->protinfo.af_ipx.type; + sipx.sipx_type = sk->protinfo.af_ipx.type; memcpy(uaddr,&sipx,sizeof(sipx)); - return 0; -} -#if 0 -/* - * User to dump IPX packets (debugging) - */ -void dump_data(char *str,unsigned char *d, int len) -{ - static char h2c[] = "0123456789ABCDEF"; - int l,i; - char *p, b[64]; - for (l=0;len > 0 && l<16;l++) - { - p = b; - for (i=0; i < 8 ; i++, --len) - { - if (len > 0) - { - *(p++) = h2c[(d[i] >> 4) & 0x0f]; - *(p++) = h2c[d[i] & 0x0f]; - } - else - { - *(p++) = ' '; - *(p++) = ' '; - } - *(p++) = ' '; - } - *(p++) = '-'; - *(p++) = ' '; - len += 8; - for (i=0; i < 8 ; i++, --len) - { - if (len > 0) - *(p++) = ' '<= d[i] && d[i]<'\177' ? d[i] : '.'; - else - *(p++) = ' '; - } - *p = '\000'; - d += i; - printk(KERN_DEBUG"%s-%04X: %s\n",str,l*8,b); - } -} - -void dump_addr(char *str,ipx_address *p) -{ - printk(KERN_DEBUG"%s: %08lX:%02X%02X%02X%02X%02X%02X:%04X\n", - str,(long unsigned int)ntohl(p->net),p->node[0],p->node[1],p->node[2], - p->node[3],p->node[4],p->node[5],ntohs(p->sock)); -} - -void dump_hdr(char *str,struct ipxhdr *p) -{ - printk(KERN_DEBUG"%s: CHKSUM=%04X SIZE=%d (%04X) HOPS=%d (%02X) TYPE=%02X\n", - str,p->ipx_checksum,ntohs(p->ipx_pktsize),ntohs(p->ipx_pktsize), - p->ipx_tctrl,p->ipx_tctrl,p->ipx_type); - dump_addr(" IPX-DST",&p->ipx_dest); - dump_addr(" IPX-SRC",&p->ipx_source); -} - -void dump_pkt(char *str,struct ipxhdr *p) -{ - int len = ntohs(p->ipx_pktsize); - dump_hdr(str,p); - if (len > 30) - dump_data(str,(unsigned char *)p + 30, len - 30); + return (0); } -#endif int ipx_rcv(struct sk_buff *skb, struct device *dev, struct packet_type *pt) { /* NULL here for pt means the packet was looped back */ - ipx_interface *intrfc; + ipx_interface *intrfc; struct ipxhdr *ipx; ipx = skb->nh.ipxh; /* Too small? */ - if(ntohs(ipx->ipx_pktsize)<sizeof(struct ipxhdr)) { + if(ntohs(ipx->ipx_pktsize) < sizeof(struct ipxhdr)) + { kfree_skb(skb); - return 0; + return (0); } - if(ipx->ipx_checksum!=IPX_NO_CHECKSUM) + if(ipx->ipx_checksum != IPX_NO_CHECKSUM) { - if(ipx_set_checksum(ipx, ntohs(ipx->ipx_pktsize))!=ipx->ipx_checksum) + if(ipx_set_checksum(ipx, ntohs(ipx->ipx_pktsize)) != ipx->ipx_checksum) { kfree_skb(skb); - return 0; + return (0); } } /* Determine what local ipx endpoint this is */ intrfc = ipxitf_find_using_phys(dev, pt->type); - if (intrfc == NULL) + if(intrfc == NULL) { - if (ipxcfg_auto_create_interfaces && - ntohl(ipx->ipx_dest.net)!=0L) + if(ipxcfg_auto_create_interfaces + && ntohl(ipx->ipx_dest.net) != 0L) { intrfc = ipxitf_auto_create(dev, pt->type); } - if (intrfc == NULL) { - /* Not one of ours */ + if(intrfc == NULL) /* Not one of ours */ + { kfree_skb(skb); - return 0; + return (0); } } - return ipxitf_rcv(intrfc, skb); + return (ipxitf_rcv(intrfc, skb)); } static int ipx_sendmsg(struct socket *sock, struct msghdr *msg, int len, struct scm_cookie *scm) { - struct sock *sk=sock->sk; + struct sock *sk = sock->sk; struct sockaddr_ipx *usipx=(struct sockaddr_ipx *)msg->msg_name; struct sockaddr_ipx local_sipx; int retval; int flags = msg->msg_flags; - if (sk->zapped) - return -EIO; /* Socket not bound */ - if (flags&~MSG_DONTWAIT) - return -EINVAL; + if(sk->zapped) + return (-EIO); /* Socket not bound */ + if(flags & ~MSG_DONTWAIT) + return (-EINVAL); if(usipx) { @@ -2120,192 +2080,200 @@ static int ipx_sendmsg(struct socket *sock, struct msghdr *msg, int len, memcpy(uaddr.sipx_node, sk->protinfo.af_ipx.intrfc ->if_node, IPX_NODE_LEN); #endif - ret = ipx_bind (sock, (struct sockaddr *)&uaddr, + ret = ipx_bind(sock, (struct sockaddr *)&uaddr, sizeof(struct sockaddr_ipx)); - if (ret != 0) return ret; + if(ret != 0) + return (ret); } - if(msg->msg_namelen <sizeof(*usipx)) - return -EINVAL; + if(msg->msg_namelen < sizeof(*usipx)) + return (-EINVAL); if(usipx->sipx_family != AF_IPX) - return -EINVAL; + return (-EINVAL); } else { - if(sk->state!=TCP_ESTABLISHED) - return -ENOTCONN; + if(sk->state != TCP_ESTABLISHED) + return (-ENOTCONN); + usipx=&local_sipx; - usipx->sipx_family=AF_IPX; - usipx->sipx_type=sk->protinfo.af_ipx.type; - usipx->sipx_port=sk->protinfo.af_ipx.dest_addr.sock; - usipx->sipx_network=sk->protinfo.af_ipx.dest_addr.net; + usipx->sipx_family = AF_IPX; + usipx->sipx_type = sk->protinfo.af_ipx.type; + usipx->sipx_port = sk->protinfo.af_ipx.dest_addr.sock; + usipx->sipx_network = sk->protinfo.af_ipx.dest_addr.net; 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); - if (retval < 0) - return retval; + if(retval < 0) + return (retval); - return len; + return (len); } static int ipx_recvmsg(struct socket *sock, struct msghdr *msg, int size, int flags, struct scm_cookie *scm) { - struct sock *sk=sock->sk; - struct sockaddr_ipx *sipx=(struct sockaddr_ipx *)msg->msg_name; + struct sock *sk = sock->sk; + struct sockaddr_ipx *sipx = (struct sockaddr_ipx *)msg->msg_name; struct ipxhdr *ipx = NULL; struct sk_buff *skb; int copied, err; - if (sk->zapped) - return -ENOTCONN; + if(sk->zapped) + return (-ENOTCONN); - skb=skb_recv_datagram(sk,flags&~MSG_DONTWAIT,flags&MSG_DONTWAIT,&err); - if (!skb) + skb = skb_recv_datagram(sk,flags&~MSG_DONTWAIT,flags&MSG_DONTWAIT,&err); + if(!skb) goto out; - ipx = skb->nh.ipxh; - copied = ntohs(ipx->ipx_pktsize) - sizeof(struct ipxhdr); + ipx = skb->nh.ipxh; + copied = ntohs(ipx->ipx_pktsize) - sizeof(struct ipxhdr); if(copied > size) { copied=size; - msg->msg_flags|=MSG_TRUNC; + msg->msg_flags |= MSG_TRUNC; } err = skb_copy_datagram_iovec(skb, sizeof(struct ipxhdr), msg->msg_iov, copied); - if (err) + if(err) goto out_free; - sk->stamp=skb->stamp; + sk->stamp = skb->stamp; msg->msg_namelen = sizeof(*sipx); if(sipx) { - sipx->sipx_family=AF_IPX; - sipx->sipx_port=ipx->ipx_source.sock; + sipx->sipx_family = AF_IPX; + sipx->sipx_port = ipx->ipx_source.sock; memcpy(sipx->sipx_node,ipx->ipx_source.node,IPX_NODE_LEN); - sipx->sipx_network=ipx->ipx_source.net; - sipx->sipx_type = ipx->ipx_type; + sipx->sipx_network = ipx->ipx_source.net; + sipx->sipx_type = ipx->ipx_type; } err = copied; out_free: skb_free_datagram(sk, skb); out: - return err; + return (err); } /* - * FIXME: We have to support shutdown really. + * FIXME: We have to really support shutdown. */ - static int ipx_shutdown(struct socket *sk,int how) { - return -EOPNOTSUPP; + return (-EOPNOTSUPP); } static int ipx_ioctl(struct socket *sock,unsigned int cmd, unsigned long arg) { - long amount=0; - struct sock *sk=sock->sk; + long amount = 0; + struct sock *sk = sock->sk; switch(cmd) { case TIOCOUTQ: amount = sk->sndbuf - atomic_read(&sk->wmem_alloc); - if(amount<0) - amount=0; - return put_user(amount, (int *)arg); + if(amount < 0) + amount = 0; + return (put_user(amount, (int *)arg)); + case TIOCINQ: { struct sk_buff *skb; /* These two are safe on a single CPU system as only user tasks fiddle here */ - if((skb=skb_peek(&sk->receive_queue))!=NULL) - amount=skb->len-sizeof(struct ipxhdr); - return put_user(amount, (int *)arg); + if((skb = skb_peek(&sk->receive_queue)) != NULL) + amount = skb->len - sizeof(struct ipxhdr); + return (put_user(amount, (int *)arg)); } + case SIOCADDRT: case SIOCDELRT: if(!suser()) - return -EPERM; - return(ipxrtr_ioctl(cmd,(void *)arg)); + return (-EPERM); + return (ipxrtr_ioctl(cmd,(void *)arg)); + case SIOCSIFADDR: case SIOCAIPXITFCRT: case SIOCAIPXPRISLT: if(!suser()) - return -EPERM; + return (-EPERM); + case SIOCGIFADDR: - return(ipxitf_ioctl(cmd,(void *)arg)); + return (ipxitf_ioctl(cmd,(void *)arg)); + case SIOCIPXCFGDATA: - { - return(ipxcfg_get_config_data((void *)arg)); - } + return (ipxcfg_get_config_data((void *)arg)); + case SIOCGSTAMP: { int ret = -EINVAL; - if (sk) + if(sk) { - if(sk->stamp.tv_sec==0) - return -ENOENT; + if(sk->stamp.tv_sec == 0) + return (-ENOENT); ret = -EFAULT; - if (!copy_to_user((void *)arg, &sk->stamp, + if(!copy_to_user((void *)arg, &sk->stamp, sizeof(struct timeval))) ret = 0; } - return ret; + + return (ret); } + case SIOCGIFDSTADDR: case SIOCSIFDSTADDR: case SIOCGIFBRDADDR: case SIOCSIFBRDADDR: case SIOCGIFNETMASK: case SIOCSIFNETMASK: - return -EINVAL; + return (-EINVAL); + default: - return(dev_ioctl(cmd,(void *) arg)); + return (dev_ioctl(cmd,(void *) arg)); } - /*NOTREACHED*/ - return(0); + + /*NOT REACHED*/ + return (0); } /* - * SPX interface support + * SPX interface support */ int ipx_register_spx(struct proto_ops **p, struct net_proto_family *spx) { - if(spx_family_ops!=NULL) - return -EBUSY; - cli(); - MOD_INC_USE_COUNT; - *p=&ipx_dgram_ops; - spx_family_ops=spx; - sti(); - return 0; + if(spx_family_ops!=NULL) + return -EBUSY; + cli(); + MOD_INC_USE_COUNT; + *p=&ipx_dgram_ops; + spx_family_ops=spx; + sti(); + return 0; } int ipx_unregister_spx(void) { - spx_family_ops=NULL; - MOD_DEC_USE_COUNT; - return 0; + spx_family_ops=NULL; + MOD_DEC_USE_COUNT; + return 0; } - /* - * Socket family declarations + * Socket family declarations */ - + static struct net_proto_family ipx_family_ops = { - AF_IPX, + PF_IPX, ipx_create }; static struct proto_ops ipx_dgram_ops = { - AF_IPX, + PF_IPX, sock_no_dup, ipx_release, ipx_bind, @@ -2352,10 +2320,10 @@ static struct notifier_block ipx_dev_notifier={ }; -extern struct datalink_proto *make_EII_client(void); -extern struct datalink_proto *make_8023_client(void); -extern void destroy_EII_client(struct datalink_proto *); -extern void destroy_8023_client(struct datalink_proto *); +extern struct datalink_proto *make_EII_client(void); +extern struct datalink_proto *make_8023_client(void); +extern void destroy_EII_client(struct datalink_proto *); +extern void destroy_8023_client(struct datalink_proto *); struct proc_dir_entry ipx_procinfo = { PROC_NET_IPX, 3, "ipx", S_IFREG | S_IRUGO, @@ -2372,32 +2340,29 @@ struct proc_dir_entry ipx_rt_procinfo = { 1, 0, 0, 0, &proc_net_inode_operations, ipx_rt_get_info }; -static unsigned char ipx_8022_type = 0xE0; -static unsigned char ipx_snap_id[5] = { 0x0, 0x0, 0x0, 0x81, 0x37 }; +static unsigned char ipx_8022_type = 0xE0; +static unsigned char ipx_snap_id[5] = { 0x0, 0x0, 0x0, 0x81, 0x37 }; -void -ipx_proto_init(struct net_proto *pro) +void ipx_proto_init(struct net_proto *pro) { (void) sock_register(&ipx_family_ops); pEII_datalink = make_EII_client(); - ipx_dix_packet_type.type=htons(ETH_P_IPX); + ipx_dix_packet_type.type = htons(ETH_P_IPX); dev_add_pack(&ipx_dix_packet_type); p8023_datalink = make_8023_client(); - ipx_8023_packet_type.type=htons(ETH_P_802_3); + ipx_8023_packet_type.type = htons(ETH_P_802_3); dev_add_pack(&ipx_8023_packet_type); - if ((p8022_datalink = register_8022_client(ipx_8022_type, ipx_rcv)) == NULL) + if((p8022_datalink = register_8022_client(ipx_8022_type,ipx_rcv)) == NULL) printk(KERN_CRIT "IPX: Unable to register with 802.2\n"); - if ((p8022tr_datalink = register_8022tr_client(ipx_8022_type, ipx_rcv)) == NULL) - printk(KERN_CRIT "IPX: Unable to register with 802.2TR\n"); - - if ((pSNAP_datalink = register_snap_client(ipx_snap_id, ipx_rcv)) == NULL) + if((pSNAP_datalink = register_snap_client(ipx_snap_id,ipx_rcv)) == NULL) printk(KERN_CRIT "IPX: Unable to register with SNAP\n"); register_netdevice_notifier(&ipx_dev_notifier); + #ifdef CONFIG_PROC_FS proc_net_register(&ipx_procinfo); proc_net_register(&ipx_if_procinfo); @@ -2414,7 +2379,8 @@ int ipx_if_offset(unsigned long ipx_net_number) ipx_route *rt = NULL; rt = ipxrtr_lookup(ipx_net_number); - return ( rt ? rt->ir_intrfc->if_ipx_offset : -ENETUNREACH ); + + return (rt ? rt->ir_intrfc->if_ipx_offset : -ENETUNREACH); } /* Export symbols for higher layers */ @@ -2424,7 +2390,6 @@ EXPORT_SYMBOL(ipx_remove_socket); EXPORT_SYMBOL(ipx_register_spx); EXPORT_SYMBOL(ipx_unregister_spx); - #ifdef MODULE /* Note on MOD_{INC,DEC}_USE_COUNT: * @@ -2443,10 +2408,11 @@ static void ipx_proto_finito(void) { ipx_interface *ifc; - while (ipx_interfaces) { + while(ipx_interfaces) + { ifc = ipx_interfaces; - ipx_interfaces = ifc->if_next; - ifc->if_next = NULL; + ipx_interfaces = ifc->if_next; + ifc->if_next = NULL; ipxitf_down(ifc); } @@ -2459,21 +2425,18 @@ static void ipx_proto_finito(void) unregister_netdevice_notifier(&ipx_dev_notifier); unregister_snap_client(ipx_snap_id); - pSNAP_datalink = NULL; - - unregister_8022tr_client(ipx_8022_type); - p8022tr_datalink = NULL; + pSNAP_datalink = NULL; unregister_8022_client(ipx_8022_type); - p8022_datalink = NULL; + p8022_datalink = NULL; dev_remove_pack(&ipx_8023_packet_type); destroy_8023_client(p8023_datalink); - p8023_datalink = NULL; + p8023_datalink = NULL; dev_remove_pack(&ipx_dix_packet_type); destroy_EII_client(pEII_datalink); - pEII_datalink = NULL; + pEII_datalink = NULL; (void) sock_unregister(ipx_family_ops.family); @@ -2483,7 +2446,7 @@ static void ipx_proto_finito(void) int init_module(void) { ipx_proto_init(NULL); - return 0; + return (0); } void cleanup_module(void) @@ -2491,4 +2454,6 @@ void cleanup_module(void) ipx_proto_finito(); return; } -#endif /* def MODULE */ + +#endif /* MODULE */ +#endif /* CONFIG_IPX || CONFIG_IPX_MODULE */ diff --git a/net/ipx/af_spx.c b/net/ipx/af_spx.c index a14ad0a31..fb2cffeab 100644 --- a/net/ipx/af_spx.c +++ b/net/ipx/af_spx.c @@ -48,6 +48,8 @@ static void spx_retransmit(unsigned long data); static void spx_watchdog(unsigned long data); void spx_rcv(struct sock *sk, int bytes); +extern void ipx_remove_socket(struct sock *sk); + /* Create the SPX specific data */ static int spx_sock_init(struct sock *sk) { @@ -83,7 +85,7 @@ static int spx_create(struct socket *sock, int protocol) { struct sock *sk; - sk = sk_alloc(AF_IPX, GFP_KERNEL, 1); + sk = sk_alloc(PF_IPX, GFP_KERNEL, 1); if(sk == NULL) return (-ENOMEM); @@ -328,6 +330,8 @@ static int spx_connect(struct socket *sock, struct sockaddr *uaddr, * As we simply have a default retry time of 1*HZ and a max retry * time of 5*HZ. Between those values we increase the timeout based * on the number of retransmit tries. + * + * FixMe: This is quite fake, but will work for now. (JS) */ static inline unsigned long spx_calc_rtt(int tries) { @@ -344,11 +348,12 @@ static int spx_route_skb(struct spx_opt *pdata, struct sk_buff *skb, int type) int err = 0; skb = skb_unshare(skb, GFP_ATOMIC); - if(skb==NULL) - return -ENOBUFS; + if(skb == NULL) + return (-ENOBUFS); switch(type) { + case (CONREQ): case (DATA): if(!skb_queue_empty(&pdata->retransmit_queue)) { @@ -366,7 +371,6 @@ static int spx_route_skb(struct spx_opt *pdata, struct sk_buff *skb, int type) skb_queue_tail(&pdata->retransmit_queue, skb2); case (ACK): - case (CONREQ): case (CONACK): case (WDREQ): case (WDACK): @@ -388,7 +392,8 @@ static int spx_transmit(struct sock *sk, struct sk_buff *skb, int type, int len) { struct spx_opt *pdata = &sk->tp_pinfo.af_spx; struct ipxspxhdr *ipxh; - int flags, err; + unsigned long flags; + int err; if(skb == NULL) { @@ -397,11 +402,11 @@ static int spx_transmit(struct sock *sk, struct sk_buff *skb, int type, int len) save_flags(flags); cli(); - skb = sock_alloc_send_skb(sk, size, 0, 0, &err); + skb = sock_alloc_send_skb(sk, size, 1, 0, &err); if(skb == NULL) return (-ENOMEM); skb_reserve(skb, offset); - skb->nh.raw = skb_put(skb, sizeof(struct ipxspxhdr)); + skb->h.raw = skb->nh.raw = skb_put(skb,sizeof(struct ipxspxhdr)); restore_flags(flags); } @@ -435,10 +440,10 @@ static int spx_transmit(struct sock *sk, struct sk_buff *skb, int type, int len) pdata->sequence++; break; - case (ACK): /* Connection/WD/Data ACK */ + case (ACK): /* ACK */ pdata->rmt_seq++; - case (WDACK): - case (CONACK): + case (WDACK): /* WD ACK */ + case (CONACK): /* Connection ACK */ ipxh->spx.cctl = CCTL_SYS; ipxh->spx.ackseq = htons(pdata->rmt_seq); break; @@ -472,9 +477,7 @@ static int spx_transmit(struct sock *sk, struct sk_buff *skb, int type, int len) } /* Send data */ - spx_route_skb(pdata, skb, type); - - return (0); + return (spx_route_skb(pdata, skb, type)); } /* Check the state of the connection and send a WD request if needed. */ @@ -484,6 +487,8 @@ static void spx_watchdog(unsigned long data) struct spx_opt *pdata = &sk->tp_pinfo.af_spx; del_timer(&pdata->watchdog); + if(pdata->state == SPX_CLOSED) + return; if(pdata->retries > pdata->max_retries) { spx_close_socket(sk); /* Unilateral Abort */ @@ -502,21 +507,27 @@ static void spx_retransmit(unsigned long data) struct sock *sk = (struct sock*)data; struct spx_opt *pdata = &sk->tp_pinfo.af_spx; struct sk_buff *skb; + unsigned long flags; int err; del_timer(&pdata->retransmit); + if(pdata->state == SPX_CLOSED) + return; if(pdata->retransmits > RETRY_COUNT) { spx_close_socket(sk); /* Unilateral Abort */ return; } - /* need to leave skb on the queue! */ + /* Need to leave skb on the queue, aye the fear */ + save_flags(flags); + cli(); skb = skb_peek(&pdata->retransmit_queue); if(skb_cloned(skb)) skb = skb_copy(skb, GFP_ATOMIC); else skb = skb_clone(skb, GFP_ATOMIC); + restore_flags(flags); pdata->retransmit.expires = jiffies + spx_calc_rtt(pdata->retransmits); add_timer(&pdata->retransmit); @@ -527,13 +538,46 @@ static void spx_retransmit(unsigned long data) return; } +/* Check packet for retransmission, ConReqAck aware */ +static int spx_retransmit_chk(struct spx_opt *pdata, int ackseq, int type) +{ + struct ipxspxhdr *ipxh; + struct sk_buff *skb; + + skb = skb_dequeue(&pdata->retransmit_queue); + if(!skb) + return (-ENOENT); + + /* Check Data/ACK seq */ + switch(type) + { + case ACK: /* Check Sequence, Should == 1 */ + ipxh = (struct ipxspxhdr *)skb->nh.raw; + if(!(ntohs(ipxh->spx.sequence) - htons(ackseq))) + break; + + case CONACK: + del_timer(&pdata->retransmit); + pdata->retransmits = 0; + kfree_skb(skb); + if(skb_queue_empty(&pdata->retransmit_queue)) + { + skb = skb_dequeue(&pdata->transmit_queue); + if(skb != NULL) + spx_route_skb(pdata, skb, TQUEUE); + } + return (0); + } + + skb_queue_head(&pdata->retransmit_queue, skb); + return (-1); +} + /* SPX packet receive engine */ void spx_rcv(struct sock *sk, int bytes) { struct sk_buff *skb; - struct sk_buff *skb2; struct ipxspxhdr *ipxh; - struct ipxspxhdr *ipxh2; struct spx_opt *pdata = &sk->tp_pinfo.af_spx; skb = skb_dequeue(&sk->receive_queue); @@ -543,15 +587,13 @@ void spx_rcv(struct sock *sk, int bytes) /* Can't receive on a closed connection */ if((pdata->state == SPX_CLOSED) && (ipxh->spx.sequence != 0)) - return; + goto toss_skb; if(ntohs(ipxh->ipx.ipx_pktsize) < SPX_SYS_PKT_LEN) - return; + goto toss_skb; if(ipxh->ipx.ipx_type != IPX_TYPE_SPX) - return; - - /* insanity - rcv'd ACK of unsent data ?? */ + goto toss_skb; if(ntohs(ipxh->spx.ackseq) > pdata->sequence) - return; + goto toss_skb; /* Reset WD timer on any received packet */ del_timer(&pdata->watchdog); @@ -577,7 +619,7 @@ void spx_rcv(struct sock *sk, int bytes) } else /* WD Request */ spx_transmit(sk, skb, WDACK, 0); - break; + goto finish; case CCTL_SYS: /* ACK */ if((ipxh->spx.dtype == 0) /* ConReq ACK */ @@ -588,62 +630,56 @@ void spx_rcv(struct sock *sk, int bytes) && (pdata->state != SPX_CONNECTED)) { pdata->state = SPX_CONNECTED; + pdata->dest_connid = ipxh->spx.sconn; + + if(spx_retransmit_chk(pdata, 0, CONACK) < 0) + goto toss_skb; skb_queue_tail(&sk->receive_queue, skb); wake_up_interruptible(sk->sleep); - break; - } - - /* Check Data/ACK seq */ - skb2 = skb_dequeue(&pdata->retransmit_queue); - if(skb2) - { - ipxh2 = (struct ipxspxhdr *)skb2->nh.raw; - if((ntohs(ipxh2->spx.sequence) - == (ntohs(ipxh->spx.ackseq) - 1)) - || (ntohs(ipxh2->spx.sequence) == 65535 - && ntohs(ipxh->spx.ackseq) == 0)) - { - del_timer(&pdata->retransmit); - pdata->retransmits = 0; - kfree_skb(skb2); - if(skb_queue_empty(&pdata->retransmit_queue)) - { - skb2 = skb_dequeue(&pdata->transmit_queue); - if(skb2 != NULL) - spx_route_skb(pdata, skb2, TQUEUE); - } - } - else /* Out of Seq - ERROR! */ - skb_queue_head(&pdata->retransmit_queue, skb2); + goto finish; } - kfree_skb(skb); - break; + spx_retransmit_chk(pdata, ipxh->spx.ackseq, ACK); + goto toss_skb; - case (CCTL_ACK): /* Informed Disconnect */ + case (CCTL_ACK): + /* Informed Disconnect */ if(ipxh->spx.dtype == SPX_DTYPE_ECONN) { + spx_transmit(sk, skb, DISACK, 0); spx_close_socket(sk); + goto finish; } - break; + /* Fall through */ default: if(ntohs(ipxh->spx.sequence) == pdata->rmt_seq) { pdata->rmt_seq = ntohs(ipxh->spx.sequence); + pdata->rmt_ack = ntohs(ipxh->spx.ackseq); + if(pdata->rmt_ack > 0 || pdata->rmt_ack == 0) + spx_retransmit_chk(pdata,pdata->rmt_ack, ACK); + skb_queue_tail(&pdata->rcv_queue, skb); wake_up_interruptible(sk->sleep); - spx_transmit(sk, NULL, ACK, 0); - break; + if(ipxh->spx.cctl&CCTL_ACK) + spx_transmit(sk, NULL, ACK, 0); + goto finish; } - /* Catch All */ - kfree_skb(skb); - break; + if(ipxh->spx.dtype == SPX_DTYPE_ECACK) + { + if(pdata->state != SPX_CLOSED) + spx_close_socket(sk); + goto toss_skb; + } } +toss_skb: /* Catch All */ + kfree_skb(skb); +finish: return; } @@ -665,13 +701,16 @@ static int spx_sendmsg(struct socket *sock, struct msghdr *msg, int len, offset = ipx_if_offset(sk->tp_pinfo.af_spx.dest_addr.net); size = offset + sizeof(struct ipxspxhdr) + len; + + cli(); skb = sock_alloc_send_skb(sk, size, 0, flags&MSG_DONTWAIT, &err); if(skb == NULL) return (err); + sti(); skb->sk = sk; skb_reserve(skb, offset); - skb->nh.raw = skb_put(skb, sizeof(struct ipxspxhdr)); + skb->h.raw = skb->nh.raw = skb_put(skb, sizeof(struct ipxspxhdr)); err = memcpy_fromiovec(skb_put(skb, len), msg->msg_iov, len); if(err) @@ -806,7 +845,7 @@ static int spx_getsockopt(struct socket *sock, int level, int optname, } static struct proto_ops spx_operations = { - AF_IPX, + PF_IPX, sock_no_dup, spx_release, spx_bind, @@ -827,7 +866,7 @@ static struct proto_ops spx_operations = { static struct net_proto_family spx_family_ops= { - AF_IPX, + PF_IPX, spx_create }; @@ -842,9 +881,9 @@ void spx_proto_init(void) if (error) printk(KERN_ERR "SPX: unable to register with IPX.\n"); - /* route socket(AF_IPX, SOCK_SEQPACKET) calls through spx_create() */ + /* route socket(PF_IPX, SOCK_SEQPACKET) calls through spx_create() */ - printk(KERN_INFO "Sequenced Packet eXchange (SPX) 0.01 for Linux NET3.037\n"); + printk(KERN_INFO "Sequenced Packet eXchange (SPX) 0.02 for Linux NET3.037\n"); return; } |