Skip site navigation (1)Skip section navigation (2)
Date:      Mon, 04 Aug 1997 19:59:21 -0500
From:      Alex Nash <nash@mcs.com>
To:        Daniel Holmes <danielh@dakcs.com>
Cc:        freebsd-bugs@hub.freebsd.org
Subject:   Re: bin/4209: ipfw does not work with multiple digit interface numbers
Message-ID:  <33E67AE9.31DFF4F5@mcs.com>
References:  <199708041600.JAA07543@hub.freebsd.org>

next in thread | previous in thread | raw e-mail | index | archive | help
Daniel Holmes wrote:
>  I did check the source to ipfw.c over the weekend, and it looks like
>  when it sets up the unit name and number, it sets the last
>  character from the string to a null but it looks like it gets
>  everything after the first digit on the unit number.  At line 742 in ipfw.c:
> 
>         rule.fw_via_name[sizeof(rule.fw_via_name) - 1] = '\0';
> 
>  changing that to
> 
>         rule.fw_via_name[sizeof(rule.fw_via_name)] = '\0';

You don't want that, it'll overwrite the unit field.

The real problem is that the name field is fixed at 6 characters,
even though net/if.h defines IFNAMSIZ to be 16.  The following
(briefly tested) patch discards some flexibility in ICMP type
handling in return for a longer name size.  Previously, any ICMP
type from 0-255 could be used even though a only handful were
useful (typically 0-18).  Since the ip_fw structure couldn't be
expanded beyond its current 108 byte size (due to setsockopt),
I threw out some of the not-so-often used ICMP types -- those
above 31.

I've purposely resized the structure to 104 bytes to make it
incompatible with previous versions of ipfw.

Since the fine folks at Whistle Communications have kept the
2.2 and -current trees in sync, this patch should apply cleanly
to both trees.

Alex

Index: src/sbin/ipfw/ipfw.c
===================================================================
RCS file: /cvs/src/sbin/ipfw/ipfw.c,v
retrieving revision 1.34.2.5
diff -c -r1.34.2.5 ipfw.c
*** ipfw.c	1997/06/23 22:34:24	1.34.2.5
--- ipfw.c	1997/08/04 23:41:07
***************
*** 384,390 ****
  
  		printf(" icmptype");
  
! 		for (type_index = 0; type_index < 256; ++type_index)
  			if (chain->fw_icmptypes[type_index / (sizeof(unsigned) * 8)] & 
  				(1U << (type_index % (sizeof(unsigned) * 8)))) {
  				printf("%c%d", first == 1 ? ' ' : ',', type_index);
--- 384,390 ----
  
  		printf(" icmptype");
  
! 		for (type_index = 0; type_index < IP_FW_ICMPTYPES_DIM *
sizeof(unsigned) * 8; ++type_index)
  			if (chain->fw_icmptypes[type_index / (sizeof(unsigned) * 8)] & 
  				(1U << (type_index % (sizeof(unsigned) * 8)))) {
  				printf("%c%d", first == 1 ? ' ' : ',', type_index);
***************
*** 697,704 ****
  		if ( *c != ',' && *c != '\0' )
  			show_usage("invalid ICMP type");
  
! 		if (icmptype > 255)
! 			show_usage("ICMP types are between 0 and 255 inclusive");
  
  		types[icmptype / (sizeof(unsigned) * 8)] |= 
  			1 << (icmptype % (sizeof(unsigned) * 8));
--- 697,704 ----
  		if ( *c != ',' && *c != '\0' )
  			show_usage("invalid ICMP type");
  
! 		if (icmptype >= IP_FW_ICMPTYPES_DIM * sizeof(unsigned) * 8)
! 			show_usage("ICMP type out of range");
  
  		types[icmptype / (sizeof(unsigned) * 8)] |= 
  			1 << (icmptype % (sizeof(unsigned) * 8));
Index: src/sys/netinet/ip_fw.h
===================================================================
RCS file: /cvs/src/sys/netinet/ip_fw.h,v
retrieving revision 1.23.2.2
diff -c -r1.23.2.2 ip_fw.h
*** ip_fw.h	1997/06/20 23:05:34	1.23.2.2
--- ip_fw.h	1997/08/04 22:58:41
***************
*** 17,22 ****
--- 17,24 ----
  #ifndef _IP_FW_H
  #define _IP_FW_H
  
+ #include <net/if.h>
+ 
  /*
   * This union structure identifies an interface, either explicitly
   * by name or implicitly by IP address. The flags IP_FW_F_IIFNAME
***************
*** 33,39 ****
  union ip_fw_if {
      struct in_addr fu_via_ip;	/* Specified by IP address */
      struct {			/* Specified by interface name */
! #define FW_IFNLEN	6	/* To keep structure on 2^x boundary */
  	    char  name[FW_IFNLEN];
  	    short unit;		/* -1 means match any unit */
      } fu_via_if;
--- 35,41 ----
  union ip_fw_if {
      struct in_addr fu_via_ip;	/* Specified by IP address */
      struct {			/* Specified by interface name */
! #define FW_IFNLEN     IFNAMSIZ
  	    char  name[FW_IFNLEN];
  	    short unit;		/* -1 means match any unit */
      } fu_via_if;
***************
*** 58,64 ****
      u_short fw_pts[IP_FW_MAX_PORTS];	/* Array of port numbers to match
*/
      u_char fw_ipopt,fw_ipnopt;		/* IP options set/unset */
      u_char fw_tcpf,fw_tcpnf;		/* TCP flags set/unset */
! #define IP_FW_ICMPTYPES_DIM (256 / (sizeof(unsigned) * 8))
      unsigned fw_icmptypes[IP_FW_ICMPTYPES_DIM]; /* ICMP types bitmap
*/
      long timestamp;			/* timestamp (tv_sec) of last match */
      union ip_fw_if fw_in_if, fw_out_if;	/* Incoming and outgoing
interfaces */
--- 60,66 ----
      u_short fw_pts[IP_FW_MAX_PORTS];	/* Array of port numbers to match
*/
      u_char fw_ipopt,fw_ipnopt;		/* IP options set/unset */
      u_char fw_tcpf,fw_tcpnf;		/* TCP flags set/unset */
! #define IP_FW_ICMPTYPES_DIM (32 / (sizeof(unsigned) * 8))
      unsigned fw_icmptypes[IP_FW_ICMPTYPES_DIM]; /* ICMP types bitmap
*/
      long timestamp;			/* timestamp (tv_sec) of last match */
      union ip_fw_if fw_in_if, fw_out_if;	/* Incoming and outgoing
interfaces */



Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?33E67AE9.31DFF4F5>