smoot@POP.UTEXAS.EDU (Smoot Carl-Mitchell) (10/28/85)
I discovered a botch in my subnet implementation which I posted about a month ago. I've updated the sources whcih are available in ~ftp/pub/subnet.tar on sally.utexas.edu (formerly ut-sally.arpa). In addition I added a sanity check to allow hosts with non-zero subnets to coexist with hosts with subnet 0 on the same network. The pertinent code changes are in if_subenable (in if_ether.c) and in if_loop.c. (which is where the botch is). The botch which I overlooked is in loattach (in if_loop.c). Change the following line: sin->sin_addr.s_addr = 0xff000000; to: sin->sin_addr.s_addr = htonl(0xff000000); The error is obvious and dumb. Here is a listing of the latest version of if_subenable with the sanity check added: /* determine if target address is on an interface with arp subnet routing * enabled */ if_subenable(itaddr, sinterface) struct in_addr itaddr; struct ifnet *sinterface; { struct route ro; struct sockaddr_in *sin; struct sockaddr wildcard; extern struct ifnet *if_ifonnetof(); /* target address is on a local network */ if (in_localaddr(itaddr)) { int net; struct ifnet *interface; net = in_netof(itaddr); /* sanity check - don't match if target is on the same * interface the arp request came from */ if (sinterface != NULL && net == sinterface->if_net) return(0); interface = if_ifonnetof(net); if (interface == NULL) { /* this should never happen */ printf("subenable - interface not found for net - %x\n", net); return(0); } return(interface->if_flags & IFF_SUBARP); } /* if target is not local then * look in routing table for the interface to use */ sin = (struct sockaddr_in *)(&ro.ro_dst); sin->sin_family = AF_INET; sin->sin_addr = itaddr; ro.ro_rt = NULL; (void) rtalloc(&ro); if (ro.ro_rt != NULL && ((struct sockaddr_in *)(&ro.ro_rt->rt_dst))->sin_addr.s_addr != 0 && ro.ro_rt->rt_ifp->if_flags & IFF_SUBARP && sinterface != ro.ro_rt->rt_ifp) return(1); return(0); }