Subject: bin/7791: routed: byteorder problem
To: None <gnats-bugs@gnats.netbsd.org>
From: None <ronald@chersonese.com>
List: netbsd-bugs
Date: 06/16/1999 03:05:45
>Number:         7791
>Category:       bin
>Synopsis:       netmasks in sockaddrs need to be in network order
>Confidential:   no
>Severity:       serious
>Priority:       medium
>Responsible:    bin-bug-people (Utility Bug People)
>State:          open
>Class:          sw-bug
>Submitter-Id:   net
>Arrival-Date:   Wed Jun 16 03:05:00 1999
>Last-Modified:
>Originator:     Ronald Khoo
>Organization:
	Tea and biscuits at 1630hrs
>Release:        1.4C as per uname below
>Environment:
	
System: NetBSD leek.chersonese.com 1.4C NetBSD 1.4C (LEEK_IPF_GDB) #0: Mon Jun 14 21:59:02 MYT 1999 root@leek.chersonese.com:/usr/src/sys/arch/i386/compile/LEEK_IPF_GDB i386


>Description:
routed's code uses host-byteorder netmasks everywhere in its code.
this is fine everywhere except in the radix tree code which then
can't find hosts in a network route.  But only if the machine's
byteorder is other than network byte order :-)
>How-To-Repeat:
Do this on a little-endian machine like an i386.
The gateway specified in /etc/gateways below is most definitely
reacheable via the local network, but rtfind() can't find it.

cabbage# netstat -in ; netstat -rn
Name  Mtu   Network       Address              Ipkts Ierrs    Opkts Oerrs Colls
fxp0  1500  <Link>        00:a0:c9:5c:a5:f9     4653     1     2972     0     0
fxp0  1500  172.31        172.31.0.2            4653     1     2972     0     0
lo0   32976 <Link>                               552     0      552     0     0
lo0   32976 127           127.0.0.1              552     0      552     0     0
Routing tables

Internet:
Destination        Gateway            Flags     Refs     Use    Mtu  Interface
127.0.0.1          127.0.0.1          UH          0      552      -  lo0
172.31             link#1             UC          0        0      -  fxp0
172.31.0.1         00:a0:c9:4d:21:97  UHL         1     2942      -  fxp0
cabbage# cat /etc/gateways
no_rdisc
no_rip_mcast
net 172.30.0.0 gateway 172.31.0.1 metric 0 passive
cabbage# routed -d
routed: unreachable gateway 172.31.0.1 in /etc/gateways
^C-- 17:34:47 --
exiting with signal 2
cabbage# 
>Fix:
I think it's sufficient to convert the netmasks into network byte order
only when they are being assigned to a sockaddr_in.   At the very least,
the test case above works with the patch below.

*** table.c.orig	Wed Jun 16 17:35:59 1999
--- table.c	Wed Jun 16 17:37:13 1999
***************
*** 1653,1659 ****
  	struct rt_entry *rt;
  
  	dst_sock.sin_addr.s_addr = dst;
! 	mask_sock.sin_addr.s_addr = mask;
  	masktrim(&mask_sock);
  	rt = (struct rt_entry *)rhead->rnh_lookup(&dst_sock,&mask_sock,rhead);
  	if (!rt
--- 1653,1659 ----
  	struct rt_entry *rt;
  
  	dst_sock.sin_addr.s_addr = dst;
! 	mask_sock.sin_addr.s_addr = htonl(mask);
  	masktrim(&mask_sock);
  	rt = (struct rt_entry *)rhead->rnh_lookup(&dst_sock,&mask_sock,rhead);
  	if (!rt
***************
*** 1704,1710 ****
  		if ((smask & ~mask) == 0 && mask > smask)
  			state |= RS_SUBNET;
  	}
! 	mask_sock.sin_addr.s_addr = mask;
  	masktrim(&mask_sock);
  	rt->rt_mask = mask;
  	rt->rt_state = state;
--- 1704,1710 ----
  		if ((smask & ~mask) == 0 && mask > smask)
  			state |= RS_SUBNET;
  	}
! 	mask_sock.sin_addr.s_addr = htonl(mask);
  	masktrim(&mask_sock);
  	rt->rt_mask = mask;
  	rt->rt_state = state;
***************
*** 1843,1849 ****
  	}
  
  	dst_sock.sin_addr.s_addr = rt->rt_dst;
! 	mask_sock.sin_addr.s_addr = rt->rt_mask;
  	masktrim(&mask_sock);
  	if (rt != (struct rt_entry *)rhead->rnh_deladdr(&dst_sock, &mask_sock,
  							rhead)) {
--- 1843,1849 ----
  	}
  
  	dst_sock.sin_addr.s_addr = rt->rt_dst;
! 	mask_sock.sin_addr.s_addr = htonl(rt->rt_mask);
  	masktrim(&mask_sock);
  	if (rt != (struct rt_entry *)rhead->rnh_deladdr(&dst_sock, &mask_sock,
  							rhead)) {
>Audit-Trail:
>Unformatted: