NetBSD-Bugs archive
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index][Old Index]
kern/40621: net/if_srt.c uses wrong byte order for masks on little endian systems
>Number: 40621
>Category: kern
>Synopsis: net/if_srt.c uses wrong byte order for masks on little endian
>systems
>Confidential: no
>Severity: serious
>Priority: medium
>Responsible: kern-bug-people
>State: open
>Class: sw-bug
>Submitter-Id: net
>Arrival-Date: Thu Feb 12 10:50:00 +0000 2009
>Originator: Dr. Wolfgang Stukenbrock
>Release: NetBSD 5_RC
>Organization:
Dr. Nagler & Company GmbH
>Environment:
System: NetBSD s012 4.0 NetBSD 4.0 (NSW-S012) #1: Thu Sep 11 12:21:03 CEST 2008
root@s012:/usr/src/sys/arch/amd64/compile/NSW-S012 amd64
Architecture: x86_64
Machine: amd64
>Description:
In order to forward a packet dependant on the source address, the
if_srt.c interface will search a matching entry in a list of configured rules.
During compare a static netmask-field is used.
This field is initialized in a static way at compile time.
The network-addresses are in network-byte-order when the compare is
done, but the netmask-array is initialized with host-byte-order.
The compare operation will not produce the indented results ...
>How-To-Repeat:
Try to use the source-address-routing module on e.g. an i386-machine.
>Fix:
apply the following fix to ths sourde file "src/sys/net/if_srt.c".
The htonl() macro will resolve to something that may be uses in a
static initialisation as long as the GNU-compiler is called with an
optimisation flag set.
(see /usr/include/sys/bswap.h) This is true for all cases - as long as
I know - so it can be used here.
This fix will also change the type of the array from "unsigned int" to
"in_addr_t", because this is the type used for IPv4 addresses used for s_addr.
remark: if for any reasons the use of htonl() should be avoided in the
static initialisation, than the array should be initialized in host-byte-order
as done before an a short loop should be added in srtattach() that will
correct the byte-order once. From my point of view it should be no option to do
the htonl() each time the compare is done for performance reasons.
--- if_srt.c 2009/02/12 09:58:04 1.1
+++ if_srt.c 2009/02/12 10:17:24
@@ -58,16 +58,17 @@
/* Internal routines. */
-static unsigned int ipv4_masks[33]
- = { 0x00000000, /* /0 */
- 0x80000000, 0xc0000000, 0xe0000000, 0xf0000000, /* /1 - /4 */
- 0xf8000000, 0xfc000000, 0xfe000000, 0xff000000, /* /5 - /8 */
- 0xff800000, 0xffc00000, 0xffe00000, 0xfff00000, /* /9 - /12 */
- 0xfff80000, 0xfffc0000, 0xfffe0000, 0xffff0000, /* /13 - /16 */
- 0xffff8000, 0xffffc000, 0xffffe000, 0xfffff000, /* /17 - /20 */
- 0xfffff800, 0xfffffc00, 0xfffffe00, 0xffffff00, /* /21 - /24 */
- 0xffffff80, 0xffffffc0, 0xffffffe0, 0xfffffff0, /* /25 - /28 */
- 0xfffffff8, 0xfffffffc, 0xfffffffe, 0xffffffff /* /29 - /32 */ };
+/* remark: in the NetBSD header fiels htonl() resolves to something usable in
static initialisation */
+static const in_addr_t ipv4_masks[33]
+ = { htonl(0x00000000), /* /0 */
+ htonl(0x80000000), htonl(0xc0000000), htonl(0xe0000000),
htonl(0xf0000000), /* /1 - /4 */
+ htonl(0xf8000000), htonl(0xfc000000), htonl(0xfe000000),
htonl(0xff000000), /* /5 - /8 */
+ htonl(0xff800000), htonl(0xffc00000), htonl(0xffe00000),
htonl(0xfff00000), /* /9 - /12 */
+ htonl(0xfff80000), htonl(0xfffc0000), htonl(0xfffe0000),
htonl(0xffff0000), /* /13 - /16 */
+ htonl(0xffff8000), htonl(0xffffc000), htonl(0xffffe000),
htonl(0xfffff000), /* /17 - /20 */
+ htonl(0xfffff800), htonl(0xfffffc00), htonl(0xfffffe00),
htonl(0xffffff00), /* /21 - /24 */
+ htonl(0xffffff80), htonl(0xffffffc0), htonl(0xffffffe0),
htonl(0xfffffff0), /* /25 - /28 */
+ htonl(0xfffffff8), htonl(0xfffffffc), htonl(0xfffffffe),
htonl(0xffffffff) /* /29 - /32 */ };
static void update_mtu(SOFTC *sc)
{
>Unformatted:
Home |
Main Index |
Thread Index |
Old Index