This is the mail archive of the libc-hacker@sourceware.cygnus.com mailing list for the glibc project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]

[danyd@fastrac.net.au] libc/846: struct ip_fw mismatch between netinet/ip_fw.h and linux/ip_fw.h



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



>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:




Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]