freebsd-skq/sbin/ipfw
Jordan K. Hubbard 0a87b23329 Latest changes from Uben.
Submitted by:	uben
1994-10-31 23:58:04 +00:00
..
ipfw.1 Fix up the man page a little more, delete the README that crept in 1994-10-28 15:12:22 +00:00
ipfw.c Latest changes from Uben. 1994-10-31 23:58:04 +00:00
Makefile Add the ipfw command, for IP firewall construction. 1994-10-28 15:06:53 +00:00
README Add the ipfw command, for IP firewall construction. 1994-10-28 15:06:53 +00:00

*****************************************************************************
27 Oct 94
Hi again!
So thanx to Brian McGovern , i'v took this piece of code in hands again
and made some changes:
 1) Port to FreeBSD 2.0 , so we will not go after time.
 2) Some minor changes in kernel part to improve speed and such..
 3) Chane in behaviour: now any recently added firewall definition
      preferred on other matching but older firewalls.
      REMEMBER: in any case universal IP firewall has larger preference
                then special TCP/UDP/ICMP firewalls.
 4) Cosmetical changes to control programm. Now it is called ipfw.
 5) Changed ip_firewall.* to ip_fw.* in kernel,and shortened some long
    variable names.
 6) From now on we have user defined *policy*,which is DENY/ACCEPT for
    every packet which does not matches any of firewalls.I.e.: if any
    firewall defined and packet does not match them you may set it up
    so it will be anyway throwed or anyway accepted.
Mostly that's all.
Bye!

-- 
              -= Ugen J.S.Antsilevich =-
        NetVision - Commercial Internet Provider     
-----------------------------------------------------[C]---
NetVision  -  Home of Israeli Commercial Internet     
     E-mail: ugen@NetVision.net.il                   
       HTTP: http://www.NetVision.net.il/~ugen/
     Phone: +972-4-550330      Fax: +972-4-550122   

*****************************************************************************
10 Jul 94
Hi again...So i sitted and stared at this nice working tool and thought to 
myself that it's nice but something there it needs and have not..
So i took a piece of file and a keyboard and typed some strings.
What it was is:

o  List  facility improved...Now listing of currently installed firewall
   entries does not go through kernel printf's ,which is really unnice to 
   one who runs it NOT from console:)

o Really important facility of deleting entries added..Yes , till this 
  day you had to remove all entries and then add them one by one again
  to remove actually just one.Now it's over:)

o All this changes documented in this readme,while you will see where i
  added my words just by vast number of mistaces in English.Well,i hope
  you will forgive one Russian guy like me:)

So enjoy this new code and if you think it needs some additions - you 
are welcome to suggest.Also i made some more warnings , while compiling
this code,i have no a clue where do they come from,however they does not
make any bad to programm.But if you will find way to remove them,feel free 
to do it and post anywhere(and notify me as i also need this:)

 Bye!                                                 Ugen J.S.Antsilevich


##########################################################################
# Ugen J.S.Antsilevich            NetVision (Israel) System Staff Member #
#------------------------------------------------------------------------#
#   Email:   ugen@NetVision.net.il        | Phone:  972-4-550330         #
#            ugen@NetManage.co.il         | Fax:    972-4-550122         # 
#------------------------------------------------------------------------#
#   WWW HomePage: http://www.NetVision.net.il/~ugen                      #
#   Special : Volk@Les.Tambov.SU                                         #
##########################################################################


*****************************************************************************
8 Jul 94
OK..so first of all,this is simple port to FreeBSD by Ugen J.S.Antsilevich
Actually all i had to do is to find appropriate place in kernel source files
for ipfirewall stuff..so all your thanks should go to the author...
Anyway i am porting it now to 1.1.5 (not much job though..:) so if you want
to ask something about write to me:

ugen@NetVision.net.il

That's it and let the --==REAL==-- author speak...
*****************************************************************************

Here's my ipfirewall facility.  I consider it to still be beta quality mostly
because the various interfaces are pretty crude.  Here's some information that
you'll probably find useful (in roughly the order in which you'll need to know
it).  Some of this will be absurdly simplistic.  Better safe than sorry...

This software was written for BSD/386.  The current version has been ported
to BSD/386 v1.1.  The context diffs are with respect to that version of
BSD/386.  If you don't have access to BSD/386 v1.1 and can't make sense out of
the diffs, contact me and I'll send you the entire files (they are copyrighted
by UC-Berkeley with very 'friendly' conditions).

Speaking of copyrights, here's mine:

/*
 *  Copyright (c) 1993 Daniel Boulet
 *  Copyright (c) 1994 Ugen J.S.Antsilevich
 *
 *  Redistribution and use in source forms, with and without modification,
 *  are permitted provided that this entire comment appears intact.
 *
 *  Redistribution in binary form may occur without any restrictions.
 *  Obviously, it would be nice if you gave credit where credit is due
 *  but requiring it would be too onerous.
 *
 *  This software is provided ``AS IS'' without any warranties of any kind.
 */

Enough introductory stuff, here we go...

    1) The file IPFIREWALL is the configuration of kernel i use with
       IPFIREWALL and GATEWAY options enabled.  You may not find it useful.
       About the only key things are that it enables the IPFIREWALL
       option and the GATEWAY option.  IPFIREWALL turns on my
       stuff and GATEWAY turns your machine into an IP router.

       There is nothing magical about the name of this file or the
       ident name for the kernel.

    2) The files ip_fw.c and ip_fw.h are new files that should be
       placed into the /usr/src/sys/netinet directory.

    3) The files ip_input.c and raw_ip.c are new patched versions of the
       same files , they made up for version 2.0 of FreeBSD,however it was
       some pre-Beta release we worked on , so to add it to other releases
       just find all parts of code surrounded by:
         #ifdef IPFIREWALL
         ....
         #endif
       and place in the appropriate places in the same files.
       All those files are in /usr/src/sys/netinet directory of corse.

    4) Add the line "netinet/ip_fw.c    optional ipfirewall" to the
       file /usr/src/sys/conf/files.  This tells the config program to
       include the netinet/ip_fw.c file if the IPFIREWALL option is
       defined for a kernel.

    5) The Makefile and ipfw.c files should go into directory probably
       back in your home directory tree somewhere.  If this ever becomes a
       part of the system then they should go into the (newly created)
       directory /usr/src/sbin/ipfw. 

    6) Build yourself a kernel, make a backup of the current kernel and
       and install the new one.  It should behave in a completely normal
       fashion since you won't have defined any firewalls yet.

    7) Explore the ipfw program.  The smartest way to do this is to
       compile the program and then run it.To do it you SHOULD be root
       as the programm uses setsockopt on RAW sockets to define firewalls,
       and also reads kernel symbols.If any other user will run ipw
       it will detect that it isn't being run by root and will just
       complain and exit.
       The ipfw program takes command line parameters
       and (assuming they are valid) issues a single appropriate setsockopt
       call.  If you're defining 5 firewalls then you'll have to run the
       program 5 times.  See below for a description of the command syntax
       of ipfirewall.

     ====================================================================
       WARNING!!! WARNING!!! WARNING!!! WARNING!!! WARNING!!! WARNING!!!
       The ipfw program can be used to put your machine into very
       disfunctional state.So if you want to test it make sure you
        a) Have read carifully this README till it's end.
        b) First time run it from machine console,as else you can 
           simply shut down your own access to it. 
     ====================================================================
       Make sure that you never setup the program as setuid root!!! Instead,
       always run it from the root command line or from "/etc/rc.local"
       as part of the boot process.

    8) Use the "ipfirewall" checkb or checkf command (see below) to pass some
       test packets through the firewalls that you've defined.

    9) You may find it useful to create a file in which the first line is
       "ipfirewall flush" to flush any existing firewalls and the remaining
       lines are the ipfirewall commands needed to define the firewalls that
       you want to use.  This will ensure that you're always working from a
       known state.

   10) If you've gotten this far then you're probably ready to let the critter
       see prime time.  Copy your file of ipfirewall commands into the
       /etc/rc.local file and reboot the system.  Once you're up, use the
       ipfirewall list command to see that you've got the firewalls that you
       wanted and try to test the firewall with real packets from trusted
       and untrusted hosts.

Enough of that.  Here's the syntax for the ipfirewall command.  It is rather
complex and yet simple at the same time (if you know what I mean).  There
are seven sub-commands.  Probably the easiest way to get into this is to give
you a roughly BNF style grammar for the command (curly brackets are used for
precedence, alternatives are separated by |, optional things are enclosed
in square brackets, white space is required if it appears below and must
not appear if there isn't any between the tokens below (i.e. no white space
around periods, colons or slashes, whitespace required between all other
tokens)):

	command ::= ipfirewall <list> | <flush> | <check> | <add> | <del>

	<list> ::= list

	<flush> ::= flush

	<check> ::= { checkb[locking] | checkf[orwarding] } <chkparms>

	<add> ::= { addb[locking] | addf[orwarding] } <add-del-parms>

	<del> ::= { delb[locking] | delf[orwarding] } <add-del-parms>

	<chkparms> ::= <protocol> from <ipaddr> <port> to <ipaddr> <port>

	<protocol> ::= tcp | udp

	<ipaddr> ::= <int>.<int>.<int>.<int> | <hostname>

	<hostname> ::= a host name from /etc/hosts

	<port> ::= <int> | <service>

	<service> ::= a service from /etc/services

	<int> ::= a non-negative integer

	<add-del-parms> ::= { accept | deny } { <universal_firewall> | <protocol_firewall> }

	<universal_firewall> ::= all from <masked_ipaddr> to <masked_ipaddr>

	<masked_ipaddr> ::= { <ipaddr>/<bits> } | { <ipaddr>:<ipaddr> } | <ipaddr>

	<bits> ::= integer in the range 0 to 32 inclusive

	<protocol_firewall> ::= <protocol> from <end_firewall> to <end_firewall>

	<end_firewall> ::= <masked_ipaddr> <port_list>

	<port_list> ::= [ <port>:<port> ] <sub_port_list>

	<sub_port_list> ::= <port> [ <sub_port_list> ]

Although I think that the above grammar is complete, it isn't exactly what
one would call easy to comprehend!  Here's the basic idea along with what
each of the forms mean:

    The "ipfirewall list" command prints a list of the firewalls on both the
    forwarding and blocking chain in some more or less understudable format.

    The "ipfirewall flush" command empties the two firewall chains.  

    The "ipfirewall addblocking" and "ipfirewall addforwarding" commands take
    a firewall description and add the firewall to the appropriate firewall
    chain.Take notice,that if you will add some description more then once,
    it will take more then one entry in memory.It does not lead to significant
    slow down of computer operation though.

    The "ipfirewall delblocking" and "ipfirewall delforwarding" commands take
    a firewall description and deletes the firewall from the appropriate 
    firewall chain.The description must be exactly the same as it was defined
    by add command.One delete command removes ALL same entries from firewall
    chains.

    There are two basic kinds of firewall descriptions.  Universal firewall
    descriptions match all IP packets between specified pairs of hosts.
    Universal firewalls only check IP addresses (i.e. they match any combination
    of protocol and port numbers).  Protocol-specific firewalls match either
    TCP/IP or UDP/IP packets between specified pairs of hosts.  In addition
    to host descriptions, protocol-specific firewalls optionally take a
    description of which port numbers to match.

    A host description consists of an IP address and a mask.  The IP address
    is specified as either a domain name or in the familiar
    nn.nn.nn.nn format.  The mask indicates how much of the IP address
    should be looked at when vetting packets.  There are two ways to
    specify the mask.  The first way is to suffix the IP address in the
    firewall with a slash and an integer in the range 0 through 32 inclusive.
    This integer is taken to be the number of high order bits of the IP
    address which are to be checked (for example, 192.153.211.0/24 checks
    the top 24 bits of the IP address, 192.153.211.17/32 checks all the
    bits and 0.0.0.0/0 checks none of the bits (i.e. all IP addresses are
    matched by this example)).  The second way to specify a mask is to
    suffix the IP address with a colon followed by another IP address.
    This second address is the mask.  Specifications equivalent to the
    above three examples using this syntax would be

	192.153.211.0:255.255.255.0
	192.153.211.17:255.255.255.255
	0.0.0.0:0.0.0.0

    The first form is taken from the syntax accepted by a Telebit NetBlazer.
    The second form is more along the lines of how a netmask is specified
    in /etc/netmasks.  Finally, if no mask is specified then a mask of all
    1's is supplied (i.e. no mask is equivalent to /32 or :255.255.255.255).

    The optional description of port numbers to mask can take three forms.
    The simplest form is to omit the list in which case all port numbers
    match.  The next form is to specify a list of port numbers (either as
    positive integers or service names from /etc/services).  The final form
    is actually a special case of the second form in which the first pair
    of port numbers is separated by a colon instead of white space.  This
    pair specifies a range of port numbers (i.e. x:y specifies that all
    ports between x and y inclusive should match).  A port description
    matches a particular port number if any of the following is true:

	- the port description is null
	- the first pair of port numbers is a range and the port number
	  is in the range (inclusive)
        - the port number is equal to any of the port numbers in the list

    There is a limit of a total of 10 port numbers in the source and
    destination port lists.  This limit is arbitrary and easy to increase.
    It is determined by the value of the IP_FIREWALL_MAX_PORTS #define
    variable in ip_firewall.h.  Each increase of 1 for this value adds two
    bytes to the size of each firewall.  Since the size of a firewall is only
    slightly over 30 bytes right now, this limit of 10 could probably
    be increased by quite a bit before it became a concern.  I've been
    thinking of increasing it to 20 which would be longer than any
    reasonable firewall would need and would only consume 20 more bytes
    per firewall.  The counter argument to any increase is that it is
    always possible to construct an equivalent set of two or more firewalls
    that behaves like a single firewall with a really long port list.

    This probably all sounds hopelessly complicated.  It is actually not
    all that tricky (I'm just not very good at explaining it yet).  A few
    examples will probably help a lot now:

	Block all IP packets originating from the host hackers-den:

	    ipfirewall addb deny all from hackers-den to 0.0.0.0/0

	Block all telnet packets to our telnet server from anywhere:

	    ipfirewall addb deny tcp from 0.0.0.0/0 to mymachine/32 telnet

	Don't forward telnet, rlogin and rsh packets onto our local
	class C network:

	    ipfirewall addf deny tcp from 0.0.0.0/0 to ournetwork/24 telnet login shell

	Don't let anyone on the local machine or any machine inside
	our local network ftp access to games.com:

	    ipfirewall addb deny tcp from games.com ftp to 0.0.0.0/0

	This last one might look a little strange.  It doesn't prevent
	anyone from sending packets to the games.com ftp server.  What it
	does do is block any packets that the games.com ftp server sends
	back!

    The "ipfirewall checkblocking" and "ipfirewall checkforwarding" commands
    take a description of an IP packet and check to see if the blocking
    or forwarding chain of firewalls respectively accept or reject the packet.
    It is used to make sure that the firewalls that you've defined work as
    expected.  The basic syntax is probably best understood by looking at
    a couple of examples:

	ipfirewall checkb from bsdi.com 3001 to mymachine telnet

    checks to see if the blocking firewall will block a telnet packet from
    a telnet session originating on bsdi.com to the host mymachine will be
    blocked or not.  Note that someone connecting to our telnet server
    could be using practically any port number.  To be really sure, the
    firewall used to prevent access should be as simple as possible and/or
    you should try a variety of port numbers in addition to the rather
    arbitrarily chosen port of 3001.

    One final note on the check* ,add* and del* command syntax.  The noise word
    "to" exists in the syntax so that I can detect the end of a list of
    port numbers in the from description.  Since I needed a noise word to
    detect this case, I added the noise word "from" in front of the from
    case for consistency.

    Finally, have a look at the file "filters".  It is the set of filters
    that I run at home.<Danny>
    Also check "scripts",where individual access restrictions written.
    We use those for our dial-in PPP/SLIP users,to allow some of them
    to access our internal networks,while disallowing other.This way we 
    open access to user's IP,when he enters the system ,and shut it
    down when he leaves.All those changes may be applyed at any time,
    and so entries added and deleted from firewall while system is
    is working.No any side effects will arise.<Ugen>

Now for a bit of a description of how the firewalls are applied (i.e. what
happens in the kernel):

    When an IP packet is received, the ipintr() routine in ip_input.c is
    called.  This routine does a bit of basic error checking.  If it
    detects any errors in the packet it generally drops the packet on
    the floor.  The idea behind the ipfirewall facility is to treat packets
    that we don't want to accept as bad packets (i.e. drop them on the
    floor).  The ipfirewall facility intercedes in the normal processing
    at two points.  Just after the basic sanity checks are done, we pass
    any packets not targeted at the loopback network (127.0.0.0/8) to the
    firewall checker along with the chain of blocking firewalls.If the firewall
    checker tells us to block the packet then we branch to the "bad:" label
    in ipintr() which is where all bad packets are dropped on the floor.
    Otherwise, we allow normal processing of the packet to continue.  The
    exact point at which we intercede was chosen to be after the basic
    sanity checking and before the option processing is done.  We want to
    be after the basic sanity checking so that we don't have to be able
    to handle complete garbage.  We want to be before the option processing
    because option processing is done in separate rather complex routine.
    Why bother doing this special processing if we might be dropping the
    packet?

    The second point at which we intercede is when a packet is about to be
    forwarded to another host.  All such packets are passed to the ip_forward
    routine.  The ipfirewall code is at the very top of this routine.  If
    the packet isn't targetted at the loopback interface (is it possible
    that it could be when we reach this point?  I doubt it but safety first)
    then pass the packet to the firewall checker along with the forwarding
    firewall chain.  If the firewall checker indicates that the packet should
    not be forwarded then we drop in (using code copied from a few lines
    further into the routine which drops broadcast packets which are not
    to be forwarded).

There are a couple of consequences of this approach:

    1) Packets which are blocked are never forwarded (something to keep
       in mind when designing firewalls).
    2) Packets targeted at the loopback interface (127.0.0.0/8) are never
       blocked.  Blocking packets to the loopback interface seems pointless
       and potentially quite confusing.  It also makes a possibly common
       case very cheap.
    3) The sender of a packet which is blocked receives no indication that
       the packet was dropped.  The Telebit NetBlazer can be configured to
       silently drop a blocked packet or to send back a "you can't get there
       from here" packet to the sender.  Implementing the later would have
       been more work (possibly quite a bit more, I don't really know).  Also,
       I don't see any reason to give a potential hacker any more information
       than necessary.  Dropping the packet into the bit bucket seems like
       the best way to keep a hacker guessing.<Danny>
       Well,anyway i working on this feature.It would be made optional and
       configurable by some ICMP_UNREACH_ON_DROP or like this.<Ugen>

Now for some details on how the firewall checker works:

    The firewall checker takes two parameters.  The first parameter is a pointer
    to the packet in question. The second parameter is a pointer to the
    appropriate firewall chain. At the present time, the firewall checker passes
    these parameters to a second routine which is the real firewall checker.
    If the real checker says NO then an appropriate message is printed
    onto the console.  This is useful for debugging purposes.  Whether or
    not it remains in the long term depends on whether it is considered useful
    for logging purposes (I'm a little reluctant to leave it in since it
    provides a hacker with a way to commit a "denial of service" offense
    against you by filling up your /var/log/messages file's file system
    with error messages.  There are ways of preventing this but ...<Danny>).
    In default configuration now no information about dropped packets
    printed.You may,however,define it,as i do by adding
    option		IPFIREWALL_VERBOSE
    to your kernel configuration file.Very useful thingy!<Ugen>

    A return value of 0 from this routine (or the real firewall checker)
    indicates that the packet is to be dropped.  A value of 1 indicates
    that the packet is to be accepted.  In the early testing stages you
    might want to make the top level firewall checker always return 1 even
    if the real checker returns 0 just in case the real firewall checker
    screws up (or your firewalls aren't as well designed as they should be).
    In fact, this might be a useful optional feature (providing a way to
    leave a door unlocked doesn't seem all that wise but it has to be
    balanced against the inconvenience to legitimate users who might get
    screwed up by poorly designed firewalls).

    The real firewall returns 1 (accept the packet) if the chain is empty.  If
    efficiency is a concern (which it is in this code), this check should
    be done in ip_input.c before calling the firewall checker.

    Assuming that there is a firewall chain to scan through, the real firewall
    checker picks up the src and dst IP addresses from the IP packet.  It
    then goes through the firewall chain looking for the first firewall that
    matches the packet.  Once a matching firewall has been found, a value of
    1 is returned if the firewall is an accept firewall and a value of 0 is
    returned otherwise.

    The following processing is done for each firewall on the chain:

	1) check the src and dst IP addresses.  If they don't match then
	   there isn't any point in looking any further at this firewall.
	   This check is done by anding the packet's IP addresses the
	   with appropriate masks and comparing the results to the
	   appropriate addresses in the firewall.  Note that the mask is
	   NOT applied to the address in the firewall.  If it has any 1
	   bits that are 0 bits in the mask then the firewall will never
	   match (this will be checked in ipfirewall soon).  If the addresses
	   match then we continue with the next step.

	2) If the firewall is a universal firewall then we've got a match.
	   Return either 0 or 1 as appropriate.  Otherwise, continue with
	   the next step.

	3) Examine the IP protocol from the packet.  If we havn't had to
	   look at it before then we get it and set a local variable to
	   IP_FIREWALL_TCP for TCP/IP packets, IP_FIREWALL_UDP for UDP/IP
	   packets, IP_FIREWALL_ICMP for ICMP packets, and IP_FIREWALL_UNIVERSAL
	   for all other packet types.  Also, if the packet is a TCP/IP or
	   a UDP/IP packet, save the source and destination port numbers
	   at this point (taking advantage of the fact that the port numbers
	   are stored in the same place in either a TCP/IP or a UDP/IP
	   packet header).  If the packet is neither a TCP/IP or a UDP/IP
	   packet then this firewall won't match it (on to the next firewall).
	   If this packet's protocol doesn't match this firewall's protocol
	   (which can't be universal or we wouldn't be here) then on to
	   the next firewall.  Otherwise, continue with the next step.

	4) We're checking either a TCP/IP or a UDP/IP packet.  If the
	   firewall's source port list is empty or the packet's source
	   port matches something in the source port list AND if the firewall's
	   destination port list is empty or the packet's destination
	   port matches something in the destination port list then
	   we've got a match (return 0 or 1 as appropriate).  Otherwise,
	   on to the next firewall.

    As indicated above, if no packet on the chain matches the packet then
    it is accepted if the first firewall was a deny firewall and it is rejected
    if the first firewall was an accept packet.  This is equivalent to the
    default behaviour of a Telebit NetBlazer.  They provide a way to override
    this behaviour.  I'm not convinced that it is necessary (I'm open to
    suggestions).

That's about it for the firewall checker.  The ipfirewall program communicates
with the kernel part of the firewall facility by making setsockopt calls
on RAW IP sockets.  Only root is allowed to open a RAW IP socket.  This
ensures that only root uses ipfirewall to manipulate the firewall facility.
Also, somewhere in the kernel source or on a man page, I read that the
RAW IP setsockopt calls are intended for manipulating the IP protocol layer
as opposed to manipulating any particular instance of a socket.  This seems
like a reasonable description of what the firewall setsockopt command
codes do.

There are seven setsockopt command codes defined by the firewall facility
(in netinet/in.h).  They are:

   IP_FLUSH_FIREWALLS		flush (i.e. free) both firewall chains.

   IP_ADD_FORWARDING_FIREWALL	add firewall pointed at by optval parm to
    				the end of the forwarding firewall chain.

   IP_ADD_BLOCKING_FIREWALL	add firewall pointed at by optval parm to
    				the end of the blocking firewall chain.

   IP_DEL_FORWARDING_FIREWALL	delete firewall pointed at by optval parm 
    				from the forwarding firewall chain.

   IP_DEL_BLOCKING_FIREWALL	delete firewall pointed at by optval parm 
    				from the blocking firewall chain.

   IP_CHECK_FORWARDING_FIREWALL pass the IP packet do the firewall checker
    				along with the forwarding firewall chain.
    				Return 0 if packet was accepted, -1 (with
    				errno set to EACCES) if it wasn't.

    IP_CHECK_BLOCKING_FIREWALL	pass the IP packet do the firewall checker
    				along with the blocking firewall chain.
    				Return 0 if packet was accepted, -1 (with
    				errno set to EACCES) if it wasn't.

    The IP_ADD_* and IP_DEL_* command codes do a fair bit of validity checking.
    It is quite unlikely that a garbage firewall could get past them that
    would cause major problems in the firewall checker.  It IS possible for
    a garbage packet to get past the checks which causes major grief because
    it either blocks or accepts packets according to unusual rules (the rules
    will conform to the ones described above but will probably come as quite
    a surprise).

    The IP_CHECK_* command codes expect the optval parameter to point
    to a struct ip immediately followed by a header appropriate to the protocol
    value described in the ip_p field of the ip header.  The exact requirements
    are as follows:

	- The length of the optval parameter must be at least

		sizeof(struct ip) + 2 * sizeof(u_short)

	  since this is the amount of memory that might be referenced by
	  the firewall checker.

	- The ip_hl field of the ip structure must be equal to

		sizeof(struct ip) / sizeof(int)

	  since this value indicates that the tcp/udp/??? header immediately
	  follows the ip header (appropriate for the purposes that this
	  interface is intended for).

    Failure to follow these rules (for either the IP_ADD_*,IP_DEL_* or the
    IP_CHECK_*_FIREWALL commands) will result in a return value of -1 with
    errno set to EINVAL (for now, it will also result in an appropriate
    message on the console).

  To read current configuration of firewalls,the kvm_read() function used.
  Symbols,which you have to find are :
  struct ip_firewall * ip_firewall_blocking_chain ;
  struct ip_firewall * ip_firewall_forwarding_chain ;
  Both are pointers to the linked list of firewall entries.
  Of corse you have to be at least kmem group member,to read kernel symbols.

That's about all that I can think of for now.  There are a couple of details
that are worth reading about in the ip_firewall.h file.  Other than that, let
me know how you do.  If you have any problems, give me a call at home (403
449-1835) or send me e-mail at "danny@BouletFermat.ab.ca".  If you call, please
keep in mind that I live in the Canadian Mountain timezone (GMT-0600).

-Danny

So that's it..if you want to say something to me-call me or mail:
Phone: 972-4-550-330 
E-mail ugen@NetVision.net.il
If you call,remember that i live in Israel timezone which is GMT+02.

-Ugen