From 530378f8b96593a1de3c7d751501b9c237015372 Mon Sep 17 00:00:00 2001 From: Mike Makonnen Date: Mon, 29 Oct 2007 00:08:24 +0000 Subject: [PATCH] Fix an error in bit shifting logic for network addresses. The route command would add incorrect routing entries if network numbers weren't fully "spelled" out according to their class. For example: # route add 128.0/16 (works) # route add 128/16 (doesn't work) # route add 193.0.0/24 (works) # route add 193/24 (doesn't work) Also, rework the way a netmask is deduced from network number if it [netmask] is not specified. Submitted by: Nuno Antunes (mostly) MFC after: 1 week --- sbin/route/route.c | 44 ++++++++++++++++++++++++-------------------- 1 file changed, 24 insertions(+), 20 deletions(-) diff --git a/sbin/route/route.c b/sbin/route/route.c index 2edea134350f..063366a3f897 100644 --- a/sbin/route/route.c +++ b/sbin/route/route.c @@ -799,28 +799,32 @@ inet_makenetandmask(net, sin, bits) rtm_addrs |= RTA_NETMASK; if (net == 0) mask = addr = 0; - else if (net < 128) { - addr = net << IN_CLASSA_NSHIFT; - mask = IN_CLASSA_NET; - } else if (net < 65536) { - addr = net << IN_CLASSB_NSHIFT; - mask = IN_CLASSB_NET; - } else if (net < 16777216L) { - addr = net << IN_CLASSC_NSHIFT; - mask = IN_CLASSC_NET; - } else { - addr = net; - if ((addr & IN_CLASSA_HOST) == 0) - mask = IN_CLASSA_NET; - else if ((addr & IN_CLASSB_HOST) == 0) - mask = IN_CLASSB_NET; - else if ((addr & IN_CLASSC_HOST) == 0) - mask = IN_CLASSC_NET; + else { + if (net <= 0xff) + addr = net << IN_CLASSA_NSHIFT; + else if (net <= 0xffff) + addr = net << IN_CLASSB_NSHIFT; + else if (net <= 0xffffff) + addr = net << IN_CLASSC_NSHIFT; else - mask = -1; + addr = net; + + if (bits != 0) + mask = 0xffffffff << (32 - bits); + else { + if (IN_CLASSA(addr)) + mask = IN_CLASSA_NET; + else if (IN_CLASSB(addr)) + mask = IN_CLASSB_NET; + else if (IN_CLASSC(addr)) + mask = IN_CLASSC_NET; + else if (IN_MULTICAST(addr)) + mask = IN_CLASSD_NET; + else + mask = 0xffffffff; + } + addr &= mask; } - if (bits) - mask = 0xffffffff << (32 - bits); sin->sin_addr.s_addr = htonl(addr); sin = &so_mask.sin; sin->sin_addr.s_addr = htonl(mask);