This is the mail archive of the
libc-hacker@sourceware.cygnus.com
mailing list for the glibc project.
[danyd@fastrac.net.au] libc/846: struct ip_fw mismatch between netinet/ip_fw.h and linux/ip_fw.h
- To: libc-hacker@cygnus.com
- Subject: [danyd@fastrac.net.au] libc/846: struct ip_fw mismatch between netinet/ip_fw.h and linux/ip_fw.h
- From: Andreas Jaeger <aj@arthur.rhein-neckar.de>
- Date: 02 Nov 1998 20:14:58 +0100
- Cc: danyd@fastrac.net.au
- Mail-Copies-To: never
We've received the appended bug report and I'd like to draw your
attention to the joy:-) of an interface that changes every few kernel
revisions.
struct ip_fw is defined by glibc in <netinet/ip_fw.h> and by the
kernel in <linux/ip_fw.h>.
glibc 2.0.7 and glibc 2.1 use:
struct ip_fw {
struct ip_fw *fw_next; /* Next firewall on chain */
struct in_addr fw_src, fw_dst; /* Source and destination IP addr */
struct in_addr fw_smsk, fw_dmsk; /* Mask for src and dest IP addr */
struct in_addr fw_via; /* IP address of interface "via" */
void *fw_viadev; /* device of interface "via" */
u_int16_t fw_flg; /* Flags word */
u_int16_t fw_nsp, fw_ndp; /* N'of src ports and # of dst ports */
/* in ports array (dst ports follow */
/* src ports; max of 10 ports in all;*/
/* count of 0 means match all ports) */
#define IP_FW_MAX_PORTS 10 /* A reasonable maximum */
u_int16_t fw_pts[IP_FW_MAX_PORTS]; /* Array of port numbers to match */
u_int32_t fw_pcnt, fw_bcnt; /* Packet and byte counters */
u_int8_t fw_tosand, fw_tosxor; /* Revised packet priority */
char fw_vianame[IFNAMSIZ]; /* name of interface "via" */
};
Linux 2.0.35 uses:
struct ip_fw
{
struct ip_fw *fw_next; /* Next firewall on chain */
struct in_addr fw_src, fw_dst; /* Source and destination IP addr */
struct in_addr fw_smsk, fw_dmsk; /* Mask for src and dest IP addr */
struct in_addr fw_via; /* IP address of interface "via" */
struct device *fw_viadev; /* device of interface "via" */
unsigned short fw_flg; /* Flags word */
unsigned short fw_nsp, fw_ndp; /* N'of src ports and # of dst ports */
/* in ports array (dst ports follow */
/* src ports; max of 10 ports in all; */
/* count of 0 means match all ports) */
#define IP_FW_MAX_PORTS 10 /* A reasonable maximum */
unsigned short fw_pts[IP_FW_MAX_PORTS]; /* Array of port numbers to match */
unsigned long fw_pcnt,fw_bcnt; /* Packet and byte counters */
unsigned char fw_tosand, fw_tosxor; /* Revised packet priority */
char fw_vianame[IFNAMSIZ]; /* name of interface "via" */
};
and finally Linux 2.1.126:
struct ip_fw
{
struct in_addr fw_src, fw_dst; /* Source and destination IP addr */
struct in_addr fw_smsk, fw_dmsk; /* Mask for src and dest IP addr */
__u32 fw_mark; /* ID to stamp on packet */
__u16 fw_proto; /* Protocol, 0 = ANY */
__u16 fw_flg; /* Flags word */
__u16 fw_invflg; /* Inverse flags */
__u16 fw_spts[2]; /* Source port range. */
__u16 fw_dpts[2]; /* Destination port range. */
__u16 fw_redirpt; /* Port to redirect to. */
__u16 fw_outputsize; /* Max amount to output to
NETLINK */
char fw_vianame[IFNAMSIZ]; /* name of interface "via" */
__u8 fw_tosand, fw_tosxor; /* Revised packet priority */
};
You'll notice two problems:
1) (as noted in the appended PR) glibc uses u_int32_t for fw_pcnt,
fw_bcnt but the kernel uses unsigned long which might be 64bit:-(.
2) The whole struct ip_fw is totally different in Linux 2.0.35 and
2.1.126. Which version should we adopt in glibc 2.0 and which one
in glibc 2.1?
For glibc 2.0 I propose to just change the size (patch included) and
for glibc 2.1 to adopt the version from Linux 2.1.126 and probably
also copy <linux/ip_masq.h> to <netinet/ip_masq.h>. Could somebody
please check which changes are really necessary?
Andreas
1998-11-02 Andreas Jaeger <aj@arthur.rhein-neckar.de>
* sysdeps/unix/sysv/linux/netinet/ip_fw.h: fw_pcnt, fw_bcnt are
defined by Linux 2.0.35 as unsigned long which might be a 64bit
type on 64bit platforms. Use unsigned long instead of u_int32_t.
Reported by danyd@fastrac.net.au [PR libc/846].
--- sysdeps/unix/sysv/linux/netinet/ip_fw.h.~1~ Wed Aug 6 01:36:05 1997
+++ sysdeps/unix/sysv/linux/netinet/ip_fw.h Mon Nov 2 20:12:56 1998
@@ -1,4 +1,4 @@
-/* Copyright (C) 1991, 92, 93, 95, 96, 97 Free Software Foundation, Inc.
+/* Copyright (C) 1991, 92, 93, 95, 96, 97, 98 Free Software Foundation, Inc.
This file is part of the GNU C Library.
The GNU C Library is free software; you can redistribute it and/or
@@ -70,7 +70,7 @@
/* count of 0 means match all ports) */
#define IP_FW_MAX_PORTS 10 /* A reasonable maximum */
u_int16_t fw_pts[IP_FW_MAX_PORTS]; /* Array of port numbers to match */
- u_int32_t fw_pcnt, fw_bcnt; /* Packet and byte counters */
+ unsigned long fw_pcnt, fw_bcnt; /* Packet and byte counters */
u_int8_t fw_tosand, fw_tosxor; /* Revised packet priority */
char fw_vianame[IFNAMSIZ]; /* name of interface "via" */
};
--
Andreas Jaeger aj@arthur.rhein-neckar.de jaeger@informatik.uni-kl.de
for pgp-key finger ajaeger@aixd1.rhrk.uni-kl.de
- To: bugs@gnu.org
- Subject: libc/846: struct ip_fw mismatch between netinet/ip_fw.h and linux/ip_fw.h
- From: danyd@fastrac.net.au
- Date: Mon, 2 Nov 1998 01:22:57 -0500
- Reply-To: danyd@fastrac.net.au
- Resent-Cc: gnats-admin@gnu.org
- Resent-Reply-To: bugs@gnu.org, danyd@fastrac.net.au
- Resent-To: libc-gnats@gnu.org
>Number: 846
>Category: libc
>Synopsis: struct ip_fw mismatch between netinet/ip_fw.h and linux/ip_fw.h
>Confidential: no
>Severity: serious
>Priority: medium
>Responsible: libc-gnats
>State: open
>Class: sw-bug
>Submitter-Id: unknown
>Arrival-Date: Mon Nov 02 01:30:01 EST 1998
>Last-Modified:
>Originator: danyd@fastrac.net.au
>Organization:
net
>Release: 2.0.7
>Environment:
RedHat 5.1 alpha Linux
>Description:
The fields fw_pcnt and fw_bcnt are defined as u_int32_t in
netinet/ip_fw.h but are defined as unsigned long in linux/ip_fw.h
This is a problem on environments where unsigned long is 64 bits as
it makes the ip_fw structure a different size and is thus rejected
by the Linux kernel.
I don't know whether this is a glibc or a linux kernel problem so I
will post this to the linux kernel group as well.
>How-To-Repeat:
Any program that attempts to issue a setsockopt call that requires
an optval pointing to an ip_fw structure in a 64 bit Linux
environment will fail with an EINVAL error
>Fix:
>Audit-Trail:
>Unformatted: