--- net/ipx/af_ipx.c.orig Wed Nov 27 10:44:21 1996 +++ net/ipx/af_ipx.c Sat Feb 22 03:28:31 1997 @@ -722,6 +722,7 @@ static const char * ipx_frame_name(unsigned short); static const char * ipx_device_name(ipx_interface *); static int ipxrtr_route_skb(struct sk_buff *); +static int ipxrtr_route_skb_type20(ipx_interface *intrfc, struct sk_buff *); static int ipxitf_rcv(ipx_interface *intrfc, struct sk_buff *skb) { @@ -766,6 +767,22 @@ } } + /* + * "This shouldn't happen, but just in case" + */ + if (ipx->ipx_tctrl > ipxcfg_max_hops) + { + kfree_skb(skb, FREE_READ); + return 0; + } + + /* + * Do the IPX Packet Type 20 routing + */ + if (ipx->ipx_type == IPX_TYPE_PPROP) + return ipxrtr_route_skb_type20(intrfc, skb); + + if (ipx->ipx_dest.net == 0L) ipx->ipx_dest.net = intrfc->if_netnum; if (ipx->ipx_source.net == 0L) @@ -1371,6 +1388,51 @@ i = r->ir_intrfc; (void)ipxitf_send(i, skb, (r->ir_routed) ? r->ir_router_node : ipx->ipx_dest.node); + return 0; +} + +static int +ipxrtr_route_skb_type20(ipx_interface *intrfc, struct sk_buff *skb) +{ + ipx_packet *ipx = (ipx_packet *) (skb->h.raw); + unsigned long *net_num = (long *) (ipx + 1); + ipx_interface *ipx_if; + struct sk_buff *skb2; + int i; + + if (ipx->ipx_tctrl > 8) + { + kfree_skb(skb, FREE_READ); + return 0; + } + + for(i = 0; i < ipx->ipx_tctrl; ++i) + if(intrfc->if_netnum == net_num[i]) + { + kfree_skb(skb, FREE_READ); + return 0; + } + + net_num[i] = intrfc->if_netnum; + ++ipx->ipx_tctrl; + + for(ipx_if = ipx_interfaces; ipx_if != NULL; ipx_if = ipx_if->if_next) + { + for(i = 0; i < ipx->ipx_tctrl; ++i) + if(ipx_if->if_netnum == net_num[i]) + break; + + if(i != ipx->ipx_tctrl) + continue; + + ipx->ipx_dest.net = ipx_if->if_netnum; + + skb2 = skb_clone(skb, GFP_ATOMIC); + ipxrtr_route_skb(skb2); + } + + kfree_skb(skb, FREE_READ); + return 0; }