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