This is a simple helper library for use with the netlink interface.
Programs which use this library must currently run as root.

Unpack the library INSIDE the ipchains source directory (1.3.7 and
above).

You need a kernel compiled with CONFIG_IP_FIREWALL (2.1.125 and
above).  You also need CONFIG_IP_FIREWALL_NETLINK, and CONFIG_ETHERTAP
set to allow packets to be injected from userspace.  /dev/tap0 must
exist.

For those in a hurry, try `make examples', which makes the library and
an example program called `show_pings' and `tcp_reset'.  See below for
details.

Using the library
-----------------

The library functions all return 0 for failure, and take a silent
flag, which means that error messages will NOT be sent to stderr.

	int fw_init_listen(int silent);

This function should be called first.  It opens /dev/fwmonitor.  If
this fails, then you are not root (Permission denied, try running as
root), your kernel does not support IP Firewalling with NETLINK (No
such device or address, try compiling a kernel with
CONFIG_IP_FIREWALL_CHAINS and CONFIG_IP_FIREWALL_NETLINK) or the
device does not exist (No such file or directory, try `mknod -m 600
/dev/fwmonitor c 36 3').

	void fw_close_listen(int silent);

This function closes files and deletes any rules created by calls to
fw_register_interest().  It should always be called on exit (even
abnormal exit).

	__u32 fw_register_interest(const struct ip_fw *packetspecs, 
				   enum fw_chain chain,
				   fw_readpktfn *fn,
				   const char *policy,
				   int is_input,
				   int silent);

This function allows you to register interest in a certain type of
packet: the rule you specify (by packetspecs) will be inserted in the
chain (specified by chainname) with the policy given (by policy), and
your function (fn) will be called each time a packet hits that rule.
A unique identifier is returned (which allows deregistration, as well
as being handed to the fw_readpktfn).

See below for discussion on is_input.

The fields of the packetspecs argument are as follows:

	struct in_addr fw_src, fw_dst;
	struct in_addr fw_smsk, fw_dmsk;

These are the IP source and destination addresses; the fw_smsk and
fw_dmsk fields indicate which bits are relevent (ie. if these are
zero, then no selection will be done based on the source/destination
IP addresses).

	__u32 fw_mark;

This is overwritten by fw_register_interest internally.

	__u16 fw_proto;

The protocol to match (eg. IPPROTO_IP).  0 is a special value meaning
any protocol.

	__u16 fw_flg;			        /* Flags word */

Valid flags are:
	IP_FW_F_PRN
	IP_FW_F_TCPSYN
	IP_FW_F_FRAG
	IP_FW_F_WILDIF

See ipfw(4) for details.  The other flags are overwritten by
fw_register_interest internally.

        __u16 fw_invflg;
	__u16 fw_spts[2];
        __u16 fw_dpts[2];
	__u16 fw_redirpt;
	char fw_vianame[IFNAMSIZ];
	__u8 fw_tosand, fw_tosxor;

See the ipfw(4) man page.

	__u16 fw_outputsize;

This sets the maximum number of bytes you will see in the
fw_readpktfn.  Setting this to 65535 will ensure you see all of every
packet (but may be unnecessarily slow if you only want to read packet
headers).

The fw_readpktfn handed to fw_register_interest() is called by
fw_do_listen() or fw_do_event() as detailed below.

	int fw_deregister_interest(__u32 rulenum, int silent);

This function allows you to deregister interest in a type of packet
The rulenum is that returned by fw_register_interest().

	int fw_do_listen(int silent);

This function simply loops, waiting for packets to come through
/dev/fwmonitor, and calling fw_do_event() when something arrives.  It
is suitable for simple programs such as show_pings, but more complex
programs might want to look at implementation of fw_do_listen and call
fw_do_event() themselves.

	int fw_do_event(int silent);

This function expects that data is available for reading from
/dev/fwmonitor.  If interest has been registered in the packet, then
the appropriate fw_readpktfn will be called.  If the fw_readpktfn
returns non-NULL, then the packet be injected into the ethertap device
(if is_input was set), or injected into a raw socket.  This
differentiation is important, because packets injected through a raw
socket do not behave like an external packet being received.  For
example, the show_pings example wants the ping packet it reinjects to
be processed normally (ie. responded to), so it needs reinjection
through the ethertap interface.  This applies to any program catching
packets in the `input' chain traversal.

NOTE THAT REINJECTING PACKETS INTO ETHERTAP WITH A SRC IP EQUAL TO AN
EXISTING INTERFACE WILL FAIL, due to internal Linux Kernel sanity
checks.  This means in particular that the case of catching and
reinjecting input packets to the `lo' interface won't work.

show_pings
----------

This example program catches ICMP ping packets, and makes a `ping'
noise using /dev/audio.  It will allow replies to odd-length ping
packets from remote hosts.  By itself it is rather useless, but serves
to demonstrate the use of the libfw library.  If you don't have audio,
try running it with the `-noaudio' flag.  It must be run as root, and
doesn't clean up well from things other than ^C.

tcp_reset
---------

Simple example program that sends a TCP reset in reply to any packets
going to the given address/port.
