aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorPeter Wemm <peter@FreeBSD.org>1997-11-16 04:52:19 +0000
committerPeter Wemm <peter@FreeBSD.org>1997-11-16 04:52:19 +0000
commitaf5dd3181a44c8c60d82fe2f4f8ff9ff81d98e26 (patch)
tree1abde20e1d717a2bf3509de2189cbe7fa3c9f91e
parentacdb2ce24a62f8b955af761b992ae020cc2303ef (diff)
downloadsrc-af5dd3181a44c8c60d82fe2f4f8ff9ff81d98e26.tar.gz
src-af5dd3181a44c8c60d82fe2f4f8ff9ff81d98e26.zip
Import ipfilter 3.2.1 (update from 3.1.8)
Notes
Notes: svn path=/vendor/ipfilter/dist/; revision=31183
-rw-r--r--contrib/ipfilter/BNF10
-rw-r--r--contrib/ipfilter/BugReport10
-rw-r--r--contrib/ipfilter/COMPILE.2.510
-rw-r--r--contrib/ipfilter/FAQ.FreeBSD104
-rw-r--r--contrib/ipfilter/FWTK/README4
-rw-r--r--contrib/ipfilter/FWTK/ftp-gw.diff75
-rw-r--r--contrib/ipfilter/FreeBSD-2.2/files.diffs4
-rw-r--r--contrib/ipfilter/FreeBSD-2.2/files.newconf.diffs6
-rwxr-xr-xcontrib/ipfilter/FreeBSD-2.2/kinstall3
-rwxr-xr-xcontrib/ipfilter/FreeBSD-2.2/unkinstall4
-rw-r--r--contrib/ipfilter/HISTORY176
-rw-r--r--contrib/ipfilter/LICENCE2
-rw-r--r--contrib/ipfilter/Makefile134
-rw-r--r--contrib/ipfilter/README7
-rw-r--r--contrib/ipfilter/fil.c670
-rw-r--r--contrib/ipfilter/fils.c203
-rw-r--r--contrib/ipfilter/inet_addr.c8
-rw-r--r--contrib/ipfilter/ip_auth.c494
-rw-r--r--contrib/ipfilter/ip_auth.h66
-rw-r--r--contrib/ipfilter/ip_compat.h499
-rw-r--r--contrib/ipfilter/ip_fil.c656
-rw-r--r--contrib/ipfilter/ip_fil.h286
-rw-r--r--contrib/ipfilter/ip_frag.c105
-rw-r--r--contrib/ipfilter/ip_frag.h20
-rw-r--r--contrib/ipfilter/ip_ftp_pxy.c161
-rw-r--r--contrib/ipfilter/ip_lfil.c993
-rw-r--r--contrib/ipfilter/ip_log.c473
-rw-r--r--contrib/ipfilter/ip_nat.c571
-rw-r--r--contrib/ipfilter/ip_nat.h61
-rw-r--r--contrib/ipfilter/ip_proxy.c79
-rw-r--r--contrib/ipfilter/ip_proxy.h35
-rw-r--r--contrib/ipfilter/ip_sfil.c394
-rw-r--r--contrib/ipfilter/ip_state.c172
-rw-r--r--contrib/ipfilter/ip_state.h43
-rw-r--r--contrib/ipfilter/ipf.c94
-rw-r--r--contrib/ipfilter/ipf.h18
-rw-r--r--contrib/ipfilter/ipft_ef.c16
-rw-r--r--contrib/ipfilter/ipft_hx.c41
-rw-r--r--contrib/ipfilter/ipft_pc.c10
-rw-r--r--contrib/ipfilter/ipft_sn.c10
-rw-r--r--contrib/ipfilter/ipft_td.c16
-rw-r--r--contrib/ipfilter/ipft_tx.c37
-rw-r--r--contrib/ipfilter/ipl.h4
-rw-r--r--contrib/ipfilter/iplang/BNF69
-rw-r--r--contrib/ipfilter/iplang/Makefile30
-rw-r--r--contrib/ipfilter/iplang/iplang.h51
-rw-r--r--contrib/ipfilter/iplang/iplang.tst11
-rw-r--r--contrib/ipfilter/iplang/iplang_l.l313
-rw-r--r--contrib/ipfilter/iplang/iplang_y.y1858
-rw-r--r--contrib/ipfilter/ipmon.c470
-rw-r--r--contrib/ipfilter/ipnat.c61
-rw-r--r--contrib/ipfilter/ipsd/Makefile10
-rw-r--r--contrib/ipfilter/ipsd/ipsd.c14
-rw-r--r--contrib/ipfilter/ipsd/ipsd.h7
-rw-r--r--contrib/ipfilter/ipsd/ipsdr.c10
-rw-r--r--contrib/ipfilter/ipsd/linux.h8
-rw-r--r--contrib/ipfilter/ipsd/sbpf.c7
-rw-r--r--contrib/ipfilter/ipsd/sdlpi.c10
-rw-r--r--contrib/ipfilter/ipsd/slinux.c9
-rw-r--r--contrib/ipfilter/ipsd/snit.c7
-rw-r--r--contrib/ipfilter/ipsend/44arp.c3
-rw-r--r--contrib/ipfilter/ipsend/Crashable1
-rw-r--r--contrib/ipfilter/ipsend/Makefile130
-rw-r--r--contrib/ipfilter/ipsend/README8
-rw-r--r--contrib/ipfilter/ipsend/arp.c21
-rw-r--r--contrib/ipfilter/ipsend/hpux.c112
-rw-r--r--contrib/ipfilter/ipsend/ip.c53
-rw-r--r--contrib/ipfilter/ipsend/ipresend.1107
-rw-r--r--contrib/ipfilter/ipsend/ipresend.c30
-rw-r--r--contrib/ipfilter/ipsend/ipsend.1109
-rw-r--r--contrib/ipfilter/ipsend/ipsend.5398
-rw-r--r--contrib/ipfilter/ipsend/ipsend.c113
-rw-r--r--contrib/ipfilter/ipsend/ipsend.h7
-rw-r--r--contrib/ipfilter/ipsend/ipsopt.c150
-rw-r--r--contrib/ipfilter/ipsend/iptest.1101
-rw-r--r--contrib/ipfilter/ipsend/iptest.c28
-rw-r--r--contrib/ipfilter/ipsend/iptests.c70
-rw-r--r--contrib/ipfilter/ipsend/larp.c15
-rw-r--r--contrib/ipfilter/ipsend/linux.h2
-rw-r--r--contrib/ipfilter/ipsend/lsock.c25
-rw-r--r--contrib/ipfilter/ipsend/resend.c62
-rw-r--r--contrib/ipfilter/ipsend/sbpf.c14
-rw-r--r--contrib/ipfilter/ipsend/sdlpi.c22
-rw-r--r--contrib/ipfilter/ipsend/sirix.c94
-rw-r--r--contrib/ipfilter/ipsend/slinux.c20
-rw-r--r--contrib/ipfilter/ipsend/snit.c16
-rw-r--r--contrib/ipfilter/ipsend/sock.c73
-rw-r--r--contrib/ipfilter/ipsend/tcpip.h75
-rw-r--r--contrib/ipfilter/ipsend/ultrix.c86
-rw-r--r--contrib/ipfilter/ipt.c45
-rw-r--r--contrib/ipfilter/ipt.h4
-rw-r--r--contrib/ipfilter/kmem.c8
-rw-r--r--contrib/ipfilter/kmem.h4
-rw-r--r--contrib/ipfilter/linux.h4
-rw-r--r--contrib/ipfilter/man/Makefile11
-rw-r--r--contrib/ipfilter/man/ipf.481
-rw-r--r--contrib/ipfilter/man/ipf.5118
-rw-r--r--contrib/ipfilter/man/ipf.8109
-rw-r--r--contrib/ipfilter/man/ipfstat.87
-rw-r--r--contrib/ipfilter/man/ipl.471
-rw-r--r--contrib/ipfilter/man/ipmon.845
-rw-r--r--contrib/ipfilter/man/ipnat.45
-rw-r--r--contrib/ipfilter/misc.c16
-rw-r--r--contrib/ipfilter/mkfilters20
-rw-r--r--contrib/ipfilter/ml_ipl.c2
-rw-r--r--contrib/ipfilter/mlf_ipl.c367
-rw-r--r--contrib/ipfilter/mli_ipl.c580
-rw-r--r--contrib/ipfilter/mln_ipl.c340
-rw-r--r--contrib/ipfilter/mls_ipl.c99
-rw-r--r--contrib/ipfilter/opt.c107
-rw-r--r--contrib/ipfilter/parse.c103
-rw-r--r--contrib/ipfilter/pcap.h4
-rw-r--r--contrib/ipfilter/rules/BASIC.NAT45
-rw-r--r--contrib/ipfilter/rules/BASIC_1.FW99
-rw-r--r--contrib/ipfilter/rules/BASIC_2.FW72
-rw-r--r--contrib/ipfilter/rules/example.104
-rw-r--r--contrib/ipfilter/rules/firewall39
-rw-r--r--contrib/ipfilter/rules/ftp-proxy40
-rw-r--r--contrib/ipfilter/rules/nat-setup77
-rw-r--r--contrib/ipfilter/samples/Makefile12
-rw-r--r--contrib/ipfilter/samples/proxy.c111
-rw-r--r--contrib/ipfilter/samples/userauth.c57
-rw-r--r--contrib/ipfilter/snoop.h4
-rw-r--r--contrib/ipfilter/solaris.c516
-rw-r--r--contrib/ipfilter/test/Makefile14
-rw-r--r--contrib/ipfilter/todo15
126 files changed, 12141 insertions, 2788 deletions
diff --git a/contrib/ipfilter/BNF b/contrib/ipfilter/BNF
index 7cb556e1a0a8..15c14fb6e2cc 100644
--- a/contrib/ipfilter/BNF
+++ b/contrib/ipfilter/BNF
@@ -1,18 +1,21 @@
filter-rule = [ insert ] action in-out [ options ] [ tos ] [ ttl ]
- [ proto ] [ ip ] .
+ [ proto ] [ ip ] [ group ].
insert = "@" decnumber .
-action = block | "pass" | log | "count" | call .
+action = block | "pass" | log | "count" | skip | auth | call .
in-out = "in" | "out" .
options = [ log ] [ "quick" ] [ "on" interface-name [ dup ] [ froute ] ] .
tos = "tos" decnumber | "tos" hexnumber .
ttl = "ttl" decnumber .
proto = "proto" protocol .
ip = srcdst [ flags ] [ with withopt ] [ icmp ] [ keep ] .
+group = [ "head" decnumber ] [ "group" decnumber ] .
block = "block" [ "return-icmp"[return-code] | "return-rst" ] .
+auth = "auth" | "preauth" .
log = "log" [ "body" ] [ "first" ] [ "or-block" ] .
call = "call" [ "now" ] function-name .
+skip = "skip" decnumber .
dup = "dup-to" interface-name[":"ipaddr] .
froute = "fastroute" | "to" interface-name .
protocol = "tcp/udp" | "udp" | "tcp" | "icmp" | decnumber .
@@ -44,7 +47,8 @@ seclvl = "unclass" | "confid" | "reserv-1" | "reserv-2" | "reserv-3" |
"reserv-4" | "secret" | "topsecret" .
icmp-type = "unreach" | "echo" | "echorep" | "squench" | "redir" |
"timex" | "paramprob" | "timest" | "timestrep" | "inforeq" |
- "inforep" | "maskreq" | "maskrep" | decnumber .
+ "inforep" | "maskreq" | "maskrep" | "routerad" |
+ "routersol" | decnumber .
icmp-code = decumber | "net-unr" | "host-unr" | "proto-unr" | "port-unr" |
"needfrag" | "srcfail" | "net-unk" | "host-unk" | "isolate" |
"net-prohib" | "host-prohib" | "net-tos" | "host-tos" .
diff --git a/contrib/ipfilter/BugReport b/contrib/ipfilter/BugReport
new file mode 100644
index 000000000000..0bd243ca1fd7
--- /dev/null
+++ b/contrib/ipfilter/BugReport
@@ -0,0 +1,10 @@
+IP Filter bug report form.
+--------------------------
+IP Filter Version:
+Operating System Version:
+Configuration: <LKM or compiled-into-kernel>
+
+Description of problem:
+
+How to repeat:
+
diff --git a/contrib/ipfilter/COMPILE.2.5 b/contrib/ipfilter/COMPILE.2.5
index ae550f896e49..6e96665f9c76 100644
--- a/contrib/ipfilter/COMPILE.2.5
+++ b/contrib/ipfilter/COMPILE.2.5
@@ -6,6 +6,10 @@ In file included from /usr/local/lib/gcc-lib/sparc-sun-solaris2.3/2.6.3/include/
from ../ip_nat.c:15:
/usr/include/sys/psw.h:19: #error Kernel include of psw.h
-Remove (comment out) the line in
-/usr/local/lib/gcc-lib/sparc-sun-solaris2.3/2.6.3include/sys/user.h
-which includes psw.h
+That means that you have a version of gcc build under on older release
+of Solaris 2.x
+
+You need to reinstall gcc after each Solaris upgrade; gcc creates its own
+set of modified system include files which are only valid for the exact
+release on which gcc was build.
+
diff --git a/contrib/ipfilter/FAQ.FreeBSD b/contrib/ipfilter/FAQ.FreeBSD
new file mode 100644
index 000000000000..3b069c9f4b53
--- /dev/null
+++ b/contrib/ipfilter/FAQ.FreeBSD
@@ -0,0 +1,104 @@
+These are Instructions for Configuring A FreeBSD Box For NAT
+After you have installed IP-Filter.
+
+You will need to change three files:
+
+/etc/rc.local
+/etc/sysconfig
+/etc/natrules
+
+You will have to:
+
+1) Load the kernel module
+2) Make the ipnat rules
+3) Load the ipnat rules
+4) Enable routing between interfaces
+5) Add static routes for the subnet ranges
+6) Configure your network interfaces
+7) reboot the computer for the changes to take effect.
+
+The FAQ was written by Chris Coleman <chris@@bbcc.ctc.edu>
+This was tested using ipfilter 3.1.4 and FreeBSD 2.1.6-RELEASE
+_________________________________________________________
+1) Loading the Kernel Module
+
+If you are using a Kernal Loadable Module you need to edit your
+/etc/rc.local file and load the module at boot time.
+use the line:
+
+ modload /lkm/if_ipl.o
+
+If you are not loading a kernel module, skip this step.
+_________________________________________________________
+2) Setting up the NAT Rules
+
+Make a file called /etc/natrules
+put in the rules that you need for your system.
+
+If you want to use the whole 10 Network. Try:
+
+map fpx0 10.0.0.0/8 -> 208.8.0.1/32 portmap tcp/udp 10000:65000
+
+_________________________________________________________
+Here is an explaination of each part of the command:
+
+map starts the command.
+
+fpx0 is the interface with the real internet address.
+
+10.0.0.0 is the subnet you want to use.
+
+/8 is the subnet mask. ie 255.0.0.0
+
+208.8.0.1 is the real ip address that you use.
+
+/32 is the subnet mask 255.255.255.255, ie only use this ip address.
+
+portmap tcp/udp 10000:65000
+ tells it to use the ports to redirect the tcp/udp calls through
+
+
+The one line should work for the whole network.
+_________________________________________________________
+3) Loading the NAT Rules:
+
+The NAT Rules will need to be loaded every time the computer
+reboots.
+
+In your /etc/rc.local put the line:
+
+ipnat -f /etc/natrules
+
+To check and see if it is loaded, as root type
+ ipnat -ls
+_________________________________________________________
+4) Enable Routing between interfaces.
+
+Tell the kernel to route these addresses.
+
+in the rc.local file put the line:
+
+sysctl -w net.inet.ip.forwarding=1
+
+_________________________________________________________
+5) Static Routes to Subnet Ranges
+
+Now you have to add a static routes for the subnet ranges.
+Edit your /etc/sysconfig to add them at bootup.
+
+static_routes="foo"
+route_foo="10.0.0.0 -netmask 0xf0000000 -interface 10.0.0.1"
+
+
+_________________________________________________________
+6) Make sure that you have your interfaces configured.
+
+I have two Intel Ether Express Pro B cards.
+One is on 208.8.0.1 The other is on 10.0.0.1
+
+You need to configure these in the /etc/sysconfig
+
+network_interfaces="fxp0 fxp1"
+ifconfig_fxp0="inet 208.8.0.1 netmask 255.255.255.0"
+ifconfig_fxp1="inet 10.0.0.1 netmask 255.0.0.0"
+_________________________________________________________
diff --git a/contrib/ipfilter/FWTK/README b/contrib/ipfilter/FWTK/README
index 216d20582036..3ed0e2fa6d21 100644
--- a/contrib/ipfilter/FWTK/README
+++ b/contrib/ipfilter/FWTK/README
@@ -3,7 +3,9 @@ There are two patch files in this directory, each allowing for the Firewall
Toolkit to be used in a transparent proxy configuration.
ftp-gw.diff - A patch written by myself for use only with IP Filter and
- ftp-gw from the Firewall Toolkit.
+ ftp-gw from the Firewall Toolkit. You need to copy ip_nat.h,
+ ip_fil.h and ip_compat.h to the ftp-gw directory to compile
+ once this patch has been applied.
fwtkp - A set of patches written by James B. Croall (jcroall@foo.org)
for use with both IP Filter and ipfwadm (for Linux) and more
diff --git a/contrib/ipfilter/FWTK/ftp-gw.diff b/contrib/ipfilter/FWTK/ftp-gw.diff
index 715d2a76735b..3052eba195c2 100644
--- a/contrib/ipfilter/FWTK/ftp-gw.diff
+++ b/contrib/ipfilter/FWTK/ftp-gw.diff
@@ -1,37 +1,16 @@
-*** ftp-gw.c.orig Sat Nov 5 10:30:16 1994
---- ftp-gw.c Sun Jul 7 12:25:15 1996
+*** ftp-gw.c.orig Sun Jun 22 16:27:42 1997
+--- ftp-gw.c Sun Jun 22 17:02:16 1997
***************
*** 11,31 ****
+--- 11,41 ----
*/
- static char RcsId[] = "$Header: /devel/CVS/IP-Filter/FWTK/ftp-gw.diff,v 2.0.2.2 1997/02/23 10:38:35 darrenr Exp $";
-
-
- #include <stdio.h>
- #include <ctype.h>
- #include <syslog.h>
- #include <sys/signal.h>
- #include <sys/ioctl.h>
- #include <sys/errno.h>
-- extern int errno;
-- extern char *sys_errlist[];
- #include <arpa/ftp.h>
- #include <arpa/telnet.h>
- #include <sys/time.h>
- #include <sys/types.h>
- #include <sys/socket.h>
- #include <netinet/in.h>
-
- extern char *rindex();
- extern char *index();
---- 11,37 ----
- */
- static char RcsId[] = "$Header: /devel/CVS/IP-Filter/FWTK/ftp-gw.diff,v 2.0.2.2 1997/02/23 10:38:35 darrenr Exp $";
+ static char RcsId[] = "$Header: /devel/CVS/IP-Filter/FWTK/ftp-gw.diff,v 2.0.2.3 1997/06/22 07:06:02 darrenr Exp $";
+ /*
+ * Patches for IP Filter NAT extensions written by Darren Reed, 7/7/96
+ * darrenr@cyber.com.au
+ */
-+ static char vIpFilter[] = "v3.1.0";
++ static char vIpFilter[] = "v3.1.11";
#include <stdio.h>
#include <ctype.h>
@@ -41,6 +20,10 @@
#include <sys/signal.h>
#include <sys/ioctl.h>
#include <sys/errno.h>
+ extern int errno;
++ #ifdef sun
+ extern char *sys_errlist[];
++ #endif
#include <arpa/ftp.h>
#include <arpa/telnet.h>
#include <sys/time.h>
@@ -53,17 +36,19 @@
extern char *index();
***************
*** 36,41 ****
---- 42,48 ----
+--- 46,54 ----
#include "firewall.h"
++ #include "ip_compat.h"
++ #include "ip_fil.h"
+ #include "ip_nat.h"
#ifndef BSIZ
#define BSIZ 2048
***************
*** 83,88 ****
---- 90,97 ----
+--- 96,103 ----
static int cmd_noop();
static int cmd_abor();
static int cmd_passthru();
@@ -81,7 +66,7 @@
if(say(0,xuf))
exit(1);
}
---- 326,335 ----
+--- 332,341 ----
if(authallflg)
if(say(0,"220-Proxy first requires authentication"))
exit(1);
@@ -94,7 +79,7 @@
}
***************
*** 338,343 ****
---- 350,357 ----
+--- 356,363 ----
exit(1);
}
@@ -117,10 +102,10 @@
short port = FTPPORT;
/* kludgy but effective. if authorizing everything call auth instead */
---- 622,631 ----
+--- 628,637 ----
***************
*** 643,648 ****
---- 655,681 ----
+--- 661,687 ----
return(sayn(0,noad,sizeof(noad)));
}
@@ -149,7 +134,7 @@
dest = "localhost";
***************
-*** 685,691 ****
+*** 685,693 ****
char ebuf[512];
strcpy(ebuf,buf);
@@ -157,14 +142,19 @@
return(say(0,buf));
}
sprintf(buf,"----GATEWAY CONNECTED TO %s----",dest);
---- 718,724 ----
+ saveline(buf);
+
+--- 724,733 ----
char ebuf[512];
strcpy(ebuf,buf);
! sprintf(buf,"521 %s,%d: %s",dest,ntohs(port),ebuf);
return(say(0,buf));
}
++
sprintf(buf,"----GATEWAY CONNECTED TO %s----",dest);
+ saveline(buf);
+
***************
*** 698,711 ****
return(say(0,buf));
@@ -181,7 +171,7 @@
}
---- 731,738 ----
+--- 738,745 ----
return(say(0,buf));
}
saveline(buf);
@@ -192,7 +182,7 @@
***************
*** 1591,1593 ****
---- 1618,1659 ----
+--- 1625,1671 ----
dup(nread);
}
#endif
@@ -224,14 +214,19 @@
+ natlookup.nl_outport = faddr.sin_port;
+ natlookup.nl_inip = laddr.sin_addr;
+ natlookup.nl_outip = faddr.sin_addr;
-+ if((natfd = open("/dev/ipl", O_RDONLY)) < 0) {
++ natlookup.nl_flags = IPN_TCP;
++ if((natfd = open(IPL_NAT, O_RDONLY)) < 0) {
+ perror("open");
+ exit(1);
+ }
+ if(ioctl(natfd, SIOCGNATL, &natlookup) == -1) {
-+ perror("ioctl");
-+ exit(1);
++ syslog(LOG_ERR, "SIOCGNATL failed: %m\n");
++ close(natfd);
++ if(say(0,"220 Ready"))
++ exit(1);
++ return 0;
+ }
+ close(natfd);
-+ return connectdest(inet_ntoa(natlookup.nl_inip),ntohs(natlookup.nl_inport));
++ return connectdest(inet_ntoa(natlookup.nl_realip),
++ ntohs(natlookup.nl_realport));
+ }
diff --git a/contrib/ipfilter/FreeBSD-2.2/files.diffs b/contrib/ipfilter/FreeBSD-2.2/files.diffs
index 8bd40ac74609..de05264b555d 100644
--- a/contrib/ipfilter/FreeBSD-2.2/files.diffs
+++ b/contrib/ipfilter/FreeBSD-2.2/files.diffs
@@ -2,7 +2,7 @@
--- /sys/conf/files Sat May 24 14:06:44 1997
***************
*** 217,222 ****
---- 217,228 ----
+--- 217,230 ----
netinet/tcp_timer.c optional inet
netinet/tcp_usrreq.c optional inet
netinet/udp_usrreq.c optional inet
@@ -13,6 +13,8 @@
+ netinet/ip_state.c optional ipfilter inet
+ netinet/ip_proxy.c optional ipfilter inet
+ netinet/mlf_ipl.c optional ipfilter inet
++ netinet/ip_auth.c optional ipfilter inet
++ netinet/ip_log.c optional ipfilter inet
netipx/ipx.c optional ipx
netipx/ipx_cksum.c optional ipx
netipx/ipx_error.c optional ipx
diff --git a/contrib/ipfilter/FreeBSD-2.2/files.newconf.diffs b/contrib/ipfilter/FreeBSD-2.2/files.newconf.diffs
index 784ef5d80a7f..67894d0f8798 100644
--- a/contrib/ipfilter/FreeBSD-2.2/files.newconf.diffs
+++ b/contrib/ipfilter/FreeBSD-2.2/files.newconf.diffs
@@ -2,7 +2,7 @@
--- files.newconf Sun Jun 25 02:19:10 1995
***************
*** 161,166 ****
---- 161,171 ----
+--- 161,175 ----
file netinet/ip_input.c inet
file netinet/ip_mroute.c inet
file netinet/ip_output.c inet
@@ -11,6 +11,10 @@
+ file netinet/ip_nat.c ipfilter
+ file netinet/ip_frag.c ipfilter
+ file netinet/ip_state.c ipfilter
++ file netinet/ip_proxy.c ipfilter
++ file netinet/ip_auth.c ipfilter
++ file netinet/ip_log.c ipfilter
++ file netinet/mlf_ipl.c ipfilter
file netinet/raw_ip.c inet
file netinet/tcp_debug.c inet
file netinet/tcp_input.c inet
diff --git a/contrib/ipfilter/FreeBSD-2.2/kinstall b/contrib/ipfilter/FreeBSD-2.2/kinstall
index 035468551efd..26b0e8ffd714 100755
--- a/contrib/ipfilter/FreeBSD-2.2/kinstall
+++ b/contrib/ipfilter/FreeBSD-2.2/kinstall
@@ -9,7 +9,8 @@ set confdir="$archdir/conf"
if ( $dir =~ */FreeBSD* ) cd ..
echo -n "Installing "
foreach i (ip_fil.[ch] ip_nat.[ch] ip_frag.[ch] ip_state.[ch] fil.c \
- ip_proxy.[ch] ip_ftp_pxy.c mlf_ipl.c ipl.h ip_compat.h)
+ ip_proxy.[ch] ip_ftp_pxy.c mlf_ipl.c ipl.h ip_compat.h \
+ ip_auth.[ch] ip_log.c)
echo -n "$i ";
cp $i /sys/netinet
chmod 644 /sys/netinet/$i
diff --git a/contrib/ipfilter/FreeBSD-2.2/unkinstall b/contrib/ipfilter/FreeBSD-2.2/unkinstall
index e31edfb69849..1955f5c415db 100755
--- a/contrib/ipfilter/FreeBSD-2.2/unkinstall
+++ b/contrib/ipfilter/FreeBSD-2.2/unkinstall
@@ -8,7 +8,9 @@ set confdir="$archdir/conf"
if ( $dir =~ */FreeBSD* ) cd ..
echo -n "Uninstalling "
-foreach i (ip_fil.[ch] ip_nat.[ch] ip_frag.[ch] ip_state.[ch] fil.c ip_compat.h)
+foreach i (ip_fil.[ch] ip_nat.[ch] ip_frag.[ch] ip_state.[ch] fil.c \
+ ip_auth.[ch] ip_proxy.[ch] ip_ftp_pxy.c ip_compat.h ip_log.c \
+ mlf_ipl.c ipl.h)
echo -n "$i ";
/bin/rm -f /sys/netinet/$i
end
diff --git a/contrib/ipfilter/HISTORY b/contrib/ipfilter/HISTORY
index 867535098125..ea561457b396 100644
--- a/contrib/ipfilter/HISTORY
+++ b/contrib/ipfilter/HISTORY
@@ -5,6 +5,182 @@
# Thanks to Craig Bishop of connect.com.au and Sun Microsystems for the
# loan of a machine to work on a Solaris 2.x port of this software.
#
+3.2.1 12/11/97 - Released
+
+port to BSD/OS 3.0
+
+port to Linux 2.0.31
+
+patches to make "map a/m -> 0/0" work with ftp proxying properly - Marc Boucher
+
+add "ipf -F s" and "ipf -F S" to flush state table entries.
+
+announce if logging is on or off when ip filter initializes.
+
+"ipf -F a" doesn't flush groups properly for Solaris.
+
+3.2 30/10/97 - Released
+
+ipnat doesn't successfully remove proxy mappings with "-rf" -
+Alexander Romanyu
+
+use K&R C function style for solaris kernel code
+
+use m_adj() to decrease packet size in ftp proxy
+
+use mbufchainlen rather than msgdsize,
+IRIX update - Marc Boucher
+
+fix NetBSD modunload bug (pfil_add_hook done twice)
+
+patches for OpenBSD 2.1 - Craig Bevins <craigb@bitcom.net.au>
+
+3.2beta10 24/10/97 - Released
+
+fix fragment table entries allocated for NAT.
+
+fix tcp checksum calculations over mbuf/mblk boundaries
+
+fix panic for blen < 0 in ftp kernel proxy - marc boucher
+
+fix flushing of rules which have been grouped.
+
+3.2beta9 20/10/97 - Released
+
+some nit picking on solaris2 with SUNWspro - Michael Lyle <mrl@rpnet.net>
+
+ftp kernel proxy patches from Marc Boucher
+
+3.2beta8 13/10/97 - Released
+
+add support for passing ICMP errors back through NAT.
+
+IRIX port update - Marc Boucher
+
+calculate correct MIN size of packet to log for UDP - Marc Boucher
+
+need htons(ETHERTYPE_x) on little endian BSD boxes - Dave Huang
+
+copyright header fixups
+
+3.2beta7 23/09/97 - Released
+
+fickup problems introduced by prior merges & changes.
+
+3.2beta6 23/09/97 - Released
+
+patch for spin-reading race condition - Marc Boucher.
+
+IRIX port by Marc Boucher.
+
+compatibility updates for Linux to ipsend
+
+3.2beta5 13/09/97 - Released
+
+patches from Bernd Ernesti for NetBSD integration (mostly prototyping and
+compiler warning things)
+
+ipf -y will resync IP#'s allocated with 0/32 in NAT to match interface if it
+changes.
+
+update manual pages and other documentation updates.
+
+3.2beta4 27/8/97 - Released
+
+enable setting IP and TCP options for iplang/
+
+Solaris2 patches from Marc Boucher.
+
+add groups for filter rules.
+
+3.2beta3 21/8/97 - Released
+
+patches for Solaris2 (interface panic solution ?): fix FIONREAD and
+replacing q_qinfo points - Marc Boucher <marc@CAM.ORG>
+
+change ipsend/* and ipsd/* copyright notices to be the same as ip filter's
+
+patch for SYN-ACK skew testing fix from Eric V. Smith <EricSmith@windsor.com>
+
+3.2beta2 6/8/97 - Released
+
+make it load on Solaris 2.3
+
+rewrote logging to remove solaris errors, introduced checking to see if the
+same packet is logged successively.
+
+fix filter cache to work when there are no rules loaded.
+
+add "raw" option to ipresend to send entire ethernet frames.
+
+nat list corruption bug - NetBSD - Klaus Klein
+
+3.2beta1 5/7/97 - Released
+
+patches from Jason Thorpe fixing: UNSIGNED_CHAR lossage, off_t being 64bits
+lossage, and other NetBSD bits.
+
+NetBSD 1.2G update.
+
+fixup fwtk patches and add protocol field for SIOCGNATL.
+
+rdr bugs reported by Alexander Romanyu (alexr@aix.krid.crimea.ua), with
+fixes:
+* rdr matched all packets of a given protocol (ignored ports).
+* severe bug in nat_delete which caused system crash/freeze.
+
+change Makefile so that CC isn't passed on for FreeBSD/NetBSD (will use
+the default CC - cc, not gcc)
+
+3.2alpha9 16/6/97 - Released
+
+added "skip" keyword.
+
+implement preauthentication of packets, as outlined by Guido.
+
+Make it compile as cleanly as possible with -Wall & general code cleanup
+
+getopt returns int, not char. Bernd Ernesti
+
+3.2alpha8 13/6/97 - Released
+
+code added to support "auth" rules which require a user program to allow them
+through. First revision and much of the code came from Guido.
+
+hex output from ipmon doesn't goto syslog when recovering from out of sync
+error. Luke Mewburn (lukem@connect.com.au)
+
+fix solaris2.6 lookup of destination ire's.
+
+ipnat doesn't throw away unused bits (after masking), causing it to
+behave incorrectly. Carson Gaspar
+
+NAT code doesn't include inteface name when matching - Alexey Mavrin
+<lha@elco.spb.ru>
+
+replace old SunOS tcpip.h with new tcpip.h (from 4.4BSD) - Jason Thorpe.
+
+update install procedures to include ip_proxy.c
+
+mask out unused bits in NAT/RDR rules.
+
+use a generic type (u_32_t) for 32bit variables, rather than rely on
+u_long being such - Jason Thorpe.
+
+create a local "netinet" directory and include from ~netinet/*" rather than
+just "*" to make keeping the code working on ports easier.
+
+add an m_copydata and m_copyback for SunOS4 (based on 4.4BSD-Lite versions)
+
+documentation updates.
+
+NetBSD update from Jason Thorpe <thorpej@netbsd.org>
+
+allow RST's through with a matching SEQ # and 0 ACK. Guido Van Rooij
+
+ipmon uses excessive amounts of CPU on Solaris2 - Reinhard Bertram
+<Reinhard.Bertram@KOM.th-darmstadt.de>
+
3.2alpha7 25/5/97 - Released
add strlen for pre-2.2 kernels - Doug Kite <dkite@websgi.icomnet.com>
diff --git a/contrib/ipfilter/LICENCE b/contrib/ipfilter/LICENCE
index c5a7767d12cf..63430af979f0 100644
--- a/contrib/ipfilter/LICENCE
+++ b/contrib/ipfilter/LICENCE
@@ -1,5 +1,5 @@
/*
- * (C)opyright 1993, 1994, 1995 by Darren Reed.
+ * Copyright (C) 1993-1997 by Darren Reed.
*
* The author accepts no responsibility for the use of this software and
* provides it on an ``as is'' basis without express or implied warranty.
diff --git a/contrib/ipfilter/Makefile b/contrib/ipfilter/Makefile
index 80cebc77f7dc..a5756bb28d66 100644
--- a/contrib/ipfilter/Makefile
+++ b/contrib/ipfilter/Makefile
@@ -1,13 +1,11 @@
#
-# (C)opyright 1993, 1994, 1995 by Darren Reed.
+# Copyright (C) 1993-1997 by Darren Reed.
#
-# This code may be freely distributed as long as it retains this notice
-# and is not changed in any way. The author accepts no responsibility
-# for the use of this software. I hate legaleese, don't you ?
+# Redistribution and use in source and binary forms are permitted
+# provided that this notice is preserved and due credit is given
+# to the original author and the contributors.
#
-# $Id: Makefile,v 2.0.2.12 1997/05/24 08:13:34 darrenr Exp $
-#
-# where to put things.
+# $Id: Makefile,v 2.0.2.26.2.1 1997/11/12 10:40:21 darrenr Exp $
#
BINDEST=/usr/local/bin
SBINDEST=/sbin
@@ -18,6 +16,7 @@ CC=gcc
DEBUG=-g
CFLAGS=-I$$(TOP)
CPU=`uname -m`
+CPUDIR=`uname -s|sed -e 's@/@@g'`-`uname -r`-`uname -m`
#
# To enable this to work as a Loadable Kernel Module...
#
@@ -40,9 +39,12 @@ LOGFAC=-DLOGFAC=LOG_LOCAL0
POLICY=-DIPF_DEFAULT_PASS=FR_PASS
#
MFLAGS="BINDEST=$(BINDEST)" "SBINDEST=$(SBINDEST)" "MANDIR=$(MANDIR)" \
- "CC=$(CC)" 'CFLAGS=$(CFLAGS) $(SOLARIS2)' "IPFLKM=$(IPFLKM)" \
+ 'CFLAGS=$(CFLAGS) $(SOLARIS2)' "IPFLKM=$(IPFLKM)" \
"IPFLOG=$(IPFLOG)" "LOGFAC=$(LOGFAC)" "POLICY=$(POLICY)" \
- "SOLARIS2=$(SOLARIS2)" "DEBUG=$(DEBUG)" "DCPU=$(CPU)"
+ "SOLARIS2=$(SOLARIS2)" "DEBUG=$(DEBUG)" "DCPU=$(CPU)" \
+ "CPUDIR=$(CPUDIR)"
+#
+SHELL=/bin/sh
#
########## ########## ########## ########## ########## ########## ##########
#
@@ -51,14 +53,18 @@ RM=/bin/rm
CHMOD=/bin/chmod
INSTALL=install
#
-DFLAGS=$(IPFLKM) $(IPFLOG) $(DEF)
all:
@echo "Chose one of the following targets for making IP filter:"
@echo ""
- @echo "solaris - auto-selects SunOS4.1.x/Solaris 2.[45]/Soalris2.[45]-x86"
- @echo "bsd - compile for 4.4BSD based Unixes (FreeBSD/NetBSD/OpenBSD)"
+ @echo "solaris - auto-selects SunOS4.1.x/Solaris 2.[45]/Solaris2.[45]-x86"
+ @echo "netbsd - compile for NetBSD"
+ @echo "openbsd - compile for OpenBSD"
+ @echo "freebsd - compile for FreeBSD 2.0, 2.1 or earlier"
+ @echo "freebsd22 - compile for FreeBSD-2.2 or greater"
+ @echo "bsd - compile for generic 4.4BSD systems"
@echo "bsdi - compile for BSD/OS"
+ @echo "irix - compile for SGI IRIX"
@echo ""
tests:
@@ -66,17 +72,21 @@ tests:
else echo test directory not present, sorry; fi
include:
- mkdir -p netinet
- (cd netinet; /bin/rm -f *; ln -s ../*.h .; ln -s ../ip_ftp_pxy.c .)
+ if [ ! -d netinet -o ! -f netinet/done ] ; then \
+ mkdir -p netinet; \
+ (cd netinet; ln -s ../*.h .; ln -s ../ip_ftp_pxy.c .); \
+ (cd netinet; ln -s ../ipsend/tcpip.h tcpip.h); \
+ touch netinet/done; \
+ fi
sunos solaris: include
./buildsunos
freebsd22 freebsd30: include
- -if [ ! -d BSD/$(CPU) ] ; then mkdir BSD/$(CPU); fi
- -rm -f BSD/$(CPU)/ioconf.h
+ make setup "TARGOS=BSD" "CPUDIR=$(CPUDIR)"
+ -rm -f BSD/$(CPUDIR)/ioconf.h
@if [ -n $(IPFILKERN) ] ; then \
- ln -s /sys/$(IPFILKERN)/ioconf.h BSD/$(CPU); \
+ ln -s /sys/$(IPFILKERN)/ioconf.h BSD/$(CPUDIR); \
elif [ ! -f `uname -v|sed -e 's@^.*:\(/[^: ]*\).*@\1@'`/ioconf.h ] ; then \
echo -n "Can't find ioconf.h in "; \
echo `uname -v|sed -e 's@^.*:\(/[^: ]*\).*@\1@'`; \
@@ -87,43 +97,58 @@ freebsd22 freebsd30: include
make freebsd
netbsd: include
- -if [ ! -d BSD/$(CPU) ] ; then mkdir BSD/$(CPU); fi
- -rm -f BSD/$(CPU)/Makefile BSD/$(CPU)/Makefile.ipsend
- -ln -s ../Makefile BSD/$(CPU)/Makefile
- -ln -s ../Makefile.ipsend BSD/$(CPU)/Makefile.ipsend
- (cd BSD/$(CPU); make build "TOP=../.." $(MFLAGS) "ML=mln_ipl.c"; cd ..)
- (cd BSD/$(CPU); make -f Makefile.ipsend "TOP=../.." $(MFLAGS); cd ..)
+ make setup "TARGOS=BSD" "CPUDIR=$(CPUDIR)"
+ (cd BSD/$(CPUDIR); make build "TOP=../.." $(MFLAGS) 'DLKM=-D_LKM' "ML=mln_ipl.c"; cd ..)
+ (cd BSD/$(CPUDIR); make -f Makefile.ipsend "TOP=../.." $(MFLAGS); cd ..)
+
+openbsd openbsd21: include
+ make setup "TARGOS=BSD" "CPUDIR=$(CPUDIR)"
+ (cd BSD/$(CPUDIR); make build "TOP=../.." $(MFLAGS) 'DLKM=-D_LKM' "ML=mln_ipl.c"; cd ..)
+ (cd BSD/$(CPUDIR); make -f Makefile.ipsend "TOP=../.." $(MFLAGS); cd ..)
freebsd freebsd20 freebsd21: include
- -if [ ! -d BSD/$(CPU) ] ; then mkdir BSD/$(CPU); fi
- -rm -f BSD/$(CPU)/Makefile BSD/$(CPU)/Makefile.ipsend
- -ln -s ../Makefile BSD/$(CPU)/Makefile
- -ln -s ../Makefile.ipsend BSD/$(CPU)/Makefile.ipsend
- (cd BSD/$(CPU); make build "TOP=../.." $(MFLAGS) "ML=mlf_ipl.c"; cd ..)
- (cd BSD/$(CPU); make -f Makefile.ipsend "TOP=../.." $(MFLAGS); cd ..)
+ make setup "TARGOS=BSD" "CPUDIR=$(CPUDIR)"
+ (cd BSD/$(CPUDIR); make build "TOP=../.." $(MFLAGS) "ML=mlf_ipl.c"; cd ..)
+ (cd BSD/$(CPUDIR); make -f Makefile.ipsend "TOP=../.." $(MFLAGS); cd ..)
bsd: include
- -if [ ! -d BSD/$(CPU) ] ; then mkdir BSD/$(CPU); fi
- -rm -f BSD/$(CPU)/Makefile BSD/$(CPU)/Makefile.ipsend
- -ln -s ../Makefile BSD/$(CPU)/Makefile
- -ln -s ../Makefile.ipsend BSD/$(CPU)/Makefile.ipsend
- (cd BSD/$(CPU); make build "TOP=../.." $(MFLAGS); cd ..)
- (cd BSD/$(CPU); make -f Makefile.ipsend "TOP=../.." $(MFLAGS); cd ..)
+ make setup "TARGOS=BSD" "CPUDIR=$(CPUDIR)"
+ (cd BSD/$(CPUDIR); make build "TOP=../.." $(MFLAGS); cd ..)
+ (cd BSD/$(CPUDIR); make -f Makefile.ipsend "TOP=../.." $(MFLAGS); cd ..)
bsdi bsdos: include
- -if [ ! -d BSD/$(CPU) ] ; then mkdir BSD/$(CPU); fi
- -rm -f BSD/$(CPU)/Makefile BSD/$(CPU)/Makefile.ipsend
- -ln -s ../Makefile BSD/$(CPU)/Makefile
- -ln -s ../Makefile.ipsend BSD/$(CPU)/Makefile.ipsend
- (cd BSD/$(CPU); make build "TOP=../.." $(MFLAGS) LKM= ; cd ..)
- (cd BSD/$(CPU); make -f Makefile.ipsend "TOP=../.." $(MFLAGS); cd ..)
+ make setup "TARGOS=BSD" "CPUDIR=$(CPUDIR)"
+ (cd BSD/$(CPUDIR); make build "TOP=../.." $(MFLAGS) LKM= ; cd ..)
+ (cd BSD/$(CPUDIR); make -f Makefile.ipsend "TOP=../.." $(MFLAGS); cd ..)
+
+irix IRIX: include
+ make setup "TARGOS=IRIX" "CPUDIR=$(CPUDIR)"
+ (cd IRIX/$(CPUDIR); smake build "TOP=../.." $(MFLAGS); cd ..)
+ (cd IRIX/$(CPUDIR); make -f Makefile.ipsend "TOP=../.." $(MFLAGS); cd ..)
+
+linux: include
+ make setup "TARGOS=Linux" "CPUDIR=$(CPUDIR)"
+ ./buildlinux
+
+linuxrev:
+ (cd Linux/$(CPUDIR); make build "TOP=../.." $(MFLAGS) LKM= ; cd ..)
+ (cd Linux/$(CPUDIR); make -f Makefile.ipsend "TOP=../.." $(MFLAGS); cd ..)
+
+setup:
+ -if [ ! -d $(TARGOS)/$(CPUDIR) ] ; then mkdir $(TARGOS)/$(CPUDIR); fi
+ -rm -f $(TARGOS)/$(CPUDIR)/Makefile $(TARGOS)/$(CPUDIR)/Makefile.ipsend
+ -ln -s ../Makefile $(TARGOS)/$(CPUDIR)/Makefile
+ -ln -s ../Makefile.ipsend $(TARGOS)/$(CPUDIR)/Makefile.ipsend
clean:
+ ${RM} -rf netinet
${RM} -f core *.o ipt fils ipf ipfstat ipftest ipmon if_ipl \
vnode_if.h $(LKM)
(cd SunOS4; make clean)
(cd SunOS5; make clean)
(cd BSD; make clean)
+ (cd Linux; make clean)
+ if [ "`uname -s`" = "IRIX" ]; then (cd IRIX; make clean); fi
[ -d test ] && (cd test; make clean)
(cd ipsend; make clean)
@@ -136,6 +161,12 @@ clean-sunos4:
clean-sunos5:
(cd SunOS5; make clean)
+clean-irix:
+ (cd IRIX; make clean)
+
+clean-linux:
+ (cd Linux; make clean)
+
get:
-@for i in ipf.c ipt.h solaris.c ipf.h kmem.c ipft_ef.c linux.h \
ipft_pc.c fil.c ipft_sn.c mln_ipl.c fils.c ipft_td.c \
@@ -150,20 +181,20 @@ get:
done
sunos4 solaris1:
- (cd SunOS4; make build TOP=.. $(MFLAGS); cd ..)
- (cd SunOS4; make -f Makefile.ipsend TOP=.. $(MFLAGS); cd ..)
+ (cd SunOS4; make build TOP=.. "CC=$(CC)" $(MFLAGS); cd ..)
+ (cd SunOS4; make -f Makefile.ipsend "CC=$(CC)" TOP=.. $(MFLAGS); cd ..)
sunos5 solaris2:
- (cd SunOS5/$(CPU); make build TOP=../.. $(MFLAGS) "SOLARIS2=$(SOLARIS2)" "CPU=-Dsparc -D__sparc__"; cd ..)
- (cd SunOS5/$(CPU); make -f Makefile.ipsend TOP=../.. $(MFLAGS); cd ..)
+ (cd SunOS5/$(CPU); make build TOP=../.. "CC=$(CC)" $(MFLAGS) "SOLARIS2=$(SOLARIS2)" "CPU=-Dsparc -D__sparc__"; cd ..)
+ (cd SunOS5/$(CPU); make -f Makefile.ipsend TOP=../.. "CC=$(CC)" $(MFLAGS); cd ..)
sunos5x86 solaris2x86:
- (cd SunOS5/$(CPU); make build TOP=../.. $(MFLAGS) "SOLARIS2=$(SOLARIS2)" "CPU=-Di86pc -Di386 -D__i386__"; cd ..)
- (cd SunOS5/$(CPU); make -f Makefile.ipsend TOP=../.. $(MFLAGS); cd ..)
+ (cd SunOS5/$(CPU); make build TOP=../.. "CC=$(CC)" $(MFLAGS) "SOLARIS2=$(SOLARIS2)" "CPU=-Di86pc -Di386 -D__i386__"; cd ..)
+ (cd SunOS5/$(CPU); make -f Makefile.ipsend TOP=../.. "CC=$(CC)" $(MFLAGS); cd ..)
-install-bsd: bsd
- (cd BSD/$(CPU); make install "TOP=../.." $(MFLAGS); cd ..)
- (cd BSD/$(CPU); make -f Makefile.ipsend INSTALL=$(INSTALL) install "TOP=../.." $(MFLAGS); cd ..)
+install-bsd:
+ (cd BSD/$(CPUDIR); make install "TOP=../.." $(MFLAGS); cd ..)
+ (cd BSD/$(CPUDIR); make -f Makefile.ipsend INSTALL=$(INSTALL) install "TOP=../.." $(MFLAGS); cd ..)
install-sunos4: solaris
(cd SunOS4; $(MAKE) "CPU=$(CPU) TOP=.." install)
@@ -171,6 +202,9 @@ install-sunos4: solaris
install-sunos5: solaris
(cd SunOS5; $(MAKE) "CPU=$(CPU) TOP=.." install)
+install-irix: irix
+ (cd IRIX; smake install "CPU=$(CPU) TOP=.." $(MFLAGS))
+
rcsget:
-@for i in ipf.c ipt.h solaris.c ipf.h kmem.c ipft_ef.c linux.h \
ipft_pc.c fil.c ipft_sn.c mln_ipl.c fils.c ipft_td.c \
diff --git a/contrib/ipfilter/README b/contrib/ipfilter/README
index b959d408f293..3fac6ecb2bf5 100644
--- a/contrib/ipfilter/README
+++ b/contrib/ipfilter/README
@@ -9,7 +9,7 @@ It is also quite possible for this small kernel extension to be installed
and used effectively on Sun workstations which don't route IP, just for
added security. It can also be integrated with the multicast patches.
It has also been tested successfully on all of the modern free BSDs as
-well as BSDI.
+well as BSDI, and SGI's IRIX 6.2.
The filter keeps a rule list for both inbound and outbound sides of
the IP packet queue and a check is made as early as possible, aiming to
@@ -42,6 +42,11 @@ of the packets being "short". ICMP and UDP packets which are too small
asked. When filtering on fragmented packets, the last fragment will get
through for TCP/UDP/ICMP packets.
+Bugs/Problems
+-------------
+If you have a problem with IP Filter on your operating system, please email
+a copy of the file "BugReport" with the details of your setup as required
+and email to darrenr@cyber.com.au.
Some general notes.
-------------------
diff --git a/contrib/ipfilter/fil.c b/contrib/ipfilter/fil.c
index b40695f829e3..4c0f8c1b74d6 100644
--- a/contrib/ipfilter/fil.c
+++ b/contrib/ipfilter/fil.c
@@ -1,13 +1,13 @@
/*
- * (C)opyright 1993-1996 by Darren Reed.
+ * Copyright (C) 1993-1997 by Darren Reed.
*
* Redistribution and use in source and binary forms are permitted
* provided that this notice is preserved and due credit is given
* to the original author and the contributors.
*/
-#if !defined(lint) && defined(LIBC_SCCS)
-static char sccsid[] = "@(#)fil.c 1.36 6/5/96 (C) 1993-1996 Darren Reed";
-static char rcsid[] = "$Id: fil.c,v 2.0.2.13 1997/05/24 07:33:37 darrenr Exp $";
+#if !defined(lint)
+static const char sccsid[] = "@(#)fil.c 1.36 6/5/96 (C) 1993-1996 Darren Reed";
+static const char rcsid[] = "@(#)$Id: fil.c,v 2.0.2.41.2.3 1997/11/12 10:44:22 darrenr Exp $";
#endif
#include <sys/errno.h>
@@ -16,7 +16,7 @@ static char rcsid[] = "$Id: fil.c,v 2.0.2.13 1997/05/24 07:33:37 darrenr Exp $";
#include <sys/time.h>
#include <sys/file.h>
#include <sys/ioctl.h>
-#if defined(_KERNEL) || defined(KERNEL)
+#if (defined(_KERNEL) || defined(KERNEL)) && !defined(linux)
# include <sys/systm.h>
#else
# include <stdio.h>
@@ -24,14 +24,18 @@ static char rcsid[] = "$Id: fil.c,v 2.0.2.13 1997/05/24 07:33:37 darrenr Exp $";
#endif
#include <sys/uio.h>
#if !defined(__SVR4) && !defined(__svr4__)
-# include <sys/mbuf.h>
+# ifndef linux
+# include <sys/mbuf.h>
+# endif
#else
# include <sys/byteorder.h>
# include <sys/dditypes.h>
# include <sys/stream.h>
#endif
-#include <sys/protosw.h>
-#include <sys/socket.h>
+#ifndef linux
+# include <sys/protosw.h>
+# include <sys/socket.h>
+#endif
#include <net/if.h>
#ifdef sun
# include <net/af.h>
@@ -40,17 +44,20 @@ static char rcsid[] = "$Id: fil.c,v 2.0.2.13 1997/05/24 07:33:37 darrenr Exp $";
#include <netinet/in.h>
#include <netinet/in_systm.h>
#include <netinet/ip.h>
-#include <netinet/ip_var.h>
+#ifndef linux
+# include <netinet/ip_var.h>
+#endif
#include <netinet/tcp.h>
#include <netinet/udp.h>
-#include <netinet/tcpip.h>
#include <netinet/ip_icmp.h>
#include "netinet/ip_compat.h"
+#include <netinet/tcpip.h>
#include "netinet/ip_fil.h"
#include "netinet/ip_proxy.h"
#include "netinet/ip_nat.h"
#include "netinet/ip_frag.h"
#include "netinet/ip_state.h"
+#include "netinet/ip_auth.h"
#ifndef MIN
#define MIN(a,b) (((a)<(b))?(a):(b))
#endif
@@ -66,52 +73,68 @@ extern int opts;
second; }
# define FR_VERBOSE(verb_pr) verbose verb_pr
# define FR_DEBUG(verb_pr) debug verb_pr
-# define FR_SCANLIST(p, ip, fi, m) fr_scanlist(p, ip, fi, m)
-# define SEND_RESET(ip, qif, q, if) send_reset(ip, if)
+# define SEND_RESET(ip, qif, if) send_reset(ip, if)
# define IPLLOG(a, c, d, e) ipllog()
+# define FR_NEWAUTH(m, fi, ip, qif) fr_newauth((mb_t *)m, fi, ip)
# if SOLARIS
# define ICMP_ERROR(b, ip, t, c, if, src) icmp_error(ip)
# else
# define ICMP_ERROR(b, ip, t, c, if, src) icmp_error(b, ip, if)
# endif
-
#else /* #ifndef _KERNEL */
# define FR_IFVERBOSE(ex,second,verb_pr) ;
# define FR_IFDEBUG(ex,second,verb_pr) ;
# define FR_VERBOSE(verb_pr)
# define FR_DEBUG(verb_pr)
-# define FR_SCANLIST(p, ip, fi, m) fr_scanlist(p, ip, fi, m)
-# define IPLLOG(a, c, d, e) ipllog(a, IPL_LOGIPF, c, d, e)
+# define IPLLOG(a, c, d, e) ipflog(a, c, d, e)
+# if SOLARIS || defined(__sgi)
+extern kmutex_t ipf_mutex, ipf_auth;
+# endif
# if SOLARIS
-extern kmutex_t ipf_mutex;
-# define SEND_RESET(ip, qif, q, if) send_reset(ip, qif, q)
+# define FR_NEWAUTH(m, fi, ip, qif) fr_newauth((mb_t *)m, fi, \
+ ip, qif)
+# define SEND_RESET(ip, qif, if) send_reset(ip, qif)
# define ICMP_ERROR(b, ip, t, c, if, src) \
- icmp_error(b, ip, t, c, if, src)
-# else
-# define FR_SCANLIST(p, ip, fi, m) fr_scanlist(p, ip, fi, m)
-# define SEND_RESET(ip, qif, q, if) send_reset((struct tcpiphdr *)ip)
-# if BSD < 199103
+ icmp_error(ip, t, c, if, src)
+# else /* SOLARIS */
+# define FR_NEWAUTH(m, fi, ip, qif) fr_newauth((mb_t *)m, fi, ip)
+# define SEND_RESET(ip, qif, if) send_reset((struct tcpiphdr *)ip)
+# ifdef __sgi
# define ICMP_ERROR(b, ip, t, c, if, src) \
- icmp_error(mtod(b, ip_t *), t, c, if, src)
+ icmp_error(b, t, c, if, src, if)
# else
-# define ICMP_ERROR(b, ip, t, c, if, src) \
+# if BSD < 199103
+# ifdef linux
+# define ICMP_ERROR(b, ip, t, c, if, src) icmp_send(b,t,c,0,if)
+# else
+# define ICMP_ERROR(b, ip, t, c, if, src) \
+ icmp_error(mtod(b, ip_t *), t, c, if, src)
+# endif /* linux */
+# else
+# define ICMP_ERROR(b, ip, t, c, if, src) \
icmp_error(b, t, c, (src).s_addr, if)
-# endif
-# endif
-#endif
+# endif /* BSD < 199103 */
+# endif /* __sgi */
+# endif /* SOLARIS || __sgi */
+#endif /* _KERNEL */
struct filterstats frstats[2] = {{0,0,0,0,0},{0,0,0,0,0}};
struct frentry *ipfilter[2][2] = { { NULL, NULL }, { NULL, NULL } },
*ipacct[2][2] = { { NULL, NULL }, { NULL, NULL } };
+struct frgroup *ipfgroups[3][2];
int fr_flags = IPF_LOGGING, fr_active = 0;
+#if defined(IPFILTER_DEFAULT_BLOCK)
+int fr_pass = FR_NOMATCH|FR_BLOCK;
+#else
int fr_pass = (IPF_DEFAULT_PASS|FR_NOMATCH);
+#endif
fr_info_t frcache[2];
static void fr_makefrip __P((int, ip_t *, fr_info_t *));
static int fr_tcpudpchk __P((frentry_t *, fr_info_t *));
-static int fr_scanlist __P((int, ip_t *, fr_info_t *, void *));
+static int frflushlist __P((int, int, int *, frentry_t *, frentry_t **));
/*
@@ -176,6 +199,8 @@ fr_info_t *fin;
fin->fin_data[0] = 0;
fin->fin_data[1] = 0;
fin->fin_rule = -1;
+ fin->fin_group = -1;
+ fin->fin_id = ip->ip_id;
#ifdef _KERNEL
fin->fin_icode = ipl_unreach;
#endif
@@ -186,10 +211,10 @@ fr_info_t *fin;
tcp = (tcphdr_t *)((char *)ip + hlen);
fin->fin_dp = (void *)tcp;
(*(((u_short *)fi) + 1)) = (*(((u_short *)ip) + 4));
- (*(((u_long *)fi) + 1)) = (*(((u_long *)ip) + 3));
- (*(((u_long *)fi) + 2)) = (*(((u_long *)ip) + 4));
+ (*(((u_32_t *)fi) + 1)) = (*(((u_32_t *)ip) + 3));
+ (*(((u_32_t *)fi) + 2)) = (*(((u_32_t *)ip) + 4));
- fi->fi_fl = (hlen > sizeof(struct ip)) ? FI_OPTIONS : 0;
+ fi->fi_fl = (hlen > sizeof(ip_t)) ? FI_OPTIONS : 0;
off = (ip->ip_off & 0x1fff) << 3;
if (ip->ip_off & 0x3fff)
fi->fi_fl |= FI_FRAG;
@@ -371,7 +396,7 @@ fr_info_t *fin;
* Could be per interface, but this gets real nasty when you don't have
* kernel sauce.
*/
-static int fr_scanlist(pass, ip, fin, m)
+int fr_scanlist(pass, ip, fin, m)
int pass;
ip_t *ip;
register fr_info_t *fin;
@@ -379,18 +404,23 @@ void *m;
{
register struct frentry *fr;
register fr_ip_t *fi = &fin->fin_fi;
- int rulen, portcmp = 0, off;
+ int rulen, portcmp = 0, off, skip = 0;
fr = fin->fin_fr;
fin->fin_fr = NULL;
fin->fin_rule = 0;
+ fin->fin_group = 0;
off = ip->ip_off & 0x1fff;
- pass |= (fi->fi_fl << 20);
+ pass |= (fi->fi_fl << 24);
if ((fi->fi_fl & FI_TCPUDP) && (fin->fin_dlen > 3) && !off)
portcmp = 1;
for (rulen = 0; fr; fr = fr->fr_next, rulen++) {
+ if (skip) {
+ skip--;
+ continue;
+ }
/*
* In all checks below, a null (zero) value in the
* filter struture is taken to mean a wildcard.
@@ -403,18 +433,19 @@ void *m;
#else
if (opts & (OPT_VERBOSE|OPT_DEBUG))
printf("\n");
- FR_VERBOSE(("%c", (pass & FR_PASS) ? 'p' : 'b'));
+ FR_VERBOSE(("%c", (pass & FR_PASS) ? 'p' :
+ (pass & FR_AUTH) ? 'a' : 'b'));
if (fr->fr_ifa && fr->fr_ifa != fin->fin_ifp)
continue;
FR_VERBOSE((":i"));
#endif
{
- register u_long *ld, *lm, *lip;
- register int i, j;
+ register u_32_t *ld, *lm, *lip;
+ register int i;
- lip = (u_long *)fi;
- lm = (u_long *)&fr->fr_mip;
- ld = (u_long *)&fr->fr_ip;
+ lip = (u_32_t *)fi;
+ lm = (u_32_t *)&fr->fr_mip;
+ ld = (u_32_t *)&fr->fr_ip;
i = ((lip[0] & lm[0]) != ld[0]);
FR_IFDEBUG(i,continue,("0. %#08x & %#08x != %#08x\n",
lip[0], lm[0], ld[0]));
@@ -462,7 +493,8 @@ void *m;
/*
* Just log this packet...
*/
- pass = fr->fr_flags;
+ if (!(skip = fr->fr_skip))
+ pass = fr->fr_flags;
if ((pass & FR_CALLNOW) && fr->fr_func)
pass = (*fr->fr_func)(pass, ip, fin);
#ifdef IPFILTER_LOG
@@ -479,7 +511,17 @@ void *m;
else
fin->fin_icode = fr->fr_icode;
fin->fin_rule = rulen;
+ fin->fin_group = fr->fr_group;
fin->fin_fr = fr;
+ if (fr->fr_grp) {
+ fin->fin_fr = fr->fr_grp;
+ pass = fr_scanlist(pass, ip, fin, m);
+ if (fin->fin_fr == NULL) {
+ fin->fin_rule = rulen;
+ fin->fin_group = fr->fr_group;
+ fin->fin_fr = fr;
+ }
+ }
if (pass & FR_QUICK)
break;
}
@@ -493,23 +535,16 @@ void *m;
* or not to pass it on or not.
*/
int fr_check(ip, hlen, ifp, out
-#ifdef _KERNEL
-# if SOLARIS
-, qif, q, mp)
+#if defined(_KERNEL) && SOLARIS
+, qif, mp)
qif_t *qif;
-queue_t *q;
-mblk_t **mp;
-# else
-, mp)
-struct mbuf **mp;
-# endif
#else
, mp)
-char *mp;
#endif
+mb_t **mp;
ip_t *ip;
int hlen;
-struct ifnet *ifp;
+void *ifp;
int out;
{
/*
@@ -518,34 +553,66 @@ int out;
fr_info_t frinfo, *fc;
register fr_info_t *fin = &frinfo;
frentry_t *fr = NULL;
- int pass, changed;
-#ifndef _KERNEL
- char *mc = mp, *m = mp;
+ int pass, changed, apass;
+#if !SOLARIS || !defined(_KERNEL)
+ register mb_t *m = *mp;
#endif
#ifdef _KERNEL
+ mb_t *mc = NULL;
# if !defined(__SVR4) && !defined(__svr4__)
- register struct mbuf *m = *mp;
- struct mbuf *mc = NULL;
+# ifdef __sgi
+ char hbuf[(0xf << 2) + sizeof(struct icmp) + sizeof(ip_t) + 8];
+# endif
+ int up;
if ((ip->ip_p == IPPROTO_TCP || ip->ip_p == IPPROTO_UDP ||
ip->ip_p == IPPROTO_ICMP)) {
- register int up = MIN(hlen + 8, ip->ip_len);
+ int plen = 0;
+
+ switch(ip->ip_p)
+ {
+ case IPPROTO_TCP:
+ plen = sizeof(tcphdr_t);
+ break;
+ case IPPROTO_UDP:
+ plen = sizeof(udphdr_t);
+ break;
+ case IPPROTO_ICMP:
+ /* 96 - enough for complete ICMP error IP header */
+ plen = sizeof(struct icmp) + sizeof(ip_t) + 8;
+ break;
+ }
+ up = MIN(hlen + plen, ip->ip_len);
if (up > m->m_len) {
+#ifdef __sgi /* Under IRIX, avoid m_pullup as it makes ping <hostname> panic */
+ if ((up > sizeof(hbuf)) || (m_length(m) < up)) {
+ frstats[out].fr_pull[1]++;
+ return -1;
+ }
+ m_copydata(m, 0, up, hbuf);
+ frstats[out].fr_pull[0]++;
+ ip = (ip_t *)hbuf;
+#else
+# ifndef linux
if ((*mp = m_pullup(m, up)) == 0) {
frstats[out].fr_pull[1]++;
return -1;
} else {
frstats[out].fr_pull[0]++;
m = *mp;
- ip = mtod(m, struct ip *);
+ ip = mtod(m, ip_t *);
}
- }
- }
+# endif
+#endif
+ } else
+ up = 0;
+ } else
+ up = 0;
# endif
# if SOLARIS
- mblk_t *mc = NULL, *m = qif->qf_m;
+ mb_t *m = qif->qf_m;
# endif
#endif
fr_makefrip(hlen, ip, fin);
@@ -554,33 +621,78 @@ int out;
fin->fin_mp = mp;
MUTEX_ENTER(&ipf_mutex);
+
+ /*
+ * Check auth now. This, combined with the check below to see if apass
+ * is 0 is to ensure that we don't count the packet twice, which can
+ * otherwise occur when we reprocess it. As it is, we only count it
+ * after it has no auth. table matchup. This also stops NAT from
+ * occuring until after the packet has been auth'd.
+ */
+ apass = fr_checkauth(ip, fin);
+
if (!out) {
changed = ip_natin(ip, hlen, fin);
- if ((fin->fin_fr = ipacct[0][fr_active]) &&
+ if (!apass && (fin->fin_fr = ipacct[0][fr_active]) &&
(FR_SCANLIST(FR_NOMATCH, ip, fin, m) & FR_ACCOUNT))
frstats[0].fr_acct++;
}
- if (!(pass = ipfr_knownfrag(ip, fin)) &&
- !(pass = fr_checkstate(ip, fin))) {
- fc = frcache + out;
- if (fc->fin_fr && !bcmp((char *)fin, (char *)fc, FI_CSIZE)) {
- /*
- * copy cached data so we can unlock the mutex
- * earlier.
- */
- bcopy((char *)fc, (char *)fin, sizeof(*fin));
- frstats[out].fr_chit++;
- pass = fin->fin_fr->fr_flags;
- } else {
- pass = fr_pass;
- if ((fin->fin_fr = ipfilter[out][fr_active]))
- pass = FR_SCANLIST(fr_pass, ip, fin, m);
- bcopy((char *)fin, (char *)fc, FI_CSIZE);
- if (pass & FR_NOMATCH)
- frstats[out].fr_nom++;
+ if (apass || (!(pass = ipfr_knownfrag(ip, fin)) &&
+ !(pass = fr_checkstate(ip, fin)))) {
+ /*
+ * If a packet is found in the auth table, then skip checking
+ * the access lists for permission but we do need to consider
+ * the result as if it were from the ACL's.
+ */
+ if (!apass) {
+ fc = frcache + out;
+ if (!bcmp((char *)fin, (char *)fc, FI_CSIZE)) {
+ /*
+ * copy cached data so we can unlock the mutex
+ * earlier.
+ */
+ bcopy((char *)fc, (char *)fin, FI_COPYSIZE);
+ frstats[out].fr_chit++;
+ if ((fr = fin->fin_fr)) {
+ fr->fr_hits++;
+ pass = fr->fr_flags;
+ } else
+ pass = fr_pass;
+ } else {
+ pass = fr_pass;
+ if ((fin->fin_fr = ipfilter[out][fr_active]))
+ pass = FR_SCANLIST(fr_pass, ip, fin, m);
+ bcopy((char *)fin, (char *)fc, FI_COPYSIZE);
+ if (pass & FR_NOMATCH)
+ frstats[out].fr_nom++;
+ }
+ fr = fin->fin_fr;
+ } else
+ pass = apass;
+
+ /*
+ * If we fail to add a packet to the authorization queue,
+ * then we drop the packet later. However, if it was added
+ * then pretend we've dropped it already.
+ */
+ if ((pass & FR_AUTH))
+ if (FR_NEWAUTH(m, fin, ip, qif) != 0)
+#ifdef _KERNEL
+ m = *mp = NULL;
+#else
+ ;
+#endif
+
+ if (pass & FR_PREAUTH) {
+ MUTEX_ENTER(&ipf_auth);
+ if ((fin->fin_fr = ipauth) &&
+ (pass = FR_SCANLIST(0, ip, fin, m)))
+ fr_authstats.fas_hits++;
+ else
+ fr_authstats.fas_miss++;
+ MUTEX_EXIT(&ipf_auth);
}
- fr = fin->fin_fr;
if (pass & FR_KEEPFRAG) {
if (fin->fin_fi.fi_fl & FI_FRAG) {
@@ -602,7 +714,11 @@ int out;
if (fr && fr->fr_func && !(pass & FR_CALLNOW))
pass = (*fr->fr_func)(pass, ip, fin);
- if (out) {
+ /*
+ * Only count/translate packets which will be passed on, out the
+ * interface.
+ */
+ if (out && (pass & FR_PASS)) {
if ((fin->fin_fr = ipacct[1][fr_active]) &&
(FR_SCANLIST(FR_NOMATCH, ip, fin, m) & FR_ACCOUNT))
frstats[1].fr_acct++;
@@ -649,7 +765,9 @@ logit:
# if SOLARIS
mc = dupmsg(m);
# else
+# ifndef linux
mc = m_copy(m, 0, M_COPYALL);
+# endif
# endif
#endif
@@ -680,7 +798,7 @@ logit:
frstats[0].fr_ret++;
} else if ((pass & FR_RETRST) &&
!(fin->fin_fi.fi_fl & FI_SHORT)) {
- if (SEND_RESET(ip, qif, q, ifp) == 0)
+ if (SEND_RESET(ip, qif, ifp) == 0)
frstats[1].fr_ret++;
}
#else
@@ -703,8 +821,9 @@ logit:
* Once we're finished return to our caller, freeing the packet if
* we are dropping it (* BSD ONLY *).
*/
-#ifdef _KERNEL
-# if !SOLARIS
+#if defined(_KERNEL)
+# if !SOLARIS
+# if !defined(linux)
if (fr) {
frdest_t *fdp = &fr->fr_tif;
@@ -718,8 +837,13 @@ logit:
}
if (!(pass & FR_PASS) && m)
m_freem(m);
+# ifdef __sgi
+ else if (changed && up && m)
+ m_copyback(m, 0, up, hbuf);
+# endif
+# endif /* !linux */
return (pass & FR_PASS) ? 0 : -1;
-# else
+# else /* !SOLARIS */
if (fr) {
frdest_t *fdp = &fr->fr_tif;
@@ -732,49 +856,23 @@ logit:
ipfr_fastroute(qif, ip, mc, mp, fin, &fr->fr_dif);
}
return (pass & FR_PASS) ? changed : -1;
-# endif
-#else
+# endif /* !SOLARIS */
+#else /* _KERNEL */
if (pass & FR_NOMATCH)
return 1;
if (pass & FR_PASS)
return 0;
+ if (pass & FR_AUTH)
+ return -2;
return -1;
-#endif
+#endif /* _KERNEL */
}
-#ifdef IPFILTER_LOG
-int fr_copytolog(dev, buf, len)
-int dev;
-char *buf;
-int len;
-{
- register char *bufp = iplbuf[dev], *tp = iplt[dev], *hp = iplh[dev];
- register int clen, tail;
-
- tail = (hp >= tp) ? (bufp + IPLLOGSIZE - hp) : (tp - hp);
- clen = MIN(tail, len);
- bcopy(buf, hp, clen);
- len -= clen;
- tail -= clen;
- hp += clen;
- buf += clen;
- if (hp == bufp + IPLLOGSIZE) {
- hp = bufp;
- tail = tp - hp;
- }
- if (len && tail) {
- clen = MIN(tail, len);
- bcopy(buf, hp, clen);
- len -= clen;
- hp += clen;
- }
- iplh[dev] = hp;
- return len;
-}
-#endif
-
-
+/*
+ * ipf_cksum
+ * addr should be 16bit aligned and len is in bytes.
+ */
u_short ipf_cksum(addr, len)
register u_short *addr;
register int len;
@@ -803,11 +901,7 @@ register int len;
* odd sizes.
*/
u_short fr_tcpsum(m, ip, tcp)
-#if SOLARIS
-mblk_t *m;
-#else
-struct mbuf *m;
-#endif
+mb_t *m;
ip_t *ip;
tcphdr_t *tcp;
{
@@ -817,12 +911,22 @@ tcphdr_t *tcp;
} bytes;
u_long sum;
u_short *sp;
- int len, add, hlen, ilen;
+ int len;
+# if SOLARIS || defined(__sgi)
+ int add, hlen;
+# endif
+
+# if SOLARIS
+ /* skip any leading M_PROTOs */
+ while(m && (MTYPE(m) != M_DATA))
+ m = m->b_cont;
+ PANIC((!m),("fr_tcpsum: no M_DATA"));
+# endif
/*
* Add up IP Header portion
*/
- ilen = len = ip->ip_len - (ip->ip_hl << 2);
+ len = ip->ip_len - (ip->ip_hl << 2);
bytes.c[0] = 0;
bytes.c[1] = IPPROTO_TCP;
sum = bytes.s;
@@ -855,35 +959,58 @@ tcphdr_t *tcp;
while (hlen) {
add = MIN(hlen, m->b_wptr - m->b_rptr);
sp = (u_short *)((caddr_t)m->b_rptr + add);
- if ((hlen -= add))
+ hlen -= add;
+ if ((caddr_t)sp >= (caddr_t)m->b_wptr) {
m = m->b_cont;
+ PANIC((!m),("fr_tcpsum: not enough data"));
+ if (!hlen)
+ sp = (u_short *)m->b_rptr;
+ }
+ }
+ }
+#endif
+#ifdef __sgi
+ /*
+ * In case we had to copy the IP & TCP header out of mbufs,
+ * skip over the mbuf bits which are the header
+ */
+ if ((caddr_t)ip != mtod(m, caddr_t)) {
+ hlen = (caddr_t)sp - (caddr_t)ip;
+ while (hlen) {
+ add = MIN(hlen, m->m_len);
+ sp = (u_short *)(mtod(m, caddr_t) + add);
+ hlen -= add;
+ if (add >= m->m_len) {
+ m = m->m_next;
+ PANIC((!m),("fr_tcpsum: not enough data"));
+ if (!hlen)
+ sp = mtod(m, u_short *);
+ }
}
}
#endif
if (!(len -= sizeof(*tcp)))
goto nodata;
- while (len > 1) {
- sum += *sp++;
- len -= 2;
+ while (len > 0) {
#if SOLARIS
- if ((caddr_t)sp > (caddr_t)m->b_wptr) {
+ if ((caddr_t)sp >= (caddr_t)m->b_wptr) {
m = m->b_cont;
PANIC((!m),("fr_tcpsum: not enough data"));
sp = (u_short *)m->b_rptr;
}
#else
-# ifdef m_data
- if ((caddr_t)sp > (m->m_data + m->m_len))
-# else
- if ((caddr_t)sp > (caddr_t)(m->m_dat + m->m_off + m->m_len))
-# endif
+ if (((caddr_t)sp - mtod(m, caddr_t)) >= m->m_len)
{
m = m->m_next;
PANIC((!m),("fr_tcpsum: not enough data"));
sp = mtod(m, u_short *);
}
#endif /* SOLARIS */
+ if (len < 2)
+ break;
+ sum += *sp++;
+ len -= 2;
}
if (len) {
bytes.c[1] = 0;
@@ -896,3 +1023,268 @@ nodata:
sum = (u_short)((~sum) & 0xffff);
return sum;
}
+
+
+#if defined(_KERNEL) && ( ((BSD < 199306) && !SOLARIS) || defined(__sgi) )
+/*
+ * Copyright (c) 1982, 1986, 1988, 1991, 1993
+ * The Regents of the University of California. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by the University of
+ * California, Berkeley and its contributors.
+ * 4. Neither the name of the University nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ * @(#)uipc_mbuf.c 8.2 (Berkeley) 1/4/94
+ * $Id: fil.c,v 2.0.2.41.2.3 1997/11/12 10:44:22 darrenr Exp $
+ */
+/*
+ * Copy data from an mbuf chain starting "off" bytes from the beginning,
+ * continuing for "len" bytes, into the indicated buffer.
+ */
+void
+m_copydata(m, off, len, cp)
+ register mb_t *m;
+ register int off;
+ register int len;
+ caddr_t cp;
+{
+ register unsigned count;
+
+ if (off < 0 || len < 0)
+ panic("m_copydata");
+ while (off > 0) {
+ if (m == 0)
+ panic("m_copydata");
+ if (off < m->m_len)
+ break;
+ off -= m->m_len;
+ m = m->m_next;
+ }
+ while (len > 0) {
+ if (m == 0)
+ panic("m_copydata");
+ count = MIN(m->m_len - off, len);
+ bcopy(mtod(m, caddr_t) + off, cp, count);
+ len -= count;
+ cp += count;
+ off = 0;
+ m = m->m_next;
+ }
+}
+
+
+# ifndef linux
+/*
+ * Copy data from a buffer back into the indicated mbuf chain,
+ * starting "off" bytes from the beginning, extending the mbuf
+ * chain if necessary.
+ */
+void
+m_copyback(m0, off, len, cp)
+ struct mbuf *m0;
+ register int off;
+ register int len;
+ caddr_t cp;
+{
+ register int mlen;
+ register struct mbuf *m = m0, *n;
+ int totlen = 0;
+
+ if (m0 == 0)
+ return;
+ while (off > (mlen = m->m_len)) {
+ off -= mlen;
+ totlen += mlen;
+ if (m->m_next == 0) {
+ n = m_getclr(M_DONTWAIT, m->m_type);
+ if (n == 0)
+ goto out;
+ n->m_len = min(MLEN, len + off);
+ m->m_next = n;
+ }
+ m = m->m_next;
+ }
+ while (len > 0) {
+ mlen = min (m->m_len - off, len);
+ bcopy(cp, off + mtod(m, caddr_t), (unsigned)mlen);
+ cp += mlen;
+ len -= mlen;
+ mlen += off;
+ off = 0;
+ totlen += mlen;
+ if (len == 0)
+ break;
+ if (m->m_next == 0) {
+ n = m_get(M_DONTWAIT, m->m_type);
+ if (n == 0)
+ break;
+ n->m_len = min(MLEN, len);
+ m->m_next = n;
+ }
+ m = m->m_next;
+ }
+out:
+#if 0
+ if (((m = m0)->m_flags & M_PKTHDR) && (m->m_pkthdr.len < totlen))
+ m->m_pkthdr.len = totlen;
+#endif
+ return;
+}
+# endif /* linux */
+#endif /* (_KERNEL) && ( ((BSD < 199306) && !SOLARIS) || __sgi) */
+
+
+frgroup_t *fr_findgroup(num, flags, which, set, fgpp)
+u_short num;
+u_32_t flags;
+int which, set;
+frgroup_t ***fgpp;
+{
+ frgroup_t *fg, **fgp;
+
+ if (which == IPL_LOGAUTH)
+ fgp = &ipfgroups[2][set];
+ else if (flags & FR_ACCOUNT)
+ fgp = &ipfgroups[1][set];
+ else if (flags & (FR_OUTQUE|FR_INQUE))
+ fgp = &ipfgroups[0][set];
+ else
+ return NULL;
+
+ while ((fg = *fgp))
+ if (fg->fg_num == num)
+ break;
+ else
+ fgp = &fg->fg_next;
+ if (fgpp)
+ *fgpp = fgp;
+ return fg;
+}
+
+
+frgroup_t *fr_addgroup(num, fp, which, set)
+u_short num;
+frentry_t *fp;
+int which, set;
+{
+ frgroup_t *fg, **fgp;
+
+ if ((fg = fr_findgroup(num, fp->fr_flags, which, set, &fgp)))
+ return fg;
+
+ KMALLOC(fg, frgroup_t *, sizeof(*fg));
+ if (fg) {
+ fg->fg_num = num;
+ fg->fg_next = *fgp;
+ fg->fg_head = fp;
+ fg->fg_start = &fp->fr_grp;
+ *fgp = fg;
+ }
+ return fg;
+}
+
+
+void fr_delgroup(num, flags, which, set)
+u_short num;
+u_32_t flags;
+int which, set;
+{
+ frgroup_t *fg, **fgp;
+
+ if (!(fg = fr_findgroup(num, flags, which, set, &fgp)))
+ return;
+
+ *fgp = fg->fg_next;
+ KFREE(fg);
+}
+
+
+
+/*
+ * recursively flush rules from the list, descending groups as they are
+ * encountered. if a rule is the head of a group and it has lost all its
+ * group members, then also delete the group reference.
+ */
+static int frflushlist(set, unit, nfreedp, list, listp)
+int set, unit, *nfreedp;
+frentry_t *list, **listp;
+{
+ register frentry_t *fp = list, *fpn;
+ register int freed = 0;
+
+ while (fp) {
+ fpn = fp->fr_next;
+ if (fp->fr_grp) {
+ fp->fr_ref -= frflushlist(set, unit, nfreedp,
+ fp->fr_grp, &fp->fr_grp);
+ }
+
+ if (fp->fr_ref == 1) {
+ if (fp->fr_grhead)
+ fr_delgroup(fp->fr_grhead, fp->fr_flags, unit,
+ set);
+ KFREE(fp);
+ *listp = fpn;
+ freed++;
+ }
+ fp = fpn;
+ }
+ *nfreedp += freed;
+ return freed;
+}
+
+
+void frflush(unit, data)
+int unit;
+caddr_t data;
+{
+ int flags = *(int *)data, flushed = 0, set = fr_active;
+
+ bzero((char *)frcache, sizeof(frcache[0]) * 2);
+
+ if (flags & FR_INACTIVE)
+ set = 1 - set;
+
+ if (unit == IPL_LOGIPF) {
+ if (flags & FR_OUTQUE) {
+ (void) frflushlist(set, unit, &flushed,
+ ipfilter[1][set],
+ &ipfilter[1][set]);
+ (void) frflushlist(set, unit, &flushed,
+ ipacct[1][set], &ipacct[1][set]);
+ }
+ if (flags & FR_INQUE) {
+ (void) frflushlist(set, unit, &flushed,
+ ipfilter[0][set],
+ &ipfilter[0][set]);
+ (void) frflushlist(set, unit, &flushed,
+ ipacct[0][set], &ipacct[0][set]);
+ }
+ }
+
+ *(int *)data = flushed;
+}
diff --git a/contrib/ipfilter/fils.c b/contrib/ipfilter/fils.c
index 20384e006f47..aeda2eed2857 100644
--- a/contrib/ipfilter/fils.c
+++ b/contrib/ipfilter/fils.c
@@ -1,5 +1,5 @@
/*
- * (C)opyright 1993-1996 by Darren Reed.
+ * Copyright (C) 1993-1997 by Darren Reed.
*
* Redistribution and use in source and binary forms are permitted
* provided that this notice is preserved and due credit is given
@@ -31,21 +31,22 @@
#include <arpa/nameser.h>
#include <resolv.h>
#include <netinet/tcp.h>
-#include "ip_compat.h"
-#include "ip_fil.h"
+#include "netinet/ip_compat.h"
+#include "netinet/ip_fil.h"
#include "ipf.h"
-#include "ip_proxy.h"
-#include "ip_nat.h"
-#include "ip_frag.h"
-#include "ip_state.h"
+#include "netinet/ip_proxy.h"
+#include "netinet/ip_nat.h"
+#include "netinet/ip_frag.h"
+#include "netinet/ip_state.h"
+#include "netinet/ip_auth.h"
#include "kmem.h"
-#ifdef __NetBSD__
+#if defined(__NetBSD__) || (__OpenBSD__)
#include <paths.h>
#endif
-#if !defined(lint) && defined(LIBC_SCCS)
-static char sccsid[] = "@(#)fils.c 1.21 4/20/96 (C) 1993-1996 Darren Reed";
-static char rcsid[] = "$Id: fils.c,v 2.0.2.9 1997/05/08 10:11:31 darrenr Exp $";
+#if !defined(lint)
+static const char sccsid[] = "@(#)fils.c 1.21 4/20/96 (C) 1993-1996 Darren Reed";
+static const char rcsid[] = "@(#)$Id: fils.c,v 2.0.2.25.2.1 1997/11/06 21:21:19 darrenr Exp $";
#endif
#ifdef _PATH_UNIX
#define VMUNIX _PATH_UNIX
@@ -70,13 +71,15 @@ static void showstats __P((int, friostat_t *));
static void showfrstates __P((int, ipfrstat_t *));
static void showlist __P((friostat_t *));
static void showipstates __P((int, ips_stat_t *));
+static void showauthstates __P((int, fr_authstat_t *));
static void Usage __P((char *));
+static void printlist __P((frentry_t *));
static void Usage(name)
char *name;
{
- fprintf(stderr, "Usage: %s [-afhIiosv] [-d <device>]\n", name);
+ fprintf(stderr, "Usage: %s [-aAfhIinosv] [-d <device>]\n", name);
exit(1);
}
@@ -85,11 +88,12 @@ int main(argc,argv)
int argc;
char *argv[];
{
+ fr_authstat_t frauthst;
friostat_t fio;
ips_stat_t ipsst;
ipfrstat_t ifrst;
- char c, *name = NULL, *device = IPL_NAME;
- int fd;
+ char *name = NULL, *device = IPL_NAME;
+ int c, fd;
if (openkmem() == -1)
exit(-1);
@@ -97,13 +101,16 @@ char *argv[];
(void)setuid(getuid());
(void)setgid(getgid());
- while ((c = getopt(argc, argv, "afhIinosvd:")) != -1)
+ while ((c = getopt(argc, argv, "aAfhIinosvd:")) != -1)
{
switch (c)
{
case 'a' :
opts |= OPT_ACCNT|OPT_SHOWLIST;
break;
+ case 'A' :
+ opts |= OPT_AUTHSTATS;
+ break;
case 'd' :
device = optarg;
break;
@@ -116,12 +123,12 @@ char *argv[];
case 'i' :
opts |= OPT_INQUE|OPT_SHOWLIST;
break;
- case 'n' :
- opts |= OPT_SHOWLINENO;
- break;
case 'I' :
opts |= OPT_INACTIVE;
break;
+ case 'n' :
+ opts |= OPT_SHOWLINENO;
+ break;
case 'o' :
opts |= OPT_OUTQUE|OPT_SHOWLIST;
break;
@@ -170,9 +177,16 @@ char *argv[];
if (opts & OPT_VERBOSE)
PRINTF("opts %#x name %s\n", opts, name ? name : "<>");
+
+ if ((opts & OPT_AUTHSTATS) &&
+ (ioctl(fd, SIOCATHST, &frauthst) == -1)) {
+ perror("ioctl(SIOCATHST)");
+ exit(-1);
+ }
+
if (opts & OPT_SHOWLIST) {
showlist(&fio);
- if((opts & OPT_OUTQUE) && (opts & OPT_INQUE)){
+ if ((opts & OPT_OUTQUE) && (opts & OPT_INQUE)){
opts &= ~OPT_OUTQUE;
showlist(&fio);
}
@@ -181,6 +195,8 @@ char *argv[];
showipstates(fd, &ipsst);
else if (opts & OPT_FRSTATES)
showfrstates(fd, &ifrst);
+ else if (opts & OPT_AUTHSTATS)
+ showauthstates(fd, &frauthst);
else
showstats(fd, &fio);
}
@@ -240,25 +256,68 @@ struct friostat *fp;
fp->f_st[0].fr_pull[0], fp->f_st[0].fr_pull[1]);
PRINTF("OUT Pullups succeeded:\t%lu\tfailed:\t%lu\n",
fp->f_st[1].fr_pull[0], fp->f_st[1].fr_pull[1]);
+ PRINTF("Fastroute successes:\t%lu\tfailures:\t%lu\n",
+ fp->f_froute[0], fp->f_froute[1]);
+ PRINTF("TCP cksum fails in:\t%lu\tout%lu\n",
+ fp->f_st[0].fr_tcpbad, fp->f_st[1].fr_tcpbad);
PRINTF("Packet log flags set: (%#x)\n", frf);
if (frf & FF_LOGPASS)
PRINTF("\tpackets passed through filter\n");
if (frf & FF_LOGBLOCK)
PRINTF("\tpackets blocked by filter\n");
+ if (frf & FF_LOGNOMATCH)
+ PRINTF("\tpackets not matched by filter\n");
if (!frf)
PRINTF("\tnone\n");
}
+
+static void printlist(fp)
+frentry_t *fp;
+{
+ struct frentry fb;
+ int n;
+
+ for (n = 1; fp; n++) {
+ if (kmemcpy((char *)&fb, (u_long)fp, sizeof(fb)) == -1) {
+ perror("kmemcpy");
+ return;
+ }
+ fp = &fb;
+ if (opts & OPT_OUTQUE)
+ fp->fr_flags |= FR_OUTQUE;
+ if (opts & (OPT_HITS|OPT_VERBOSE))
+#ifdef USE_QUAD_T
+ PRINTF("%qd ", fp->fr_hits);
+#else
+ PRINTF("%ld ", fp->fr_hits);
+#endif
+ if (opts & (OPT_ACCNT|OPT_VERBOSE))
+#ifdef USE_QUAD_T
+ PRINTF("%qd ", fp->fr_bytes);
+#else
+ PRINTF("%ld ", fp->fr_bytes);
+#endif
+ if (opts & OPT_SHOWLINENO)
+ PRINTF("@%d ", n);
+ printfr(fp);
+ if (opts & OPT_VERBOSE)
+ binprint(fp);
+ if (fp->fr_grp)
+ printlist(fp->fr_grp);
+ fp = fp->fr_next;
+ }
+}
+
/*
* print out filter rule list
*/
static void showlist(fiop)
struct friostat *fiop;
{
- struct frentry fb;
struct frentry *fp = NULL;
- int i, set, n;
+ int i, set;
set = fiop->f_active;
if (opts & OPT_INACTIVE)
@@ -286,40 +345,13 @@ struct friostat *fiop;
FPRINTF(stderr, "showlist:opts %#x i %d\n", opts, i);
if (opts & OPT_VERBOSE)
- PRINTF("fp %#x set %d\n", (u_int)fp, set);
+ PRINTF("fp %p set %d\n", fp, set);
if (!fp) {
FPRINTF(stderr, "empty list for %s%s\n",
(opts & OPT_INACTIVE) ? "inactive " : "", filters[i]);
return;
}
-
- for (n = 1; fp; n++) {
- if (kmemcpy((char *)&fb, (u_long)fp, sizeof(fb)) == -1) {
- perror("kmemcpy");
- return;
- }
- fp = &fb;
- if (opts & OPT_OUTQUE)
- fp->fr_flags |= FR_OUTQUE;
- if (opts & (OPT_HITS|OPT_VERBOSE))
-#ifdef USE_QUAD_T
- PRINTF("%qd ", fp->fr_hits);
-#else
- PRINTF("%ld ", fp->fr_hits);
-#endif
- if (opts & (OPT_ACCNT|OPT_VERBOSE))
-#ifdef USE_QUAD_T
- PRINTF("%qd ", fp->fr_bytes);
-#else
- PRINTF("%ld ", fp->fr_bytes);
-#endif
- if (opts & OPT_SHOWLINENO)
- PRINTF("@%d ", n);
- printfr(fp);
- if (opts & OPT_VERBOSE)
- binprint(fp);
- fp = fp->fr_next;
- }
+ printlist(fp);
}
@@ -345,12 +377,17 @@ ips_stat_t *ipsp;
sizeof(ips)) == -1)
break;
PRINTF("%s -> ", inet_ntoa(ips.is_src));
- PRINTF("%s age %ld pass %d pr %d state %d/%d\n",
+ PRINTF("%s ttl %ld pass %d pr %d state %d/%d\n",
inet_ntoa(ips.is_dst), ips.is_age,
ips.is_pass, ips.is_p, ips.is_state[0],
ips.is_state[1]);
+#ifdef USE_QUAD_T
+ PRINTF("\tpkts %qd bytes %qd",
+ ips.is_pkts, ips.is_bytes);
+#else
PRINTF("\tpkts %ld bytes %ld",
ips.is_pkts, ips.is_bytes);
+#endif
if (ips.is_p == IPPROTO_TCP)
PRINTF("\t%hu -> %hu %lu:%lu %hu:%hu\n",
ntohs(ips.is_sport),
@@ -364,6 +401,51 @@ ips_stat_t *ipsp;
PRINTF(" %hu %hu %d\n", ips.is_icmp.ics_id,
ips.is_icmp.ics_seq,
ips.is_icmp.ics_type);
+
+ /* phil@ultimate.com ... */
+ PRINTF("\t");
+ /* from "printfr()" */
+ if (ips.is_pass & FR_PASS) {
+ PRINTF("pass");
+ } else if (ips.is_pass & FR_BLOCK) {
+ PRINTF("block");
+ if (ips.is_pass & FR_RETICMP)
+ PRINTF(" return-icmp");
+ if (ips.is_pass & FR_RETRST)
+ PRINTF(" return-rst");
+ } else if ((ips.is_pass & FR_LOGMASK) == FR_LOG) {
+ PRINTF("log");
+ if (ips.is_pass & FR_LOGBODY)
+ PRINTF(" body");
+ if (ips.is_pass & FR_LOGFIRST)
+ PRINTF(" first");
+ } else if (ips.is_pass & FR_ACCOUNT)
+ PRINTF("count");
+
+ if (ips.is_pass & FR_OUTQUE)
+ PRINTF(" out");
+ else
+ PRINTF(" in");
+
+ if ((ips.is_pass & (FR_LOGB|FR_LOGP)) != 0) {
+ PRINTF(" log");
+ if (ips.is_pass & FR_LOGBODY)
+ PRINTF(" body");
+ if (ips.is_pass & FR_LOGFIRST)
+ PRINTF(" first");
+ if (ips.is_pass & FR_LOGORBLOCK)
+ PRINTF(" or-block");
+ }
+ if (ips.is_pass & FR_QUICK)
+ PRINTF(" quick");
+ if (ips.is_pass & FR_KEEPFRAG)
+ PRINTF(" keep frags");
+ /* a given; no? */
+ if (ips.is_pass & FR_KEEPSTATE)
+ PRINTF(" keep state");
+ PRINTF("\n");
+ /* ... phil@ultimate.com */
+
istab[i] = ips.is_next;
}
}
@@ -396,3 +478,22 @@ ipfrstat_t *ifsp;
ipfrtab[i] = ifr.ipfr_next;
}
}
+
+
+static void showauthstates(fd, asp)
+int fd;
+fr_authstat_t *asp;
+{
+#ifdef USE_QUAD_T
+ printf("Authorisation hits: %qd\tmisses %qd\n", asp->fas_hits,
+ asp->fas_miss);
+#else
+ printf("Authorisation hits: %ld\tmisses %ld\n", asp->fas_hits,
+ asp->fas_miss);
+#endif
+ printf("nospace %ld\nadded %ld\nsendfail %ld\nsendok %ld\n",
+ asp->fas_nospace, asp->fas_added, asp->fas_sendfail,
+ asp->fas_sendok);
+ printf("queok %ld\nquefail %ld\nexpire %ld\n",
+ asp->fas_queok, asp->fas_quefail, asp->fas_expire);
+}
diff --git a/contrib/ipfilter/inet_addr.c b/contrib/ipfilter/inet_addr.c
index 0a83f2859dff..e7ca501c1b39 100644
--- a/contrib/ipfilter/inet_addr.c
+++ b/contrib/ipfilter/inet_addr.c
@@ -53,9 +53,9 @@
* --Copyright--
*/
-#if !defined(lint) && defined(LIBC_SCCS)
-static char sccsid[] = "@(#)inet_addr.c 8.1 (Berkeley) 6/17/93";
-static char rcsid[] = "$Id: inet_addr.c,v 2.0.2.4 1997/05/08 10:11:34 darrenr Exp $";
+#if !defined(lint)
+static const char sccsid[] = "@(#)inet_addr.c 8.1 (Berkeley) 6/17/93";
+static const char rcsid[] = "@(#)$Id: inet_addr.c,v 2.0.2.6 1997/10/19 15:39:21 darrenr Exp $";
#endif /* LIBC_SCCS and not lint */
#include <sys/param.h>
@@ -180,7 +180,7 @@ inet_aton(cp, addr)
* The value returned is in network order.
*/
#if defined(SOLARIS2) && (SOLARIS2 > 5)
-u_int
+in_addr_t
#else
u_long
#endif
diff --git a/contrib/ipfilter/ip_auth.c b/contrib/ipfilter/ip_auth.c
new file mode 100644
index 000000000000..2640a77245cc
--- /dev/null
+++ b/contrib/ipfilter/ip_auth.c
@@ -0,0 +1,494 @@
+/*
+ * Copyright (C) 1997 by Darren Reed & Guido van Rooij.
+ *
+ * Redistribution and use in source and binary forms are permitted
+ * provided that this notice is preserved and due credit is given
+ * to the original author and the contributors.
+ */
+#if !defined(lint)
+static const char rcsid[] = "@(#)$Id: ip_auth.c,v 2.0.2.21.2.2 1997/11/12 10:45:51 darrenr Exp $";
+#endif
+
+#if !defined(_KERNEL) && !defined(KERNEL)
+# include <stdlib.h>
+# include <string.h>
+#endif
+#include <sys/errno.h>
+#include <sys/types.h>
+#include <sys/param.h>
+#include <sys/time.h>
+#include <sys/file.h>
+#if defined(KERNEL) && (__FreeBSD_version >= 220000)
+# include <sys/filio.h>
+# include <sys/fcntl.h>
+#else
+# include <sys/ioctl.h>
+#endif
+#include <sys/uio.h>
+#ifndef linux
+# include <sys/protosw.h>
+#endif
+#include <sys/socket.h>
+#if defined(_KERNEL) && !defined(linux)
+# include <sys/systm.h>
+#endif
+#if !defined(__SVR4) && !defined(__svr4__)
+# ifndef linux
+# include <sys/mbuf.h>
+# endif
+#else
+# include <sys/filio.h>
+# include <sys/byteorder.h>
+# include <sys/dditypes.h>
+# include <sys/stream.h>
+# include <sys/kmem.h>
+#endif
+#if defined(__NetBSD__) || defined(__OpenBSD__) || defined(bsdi)
+# include <machine/cpu.h>
+#endif
+#include <net/if.h>
+#ifdef sun
+#include <net/af.h>
+#endif
+#include <net/route.h>
+#include <netinet/in.h>
+#include <netinet/in_systm.h>
+#include <netinet/ip.h>
+#ifndef KERNEL
+#define KERNEL
+#define NOT_KERNEL
+#endif
+#ifndef linux
+# include <netinet/ip_var.h>
+#endif
+#ifdef NOT_KERNEL
+#undef KERNEL
+#endif
+#ifdef __sgi
+# ifdef IFF_DRVRLOCK /* IRIX6 */
+#include <sys/hashing.h>
+# endif
+#endif
+#include <netinet/tcp.h>
+#if defined(__sgi) && !defined(IFF_DRVRLOCK) /* IRIX < 6 */
+extern struct ifqueue ipintrq; /* ip packet input queue */
+#else
+# ifndef linux
+# include <netinet/in_var.h>
+# include <netinet/tcp_fsm.h>
+# endif
+#endif
+#include <netinet/udp.h>
+#include <netinet/ip_icmp.h>
+#include "netinet/ip_compat.h"
+#include <netinet/tcpip.h>
+#include "netinet/ip_fil.h"
+#include "netinet/ip_auth.h"
+#if !SOLARIS && !defined(linux)
+# include <net/netisr.h>
+#endif
+
+
+#if (SOLARIS || defined(__sgi)) && defined(_KERNEL)
+extern kmutex_t ipf_auth;
+# if SOLARIS
+extern kcondvar_t ipfauthwait;
+# endif
+#endif
+#ifdef linux
+static struct wait_queue *ipfauthwait = NULL;
+#endif
+
+int fr_authsize = FR_NUMAUTH;
+int fr_authused = 0;
+int fr_defaultauthage = 600;
+fr_authstat_t fr_authstats;
+frauth_t fr_auth[FR_NUMAUTH];
+mb_t *fr_authpkts[FR_NUMAUTH];
+int fr_authstart = 0, fr_authend = 0, fr_authnext = 0;
+frauthent_t *fae_list = NULL;
+frentry_t *ipauth = NULL;
+
+
+/*
+ * Check if a packet has authorization. If the packet is found to match an
+ * authorization result and that would result in a feedback loop (i.e. it
+ * will end up returning FR_AUTH) then return FR_BLOCK instead.
+ */
+int fr_checkauth(ip, fin)
+ip_t *ip;
+fr_info_t *fin;
+{
+ u_short id = ip->ip_id;
+ u_32_t pass;
+ int i;
+
+ MUTEX_ENTER(&ipf_auth);
+ for (i = fr_authstart; i != fr_authend; ) {
+ /*
+ * index becomes -2 only after an SIOCAUTHW. Check this in
+ * case the same packet gets sent again and it hasn't yet been
+ * auth'd.
+ */
+ if ((fr_auth[i].fra_index == -2) &&
+ (id == fr_auth[i].fra_info.fin_id) &&
+ !bcmp((char *)fin,(char *)&fr_auth[i].fra_info,FI_CSIZE)) {
+ /*
+ * Avoid feedback loop.
+ */
+ if (!(pass = fr_auth[i].fra_pass) || (pass & FR_AUTH))
+ pass = FR_BLOCK;
+ fr_authstats.fas_hits++;
+ fr_auth[i].fra_index = -1;
+ fr_authused--;
+ if (i == fr_authstart) {
+ while (fr_auth[i].fra_index == -1) {
+ i++;
+ if (i == FR_NUMAUTH)
+ i = 0;
+ fr_authstart = i;
+ if (i == fr_authend)
+ break;
+ }
+ if (fr_authstart == fr_authend) {
+ fr_authnext = 0;
+ fr_authstart = fr_authend = 0;
+ }
+ }
+ MUTEX_EXIT(&ipf_auth);
+ return pass;
+ }
+ i++;
+ if (i == FR_NUMAUTH)
+ i = 0;
+ }
+ fr_authstats.fas_miss++;
+ MUTEX_EXIT(&ipf_auth);
+ return 0;
+}
+
+
+/*
+ * Check if we have room in the auth array to hold details for another packet.
+ * If we do, store it and wake up any user programs which are waiting to
+ * hear about these events.
+ */
+int fr_newauth(m, fin, ip
+#if defined(_KERNEL) && SOLARIS
+, qif)
+qif_t *qif;
+#else
+)
+#endif
+mb_t *m;
+fr_info_t *fin;
+ip_t *ip;
+{
+ int i;
+
+ MUTEX_ENTER(&ipf_auth);
+ if ((fr_authstart > fr_authend) && (fr_authstart - fr_authend == -1)) {
+ fr_authstats.fas_nospace++;
+ MUTEX_EXIT(&ipf_auth);
+ return 0;
+ }
+ if (fr_authend - fr_authstart == FR_NUMAUTH - 1) {
+ fr_authstats.fas_nospace++;
+ MUTEX_EXIT(&ipf_auth);
+ return 0;
+ }
+
+ fr_authstats.fas_added++;
+ fr_authused++;
+ i = fr_authend++;
+ if (fr_authend == FR_NUMAUTH)
+ fr_authend = 0;
+ MUTEX_EXIT(&ipf_auth);
+ fr_auth[i].fra_index = i;
+ fr_auth[i].fra_pass = 0;
+ fr_auth[i].fra_age = fr_defaultauthage;
+ bcopy((char *)fin, (char *)&fr_auth[i].fra_info, sizeof(*fin));
+#if !defined(sparc) && !defined(m68k)
+ /*
+ * No need to copyback here as we want to undo the changes, not keep
+ * them.
+ */
+# if SOLARIS && defined(_KERNEL)
+ if (ip == (ip_t *)m->b_rptr)
+# endif
+ {
+ register u_short bo;
+
+ bo = ip->ip_len;
+ ip->ip_len = htons(bo);
+# if !SOLARIS /* 4.4BSD converts this ip_input.c, but I don't in solaris.c */
+ bo = ip->ip_id;
+ ip->ip_id = htons(bo);
+# endif
+ bo = ip->ip_off;
+ ip->ip_off = htons(bo);
+ }
+#endif
+#if SOLARIS && defined(_KERNEL)
+ m->b_rptr -= qif->qf_off;
+ fr_authpkts[i] = *(mblk_t **)fin->fin_mp;
+ fr_auth[i].fra_q = qif->qf_q;
+ cv_signal(&ipfauthwait);
+#else
+ fr_authpkts[i] = m;
+# if defined(linux) && defined(_KERNEL)
+ wake_up_interruptible(&ipfauthwait);
+# else
+ WAKEUP(&fr_authnext);
+# endif
+#endif
+ return 1;
+}
+
+
+int fr_auth_ioctl(data, cmd, fr, frptr)
+caddr_t data;
+#if defined(__NetBSD__) || defined(__OpenBSD__)
+u_long cmd;
+#else
+int cmd;
+#endif
+frentry_t *fr, **frptr;
+{
+ mb_t *m;
+#if defined(_KERNEL)
+# if !SOLARIS
+ struct ifqueue *ifq;
+ int s;
+# endif
+#endif
+ frauth_t auth, *au = &auth;
+ frauthent_t *fae, **faep;
+ int i, error = 0;
+
+ switch (cmd)
+ {
+ case SIOCINIFR :
+ case SIOCRMIFR :
+ case SIOCADIFR :
+ error = EINVAL;
+ break;
+ case SIOCINAFR :
+ case SIOCRMAFR :
+ case SIOCADAFR :
+ for (faep = &fae_list; (fae = *faep); )
+ if (&fae->fae_fr == fr)
+ break;
+ else
+ faep = &fae->fae_next;
+ if (cmd == SIOCRMAFR) {
+ if (!fae)
+ error = ESRCH;
+ else {
+ *faep = fae->fae_next;
+ *frptr = fr->fr_next;
+ KFREE(fae);
+ }
+ } else {
+ KMALLOC(fae, frauthent_t *, sizeof(*fae));
+ if (fae != NULL) {
+ IRCOPY((char *)data, (char *)&fae->fae_fr,
+ sizeof(fae->fae_fr));
+ if (!fae->fae_age)
+ fae->fae_age = fr_defaultauthage;
+ fae->fae_fr.fr_hits = 0;
+ fae->fae_fr.fr_next = *frptr;
+ *frptr = &fae->fae_fr;
+ fae->fae_next = *faep;
+ *faep = fae;
+ } else
+ error = ENOMEM;
+ }
+ break;
+ case SIOCATHST:
+ IWCOPY((char *)&fr_authstats, data, sizeof(fr_authstats));
+ break;
+ case SIOCAUTHW:
+fr_authioctlloop:
+ MUTEX_ENTER(&ipf_auth);
+ if ((fr_authnext != fr_authend) && fr_authpkts[fr_authnext]) {
+ IWCOPY((char *)&fr_auth[fr_authnext++], data,
+ sizeof(fr_info_t));
+ if (fr_authnext == FR_NUMAUTH)
+ fr_authnext = 0;
+ MUTEX_EXIT(&ipf_auth);
+ return 0;
+ }
+#ifdef _KERNEL
+# if SOLARIS
+ if (!cv_wait_sig(&ipfauthwait, &ipf_auth)) {
+ mutex_exit(&ipf_auth);
+ return EINTR;
+ }
+# else
+# ifdef linux
+ interruptible_sleep_on(&ipfauthwait);
+ if (current->signal & ~current->blocked)
+ error = -EINTR;
+# else
+ error = SLEEP(&fr_authnext, "fr_authnext");
+# endif
+# endif
+#endif
+ MUTEX_EXIT(&ipf_auth);
+ if (!error)
+ goto fr_authioctlloop;
+ break;
+ case SIOCAUTHR:
+ IRCOPY(data, (caddr_t)&auth, sizeof(auth));
+ MUTEX_ENTER(&ipf_auth);
+ i = au->fra_index;
+ if ((i < 0) || (i > FR_NUMAUTH) ||
+ (fr_auth[i].fra_info.fin_id != au->fra_info.fin_id)) {
+ MUTEX_EXIT(&ipf_auth);
+ return EINVAL;
+ }
+ m = fr_authpkts[i];
+ fr_auth[i].fra_index = -2;
+ fr_auth[i].fra_pass = au->fra_pass;
+ fr_authpkts[i] = NULL;
+#ifdef _KERNEL
+ MUTEX_EXIT(&ipf_auth);
+ SPL_NET(s);
+# ifndef linux
+ if (m && au->fra_info.fin_out) {
+# if SOLARIS
+ error = fr_qout(fr_auth[i].fra_q, m);
+# else /* SOLARIS */
+ error = ip_output(m, NULL, NULL, IP_FORWARDING, NULL);
+# endif /* SOLARIS */
+ if (error)
+ fr_authstats.fas_sendfail++;
+ else
+ fr_authstats.fas_sendok++;
+ } else if (m) {
+# if SOLARIS
+ error = fr_qin(fr_auth[i].fra_q, m);
+# else /* SOLARIS */
+ ifq = &ipintrq;
+ if (IF_QFULL(ifq)) {
+ IF_DROP(ifq);
+ m_freem(m);
+ error = ENOBUFS;
+ } else {
+ IF_ENQUEUE(ifq, m);
+ schednetisr(NETISR_IP);
+ }
+# endif /* SOLARIS */
+ if (error)
+ fr_authstats.fas_quefail++;
+ else
+ fr_authstats.fas_queok++;
+ } else
+ error = EINVAL;
+# endif
+# if SOLARIS
+ if (error)
+ error = EINVAL;
+# else
+ /*
+ * If we experience an error which will result in the packet
+ * not being processed, make sure we advance to the next one.
+ */
+ if (error == ENOBUFS) {
+ fr_authused--;
+ fr_auth[i].fra_index = -1;
+ fr_auth[i].fra_pass = 0;
+ if (i == fr_authstart) {
+ while (fr_auth[i].fra_index == -1) {
+ i++;
+ if (i == FR_NUMAUTH)
+ i = 0;
+ fr_authstart = i;
+ if (i == fr_authend)
+ break;
+ }
+ if (fr_authstart == fr_authend) {
+ fr_authnext = 0;
+ fr_authstart = fr_authend = 0;
+ }
+ }
+ }
+# endif
+ SPL_X(s);
+#endif /* _KERNEL */
+ break;
+ default :
+ error = EINVAL;
+ break;
+ }
+ return error;
+}
+
+
+#ifdef _KERNEL
+/*
+ * Free all network buffer memory used to keep saved packets.
+ */
+void fr_authunload()
+{
+ register int i;
+ register frauthent_t *fae, **faep;
+ mb_t *m;
+
+ MUTEX_ENTER(&ipf_auth);
+ for (i = 0; i < FR_NUMAUTH; i++) {
+ if ((m = fr_authpkts[i])) {
+ FREE_MB_T(m);
+ fr_authpkts[i] = NULL;
+ fr_auth[i].fra_index = -1;
+ }
+ }
+
+
+ for (faep = &fae_list; (fae = *faep); ) {
+ *faep = fae->fae_next;
+ KFREE(fae);
+ }
+ MUTEX_EXIT(&ipf_auth);
+}
+
+
+/*
+ * Slowly expire held auth records. Timeouts are set
+ * in expectation of this being called twice per second.
+ */
+void fr_authexpire()
+{
+ register int i;
+ register frauth_t *fra;
+ register frauthent_t *fae, **faep;
+ mb_t *m;
+#if !SOLARIS
+ int s;
+#endif
+
+ SPL_NET(s);
+ MUTEX_ENTER(&ipf_auth);
+ for (i = 0, fra = fr_auth; i < FR_NUMAUTH; i++, fra++) {
+ if ((!--fra->fra_age) && (m = fr_authpkts[i])) {
+ FREE_MB_T(m);
+ fr_authpkts[i] = NULL;
+ fr_auth[i].fra_index = -1;
+ fr_authstats.fas_expire++;
+ fr_authused--;
+ }
+ }
+
+ for (faep = &fae_list; (fae = *faep); ) {
+ if (!--fra->fra_age) {
+ *faep = fae->fae_next;
+ KFREE(fae);
+ fr_authstats.fas_expire++;
+ } else
+ faep = &fae->fae_next;
+ }
+ MUTEX_EXIT(&ipf_auth);
+ SPL_X(s);
+}
+#endif
diff --git a/contrib/ipfilter/ip_auth.h b/contrib/ipfilter/ip_auth.h
new file mode 100644
index 000000000000..06f7cf6f00ec
--- /dev/null
+++ b/contrib/ipfilter/ip_auth.h
@@ -0,0 +1,66 @@
+/*
+ * Copyright (C) 1997 by Darren Reed & Guido Van Rooij.
+ *
+ * Redistribution and use in source and binary forms are permitted
+ * provided that this notice is preserved and due credit is given
+ * to the original author and the contributors.
+ *
+ * $Id: ip_auth.h,v 2.0.2.10 1997/10/29 12:14:07 darrenr Exp $
+ *
+ */
+#ifndef __IP_AUTH_H__
+#define __IP_AUTH_H__
+
+#define FR_NUMAUTH 32
+
+typedef struct fr_authstat {
+ U_QUAD_T fas_hits;
+ U_QUAD_T fas_miss;
+ u_long fas_nospace;
+ u_long fas_added;
+ u_long fas_sendfail;
+ u_long fas_sendok;
+ u_long fas_queok;
+ u_long fas_quefail;
+ u_long fas_expire;
+} fr_authstat_t;
+
+typedef struct frauth {
+ int fra_age;
+ int fra_index;
+ u_32_t fra_pass;
+ fr_info_t fra_info;
+#if SOLARIS
+ queue_t *fra_q;
+#endif
+} frauth_t;
+
+typedef struct frauthent {
+ struct frentry fae_fr;
+ struct frauthent *fae_next;
+ u_long fae_age;
+} frauthent_t;
+
+
+extern frentry_t *ipauth;
+extern struct fr_authstat fr_authstats;
+extern int fr_defaultauthage;
+extern int fr_authstart;
+extern int fr_authend;
+extern int fr_authsize;
+extern int fr_authused;
+extern int fr_checkauth __P((ip_t *, fr_info_t *));
+extern void fr_authexpire __P((void));
+extern void fr_authunload __P((void));
+extern mb_t *fr_authpkts[];
+#if defined(_KERNEL) && SOLARIS
+extern int fr_newauth __P((mb_t *, fr_info_t *, ip_t *, qif_t *));
+#else
+extern int fr_newauth __P((mb_t *, fr_info_t *, ip_t *));
+#endif
+#if defined(__NetBSD__) || defined(__OpenBSD__)
+extern int fr_auth_ioctl __P((caddr_t, u_long, frentry_t *, frentry_t **));
+#else
+extern int fr_auth_ioctl __P((caddr_t, int, frentry_t *, frentry_t **));
+#endif
+#endif /* __IP_AUTH_H__ */
diff --git a/contrib/ipfilter/ip_compat.h b/contrib/ipfilter/ip_compat.h
index cbb3239b2b8d..3866ef083540 100644
--- a/contrib/ipfilter/ip_compat.h
+++ b/contrib/ipfilter/ip_compat.h
@@ -1,12 +1,12 @@
/*
- * (C)opyright 1993-1997 by Darren Reed.
+ * Copyright (C) 1993-1997 by Darren Reed.
*
* Redistribution and use in source and binary forms are permitted
* provided that this notice is preserved and due credit is given
* to the original author and the contributors.
*
* @(#)ip_compat.h 1.8 1/14/96
- * $Id: ip_compat.h,v 2.0.2.11 1997/05/04 05:29:02 darrenr Exp $
+ * $Id: ip_compat.h,v 2.0.2.31.2.4 1997/11/12 10:48:43 darrenr Exp $
*/
#ifndef __IP_COMPAT_H__
@@ -17,6 +17,7 @@
# define __P(x) x
# else
# define __P(x) ()
+# define const
# endif
#endif
@@ -25,25 +26,51 @@
#endif
#if defined(_KERNEL) && !defined(KERNEL)
-#define KERNEL
+# define KERNEL
#endif
#if defined(KERNEL) && !defined(_KERNEL)
-#define _KERNEL
+# define _KERNEL
+#endif
+#if!defined(__KERNEL__) && defined(KERNEL)
+# define __KERNEL__
#endif
-#if defined(__SVR4) || defined(__svr4__)
+#if defined(__SVR4) || defined(__svr4__) || defined(__sgi)
#define index strchr
-# ifndef _KERNEL
+# if !defined(_KERNEL)
# define bzero(a,b) memset(a,0,b)
# define bcmp memcmp
# define bcopy(a,b,c) memmove(b,a,c)
# endif
#endif
+#if defined(__sgi) || defined(bsdi)
+struct ether_addr {
+ u_char ether_addr_octet[6];
+};
+#endif
+
+#ifdef __sgi
+# ifdef IPFILTER_LKM
+# define IPL_PRFX ipl
+# define IPL_EXTERN(ep) ipl##ep
+# else
+# define IPL_PRFX ipfilter
+# define IPL_EXTERN(ep) ipfilter##ep
+# endif
+#else
+# define IPL_PRFX ipl
+# define IPL_EXTERN(ep) ipl##ep
+#endif
+
+#ifdef linux
+# include <sys/sysmacros.h>
+#endif
#if SOLARIS
# define MTYPE(m) ((m)->b_datap->db_type)
# include <sys/ioccom.h>
# include <sys/sysmacros.h>
+# include <sys/kmem.h>
/*
* because Solaris 2 defines these in two places :-/
*/
@@ -59,12 +86,12 @@
# include <inet/ip.h>
# include <inet/ip_ire.h>
# undef _KERNEL
-# else
+# else /* _KERNEL */
# include <inet/common.h>
# include <inet/ip.h>
# include <inet/ip_ire.h>
-# endif
-#endif
+# endif /* _KERNEL */
+#endif /* SOLARIS */
#define IPMINLEN(i, h) ((i)->ip_len >= ((i)->ip_hl * 4 + sizeof(struct h)))
#ifndef IP_OFFMASK
@@ -75,10 +102,26 @@
# define USE_QUAD_T
# define U_QUAD_T u_quad_t
# define QUAD_T quad_t
-#else
+#else /* BSD > 199306 */
# define U_QUAD_T u_long
# define QUAD_T long
-#endif
+#endif /* BSD > 199306 */
+
+/*
+ * These operating systems already take care of the problem for us.
+ */
+#if defined(__NetBSD__) || defined(__OpenBSD__) || defined(__FreeBSD__)
+typedef u_int32_t u_32_t;
+#else
+/*
+ * Really, any arch where sizeof(long) != sizeof(int).
+ */
+# if defined(__alpha__) || defined(__alpha)
+typedef unsigned int u_32_t;
+# else
+typedef unsigned long u_32_t;
+# endif
+#endif /* __NetBSD__ || __OpenBSD__ || __FreeBSD__ */
#ifndef MAX
#define MAX(a,b) (((a) > (b)) ? (a) : (b))
@@ -141,105 +184,131 @@
#define IPOPT_FINN 205 /* FINN */
-#ifdef __FreeBSD__
-# include <machine/spl.h>
+#if defined(__FreeBSD__) && defined(KERNEL)
+# if __FreeBSD__ < 3
+# include <machine/spl.h>
+# endif
# if defined(IPFILTER_LKM) && !defined(ACTUALLY_LKM_NOT_KERNEL)
# define ACTUALLY_LKM_NOT_KERNEL
# endif
-#endif
+#endif /* __FreeBSD__ && KERNEL */
/*
* Build some macros and #defines to enable the same code to compile anywhere
* Well, that's the idea, anyway :-)
*/
-#if defined(_KERNEL) || defined(KERNEL)
+#ifdef KERNEL
# if SOLARIS
# define MUTEX_ENTER(x) mutex_enter(x)
# define MUTEX_EXIT(x) mutex_exit(x)
# define MTOD(m,t) (t)((m)->b_rptr)
# define IRCOPY(a,b,c) copyin((a), (b), (c))
# define IWCOPY(a,b,c) copyout((a), (b), (c))
-# else
-# define MUTEX_ENTER(x) ;
-# define MUTEX_EXIT(x) ;
+# define FREE_MB_T(m) freemsg(m)
+# define SPL_NET(x) ;
+# define SPL_IMP(x) ;
+# undef SPL_X
+# define SPL_X(x) ;
+# ifdef sparc
+# define ntohs(x) (x)
+# define ntohl(x) (x)
+# define htons(x) (x)
+# define htonl(x) (x)
+# endif /* sparc */
+# define KMALLOC(a,b,c) (a) = (b)kmem_alloc((c), KM_NOSLEEP)
+# define GET_MINOR(x) getminor(x)
+typedef struct qif {
+ struct qif *qf_next;
+ ill_t *qf_ill;
+ kmutex_t qf_lock;
+ void *qf_iptr;
+ void *qf_optr;
+ queue_t *qf_in;
+ queue_t *qf_out;
+ struct qinit *qf_wqinfo;
+ struct qinit *qf_rqinfo;
+ struct qinit qf_wqinit;
+ struct qinit qf_rqinit;
+ mblk_t *qf_m; /* These three fields are for passing data up from */
+ queue_t *qf_q; /* fr_qin and fr_qout to the packet processing. */
+ int qf_off;
+ int qf_len; /* this field is used for in ipfr_fastroute */
+ char qf_name[8];
+ /*
+ * in case the ILL has disappeared...
+ */
+ int qf_hl; /* header length */
+} qif_t;
+extern ill_t *get_unit __P((char *));
+# define GETUNIT(n) get_unit((n))
+# else /* SOLARIS */
+# if defined(__sgi)
+# include <sys/ksynch.h>
+# define IPF_LOCK_PL plhi
+# include <sys/sema.h>
+#undef kmutex_t
+typedef struct {
+ lock_t *l;
+ int pl;
+} kmutex_t;
+# define MUTEX_ENTER(x) (x)->pl = LOCK((x)->l, IPF_LOCK_PL);
+# define MUTEX_EXIT(x) UNLOCK((x)->l, (x)->pl);
+# else /* __sgi */
+# define MUTEX_ENTER(x) ;
+# define MUTEX_EXIT(x) ;
+# endif /* __sgi */
# ifndef linux
+# define FREE_MB_T(m) m_freem(m)
# define MTOD(m,t) mtod(m,t)
# define IRCOPY(a,b,c) bcopy((a), (b), (c))
# define IWCOPY(a,b,c) bcopy((a), (b), (c))
-# endif
+# endif /* !linux */
# endif /* SOLARIS */
# ifdef sun
-# if defined(__svr4__) || defined(__SVR4)
-extern ill_t *get_unit __P((char *));
-# define GETUNIT(n) get_unit((n))
-# else
+# if !SOLARIS
# include <sys/kmem_alloc.h>
# define GETUNIT(n) ifunit((n), IFNAMSIZ)
# endif
# else
-# define GETUNIT(n) ifunit((n))
+# ifndef linux
+# define GETUNIT(n) ifunit((n))
+# endif
# endif /* sun */
-# if defined(sun) && !defined(linux)
-# define UIOMOVE(a,b,c,d) uiomove(a,b,c,d)
+# if defined(sun) && !defined(linux) || defined(__sgi)
+# define UIOMOVE(a,b,c,d) uiomove((caddr_t)a,b,c,d)
# define SLEEP(id, n) sleep((id), PZERO+1)
+# define WAKEUP(id) wakeup(id)
# define KFREE(x) kmem_free((char *)(x), sizeof(*(x)))
# define KFREES(x,s) kmem_free((char *)(x), (s))
-# if SOLARIS
-typedef struct qif {
- struct qif *qf_next;
- ill_t *qf_ill;
- kmutex_t qf_lock;
- void *qf_iptr;
- void *qf_optr;
- queue_t *qf_in;
- queue_t *qf_out;
- void *qf_wqinfo;
- void *qf_rqinfo;
- int (*qf_inp) __P((queue_t *, mblk_t *));
- int (*qf_outp) __P((queue_t *, mblk_t *));
- mblk_t *qf_m;
- int qf_len;
- char qf_name[8];
- /*
- * in case the ILL has disappeared...
- */
- int qf_hl; /* header length */
-} qif_t;
-# define SPLNET(x) ;
-# undef SPLX
-# define SPLX(x) ;
-# ifdef sparc
-# define ntohs(x) (x)
-# define ntohl(x) (x)
-# define htons(x) (x)
-# define htonl(x) (x)
-# endif
+# if !SOLARIS
+extern void m_copydata __P((struct mbuf *, int, int, caddr_t));
+extern void m_copyback __P((struct mbuf *, int, int, caddr_t));
+# endif
+# ifdef __sgi
+# include <sys/kmem.h>
+# include <sys/ddi.h>
# define KMALLOC(a,b,c) (a) = (b)kmem_alloc((c), KM_NOSLEEP)
# define GET_MINOR(x) getminor(x)
# else
-# define KMALLOC(a,b,c) (a) = (b)new_kmem_alloc((c), KMEM_NOSLEEP)
-# endif /* __svr4__ */
+# if !SOLARIS
+# define KMALLOC(a,b,c) (a) = (b)new_kmem_alloc((c), KMEM_NOSLEEP)
+# endif /* SOLARIS */
+# endif /* __sgi */
# endif /* sun && !linux */
# ifndef GET_MINOR
# define GET_MINOR(x) minor(x)
# endif
-# if BSD >= 199306 || defined(__FreeBSD__)
+# if (BSD >= 199306) || defined(__FreeBSD__)
# include <vm/vm.h>
# if !defined(__FreeBSD__) || (defined (__FreeBSD__) && __FreeBSD__>=3)
# include <vm/vm_extern.h>
# include <sys/proc.h>
extern vm_map_t kmem_map;
-# else
+# else /* !__FreeBSD__ || (__FreeBSD__ && __FreeBSD__>=3) */
# include <vm/vm_kern.h>
-# endif /* __FreeBSD__ */
-/*
-# define KMALLOC(a,b,c) (a) = (b)kmem_alloc(kmem_map, (c))
-# define KFREE(x) kmem_free(kmem_map, (vm_offset_t)(x), \
- sizeof(*(x)))
-# define KFREES(x,s) kmem_free(kmem_map, (vm_offset_t)(x), (s))
-*/
+# endif /* !__FreeBSD__ || (__FreeBSD__ && __FreeBSD__>=3) */
# ifdef M_PFIL
# define KMALLOC(a, b, c) MALLOC((a), b, (c), M_PFIL, M_NOWAIT)
# define KFREE(x) FREE((x), M_PFIL)
@@ -248,26 +317,32 @@ extern vm_map_t kmem_map;
# define KMALLOC(a, b, c) MALLOC((a), b, (c), M_TEMP, M_NOWAIT)
# define KFREE(x) FREE((x), M_TEMP)
# define KFREES(x,s) FREE((x), M_TEMP)
-# endif
+# endif /* M_PFIL */
# define UIOMOVE(a,b,c,d) uiomove(a,b,d)
# define SLEEP(id, n) tsleep((id), PPAUSE|PCATCH, n, 0)
+# define WAKEUP(id) wakeup(id)
# endif /* BSD */
-# if defined(NetBSD1_0) && (NetBSD1_0 > 1)
-# define SPLNET(x) x = splsoftnet()
+# if defined(NetBSD) && NetBSD <= 1991011 && NetBSD >= 199407
+# define SPL_NET(x) x = splsoftnet()
+# define SPL_X(x) (void) splx(x)
# else
-# if !SOLARIS
-# define SPLNET(x) x = splnet()
-# define SPLX(x) (void) splx(x)
+# if !SOLARIS && !defined(linux)
+# define SPL_IMP(x) x = splimp()
+# define SPL_NET(x) x = splnet()
+# define SPL_X(x) (void) splx(x)
# endif
-# endif
+# endif /* NetBSD && NetBSD <= 1991011 && NetBSD >= 199407 */
# define PANIC(x,y) if (x) panic y
-#else
+#else /* KERNEL */
+# define SLEEP(x,y) ;
+# define WAKEUP(x) ;
# define PANIC(x,y) ;
# define MUTEX_ENTER(x) ;
# define MUTEX_EXIT(x) ;
-# define SPLNET(x) ;
-# undef SPLX
-# define SPLX(x) ;
+# define SPL_NET(x) ;
+# define SPL_IMP(x) ;
+# undef SPL_X
+# define SPL_X(x) ;
# define KMALLOC(a,b,c) (a) = (b)malloc(c)
# define KFREE(x) free(x)
# define KFREES(x,s) free(x)
@@ -276,25 +351,187 @@ extern vm_map_t kmem_map;
# define IWCOPY(a,b,c) bcopy((a), (b), (c))
#endif /* KERNEL */
-#ifdef linux
+#if SOLARIS
+typedef mblk_t mb_t;
+#else
+# ifdef linux
+typedef struct sk_buff mb_t;
+# else
+typedef struct mbuf mb_t;
+# endif
+#endif /* SOLARIS */
+
+#if defined(linux) || defined(__sgi)
+/*
+ * These #ifdef's are here mainly for linux, but who knows, they may
+ * not be in other places or maybe one day linux will grow up and some
+ * of these will turn up there too.
+ */
+#ifndef ICMP_UNREACH
# define ICMP_UNREACH ICMP_DEST_UNREACH
+#endif
+#ifndef ICMP_SOURCEQUENCH
# define ICMP_SOURCEQUENCH ICMP_SOURCE_QUENCH
+#endif
+#ifndef ICMP_TIMXCEED
# define ICMP_TIMXCEED ICMP_TIME_EXCEEDED
+#endif
+#ifndef ICMP_PARAMPROB
# define ICMP_PARAMPROB ICMP_PARAMETERPROB
-
+#endif
+#ifndef ICMP_TSTAMP
+# define ICMP_TSTAMP ICMP_TIMESTAMP
+#endif
+#ifndef ICMP_TSTAMPREPLY
+# define ICMP_TSTAMPREPLY ICMP_TIMESTAMPREPLY
+#endif
+#ifndef ICMP_IREQ
+# define ICMP_IREQ ICMP_INFO_REQUEST
+#endif
+#ifndef ICMP_IREQREPLY
+# define ICMP_IREQREPLY ICMP_INFO_REPLY
+#endif
+#ifndef ICMP_MASKREQ
+# define ICMP_MASKREQ ICMP_ADDRESS
+#endif
+#ifndef ICMP_MASKREPLY
+# define ICMP_MASKREPLY ICMP_ADDRESSREPLY
+#endif
+#ifndef IPVERSION
+# define IPVERSION 4
+#endif
+#ifndef IPOPT_MINOFF
+# define IPOPT_MINOFF 4
+#endif
+#ifndef IPOPT_COPIED
+# define IPOPT_COPIED(x) ((x)&0x80)
+#endif
+#ifndef IPOPT_EOL
+# define IPOPT_EOL 0
+#endif
+#ifndef IPOPT_NOP
+# define IPOPT_NOP 1
+#endif
+#ifndef IP_MF
+# define IP_MF ((u_short)0x2000)
+#endif
+#ifndef ETHERTYPE_IP
+# define ETHERTYPE_IP ((u_short)0x0800)
+#endif
+#ifndef TH_FIN
# define TH_FIN 0x01
+#endif
+#ifndef TH_SYN
# define TH_SYN 0x02
+#endif
+#ifndef TH_RST
# define TH_RST 0x04
+#endif
+#ifndef TH_PUSH
# define TH_PUSH 0x08
+#endif
+#ifndef TH_ACK
# define TH_ACK 0x10
+#endif
+#ifndef TH_URG
# define TH_URG 0x20
+#endif
+#ifndef IPOPT_EOL
+# define IPOPT_EOL 0
+#endif
+#ifndef IPOPT_NOP
+# define IPOPT_NOP 1
+#endif
+#ifndef IPOPT_RR
+# define IPOPT_RR 7
+#endif
+#ifndef IPOPT_TS
+# define IPOPT_TS 68
+#endif
+#ifndef IPOPT_SECURITY
+# define IPOPT_SECURITY 130
+#endif
+#ifndef IPOPT_LSRR
+# define IPOPT_LSRR 131
+#endif
+#ifndef IPOPT_SATID
+# define IPOPT_SATID 136
+#endif
+#ifndef IPOPT_SSRR
+# define IPOPT_SSRR 137
+#endif
+#ifndef IPOPT_SECUR_UNCLASS
+# define IPOPT_SECUR_UNCLASS ((u_short)0x0000)
+#endif
+#ifndef IPOPT_SECUR_CONFID
+# define IPOPT_SECUR_CONFID ((u_short)0xf135)
+#endif
+#ifndef IPOPT_SECUR_EFTO
+# define IPOPT_SECUR_EFTO ((u_short)0x789a)
+#endif
+#ifndef IPOPT_SECUR_MMMM
+# define IPOPT_SECUR_MMMM ((u_short)0xbc4d)
+#endif
+#ifndef IPOPT_SECUR_RESTR
+# define IPOPT_SECUR_RESTR ((u_short)0xaf13)
+#endif
+#ifndef IPOPT_SECUR_SECRET
+# define IPOPT_SECUR_SECRET ((u_short)0xd788)
+#endif
+#ifndef IPOPT_SECUR_TOPSECRET
+# define IPOPT_SECUR_TOPSECRET ((u_short)0x6bc5)
+#endif
+#ifndef IPOPT_OLEN
+# define IPOPT_OLEN 1
+#endif
+#endif /* linux || __sgi */
+
+#ifdef linux
+/*
+ * TCP States
+ */
+#define TCPS_CLOSED 0 /* closed */
+#define TCPS_LISTEN 1 /* listening for connection */
+#define TCPS_SYN_SENT 2 /* active, have sent syn */
+#define TCPS_SYN_RECEIVED 3 /* have send and received syn */
+/* states < TCPS_ESTABLISHED are those where connections not established */
+#define TCPS_ESTABLISHED 4 /* established */
+#define TCPS_CLOSE_WAIT 5 /* rcvd fin, waiting for close */
+/* states > TCPS_CLOSE_WAIT are those where user has closed */
+#define TCPS_FIN_WAIT_1 6 /* have closed, sent fin */
+#define TCPS_CLOSING 7 /* closed xchd FIN; await FIN ACK */
+#define TCPS_LAST_ACK 8 /* had fin and close; await FIN ACK */
+/* states > TCPS_CLOSE_WAIT && < TCPS_FIN_WAIT_2 await ACK of FIN */
+#define TCPS_FIN_WAIT_2 9 /* have closed, fin is acked */
+#define TCPS_TIME_WAIT 10 /* in 2*msl quiet wait after close */
+
+/*
+ * file flags.
+ */
+#define FWRITE WRITE
+#define FREAD READ
+/*
+ * mbuf related problems.
+ */
+#define mtod(m,t) (t)((m)->data)
+#define m_len len
+#define m_next next
+
+#define IP_DF 0x8000
typedef struct {
__u16 th_sport;
__u16 th_dport;
__u32 th_seq;
__u32 th_ack;
- __u8 th_x;
+# if defined(__i386__) || defined(__MIPSEL__) || defined(__alpha__) ||\
+ defined(vax)
+ __u8 th_res:4;
+ __u8 th_off:4;
+#else
+ __u8 th_off:4;
+ __u8 th_res:4;
+#endif
__u8 th_flags;
__u16 th_win;
__u16 th_sum;
@@ -305,7 +542,7 @@ typedef struct {
__u16 uh_sport;
__u16 uh_dport;
__u16 uh_ulen;
- __u16 uh_sun;
+ __u16 uh_sum;
} udphdr_t;
typedef struct {
@@ -331,7 +568,7 @@ typedef struct {
/*
* Structure of an icmp header.
*/
-struct icmp {
+typedef struct icmp {
u_char icmp_type; /* type of message, see below */
u_char icmp_code; /* type sub code */
u_short icmp_cksum; /* ones complement cksum of struct */
@@ -368,8 +605,10 @@ struct icmp {
# define icmp_ip icmp_dun.id_ip.idi_ip
# define icmp_mask icmp_dun.id_mask
# define icmp_data icmp_dun.id_data
-};
+} icmphdr_t;
+# ifndef LINUX_IPOVLY
+# define LINUX_IPOVLY
struct ipovly {
caddr_t ih_next, ih_prev; /* for protocol sequence q's */
u_char ih_x1; /* (unused) */
@@ -378,36 +617,98 @@ struct ipovly {
struct in_addr ih_src; /* source internet address */
struct in_addr ih_dst; /* destination internet address */
};
+# endif
-# define SPLX(x) (void)
-# define SPLNET(x) (void)
+typedef struct {
+ __u8 ether_dhost[6];
+ __u8 ether_shost[6];
+ __u16 ether_type;
+} ether_header_t;
-# define bcopy(a,b,c) memmove(b,a,c)
-# define bcmp(a,b,c) memcmp(a,b,c)
+typedef struct uio {
+ int uio_resid;
+ int uio_rw;
+ caddr_t uio_buf;
+} uio_t;
-# define UNITNAME(n) dev_get((n))
-# define ifnet device
+# define UIO_READ 0
+# define UIO_WRITE 1
+# define UIOMOVE(a, b, c, d) uiomove(a,b,c,d)
-# define KMALLOC(a,b,c) (a) = (b)kmalloc((c), GFP_ATOMIC)
-# define KFREE(x) kfree_s((x), sizeof(*(x)))
-# define KFREES(x,s) kfree_s((x), (s))
-# define IRCOPY(a,b,c) { \
- error = verify_area(VERIFY_READ, \
- (b) ,sizeof((b))); \
+/*
+ * For masking struct ifnet onto struct device
+ */
+# define if_name name
+
+# ifdef KERNEL
+# define GETUNIT(x) dev_get(x)
+# define FREE_MB_T(m) kfree_skb(m, FREE_WRITE)
+# define uniqtime do_gettimeofday
+# undef INT_MAX
+# undef UINT_MAX
+# undef LONG_MAX
+# undef ULONG_MAX
+# include <linux/netdevice.h>
+# define SPL_X(x)
+# define SPL_NET(x)
+# define SPL_IMP(x)
+
+# define bcmp(a,b,c) memcmp(a,b,c)
+# define bcopy(a,b,c) memcpy(b,a,c)
+# define bzero(a,c) memset(a,0,c)
+
+# define UNITNAME(n) dev_get((n))
+
+# define KMALLOC(a,b,c) (a) = (b)kmalloc((c), GFP_ATOMIC)
+# define KFREE(x) kfree_s((x), sizeof(*(x)))
+# define KFREES(x,s) kfree_s((x), (s))
+# define IRCOPY(a,b,c) { \
+ error = verify_area(VERIFY_READ, (a) ,(c)); \
if (!error) \
memcpy_fromfs((b), (a), (c)); \
}
-# define IWCOPY(a,b,c) { \
- error = verify_area(VERIFY_WRITE, \
- (b) ,sizeof((b))); \
+# define IWCOPY(a,b,c) { \
+ error = verify_area(VERIFY_WRITE, (b), (c)); \
if (!error) \
memcpy_tofs((b), (a), (c)); \
}
+# else
+# define __KERNEL__
+# undef INT_MAX
+# undef UINT_MAX
+# undef LONG_MAX
+# undef ULONG_MAX
+# include <linux/netdevice.h>
+# undef __KERNEL__
+# endif
+# define ifnet device
#else
typedef struct tcphdr tcphdr_t;
typedef struct udphdr udphdr_t;
typedef struct icmp icmphdr_t;
typedef struct ip ip_t;
+typedef struct ether_header ether_header_t;
#endif /* linux */
+#if defined(hpux) || defined(linux)
+struct ether_addr {
+ char ether_addr_octet[6];
+};
+#endif
+
+/*
+ * XXX - This is one of those *awful* hacks which nobody likes
+ */
+#ifdef ultrix
+#define A_A
+#else
+#define A_A &
+#endif
+
+#ifndef ICMP_ROUTERADVERT
+# define ICMP_ROUTERADVERT 9
+#endif
+#ifndef ICMP_ROUTERSOLICIT
+# define ICMP_ROUTERSOLICIT 10
+#endif
#endif /* __IP_COMPAT_H__ */
diff --git a/contrib/ipfilter/ip_fil.c b/contrib/ipfilter/ip_fil.c
index b79c030bb822..c3c758e74396 100644
--- a/contrib/ipfilter/ip_fil.c
+++ b/contrib/ipfilter/ip_fil.c
@@ -1,23 +1,23 @@
/*
- * (C)opyright 1993-1997 by Darren Reed.
+ * Copyright (C) 1993-1997 by Darren Reed.
*
* Redistribution and use in source and binary forms are permitted
* provided that this notice is preserved and due credit is given
* to the original author and the contributors.
*/
-#if !defined(lint) && defined(LIBC_SCCS)
-static char sccsid[] = "@(#)ip_fil.c 2.41 6/5/96 (C) 1993-1995 Darren Reed";
-static char rcsid[] = "$Id: ip_fil.c,v 2.0.2.12 1997/05/24 07:39:56 darrenr Exp $";
+#if !defined(lint)
+static const char sccsid[] = "@(#)ip_fil.c 2.41 6/5/96 (C) 1993-1995 Darren Reed";
+static const char rcsid[] = "@(#)$Id: ip_fil.c,v 2.0.2.44.2.2 1997/11/12 10:49:25 darrenr Exp $";
#endif
#ifndef SOLARIS
#define SOLARIS (defined(sun) && (defined(__svr4__) || defined(__SVR4)))
#endif
+#if defined(KERNEL) && !defined(_KERNEL)
+# define _KERNEL
+#endif
#ifdef __FreeBSD__
-# if defined(KERNEL) && !defined(_KERNEL)
-# define _KERNEL
-# endif
# if defined(_KERNEL) && !defined(IPFILTER_LKM)
# include <sys/osreldate.h>
# else
@@ -25,8 +25,10 @@ static char rcsid[] = "$Id: ip_fil.c,v 2.0.2.12 1997/05/24 07:39:56 darrenr Exp
# endif
#endif
#ifndef _KERNEL
-#include <stdio.h>
-#include <string.h>
+# include <stdio.h>
+# include <string.h>
+# include <stdlib.h>
+# include <ctype.h>
#endif
#include <sys/errno.h>
#include <sys/types.h>
@@ -40,28 +42,40 @@ static char rcsid[] = "$Id: ip_fil.c,v 2.0.2.12 1997/05/24 07:39:56 darrenr Exp
#endif
#include <sys/time.h>
#ifdef _KERNEL
-#include <sys/systm.h>
+# include <sys/systm.h>
#endif
#include <sys/uio.h>
#if !SOLARIS
-#include <sys/dir.h>
-#include <sys/mbuf.h>
+# if (NetBSD > 199609) || (OpenBSD > 199603)
+# include <sys/dirent.h>
+# else
+# include <sys/dir.h>
+# endif
+# include <sys/mbuf.h>
#else
-#include <sys/filio.h>
+# include <sys/filio.h>
#endif
#include <sys/protosw.h>
#include <sys/socket.h>
#include <net/if.h>
#ifdef sun
-#include <net/af.h>
+# include <net/af.h>
#endif
#if __FreeBSD_version >= 300000
# include <net/if_var.h>
#endif
+#ifdef __sgi
+#include <sys/debug.h>
+# ifdef IFF_DRVRLOCK /* IRIX6 */
+#include <sys/hashing.h>
+# endif
+#endif
#include <net/route.h>
#include <netinet/in.h>
+#if !(defined(__sgi) && !defined(IFF_DRVRLOCK)) /* IRIX < 6 */
#include <netinet/in_var.h>
+#endif
#include <netinet/in_systm.h>
#include <netinet/ip.h>
#include <netinet/ip_var.h>
@@ -78,6 +92,7 @@ static char rcsid[] = "$Id: ip_fil.c,v 2.0.2.12 1997/05/24 07:39:56 darrenr Exp
#include "netinet/ip_nat.h"
#include "netinet/ip_frag.h"
#include "netinet/ip_state.h"
+#include "netinet/ip_auth.h"
#ifndef MIN
#define MIN(a,b) (((a)<(b))?(a):(b))
#endif
@@ -87,45 +102,52 @@ extern int ip_optcopy __P((struct ip *, struct ip *));
extern struct protosw inetsw[];
-#if BSD < 199306
-static int (*fr_saveslowtimo) __P((void));
-extern int tcp_ttl;
+
+#ifndef _KERNEL
+# include "ipt.h"
+static struct ifnet **ifneta = NULL;
+static int nifs = 0;
#else
+# if (BSD < 199306) && !defined(__sgi)
+static int (*fr_saveslowtimo) __P((void));
+# else
static void (*fr_saveslowtimo) __P((void));
+# endif
+# if (BSD < 199306) || defined(__sgi)
+extern int tcp_ttl;
+# endif
#endif
int ipl_inited = 0;
int ipl_unreach = ICMP_UNREACH_FILTER;
+u_long ipl_frouteok[2] = {0, 0};
-#ifndef _KERNEL
-#include "ipt.h"
-static struct ifnet **ifneta = NULL;
-static int nifs = 0;
-struct ifnet *get_unit __P((char *));
-#endif
-
-#ifdef IPFILTER_LOG
-char iplbuf[3][IPLLOGSIZE];
-caddr_t iplh[3], iplt[3];
-int iplused[3] = {0,0,0};
-#endif /* IPFILTER_LOG */
-static void frflush __P((caddr_t));
-static int frrequest __P((int, caddr_t, int));
+static void fixskip __P((frentry_t **, frentry_t *, int));
static void frzerostats __P((caddr_t));
+static void frsync __P((void));
+#if defined(__NetBSD__) || defined(__OpenBSD__)
+static int frrequest __P((int, u_long, caddr_t, int));
+#else
+static int frrequest __P((int, int, caddr_t, int));
+#endif
#ifdef _KERNEL
-static int (*fr_savep) __P((struct ip *, int, struct ifnet *,
- int, struct mbuf **));
+static int (*fr_savep) __P((ip_t *, int, void *, int, struct mbuf **));
#else
+int ipllog __P((void));
void init_ifp __P((void));
-static int (*fr_savep) __P((struct ip *, int, struct ifnet *,
- int, char *));
+# ifdef __sgi
+static int no_output __P((struct ifnet *, struct mbuf *,
+ struct sockaddr *));
+static int write_output __P((struct ifnet *, struct mbuf *,
+ struct sockaddr *));
+# else
static int no_output __P((struct ifnet *, struct mbuf *,
struct sockaddr *, struct rtentry *));
-static int write_output __P((struct ifnet *, struct mbuf *,
- struct sockaddr *, struct rtentry *));
+static int write_output __P((struct ifnet *, struct mbuf *,
+ struct sockaddr *, struct rtentry *));
+# endif
#endif
-
#if (_BSDI_VERSION >= 199510) && defined(_KERNEL)
# include <sys/device.h>
# include <sys/conf.h>
@@ -142,9 +164,19 @@ struct devsw iplsw = {
};
#endif /* _BSDI_VERSION >= 199510 && _KERNEL */
+#if defined(__NetBSD__) || defined(__OpenBSD__)
+# include <sys/conf.h>
+# if defined(NETBSD_PF)
+# include <net/pfil.h>
+/*
+ * We provide the fr_checkp name just to minimize changes later.
+ */
+int (*fr_checkp) __P((ip_t *ip, int hlen, void *ifp, int out, mb_t **mp));
+# endif /* NETBSD_PF */
+#endif /* __NetBSD__ */
#ifdef _KERNEL
-# ifdef IPFILTER_LKM
+# if defined(IPFILTER_LKM) && !defined(__sgi)
int iplidentify(s)
char *s;
{
@@ -155,34 +187,58 @@ char *s;
# endif /* IPFILTER_LKM */
+/*
+ * Try to detect the case when compiling for NetBSD with pseudo-device
+ */
+# if defined(__NetBSD__) && defined(PFIL_HOOKS)
+void
+ipfilterattach(count)
+int count;
+{
+ iplattach();
+}
+# endif
+
+
int iplattach()
{
char *defpass;
- int s, i;
+ int s;
+# ifdef __sgi
+ int error;
+# endif
- SPLNET(s);
+ SPL_NET(s);
if (ipl_inited || (fr_checkp == fr_check)) {
printf("IP Filter: already initialized\n");
- SPLX(s);
+ SPL_X(s);
return EBUSY;
}
+
+# ifdef NETBSD_PF
+ pfil_add_hook((void *)fr_check, PFIL_IN|PFIL_OUT);
+# endif
+
+# ifdef __sgi
+ error = ipfilter_sgi_attach();
+ if (error) {
+ SPL_X(s);
+ return error;
+ }
+# endif
+
ipl_inited = 1;
- bzero((char *)nat_table, sizeof(nat_t *) * NAT_SIZE * 2);
+ bzero((char *)frcache, sizeof(frcache));
+ bzero((char *)nat_table, sizeof(nat_table));
fr_savep = fr_checkp;
fr_checkp = fr_check;
fr_saveslowtimo = inetsw[0].pr_slowtimo;
inetsw[0].pr_slowtimo = ipfr_slowtimer;
- /*
- * Set log buffer pointers for each of the log buffers
- */
-#ifdef IPFILTER_LOG
- for (i = 0; i <= 2; i++) {
- iplh[i] = iplbuf[i];
- iplt[i] = iplbuf[i];
- }
-#endif
- SPLX(s);
+# ifdef IPFILTER_LOG
+ ipflog_init();
+# endif
+ SPL_X(s);
if (fr_pass & FR_PASS)
defpass = "pass";
else if (fr_pass & FR_BLOCK)
@@ -190,35 +246,52 @@ int iplattach()
else
defpass = "no-match -> block";
- printf("IP Filter: initialized. Default = %s all\n", defpass);
+ printf("IP Filter: initialized. Default = %s all, Logging = %s\n",
+ defpass,
+# ifdef IPFILTER_LOG
+ "enabled");
+# else
+ "disabled");
+# endif
return 0;
}
+/*
+ * Disable the filter by removing the hooks from the IP input/output
+ * stream.
+ */
int ipldetach()
{
int s, i = FR_INQUE|FR_OUTQUE;
- SPLNET(s);
+ SPL_NET(s);
if (!ipl_inited)
{
printf("IP Filter: not initialized\n");
- SPLX(s);
- return EBUSY;
+ SPL_X(s);
+ return 0;
}
-#if defined(IPFILTER_LKM) || defined(IPFILTER)
fr_checkp = fr_savep;
-#endif
inetsw[0].pr_slowtimo = fr_saveslowtimo;
- frflush((caddr_t)&i);
+ frflush(IPL_LOGIPF, (caddr_t)&i);
ipl_inited = 0;
+# ifdef NETBSD_PF
+ pfil_remove_hook((void *)fr_check, PFIL_IN|PFIL_OUT);
+# endif
+
+# ifdef __sgi
+ ipfilter_sgi_detach();
+# endif
+
ipfr_unload();
ip_natunload();
fr_stateunload();
+ fr_authunload();
- SPLX(s);
+ SPL_X(s);
return 0;
}
#endif /* _KERNEL */
@@ -240,53 +313,24 @@ caddr_t data;
fio.f_acctout[0] = ipacct[1][0];
fio.f_acctout[1] = ipacct[1][1];
fio.f_active = fr_active;
+ fio.f_froute[0] = ipl_frouteok[0];
+ fio.f_froute[1] = ipl_frouteok[1];
IWCOPY((caddr_t)&fio, data, sizeof(fio));
bzero((char *)frstats, sizeof(*frstats) * 2);
}
-static void frflush(data)
-caddr_t data;
-{
- struct frentry *f, **fp;
- int flags = *(int *)data, flushed = 0, set = fr_active;
-
- bzero((char *)frcache, sizeof(frcache[0]) * 2);
-
- if (flags & FR_INACTIVE)
- set = 1 - set;
- if (flags & FR_OUTQUE) {
- for (fp = &ipfilter[1][set]; (f = *fp); ) {
- *fp = f->fr_next;
- KFREE(f);
- flushed++;
- }
- for (fp = &ipacct[1][set]; (f = *fp); ) {
- *fp = f->fr_next;
- KFREE(f);
- flushed++;
- }
- }
- if (flags & FR_INQUE) {
- for (fp = &ipfilter[0][set]; (f = *fp); ) {
- *fp = f->fr_next;
- KFREE(f);
- flushed++;
- }
- for (fp = &ipacct[0][set]; (f = *fp); ) {
- *fp = f->fr_next;
- KFREE(f);
- flushed++;
- }
- }
- *(int *)data = flushed;
-}
-
-
/*
* Filter ioctl interface.
*/
-int iplioctl(dev, cmd, data, mode
+#ifdef __sgi
+int IPL_EXTERN(ioctl)(dev_t dev, int cmd, caddr_t data, int mode
+# ifdef _KERNEL
+ , cred_t *cp, int *rp
+# endif
+)
+#else
+int IPL_EXTERN(ioctl)(dev, cmd, data, mode
#if ((_BSDI_VERSION >= 199510) || (BSD >= 199506) || (NetBSD >= 199511) || \
(__FreeBSD_version >= 220000)) && defined(_KERNEL)
, p)
@@ -295,34 +339,43 @@ struct proc *p;
)
#endif
dev_t dev;
+#if defined(__NetBSD__) || defined(__OpenBSD__)
+u_long cmd;
+#else
int cmd;
+#endif
caddr_t data;
int mode;
+#endif /* __sgi */
{
- int error = 0, s, unit;
+#if defined(_KERNEL) && !SOLARIS
+ int s;
+#endif
+ int error = 0, unit = 0;
#ifdef _KERNEL
- unit = minor(dev);
- if ((2 < unit) || (unit < 0))
+ unit = GET_MINOR(dev);
+ if ((IPL_LOGMAX < unit) || (unit < 0))
return ENXIO;
#endif
- SPLNET(s);
+ SPL_NET(s);
if (unit == IPL_LOGNAT) {
error = nat_ioctl(data, cmd, mode);
- SPLX(s);
+ SPL_X(s);
return error;
}
if (unit == IPL_LOGSTATE) {
error = fr_state_ioctl(data, cmd, mode);
- SPLX(s);
+ SPL_X(s);
return error;
}
switch (cmd) {
case FIONREAD :
#ifdef IPFILTER_LOG
- *(int *)data = iplused[IPL_LOGIPF];
+ IWCOPY((caddr_t)&iplused[IPL_LOGIPF], (caddr_t)data,
+ sizeof(iplused[IPL_LOGIPF]));
#endif
break;
#if !defined(IPFILTER_LKM) && defined(_KERNEL)
@@ -358,7 +411,7 @@ int mode;
if (!(mode & FWRITE))
error = EPERM;
else
- error = frrequest(cmd, data, fr_active);
+ error = frrequest(unit, cmd, data, fr_active);
break;
case SIOCINIFR :
case SIOCRMIFR :
@@ -366,7 +419,7 @@ int mode;
if (!(mode & FWRITE))
error = EPERM;
else
- error = frrequest(cmd, data, 1 - fr_active);
+ error = frrequest(unit, cmd, data, 1 - fr_active);
break;
case SIOCSWAPA :
if (!(mode & FWRITE))
@@ -391,7 +444,10 @@ int mode;
fio.f_acctin[1] = ipacct[0][1];
fio.f_acctout[0] = ipacct[1][0];
fio.f_acctout[1] = ipacct[1][1];
+ fio.f_auth = ipauth;
fio.f_active = fr_active;
+ fio.f_froute[0] = ipl_frouteok[0];
+ fio.f_froute[1] = ipl_frouteok[1];
IWCOPY((caddr_t)&fio, data, sizeof(fio));
break;
}
@@ -405,58 +461,135 @@ int mode;
if (!(mode & FWRITE))
error = EPERM;
else
- frflush(data);
+ frflush(unit, data);
break;
#ifdef IPFILTER_LOG
case SIOCIPFFB :
if (!(mode & FWRITE))
error = EPERM;
- else {
- *(int *)data = iplused[unit];
- iplh[unit] = iplt[unit] = iplbuf[unit];
- iplused[unix] = 0;
- }
+ else
+ *(int *)data = ipflog_clear(unit);
break;
#endif /* IPFILTER_LOG */
case SIOCGFRST :
IWCOPY((caddr_t)ipfr_fragstats(), data, sizeof(ipfrstat_t));
break;
+ case SIOCAUTHW :
+ case SIOCAUTHR :
+ if (!(mode & FWRITE)) {
+ error = EPERM;
+ break;
+ }
+ case SIOCATHST :
+ error = fr_auth_ioctl(data, cmd, NULL, NULL);
+ break;
+ case SIOCFRSYN :
+ if (!(mode & FWRITE))
+ error = EPERM;
+ else {
+#if defined(_KERNEL) && defined(__sgi)
+ ipfsync();
+#endif
+ frsync();
+ }
+ break;
default :
error = EINVAL;
break;
}
- SPLX(s);
+ SPL_X(s);
return error;
}
-static int frrequest(req, data, set)
-int req, set;
+static void frsync()
+{
+#ifdef _KERNEL
+ struct ifnet *ifp;
+
+# if defined(__OpenBSD__) || (NetBSD >= 199511)
+ for (ifp = ifnet.tqh_first; ifp; ifp = ifp->if_list.tqe_next)
+# else
+ for (ifp = ifnet; ifp; ifp = ifp->if_next)
+# endif
+ ip_natsync(ifp);
+#endif
+}
+
+
+static void fixskip(listp, rp, addremove)
+frentry_t **listp, *rp;
+int addremove;
+{
+ frentry_t *fp;
+ int rules = 0, rn = 0;
+
+ for (fp = *listp; fp && (fp != rp); fp = fp->fr_next, rules++)
+ ;
+
+ if (!fp)
+ return;
+
+ for (fp = *listp; fp && (fp != rp); fp = fp->fr_next, rn++)
+ if (fp->fr_skip && (rn + fp->fr_skip >= rules))
+ fp->fr_skip += addremove;
+}
+
+
+static int frrequest(unit, req, data, set)
+int unit;
+#if defined(__NetBSD__) || defined(__OpenBSD__)
+u_long req;
+#else
+int req;
+#endif
+int set;
caddr_t data;
{
register frentry_t *fp, *f, **fprev;
register frentry_t **ftail;
frentry_t frd;
frdest_t *fdp;
- int error = 0, in;
+ frgroup_t *fg = NULL;
+ int error = 0, in, group;
fp = &frd;
IRCOPY(data, (caddr_t)fp, sizeof(*fp));
+ /*
+ * Check that the group number does exist and that if a head group
+ * has been specified, doesn't exist.
+ */
+ if (fp->fr_grhead &&
+ fr_findgroup(fp->fr_grhead, fp->fr_flags, unit, set, NULL))
+ return EEXIST;
+ if (fp->fr_group &&
+ !fr_findgroup(fp->fr_group, fp->fr_flags, unit, set, NULL))
+ return ESRCH;
+
in = (fp->fr_flags & FR_INQUE) ? 0 : 1;
- if (fp->fr_flags & FR_ACCOUNT) {
+
+ if (unit == IPL_LOGAUTH)
+ ftail = fprev = &ipauth;
+ else if (fp->fr_flags & FR_ACCOUNT)
ftail = fprev = &ipacct[in][set];
- } else if (fp->fr_flags & (FR_OUTQUE|FR_INQUE))
+ else if (fp->fr_flags & (FR_OUTQUE|FR_INQUE))
ftail = fprev = &ipfilter[in][set];
else
return ESRCH;
+ if ((group = fp->fr_group)) {
+ if (!(fg = fr_findgroup(group, fp->fr_flags, unit, set, NULL)))
+ return ESRCH;
+ ftail = fprev = fg->fg_start;
+ }
+
bzero((char *)frcache, sizeof(frcache[0]) * 2);
if (*fp->fr_ifname) {
fp->fr_ifa = GETUNIT(fp->fr_ifname);
if (!fp->fr_ifa)
- fp->fr_ifa = (struct ifnet *)-1;
+ fp->fr_ifa = (void *)-1;
}
fdp = &fp->fr_dif;
@@ -512,19 +645,39 @@ caddr_t data;
if (!f)
error = ESRCH;
else {
+ if (f->fr_ref > 1)
+ return EBUSY;
+ if (fg && fg->fg_head)
+ fg->fg_head->fr_ref--;
+ if (unit == IPL_LOGAUTH)
+ return fr_auth_ioctl(data, req, f, ftail);
+ if (f->fr_grhead)
+ fr_delgroup(f->fr_grhead, fp->fr_flags, unit,
+ set);
+ fixskip(fprev, f, -1);
*ftail = f->fr_next;
- (void) KFREE(f);
+ KFREE(f);
}
} else {
if (f)
error = EEXIST;
else {
+ if (unit == IPL_LOGAUTH)
+ return fr_auth_ioctl(data, req, f, ftail);
KMALLOC(f, frentry_t *, sizeof(*f));
if (f != NULL) {
+ if (fg && fg->fg_head)
+ fg->fg_head->fr_ref++;
bcopy((char *)fp, (char *)f, sizeof(*f));
+ f->fr_ref = 1;
f->fr_hits = 0;
f->fr_next = *ftail;
*ftail = f;
+ if (req == SIOCINIFR || req == SIOCINAFR)
+ fixskip(fprev, f, 1);
+ f->fr_grp = NULL;
+ if ((group = f->fr_grhead))
+ fg = fr_addgroup(group, f, unit, set);
} else
error = ENOMEM;
}
@@ -537,8 +690,15 @@ caddr_t data;
/*
* routines below for saving IP headers to buffer
*/
-int iplopen(dev, flags
-#if ((_BSDI_VERSION >= 199510) || (BSD >= 199506) || (NetBSD >= 199511) || \
+#ifdef __sgi
+# ifdef _KERNEL
+int IPL_EXTERN(open)(dev_t *pdev, int flags, int devtype, cred_t *cp)
+# else
+int IPL_EXTERN(open)(dev_t dev, int flags)
+# endif
+#else
+int IPL_EXTERN(open)(dev, flags
+# if ((_BSDI_VERSION >= 199510) || (BSD >= 199506) || (NetBSD >= 199511) || \
(__FreeBSD_version >= 220000)) && defined(_KERNEL)
, devtype, p)
int devtype;
@@ -548,8 +708,13 @@ struct proc *p;
# endif
dev_t dev;
int flags;
+#endif /* __sgi */
{
- u_int min = minor(dev);
+#if defined(__sgi) && defined(_KERNEL)
+ u_int min = geteminor(*pdev);
+#else
+ u_int min = GET_MINOR(dev);
+#endif
if (2 < min)
min = ENXIO;
@@ -559,8 +724,11 @@ int flags;
}
-int iplclose(dev, flags
-#if ((_BSDI_VERSION >= 199510) || (BSD >= 199506) || (NetBSD >= 199511) || \
+#ifdef __sgi
+int IPL_EXTERN(close)(dev_t dev, int flags, int devtype, cred_t *cp)
+#else
+int IPL_EXTERN(close)(dev, flags
+# if ((_BSDI_VERSION >= 199510) || (BSD >= 199506) || (NetBSD >= 199511) || \
(__FreeBSD_version >= 220000)) && defined(_KERNEL)
, devtype, p)
int devtype;
@@ -570,8 +738,9 @@ struct proc *p;
# endif
dev_t dev;
int flags;
+#endif /* __sgi */
{
- u_int min = minor(dev);
+ u_int min = GET_MINOR(dev);
if (2 < min)
min = ENXIO;
@@ -580,144 +749,32 @@ int flags;
return min;
}
-# ifdef IPFILTER_LOG
/*
* iplread/ipllog
* both of these must operate with at least splnet() lest they be
* called during packet processing and cause an inconsistancy to appear in
* the filter lists.
*/
+#ifdef __sgi
+int IPL_EXTERN(read)(dev_t dev, uio_t *uio, cred_t *crp)
+#else
# if BSD >= 199306
-int iplread(dev, uio, ioflag)
+int IPL_EXTERN(read)(dev, uio, ioflag)
int ioflag;
# else
-int iplread(dev, uio)
+int IPL_EXTERN(read)(dev, uio)
# endif
dev_t dev;
register struct uio *uio;
+#endif /* __sgi */
{
- register int ret, s, unit;
- register size_t sz, sx;
- int error;
-
- unit = minor(dev);
- if ((2 < unit) || (unit < 0))
- return ENXIO;
-
- if (!uio->uio_resid)
- return 0;
-
- while (!iplused[unit]) {
- error = SLEEP(iplbuf[unit], "ipl sleep");
- if (error)
- return error;
- }
- SPLNET(s);
-
- sx = sz = MIN(uio->uio_resid, iplused[unit]);
- if (iplh[unit] < iplt[unit])
- sz = MIN(sz, IPLLOGSIZE - (iplt[unit] - iplbuf[unit]));
- sx -= sz;
-
-# if BSD >= 199306 || defined(__FreeBSD__)
- uio->uio_rw = UIO_READ;
+# ifdef IPFILTER_LOG
+ return ipflog_read(GET_MINOR(dev), uio);
+# else
+ return ENXIO;
# endif
- if (!(ret = UIOMOVE(iplt[unit], sz, UIO_READ, uio))) {
- iplt[unit] += sz;
- iplused[unit] -= sz;
- if ((iplh[unit] < iplt[unit]) && (iplt[unit] == iplbuf[unit] + IPLLOGSIZE))
- iplt[unit] = iplbuf[unit];
-
- if (sx && !(ret = UIOMOVE(iplt[unit], sx, UIO_READ, uio))) {
- iplt[unit] += sx;
- iplused[unit] -= sx;
- if ((iplh[unit] < iplt[unit]) && (iplt[unit] == iplbuf[unit] + IPLLOGSIZE))
- iplt[unit] = iplbuf[unit];
- }
- if (!iplused[unit]) /* minimise wrapping around the end */
- iplh[unit] = iplt[unit] = iplbuf[unit];
- }
- SPLX(s);
- return ret;
}
-# endif /* IPFILTER_LOG */
-
-
-# ifdef IPFILTER_LOG
-int ipllog(flags, dev, ip, fin, m)
-u_int flags;
-int dev;
-ip_t *ip;
-register fr_info_t *fin;
-struct mbuf *m;
-{
- struct ipl_ci iplci;
- register int len, mlen, hlen;
- struct ifnet *ifp = fin->fin_ifp;
-
- hlen = fin->fin_hlen;
- if (ip->ip_p == IPPROTO_TCP || ip->ip_p == IPPROTO_UDP)
- hlen += MIN(sizeof(tcphdr_t), fin->fin_dlen);
- else if (ip->ip_p == IPPROTO_ICMP) {
- struct icmp *icmp = (struct icmp *)((char *)ip + hlen);
-
- switch (icmp->icmp_type) {
- case ICMP_UNREACH :
- case ICMP_SOURCEQUENCH :
- case ICMP_REDIRECT :
- case ICMP_TIMXCEED :
- case ICMP_PARAMPROB :
- hlen += MIN(sizeof(struct icmp) + 8, fin->fin_dlen);
- break;
- default :
- hlen += MIN(sizeof(struct icmp), fin->fin_dlen);
- break;
- }
- }
- mlen = (flags & FR_LOGBODY) ? MIN(ip->ip_len - hlen, 128) : 0;
- len = hlen + sizeof(iplci) + mlen;
- if (iplused[dev] + len > IPLLOGSIZE)
- return 0;
- iplused[dev] += len;
-
-# ifdef sun
- uniqtime(&iplci);
-# endif
-# if BSD >= 199306 || defined(__FreeBSD__)
- microtime((struct timeval *)&iplci);
-# endif
- iplci.flags = flags;
- iplci.hlen = (u_char)hlen;
- iplci.plen = (u_char)mlen;
- iplci.rule = fin->fin_rule;
-# if (defined(NetBSD) && (NetBSD <= 1991011) && (NetBSD >= 199603))
- strncpy(iplci.ifname, ifp->if_xname, IFNAMSIZ);
-# else
- iplci.unit = (u_char)ifp->if_unit;
- if ((iplci.ifname[0] = ifp->if_name[0]))
- if ((iplci.ifname[1] = ifp->if_name[1]))
- if ((iplci.ifname[2] = ifp->if_name[2]))
- iplci.ifname[3] = ifp->if_name[3];
-# endif
- if (iplh[dev] == iplbuf[dev] + IPLLOGSIZE)
- iplh[dev] = iplbuf[dev];
-
- /*
- * Gauranteed to succeed from above
- */
- (void) fr_copytolog(dev, (char *)&iplci, sizeof(iplci));
-
- for (len -= sizeof(iplci); m && len > 0; m = m->m_next, len -= hlen) {
- hlen = MIN(len, m->m_len);
- if (fr_copytolog(dev, mtod(m, char *), hlen))
- break;
- }
-
- wakeup(iplbuf[dev]);
- return 1;
-}
-# endif /* IPFILTER_LOG */
/*
* send_reset - this could conceivably be a call to tcp_respond(), but that
@@ -727,17 +784,17 @@ int send_reset(ti)
struct tcpiphdr *ti;
{
struct tcpiphdr *tp;
- struct ip *ip;
struct tcphdr *tcp;
struct mbuf *m;
int tlen = 0;
-#if defined(__FreeBSD_version) && (__FreeBSD_version >= 220000)
+ ip_t *ip;
+# if defined(__FreeBSD_version) && (__FreeBSD_version >= 220000)
struct route ro;
-#endif
+# endif
if (ti->ti_flags & TH_RST)
return -1; /* feedback loop */
-# if BSD < 199306
+# if (BSD < 199306) || defined(__sgi)
m = m_get(M_DONTWAIT, MT_HEADER);
# else
m = m_gethdr(M_DONTWAIT, MT_HEADER);
@@ -745,8 +802,6 @@ struct tcpiphdr *ti;
# endif
if (m == NULL)
return -1;
-#if defined(__FreeBSD_version) && (__FreeBSD_version >= 220000)
-#endif
if (ti->ti_flags & TH_SYN)
tlen = 1;
@@ -774,29 +829,29 @@ struct tcpiphdr *ti;
ip->ip_tos = ((struct ip *)ti)->ip_tos;
ip->ip_p = ((struct ip *)ti)->ip_p;
ip->ip_len = sizeof (struct tcpiphdr);
-# if BSD < 199306
+# if (BSD < 199306) || defined(__sgi)
ip->ip_ttl = tcp_ttl;
# else
ip->ip_ttl = ip_defttl;
# endif
-#if defined(__FreeBSD_version) && (__FreeBSD_version >= 220000)
+# if defined(__FreeBSD_version) && (__FreeBSD_version >= 220000)
bzero((char *)&ro, sizeof(ro));
(void) ip_output(m, (struct mbuf *)0, &ro, 0, 0);
if (ro.ro_rt)
RTFREE(ro.ro_rt);
-#else
+# else
/*
* extra 0 in case of multicast
*/
(void) ip_output(m, (struct mbuf *)0, 0, 0, 0);
-#endif
+# endif
return 0;
}
-# if !defined(IPFILTER_LKM) && !(__FreeBSD_version >= 300000)
-# if BSD < 199306
+# if !defined(IPFILTER_LKM) && (__FreeBSD_version < 300000) && !defined(__sgi)
+# if (BSD < 199306)
int iplinit __P((void));
int
@@ -810,7 +865,18 @@ iplinit()
(void) iplattach();
ip_init();
}
-# endif
+# endif /* ! __NetBSD__ */
+
+
+size_t mbufchainlen(m0)
+register struct mbuf *m0;
+{
+ register size_t len = 0;
+
+ for (; m0; m0 = m0->m_next)
+ len += m0->m_len;
+ return len;
+}
void ipfr_fastroute(m0, fin, fdp)
@@ -836,10 +902,11 @@ frdest_t *fdp;
dst = (struct sockaddr_in *)&ro->ro_dst;
dst->sin_family = AF_INET;
dst->sin_addr = fdp->fd_ip.s_addr ? fdp->fd_ip : ip->ip_dst;
-#ifdef __bsdi__
+# ifdef __bsdi__
dst->sin_len = sizeof(*dst);
-#endif
-#if (BSD >= 199306) && !defined(__NetBSD__) && !defined(__bsdi__)
+# endif
+# if (BSD >= 199306) && !defined(__NetBSD__) && !defined(__bsdi__) && \
+ !defined(__OpenBSD__)
# ifdef RTF_CLONING
rtalloc_ign(ro, RTF_CLONING);
# else
@@ -981,6 +1048,11 @@ sendorfree:
}
}
done:
+ if (!error)
+ ipl_frouteok[0]++;
+ else
+ ipl_frouteok[1]++;
+
if (ro->ro_rt) {
RTFREE(ro->ro_rt);
}
@@ -992,18 +1064,31 @@ bad:
#else /* #ifdef _KERNEL */
+#ifdef __sgi
+static int no_output __P((struct ifnet *ifp, struct mbuf *m,
+ struct sockaddr *s))
+#else
static int no_output __P((struct ifnet *ifp, struct mbuf *m,
struct sockaddr *s, struct rtentry *rt))
+#endif
{
return 0;
}
# ifdef __STDC__
+#ifdef __sgi
+static int write_output __P((struct ifnet *ifp, struct mbuf *m,
+ struct sockaddr *s))
+#else
static int write_output __P((struct ifnet *ifp, struct mbuf *m,
struct sockaddr *s, struct rtentry *rt))
+#endif
{
+# if !(defined(NetBSD) && (NetBSD <= 1991011) && (NetBSD >= 199606)) || \
+ (defined(OpenBSD) && (OpenBSD >= 199603))
ip_t *ip = (ip_t *)m;
+# endif
# else
static int write_output(ifp, ip)
struct ifnet *ifp;
@@ -1013,18 +1098,20 @@ ip_t *ip;
FILE *fp;
char fname[32];
-#if (defined(NetBSD) && (NetBSD <= 1991011) && (NetBSD >= 199606))
+# if (defined(NetBSD) && (NetBSD <= 1991011) && (NetBSD >= 199606)) || \
+ (defined(OpenBSD) && (OpenBSD >= 199603))
sprintf(fname, "/tmp/%s", ifp->if_xname);
if ((fp = fopen(fname, "a"))) {
fclose(fp);
}
-#else
+# else
sprintf(fname, "/tmp/%s%d", ifp->if_name, ifp->if_unit);
if ((fp = fopen(fname, "a"))) {
fwrite((char *)ip, ntohs(ip->ip_len), 1, fp);
fclose(fp);
}
-#endif
+# endif
+ return 0;
}
@@ -1032,12 +1119,13 @@ struct ifnet *get_unit(name)
char *name;
{
struct ifnet *ifp, **ifa;
-#if (defined(NetBSD) && (NetBSD <= 1991011) && (NetBSD >= 199606))
+# if (defined(NetBSD) && (NetBSD <= 1991011) && (NetBSD >= 199606)) || \
+ (defined(OpenBSD) && (OpenBSD >= 199603))
for (ifa = ifneta; ifa && (ifp = *ifa); ifa++) {
if (!strcmp(name, ifp->if_xname))
return ifp;
}
-#else
+# else
char ifname[32], *s;
for (ifa = ifneta; ifa && (ifp = *ifa); ifa++) {
@@ -1045,7 +1133,7 @@ char *name;
if (!strcmp(name, ifname))
return ifp;
}
-#endif
+# endif
if (!ifneta) {
ifneta = (struct ifnet **)malloc(sizeof(ifp) * 2);
@@ -1061,9 +1149,10 @@ char *name;
}
ifp = ifneta[nifs - 1];
-#if (defined(NetBSD) && (NetBSD <= 1991011) && (NetBSD >= 199606))
+# if (defined(NetBSD) && (NetBSD <= 1991011) && (NetBSD >= 199606)) || \
+ (defined(OpenBSD) && (OpenBSD >= 199603))
strncpy(ifp->if_xname, name, sizeof(ifp->if_xname));
-#else
+# else
for (s = name; *s && !isdigit(*s); s++)
;
if (*s && isdigit(*s)) {
@@ -1075,25 +1164,27 @@ char *name;
ifp->if_name = strdup(name);
ifp->if_unit = -1;
}
-#endif
+# endif
ifp->if_output = no_output;
return ifp;
}
+
void init_ifp()
{
FILE *fp;
struct ifnet *ifp, **ifa;
char fname[32];
-#if (defined(NetBSD) && (NetBSD <= 1991011) && (NetBSD >= 199606))
+# if (defined(NetBSD) && (NetBSD <= 1991011) && (NetBSD >= 199606)) || \
+ (defined(OpenBSD) && (OpenBSD >= 199603))
for (ifa = ifneta; ifa && (ifp = *ifa); ifa++) {
ifp->if_output = write_output;
sprintf(fname, "/tmp/%s", ifp->if_xname);
if ((fp = fopen(fname, "w")))
fclose(fp);
}
-#else
+# else
for (ifa = ifneta; ifa && (ifp = *ifa); ifa++) {
ifp->if_output = write_output;
@@ -1101,7 +1192,7 @@ void init_ifp()
if ((fp = fopen(fname, "w")))
fclose(fp);
}
-#endif
+# endif
}
@@ -1118,13 +1209,18 @@ frdest_t *fdp;
ip->ip_len = htons((u_short)ip->ip_len);
ip->ip_off = htons((u_short)(ip->ip_off | IP_MF));
ip->ip_sum = 0;
+#ifdef __sgi
+ (*ifp->if_output)(ifp, (void *)ip, NULL);
+#else
(*ifp->if_output)(ifp, (void *)ip, NULL, 0);
+#endif
}
-void ipllog()
+int ipllog __P((void))
{
verbose("l");
+ return 0;
}
diff --git a/contrib/ipfilter/ip_fil.h b/contrib/ipfilter/ip_fil.h
index 661e109f407e..39cca349e319 100644
--- a/contrib/ipfilter/ip_fil.h
+++ b/contrib/ipfilter/ip_fil.h
@@ -1,17 +1,25 @@
/*
- * (C)opyright 1993-1997 by Darren Reed.
+ * Copyright (C) 1993-1997 by Darren Reed.
*
* Redistribution and use in source and binary forms are permitted
* provided that this notice is preserved and due credit is given
* to the original author and the contributors.
*
* @(#)ip_fil.h 1.35 6/5/96
- * $Id: ip_fil.h,v 2.0.2.13 1997/05/24 07:41:55 darrenr Exp $
+ * $Id: ip_fil.h,v 2.0.2.39.2.4 1997/11/12 10:50:02 darrenr Exp $
*/
#ifndef __IP_FIL_H__
#define __IP_FIL_H__
+/*
+ * Pathnames for various IP Filter control devices. Used by LKM
+ * and userland, so defined here.
+ */
+#define IPNAT_NAME "/dev/ipnat"
+#define IPSTATE_NAME "/dev/ipstate"
+#define IPAUTH_NAME "/dev/ipauth"
+
#ifndef SOLARIS
#define SOLARIS (defined(sun) && (defined(__svr4__) || defined(__SVR4)))
#endif
@@ -45,6 +53,9 @@
#define SIOCFRSYN _IOW('r', 73, u_int)
#define SIOCFRZST _IOWR('r', 74, struct friostat)
#define SIOCZRLST _IOWR('r', 75, struct frentry)
+#define SIOCAUTHW _IOWR('r', 76, struct fr_info)
+#define SIOCAUTHR _IOWR('r', 77, struct fr_info)
+#define SIOCATHST _IOWR('r', 78, struct fr_authstat)
#else
#define SIOCADAFR _IOW(r, 60, struct frentry)
#define SIOCRMAFR _IOW(r, 61, struct frentry)
@@ -62,6 +73,9 @@
#define SIOCFRSYN _IOW(r, 73, u_int)
#define SIOCFRZST _IOWR(r, 74, struct friostat)
#define SIOCZRLST _IOWR(r, 75, struct frentry)
+#define SIOCAUTHW _IOWR(r, 76, struct fr_info)
+#define SIOCAUTHR _IOWR(r, 77, struct fr_info)
+#define SIOCATHST _IOWR(r, 78, struct fr_authstat)
#endif
#define SIOCADDFR SIOCADAFR
#define SIOCDELFR SIOCRMAFR
@@ -75,7 +89,7 @@ typedef struct fr_ip {
u_char fi_p;
struct in_addr fi_src;
struct in_addr fi_dst;
- u_long fi_optmsk; /* bitmask composed from IP options */
+ u_32_t fi_optmsk; /* bitmask composed from IP options */
u_short fi_secmsk; /* bitmask composed from IP security options */
u_short fi_auth;
} fr_ip_t;
@@ -87,20 +101,30 @@ typedef struct fr_ip {
typedef struct fr_info {
struct fr_ip fin_fi;
- void *fin_ifp;
u_short fin_data[2];
u_short fin_out;
+ u_short fin_hlen;
u_char fin_tcpf;
- u_char fin_icode;
+ u_char fin_icode; /* From here on is packet specific */
u_short fin_rule;
- u_short fin_hlen;
+ u_short fin_group;
u_short fin_dlen;
- char *fin_dp; /* start of data past IP header */
+ u_short fin_id;
+ void *fin_ifp;
struct frentry *fin_fr;
+ char *fin_dp; /* start of data past IP header */
void *fin_mp;
} fr_info_t;
-#define FI_CSIZE (sizeof(struct fr_ip) + 11)
+/*
+ * Size for compares on fr_info structures
+ */
+#define FI_CSIZE (sizeof(struct fr_ip) + sizeof(u_short) * 4 + \
+ sizeof(u_char))
+/*
+ * Size for copying cache fr_info structure
+ */
+#define FI_COPYSIZE (sizeof(fr_info_t) - sizeof(void *) * 2)
typedef struct frdest {
void *fd_ifp;
@@ -110,9 +134,13 @@ typedef struct frdest {
typedef struct frentry {
struct frentry *fr_next;
- struct ifnet *fr_ifa;
+ u_short fr_group; /* group to which this rule belongs */
+ u_short fr_grhead; /* group # which this rule starts */
+ struct frentry *fr_grp;
+ int fr_ref; /* reference count - for grouping */
+ void *fr_ifa;
/*
- * There are only incremented when a packet matches this rule and
+ * These are only incremented when a packet matches this rule and
* it is the last match
*/
U_QUAD_T fr_hits;
@@ -135,8 +163,9 @@ typedef struct frentry {
u_short fr_sport;
u_short fr_stop; /* top port for <> and >< */
u_short fr_dtop; /* top port for <> and >< */
- u_long fr_flags; /* per-rule flags && options (see below) */
- int (*fr_func) __P((int, struct ip *, fr_info_t *)); /* call this function */
+ u_32_t fr_flags; /* per-rule flags && options (see below) */
+ int fr_skip; /* # of rules to skip */
+ int (*fr_func) __P((int, ip_t *, fr_info_t *)); /* call this function */
char fr_icode; /* return ICMP code */
char fr_ifname[IFNAMSIZ];
struct frdest fr_tif; /* "to" interface */
@@ -159,10 +188,10 @@ typedef struct frentry {
/*
* fr_flags
*/
-#define FR_BLOCK 0x00001
-#define FR_PASS 0x00002
-#define FR_OUTQUE 0x00004
-#define FR_INQUE 0x00008
+#define FR_BLOCK 0x00001 /* do not allow packet to pass */
+#define FR_PASS 0x00002 /* allow packet to pass */
+#define FR_OUTQUE 0x00004 /* outgoing packets */
+#define FR_INQUE 0x00008 /* ingoing packets */
#define FR_LOG 0x00010 /* Log */
#define FR_LOGB 0x00011 /* Log-fail */
#define FR_LOGP 0x00012 /* Log-pass */
@@ -170,7 +199,7 @@ typedef struct frentry {
#define FR_LOGFIRST 0x00040 /* Log the first byte if state held */
#define FR_RETRST 0x00080 /* Return TCP RST packet - reset connection */
#define FR_RETICMP 0x00100 /* Return ICMP unreachable packet */
-#define FR_NOMATCH 0x00200
+#define FR_NOMATCH 0x00200 /* no match occured */
#define FR_ACCOUNT 0x00400 /* count packet bytes */
#define FR_KEEPFRAG 0x00800 /* keep fragment information */
#define FR_KEEPSTATE 0x01000 /* keep `connection' state information */
@@ -182,10 +211,20 @@ typedef struct frentry {
#define FR_LOGORBLOCK 0x40000 /* block the packet if it can't be logged */
#define FR_NOTSRCIP 0x80000 /* not the src IP# */
#define FR_NOTDSTIP 0x100000 /* not the dst IP# */
+#define FR_AUTH 0x200000 /* use authentication */
+#define FR_PREAUTH 0x400000 /* require preauthentication */
#define FR_LOGMASK (FR_LOG|FR_LOGP|FR_LOGB)
+
/*
- * recognized flags for SIOCGETFF and SIOCSETFF
+ * These correspond to #define's for FI_* and are stored in fr_flags
+ */
+#define FF_OPTIONS 0x01000000
+#define FF_TCPUDP 0x02000000
+#define FF_FRAG 0x04000000
+#define FF_SHORT 0x08000000
+/*
+ * recognized flags for SIOCGETFF and SIOCSETFF, and get put in fr_flags
*/
#define FF_LOGPASS 0x10000000
#define FF_LOGBLOCK 0x20000000
@@ -220,6 +259,7 @@ typedef struct filterstats {
u_long fr_bads; /* bad attempts to allocate packet state */
u_long fr_ads; /* new packet state kept */
u_long fr_chit; /* cached hit */
+ u_long fr_tcpbad; /* TCP checksum check failures */
u_long fr_pull[2]; /* good and bad pullup attempts */
#if SOLARIS
u_long fr_bad; /* bad IP packets to the filter */
@@ -237,34 +277,59 @@ typedef struct friostat {
struct frentry *f_fout[2];
struct frentry *f_acctin[2];
struct frentry *f_acctout[2];
+ struct frentry *f_auth;
+ u_long f_froute[2];
int f_active;
} friostat_t;
-typedef struct optlist {
+typedef struct optlist {
u_short ol_val;
- int ol_bit;
+ int ol_bit;
} optlist_t;
+
/*
- * Log structure. Each packet header logged is prepended by one of these,
- * minimize size to make most effective use of log space which should
- * (ideally) be a muliple of the most common log entry size.
+ * Group list structure.
*/
-typedef struct ipl_ci {
- u_long sec;
- u_long usec;
- u_char hlen;
- u_char plen;
- u_short rule; /* assume never more than 64k rules, total */
-#if (defined(NetBSD) && (NetBSD <= 1991011) && (NetBSD >= 199603))
- u_long flags;
- u_char ifname[IFNAMSIZ]; /* = 32 bytes */
+typedef struct frgroup {
+ u_short fg_num;
+ struct frgroup *fg_next;
+ struct frentry *fg_head;
+ struct frentry **fg_start;
+} frgroup_t;
+
+
+/*
+ * Log structure. Each packet header logged is prepended by one of these.
+ * Following this in the log records read from the device will be an ipflog
+ * structure which is then followed by any packet data.
+ */
+typedef struct iplog {
+ u_long ipl_magic;
+ u_long ipl_sec;
+ u_long ipl_usec;
+ u_int ipl_len;
+ u_int ipl_count;
+ size_t ipl_dsize;
+ struct iplog *ipl_next;
+} iplog_t;
+
+#define IPL_MAGIC 0x49504c4d /* 'IPLM' */
+
+typedef struct ipflog {
+#if (defined(NetBSD) && (NetBSD <= 1991011) && (NetBSD >= 199603)) || \
+ (defined(OpenBSD) && (OpenBSD >= 199603))
+ u_char fl_ifname[IFNAMSIZ];
#else
- u_long flags;
- u_int unit;
- u_char ifname[4]; /* = 24 bytes */
+ u_int fl_unit;
+ u_char fl_ifname[4];
#endif
-} ipl_ci_t;
+ u_char fl_plen; /* extra data after hlen */
+ u_char fl_hlen; /* length of IP headers saved */
+ u_short fl_rule; /* assume never more than 64k rules, total */
+ u_short fl_group;
+ u_32_t fl_flags;
+} ipflog_t;
#ifndef ICMP_UNREACH_FILTER
@@ -275,15 +340,15 @@ typedef struct ipl_ci {
#define IPF_LOGGING 0
#endif
#ifndef IPF_DEFAULT_PASS
-#define IPF_DEFAULT_PASS 0
+#define IPF_DEFAULT_PASS FR_PASS
#endif
#define IPMINLEN(i, h) ((i)->ip_len >= ((i)->ip_hl * 4 + sizeof(struct h)))
#define IPLLOGSIZE 8192
/*
- * Device filenames. Use ipf on Solaris2 because ipl is already a name used
- * by something else.
+ * Device filenames for reading log information. Use ipf on Solaris2 because
+ * ipl is already a name used by something else.
*/
#ifndef IPL_NAME
# if SOLARIS
@@ -292,11 +357,15 @@ typedef struct ipl_ci {
# define IPL_NAME "/dev/ipl"
# endif
#endif
-#define IPL_NAT "/dev/ipnat"
-#define IPL_STATE "/dev/ipstate"
+#define IPL_NAT IPNAT_NAME
+#define IPL_STATE IPSTATE_NAME
+#define IPL_AUTH IPAUTH_NAME
+
#define IPL_LOGIPF 0 /* Minor device #'s for accessing logs */
#define IPL_LOGNAT 1
#define IPL_LOGSTATE 2
+#define IPL_LOGAUTH 3
+#define IPL_LOGMAX 3
#if !defined(CDEV_MAJOR) && defined (__FreeBSD_version) && \
(__FreeBSD_version >= 220000)
@@ -304,78 +373,145 @@ typedef struct ipl_ci {
#endif
#ifndef _KERNEL
-extern int fr_check __P((struct ip *, int, struct ifnet *, int, char *));
-extern int (*fr_checkp) __P((struct ip *, int, struct ifnet *,
- int, char *));
-extern int send_reset __P((struct ip *, struct ifnet *));
-extern int icmp_error __P((struct ip *, struct ifnet *));
-extern void ipllog __P((void));
-extern void ipfr_fastroute __P((struct ip *, fr_info_t *, frdest_t *));
+extern int fr_check __P((ip_t *, int, void *, int, mb_t **));
+extern int (*fr_checkp) __P((ip_t *, int, void *, int, mb_t **));
+extern int send_reset __P((ip_t *, struct ifnet *));
+extern int icmp_error __P((ip_t *, struct ifnet *));
+extern int ipf_log __P((void));
+extern void ipfr_fastroute __P((ip_t *, fr_info_t *, frdest_t *));
+extern struct ifnet *get_unit __P((char *));
+# define FR_SCANLIST(p, ip, fi, m) fr_scanlist(p, ip, fi, m)
+# if defined(__NetBSD__) || defined(__OpenBSD__)
+extern int iplioctl __P((dev_t, u_long, caddr_t, int));
+# else
extern int iplioctl __P((dev_t, int, caddr_t, int));
+# endif
extern int iplopen __P((dev_t, int));
extern int iplclose __P((dev_t, int));
#else /* #ifndef _KERNEL */
+# if defined(__NetBSD__) && defined(PFIL_HOOKS)
+extern int ipfilterattach __P((int));
+# endif
extern int iplattach __P((void));
-extern int ipldetach __P((void));
+extern int ipl_enable __P((void));
+extern int ipl_disable __P((void));
+extern void ipflog_init __P((void));
+extern int ipflog_clear __P((int));
+extern int ipflog_read __P((int, struct uio *));
+extern int ipflog __P((u_int, ip_t *, fr_info_t *, mb_t *));
+extern int ipllog __P((int, u_long, void **, size_t *, int *, int));
# if SOLARIS
-extern int fr_check __P((struct ip *, int, struct ifnet *, int, qif_t *,
- queue_t *, mblk_t **));
-extern int (*fr_checkp) __P((struct ip *, int, struct ifnet *,
- int, qif_t *, queue_t *, mblk_t *));
-extern int icmp_error __P((queue_t *, ip_t *, int, int, qif_t *,
+extern int fr_check __P((ip_t *, int, void *, int, qif_t *, mb_t **));
+extern int (*fr_checkp) __P((ip_t *, int, void *,
+ int, qif_t *, mb_t **));
+extern int icmp_error __P((ip_t *, int, int, qif_t *,
struct in_addr));
extern int iplioctl __P((dev_t, int, int, int, cred_t *, int *));
extern int iplopen __P((dev_t *, int, int, cred_t *));
extern int iplclose __P((dev_t, int, int, cred_t *));
extern int ipfsync __P((void));
+extern int send_reset __P((ip_t *, qif_t *));
+extern int ipfr_fastroute __P((qif_t *, ip_t *, mblk_t *, mblk_t **,
+ fr_info_t *, frdest_t *));
+extern void copyin_mblk __P((mblk_t *, int, int, char *));
+extern void copyout_mblk __P((mblk_t *, int, int, char *));
+extern int fr_qin __P((queue_t *, mblk_t *));
+extern int fr_qout __P((queue_t *, mblk_t *));
# ifdef IPFILTER_LOG
extern int iplread __P((dev_t, struct uio *, cred_t *));
# endif
-extern u_short fr_tcpsum __P((mblk_t *, ip_t *, tcphdr_t *));
# else /* SOLARIS */
-extern int fr_check __P((struct ip *, int, struct ifnet *, int,
- struct mbuf **));
-extern int (*fr_checkp) __P((struct ip *, int, struct ifnet *, int,
- struct mbuf **));
+extern int fr_check __P((ip_t *, int, void *, int, mb_t **));
+extern int (*fr_checkp) __P((ip_t *, int, void *, int, mb_t **));
extern int send_reset __P((struct tcpiphdr *));
-extern int ipllog __P((u_int, int, struct ip *, fr_info_t *, struct mbuf *));
-extern void ipfr_fastroute __P((struct mbuf *, fr_info_t *, frdest_t *));
-# ifdef IPFILTER_LKM
+extern void ipfr_fastroute __P((mb_t *, fr_info_t *, frdest_t *));
+extern size_t mbufchainlen __P((mb_t *));
+# ifdef __sgi
+# include <sys/cred.h>
+extern int iplioctl __P((dev_t, int, caddr_t, int, cred_t *, int *));
+extern int iplopen __P((dev_t *, int, int, cred_t *));
+extern int iplclose __P((dev_t, int, int, cred_t *));
+extern int iplread __P((dev_t, struct uio *, cred_t *));
+extern int ipfsync __P((void));
+extern int ipfilter_sgi_attach __P((void));
+extern void ipfilter_sgi_detach __P((void));
+extern void ipfilter_sgi_intfsync __P((void));
+# else
+# ifdef IPFILTER_LKM
extern int iplidentify __P((char *));
-# endif
-extern u_short fr_tcpsum __P((struct mbuf *, ip_t *, tcphdr_t *));
-# if (_BSDI_VERSION >= 199510) || (__FreeBSD_version >= 220000) || \
+# endif
+# if (_BSDI_VERSION >= 199510) || (__FreeBSD_version >= 220000) || \
(NetBSD >= 199511)
+# ifdef __NetBSD__
+extern int iplioctl __P((dev_t, u_long, caddr_t, int, struct proc *));
+# else
extern int iplioctl __P((dev_t, int, caddr_t, int, struct proc *));
+# endif
extern int iplopen __P((dev_t, int, int, struct proc *));
extern int iplclose __P((dev_t, int, int, struct proc *));
-# else
+# else
+# if defined(__OpenBSD__)
+extern int iplioctl __P((dev_t, u_long, caddr_t, int));
+# else /* __OpenBSD__ */
+# ifndef linux
extern int iplioctl __P((dev_t, int, caddr_t, int));
+# else
+extern int iplioctl(struct inode *, struct file *, u_int, u_long);
+# endif
+# endif /* __OpenBSD__ */
+# ifndef linux
extern int iplopen __P((dev_t, int));
extern int iplclose __P((dev_t, int));
-# endif /* (_BSDI_VERSION >= 199510) */
-# ifdef IPFILTER_LOG
+# else
+extern int iplopen __P((struct inode *, struct file *));
+extern void iplclose __P((struct inode *, struct file *));
+# endif /* !linux */
+# endif /* (_BSDI_VERSION >= 199510) */
# if BSD >= 199306
extern int iplread __P((dev_t, struct uio *, int));
# else
+# ifndef linux
extern int iplread __P((dev_t, struct uio *));
+# else
+extern int iplread(struct inode *, struct file *, char *, int);
+# endif /* !linux */
# endif /* BSD >= 199306 */
-# else
-# define iplread noread
-# endif /* IPFILTER_LOG */
+# endif /* __ sgi */
# endif /* SOLARIS */
#endif /* #ifndef _KERNEL */
+
+/*
+ * Post NetBSD 1.2 has the PFIL interface for packet filters. This turns
+ * on those hooks. We don't need any special mods in non-IP Filter code
+ * with this!
+ */
+#if (defined(NetBSD) && (NetBSD > 199609) && (NetBSD <= 1991011)) || \
+ (defined(NetBSD1_2) && NetBSD1_2 > 1)
+# define NETBSD_PF
+#endif
+
+extern int ipldetach __P((void));
+extern u_short fr_tcpsum __P((mb_t *, ip_t *, tcphdr_t *));
+#define FR_SCANLIST(p, ip, fi, m) fr_scanlist(p, ip, fi, m)
+extern int fr_scanlist __P((int, ip_t *, fr_info_t *, void *));
extern u_short ipf_cksum __P((u_short *, int));
extern int fr_copytolog __P((int, char *, int));
+extern void frflush __P((int, caddr_t));
+extern frgroup_t *fr_addgroup __P((u_short, frentry_t *, int, int));
+extern frgroup_t *fr_findgroup __P((u_short, u_32_t, int, int, frgroup_t ***));
+extern void fr_delgroup __P((u_short, u_32_t, int, int));
extern int ipl_unreach;
extern int ipl_inited;
+extern u_long ipl_frouteok[2];
extern int fr_pass;
extern int fr_flags;
extern int fr_active;
-extern fr_info_t frcache[];
-extern char *iplh[3], *iplt[3];
-extern char iplbuf[3][IPLLOGSIZE];
-extern int iplused[3];
+extern fr_info_t frcache[2];
+#ifdef IPFILTER_LOG
+extern iplog_t **iplh[IPL_LOGMAX+1], *iplt[IPL_LOGMAX+1];
+extern int iplused[IPL_LOGMAX + 1];
+#endif
extern struct frentry *ipfilter[2][2], *ipacct[2][2];
+extern struct frgroup *ipfgroups[3][2];
extern struct filterstats frstats[];
#endif /* __IP_FIL_H__ */
diff --git a/contrib/ipfilter/ip_frag.c b/contrib/ipfilter/ip_frag.c
index 9b9bce35e7eb..923f68522261 100644
--- a/contrib/ipfilter/ip_frag.c
+++ b/contrib/ipfilter/ip_frag.c
@@ -1,13 +1,13 @@
/*
- * (C)opyright 1993,1994,1995 by Darren Reed.
+ * Copyright (C) 1993-1997 by Darren Reed.
*
* Redistribution and use in source and binary forms are permitted
* provided that this notice is preserved and due credit is given
* to the original author and the contributors.
*/
-#if !defined(lint) && defined(LIBC_SCCS)
-static char sccsid[] = "@(#)ip_frag.c 1.11 3/24/96 (C) 1993-1995 Darren Reed";
-static char rcsid[] = "$Id: ip_frag.c,v 2.0.2.10 1997/05/24 07:36:23 darrenr Exp $";
+#if !defined(lint)
+static const char sccsid[] = "@(#)ip_frag.c 1.11 3/24/96 (C) 1993-1995 Darren Reed";
+static const char rcsid[] = "@(#)$Id: ip_frag.c,v 2.0.2.19.2.1 1997/11/12 10:50:21 darrenr Exp $";
#endif
#if !defined(_KERNEL) && !defined(KERNEL)
@@ -26,13 +26,17 @@ static char rcsid[] = "$Id: ip_frag.c,v 2.0.2.10 1997/05/24 07:36:23 darrenr Exp
#include <sys/ioctl.h>
#endif
#include <sys/uio.h>
+#ifndef linux
#include <sys/protosw.h>
+#endif
#include <sys/socket.h>
-#ifdef _KERNEL
+#if defined(_KERNEL) && !defined(linux)
# include <sys/systm.h>
#endif
#if !defined(__SVR4) && !defined(__svr4__)
-# include <sys/mbuf.h>
+# ifndef linux
+# include <sys/mbuf.h>
+# endif
#else
# include <sys/byteorder.h>
# include <sys/dditypes.h>
@@ -48,27 +52,30 @@ static char rcsid[] = "$Id: ip_frag.c,v 2.0.2.10 1997/05/24 07:36:23 darrenr Exp
#include <netinet/in.h>
#include <netinet/in_systm.h>
#include <netinet/ip.h>
+#ifndef linux
#include <netinet/ip_var.h>
+#endif
#include <netinet/tcp.h>
#include <netinet/udp.h>
-#include <netinet/tcpip.h>
#include <netinet/ip_icmp.h>
#include "netinet/ip_compat.h"
+#include <netinet/tcpip.h>
#include "netinet/ip_fil.h"
#include "netinet/ip_proxy.h"
#include "netinet/ip_nat.h"
#include "netinet/ip_frag.h"
#include "netinet/ip_state.h"
+#include "netinet/ip_auth.h"
ipfr_t *ipfr_heads[IPFT_SIZE];
ipfr_t *ipfr_nattab[IPFT_SIZE];
ipfrstat_t ipfr_stats;
-u_long ipfr_inuse = 0,
+int ipfr_inuse = 0,
fr_ipfrttl = 120; /* 60 seconds */
#ifdef _KERNEL
extern int ipfr_timer_id;
#endif
-#if SOLARIS && defined(_KERNEL)
+#if (SOLARIS || defined(__sgi)) && defined(_KERNEL)
extern kmutex_t ipf_frag;
extern kmutex_t ipf_natfrag;
extern kmutex_t ipf_nat;
@@ -120,7 +127,6 @@ ipfr_t *table[];
if (!bcmp((char *)&frag.ipfr_src, (char *)&fr->ipfr_src,
IPFR_CMPSZ)) {
ipfr_stats.ifs_exists++;
- MUTEX_EXIT(&ipf_frag);
return NULL;
}
@@ -131,7 +137,6 @@ ipfr_t *table[];
KMALLOC(fr, ipfr_t *, sizeof(*fr));
if (fr == NULL) {
ipfr_stats.ifs_nomem++;
- MUTEX_EXIT(&ipf_frag);
return NULL;
}
@@ -183,7 +188,7 @@ nat_t *nat;
MUTEX_ENTER(&ipf_natfrag);
if ((ipf = ipfr_new(ip, fin, pass, ipfr_nattab))) {
ipf->ipfr_data = nat;
- nat->nat_frag = ipf;
+ nat->nat_data = ipf;
}
MUTEX_EXIT(&ipf_natfrag);
return ipf ? 0 : -1;
@@ -201,7 +206,6 @@ ipfr_t *table[];
{
ipfr_t *f, frag;
u_int idx;
- int ret;
/*
* For fragments, we record protocol, packet id, TOS and both IP#'s
@@ -242,16 +246,16 @@ ipfr_t *table[];
table[idx] = f;
}
off = ip->ip_off;
- atoff = (off & 0x1fff) - (fin->fin_dlen >> 3);
+ atoff = off + (fin->fin_dlen >> 3);
/*
* If we've follwed the fragments, and this is the
* last (in order), shrink expiration time.
*/
- if (atoff == f->ipfr_off) {
+ if ((off & 0x1fff) == f->ipfr_off) {
if (!(off & IP_MF))
f->ipfr_ttl = 1;
else
- f->ipfr_off = off;
+ f->ipfr_off = atoff;
}
ipfr_stats.ifs_hits++;
return f;
@@ -261,7 +265,7 @@ ipfr_t *table[];
/*
- * functional interface for normal lookups of the fragment cache
+ * functional interface for NAT lookups of the NAT fragment cache
*/
nat_t *ipfr_nat_knownfrag(ip, fin)
ip_t *ip;
@@ -271,15 +275,25 @@ fr_info_t *fin;
ipfr_t *ipf;
MUTEX_ENTER(&ipf_natfrag);
- ipf = ipfr_lookup(ip, fin, ipfr_heads);
- nat = ipf ? ipf->ipfr_data : NULL;
+ ipf = ipfr_lookup(ip, fin, ipfr_nattab);
+ if (ipf) {
+ nat = ipf->ipfr_data;
+ /*
+ * This is the last fragment for this packet.
+ */
+ if (ipf->ipfr_ttl == 1) {
+ nat->nat_data = NULL;
+ ipf->ipfr_data = NULL;
+ }
+ } else
+ nat = NULL;
MUTEX_EXIT(&ipf_natfrag);
return nat;
}
/*
- * functional interface for NAT lookups of the NAT fragment cache
+ * functional interface for normal lookups of the fragment cache
*/
int ipfr_knownfrag(ip, fin)
ip_t *ip;
@@ -297,6 +311,25 @@ fr_info_t *fin;
/*
+ * forget any references to this external object.
+ */
+void ipfr_forget(nat)
+void *nat;
+{
+ ipfr_t *fr;
+ int idx;
+
+ MUTEX_ENTER(&ipf_natfrag);
+ for (idx = IPFT_SIZE - 1; idx >= 0; idx--)
+ for (fr = ipfr_heads[idx]; fr; fr = fr->ipfr_next)
+ if (fr->ipfr_data == nat)
+ fr->ipfr_data = NULL;
+
+ MUTEX_EXIT(&ipf_natfrag);
+}
+
+
+/*
* Free memory in use by fragment state info. kept.
*/
void ipfr_unload()
@@ -304,11 +337,7 @@ void ipfr_unload()
ipfr_t **fp, *fr;
nat_t *nat;
int idx;
-#if !SOLARIS && defined(_KERNEL)
- int s;
-#endif
- SPLNET(s);
MUTEX_ENTER(&ipf_frag);
for (idx = IPFT_SIZE - 1; idx >= 0; idx--)
for (fp = &ipfr_heads[idx]; (fr = *fp); ) {
@@ -323,14 +352,13 @@ void ipfr_unload()
for (fp = &ipfr_nattab[idx]; (fr = *fp); ) {
*fp = fr->ipfr_next;
if ((nat = (nat_t *)fr->ipfr_data)) {
- if (nat->nat_frag == fr)
- nat->nat_frag = NULL;
+ if (nat->nat_data == fr)
+ nat->nat_data = NULL;
}
KFREE(fr);
}
MUTEX_EXIT(&ipf_natfrag);
MUTEX_EXIT(&ipf_nat);
- SPLX(s);
}
@@ -339,7 +367,7 @@ void ipfr_unload()
* Slowly expire held state for fragments. Timeouts are set * in expectation
* of this being called twice per second.
*/
-# if (BSD >= 199306) || SOLARIS
+# if (BSD >= 199306) || SOLARIS || defined(__sgi)
void ipfr_slowtimer()
# else
int ipfr_slowtimer()
@@ -349,8 +377,12 @@ int ipfr_slowtimer()
nat_t *nat;
int s, idx;
+#ifdef __sgi
+ ipfilter_sgi_intfsync();
+#endif
+
+ SPL_NET(s);
MUTEX_ENTER(&ipf_frag);
- SPLNET(s);
/*
* Go through the entire table, looking for entries to expire,
@@ -399,8 +431,8 @@ int ipfr_slowtimer()
ipfr_stats.ifs_expire++;
ipfr_inuse--;
if ((nat = (nat_t *)fr->ipfr_data)) {
- if (nat->nat_frag == fr)
- nat->nat_frag = NULL;
+ if (nat->nat_data == fr)
+ nat->nat_data = NULL;
}
KFREE(fr);
} else
@@ -408,16 +440,17 @@ int ipfr_slowtimer()
}
MUTEX_EXIT(&ipf_natfrag);
MUTEX_EXIT(&ipf_nat);
- SPLX(s);
-# if SOLARIS
+ SPL_X(s);
fr_timeoutstate();
ip_natexpire();
+ fr_authexpire();
+# if SOLARIS
ipfr_timer_id = timeout(ipfr_slowtimer, NULL, drv_usectohz(500000));
# else
- fr_timeoutstate();
- ip_natexpire();
+# ifndef linux
ip_slowtimo();
-# if BSD < 199306
+# endif
+# if (BSD < 199306) && !defined(__sgi)
return 0;
# endif
# endif
diff --git a/contrib/ipfilter/ip_frag.h b/contrib/ipfilter/ip_frag.h
index df275babb318..ade7139e4933 100644
--- a/contrib/ipfilter/ip_frag.h
+++ b/contrib/ipfilter/ip_frag.h
@@ -1,12 +1,12 @@
/*
- * (C)opyright 1993-1997 by Darren Reed.
+ * Copyright (C) 1993-1997 by Darren Reed.
*
* Redistribution and use in source and binary forms are permitted
* provided that this notice is preserved and due credit is given
* to the original author and the contributors.
*
* @(#)ip_frag.h 1.5 3/24/96
- * $Id: ip_frag.h,v 2.0.2.7 1997/05/08 10:10:18 darrenr Exp $
+ * $Id: ip_frag.h,v 2.0.2.12 1997/10/23 14:56:01 darrenr Exp $
*/
#ifndef __IP_FRAG_H__
@@ -41,14 +41,16 @@ typedef struct ipfrstat {
#define IPFR_CMPSZ (4 + 4 + 2 + 1 + 1)
-extern ipfrstat_t *ipfr_fragstats __P((void));
-extern int ipfr_newfrag __P((ip_t *, fr_info_t *, int));
-extern int ipfr_nat_newfrag __P((ip_t *, fr_info_t *, int, struct nat *));
-extern nat_t *ipfr_nat_knownfrag __P((ip_t *, fr_info_t *));
-extern int ipfr_knownfrag __P((ip_t *, fr_info_t *));
-extern void ipfr_unload __P((void));
+extern int fr_ipfrttl;
+extern ipfrstat_t *ipfr_fragstats __P((void));
+extern int ipfr_newfrag __P((ip_t *, fr_info_t *, int));
+extern int ipfr_nat_newfrag __P((ip_t *, fr_info_t *, int, struct nat *));
+extern nat_t *ipfr_nat_knownfrag __P((ip_t *, fr_info_t *));
+extern int ipfr_knownfrag __P((ip_t *, fr_info_t *));
+extern void ipfr_forget __P((void *));
+extern void ipfr_unload __P((void));
-#if (BSD >= 199306) || SOLARIS
+#if (BSD >= 199306) || SOLARIS || defined(__sgi)
extern void ipfr_slowtimer __P((void));
#else
extern int ipfr_slowtimer __P((void));
diff --git a/contrib/ipfilter/ip_ftp_pxy.c b/contrib/ipfilter/ip_ftp_pxy.c
index 48196e97fd0f..5d6ce1fc002d 100644
--- a/contrib/ipfilter/ip_ftp_pxy.c
+++ b/contrib/ipfilter/ip_ftp_pxy.c
@@ -1,5 +1,6 @@
/*
- * Simple FTP transparent proxy for in-kernel.
+ * Simple FTP transparent proxy for in-kernel use. For use with the NAT
+ * code.
*/
#define isdigit(x) ((x) >= '0' && (x) <= '9')
@@ -10,6 +11,29 @@
#define IPF_MAXPORTLEN 30
+int ippr_ftp_init __P((fr_info_t *, ip_t *, tcphdr_t *,
+ ap_session_t *, nat_t *));
+int ippr_ftp_in __P((fr_info_t *, ip_t *, tcphdr_t *,
+ ap_session_t *, nat_t *));
+int ippr_ftp_out __P((fr_info_t *, ip_t *, tcphdr_t *,
+ ap_session_t *, nat_t *));
+u_short ipf_ftp_atoi __P((char **));
+
+
+int ippr_ftp_init __P((fr_info_t *, ip_t *, tcphdr_t *, ap_session_t *,
+ nat_t *));
+int ippr_ftp_in __P((fr_info_t *, ip_t *, tcphdr_t *, ap_session_t *,
+ nat_t *));
+int ippr_ftp_out __P((fr_info_t *, ip_t *, tcphdr_t *, ap_session_t *,
+ nat_t *));
+
+u_short ipf_ftp_atoi __P((char **));
+
+
+
+/*
+ * FTP application proxy initialization.
+ */
int ippr_ftp_init(fin, ip, tcp, aps, nat)
fr_info_t *fin;
ip_t *ip;
@@ -30,13 +54,18 @@ tcphdr_t *tcp;
ap_session_t *aps;
nat_t *nat;
{
- int ch = 0;
u_long sum1, sum2;
+ short sel;
- if (tcp->th_dport != aps->aps_dport) {
+ if (tcp->th_sport == aps->aps_dport) {
sum2 = (u_long)ntohl(tcp->th_ack);
- if (aps->aps_seqoff && (sum2 > aps->aps_after)) {
- sum1 = (u_long)aps->aps_seqoff;
+ sel = aps->aps_sel;
+ if ((aps->aps_after[!sel] > aps->aps_after[sel]) &&
+ (sum2 > aps->aps_after[!sel])) {
+ sel = aps->aps_sel = !sel; /* switch to other set */
+ }
+ if (aps->aps_seqoff[sel] && (sum2 > aps->aps_after[sel])) {
+ sum1 = (u_long)aps->aps_seqoff[sel];
tcp->th_ack = htonl(sum2 - sum1);
return 2;
}
@@ -45,6 +74,12 @@ nat_t *nat;
}
+/*
+ * ipf_ftp_atoi - implement a version of atoi which processes numbers in
+ * pairs separated by commas (which are expected to be in the range 0 - 255),
+ * returning a 16 bit number combining either side of the , as the MSB and
+ * LSB.
+ */
u_short ipf_ftp_atoi(ptr)
char **ptr;
{
@@ -75,42 +110,38 @@ tcphdr_t *tcp;
ap_session_t *aps;
nat_t *nat;
{
- register u_long sum1, sum2, sumd;
+ register u_long sum1, sum2;
char newbuf[IPF_MAXPORTLEN+1];
- char portbuf[IPF_MAXPORTLEN+1], *s, c;
- int ch = 0, off = (ip->ip_hl << 2) + (tcp->th_off << 2), len;
+ char portbuf[IPF_MAXPORTLEN+1], *s;
+ int ch = 0, off = (ip->ip_hl << 2) + (tcp->th_off << 2);
u_int a1, a2, a3, a4;
u_short a5, a6;
- int olen, dlen, nlen, inc = 0, blen;
+ int olen, dlen, nlen = 0, inc = 0;
tcphdr_t tcph, *tcp2 = &tcph;
void *savep;
nat_t *ipn;
struct in_addr swip;
+ mb_t *m = *(mb_t **)fin->fin_mp;
+
#if SOLARIS
- mblk_t *m1, *m = *(mblk_t **)fin->fin_mp;
+ mb_t *m1;
- dlen = m->b_wptr - m->b_rptr - off;
- blen = m->b_datap->db_lim - m->b_datap->db_base;
+ /* skip any leading M_PROTOs */
+ while(m && (MTYPE(m) != M_DATA))
+ m = m->b_cont;
+ PANIC((!m),("ippr_ftp_out: no M_DATA"));
+
+ dlen = msgdsize(m) - off;
bzero(portbuf, sizeof(portbuf));
- copyout_mblk(m, off, portbuf, MIN(sizeof(portbuf), dlen));
+ copyout_mblk(m, off, MIN(sizeof(portbuf), dlen), portbuf);
#else
- struct mbuf *m1, *m = *(struct mbuf **)fin->fin_mp;
-
- dlen = m->m_len - off;
-# if BSD >= 199306
- blen = (MLEN - m->m_len) - (m->m_data - m->m_dat);
-# else
- blen = (MLEN - m->m_len) - m->m_off;
-# endif
- if (blen < 0)
- panic("blen < 0 - size of mblk/mbuf wrong");
+ dlen = mbufchainlen(m) - off;
bzero(portbuf, sizeof(portbuf));
m_copydata(m, off, MIN(sizeof(portbuf), dlen), portbuf);
#endif
portbuf[IPF_MAXPORTLEN] = '\0';
- len = MIN(32, dlen);
- if ((len < IPF_MINPORTLEN) || strncmp(portbuf, "PORT ", 5))
+ if ((dlen < IPF_MINPORTLEN) || strncmp(portbuf, "PORT ", 5))
goto adjust_seqack;
/*
@@ -149,30 +180,48 @@ nat_t *nat;
a1, a2, a3, a4, a5, a6);
nlen = strlen(newbuf);
inc = nlen - olen;
- if (tcp->th_seq > aps->aps_after) {
- aps->aps_after = ntohl(tcp->th_seq) + dlen;
- aps->aps_seqoff += inc;
- }
#if SOLARIS
- if (inc && dlen)
- if ((inc < 0) || (blen >= dlen)) {
- bcopy(m->b_rptr + off,
- m->b_rptr + off + aps->aps_seqoff, dlen);
- }
for (m1 = m; m1->b_cont; m1 = m1->b_cont)
;
- m1->b_wptr += inc;
- copyin_mblk(m, off, newbuf, strlen(newbuf));
+ if (inc > 0) {
+ mblk_t *nm;
+
+ /* alloc enough to keep same trailer space for lower driver */
+ nm = allocb(nlen + m1->b_datap->db_lim - m1->b_wptr, BPRI_MED);
+ PANIC((!nm),("ippr_ftp_out: allocb failed"));
+
+ nm->b_band = m1->b_band;
+ nm->b_wptr += nlen;
+
+ m1->b_wptr -= olen;
+ PANIC((m1->b_wptr < m1->b_rptr),("ippr_ftp_out: cannot handle fragmented data block"));
+
+ linkb(m1, nm);
+ } else {
+ m1->b_wptr += inc;
+ }
+ copyin_mblk(m, off, nlen, newbuf);
#else
- if (inc && dlen)
- if ((inc < 0) || (blen >= dlen)) {
- bcopy((char *)ip + off,
- (char *)ip + off + aps->aps_seqoff, dlen);
- }
- m->m_len += inc;
+ if (inc < 0)
+ m_adj(m, inc);
+ /* the mbuf chain will be extended if necessary by m_copyback() */
m_copyback(m, off, nlen, newbuf);
#endif
- ip->ip_len += inc;
+ if (inc) {
+#if SOLARIS || defined(__sgi)
+ sum1 = ip->ip_len;
+ sum2 = ip->ip_len + inc;
+
+ /* Because ~1 == -2, We really need ~1 == -1 */
+ if (sum1 > sum2)
+ sum2--;
+ sum2 -= sum1;
+ sum2 = (sum2 & 0xffff) + (sum2 >> 16);
+
+ fix_outcksum(&ip->ip_sum, sum2);
+#endif
+ ip->ip_len += inc;
+ }
ch = 1;
/*
@@ -181,24 +230,40 @@ nat_t *nat;
*/
savep = fin->fin_dp;
fin->fin_dp = (char *)tcp2;
+ bzero((char *)tcp2, sizeof(*tcp2));
tcp2->th_sport = htons(a5 << 8 | a6);
tcp2->th_dport = htons(20);
swip = ip->ip_src;
ip->ip_src = nat->nat_inip;
if ((ipn = nat_new(nat->nat_ptr, ip, fin, IPN_TCP, NAT_OUTBOUND)))
ipn->nat_age = fr_defnatage;
+ (void) fr_addstate(ip, fin, FR_INQUE|FR_PASS|FR_QUICK|FR_KEEPSTATE);
ip->ip_src = swip;
fin->fin_dp = (char *)savep;
adjust_seqack:
if (tcp->th_dport == aps->aps_dport) {
sum2 = (u_long)ntohl(tcp->th_seq);
- if (aps->aps_seqoff && (sum2 > aps->aps_after)) {
- sum1 = (u_long)aps->aps_seqoff;
- tcp->th_seq = htonl(sum2 + sum1);
- ch = 1;
+ off = aps->aps_sel;
+ if ((aps->aps_after[!off] > aps->aps_after[off]) &&
+ (sum2 > aps->aps_after[!off])) {
+ off = aps->aps_sel = !off; /* switch to other set */
+ }
+ if (aps->aps_seqoff[off]) {
+ sum1 = (u_long)aps->aps_after[off] -
+ aps->aps_seqoff[off];
+ if (sum2 > sum1) {
+ sum1 = (u_long)aps->aps_seqoff[off];
+ sum2 += sum1;
+ tcp->th_seq = htonl(sum2);
+ ch = 1;
+ }
}
- }
+ if (inc && (sum2 > aps->aps_after[!off])) {
+ aps->aps_after[!off] = sum2 + nlen - 1;
+ aps->aps_seqoff[!off] = aps->aps_seqoff[off] + inc;
+ }
+ }
return ch ? 2 : 0;
}
diff --git a/contrib/ipfilter/ip_lfil.c b/contrib/ipfilter/ip_lfil.c
new file mode 100644
index 000000000000..364bb305449a
--- /dev/null
+++ b/contrib/ipfilter/ip_lfil.c
@@ -0,0 +1,993 @@
+/*
+ * Copyright (C) 1993-1997 by Darren Reed.
+ *
+ * Redistribution and use in source and binary forms are permitted
+ * provided that this notice is preserved and due credit is given
+ * to the original author and the contributors.
+ */
+#if !defined(lint)
+static const char rcsid[] = "@(#)$Id: ip_lfil.c,v 2.0.2.1 1997/11/12 10:36:27 darrenr Exp $";
+#endif
+
+#if defined(KERNEL) && !defined(_KERNEL)
+# define _KERNEL
+#endif
+#ifndef _KERNEL
+# include <stdio.h>
+# include <string.h>
+# include <stdlib.h>
+# include <ctype.h>
+#else
+# include <linux/module.h>
+#endif
+#include <sys/errno.h>
+#include <sys/types.h>
+#include <sys/param.h>
+#include <sys/file.h>
+#include <sys/ioctl.h>
+#include <sys/time.h>
+#include <sys/uio.h>
+#include <sys/dir.h>
+#include <sys/socket.h>
+
+#include <net/if.h>
+#include <net/route.h>
+#include <netinet/in.h>
+#include <netinet/in_systm.h>
+#include <netinet/ip.h>
+#include <netinet/tcp.h>
+#include <netinet/udp.h>
+#include <netinet/ip_icmp.h>
+#ifndef _KERNEL
+# include <syslog.h>
+#endif
+#include "netinet/ip_compat.h"
+#include <netinet/tcpip.h>
+#include "netinet/ip_fil.h"
+#include "netinet/ip_proxy.h"
+#include "netinet/ip_nat.h"
+#include "netinet/ip_frag.h"
+#include "netinet/ip_state.h"
+#include "netinet/ip_auth.h"
+#ifndef MIN
+#define MIN(a,b) (((a)<(b))?(a):(b))
+#endif
+
+
+#ifndef _KERNEL
+# include "ipt.h"
+static struct ifnet **ifneta = NULL;
+static int nifs = 0;
+#endif
+
+int ipl_inited = 0;
+int ipl_unreach = ICMP_UNREACH_FILTER;
+u_long ipl_frouteok[2] = {0, 0};
+
+static void fixskip __P((frentry_t **, frentry_t *, int));
+static int frzerostats __P((caddr_t));
+static void frsync __P((void));
+#if defined(__NetBSD__) || defined(__OpenBSD__)
+static int frrequest __P((int, u_long, caddr_t, int));
+#else
+static int frrequest __P((int, u_long, caddr_t, int));
+#endif
+#ifdef _KERNEL
+static int (*fr_savep) __P((ip_t *, int, void *, int, mb_t **));
+#else
+int ipllog __P((void));
+void init_ifp __P((void));
+static int no_output __P((mb_t *, struct ifnet *));
+static int write_output __P((mb_t *, struct ifnet *));
+#endif
+
+#ifdef _KERNEL
+
+int fr_precheck(struct iphdr *ip, struct device *dev, int out, struct device **ifp)
+{
+ int hlen = ip->ihl << 2;
+
+ return fr_check((ip_t *)ip, hlen, dev, out, (mb_t **)ifp);
+}
+
+
+int iplattach()
+{
+ char *defpass;
+ int s;
+
+ if (ipl_inited || (fr_checkp == fr_precheck)) {
+ printk("IP Filter: already initialized\n");
+ return EBUSY;
+ }
+
+ ipl_inited = 1;
+ bzero((char *)frcache, sizeof(frcache));
+ bzero((char *)nat_table, sizeof(nat_table));
+ fr_savep = fr_checkp;
+ fr_checkp = fr_precheck;
+
+# ifdef IPFILTER_LOG
+ ipflog_init();
+# endif
+ if (fr_pass & FR_PASS)
+ defpass = "pass";
+ else if (fr_pass & FR_BLOCK)
+ defpass = "block";
+ else
+ defpass = "no-match -> block";
+
+ printk("IP Filter: initialized. Default = %s all, Logging = %s\n",
+ defpass,
+# ifdef IPFILTER_LOG
+ "enabled");
+# else
+ "disabled");
+# endif
+ return 0;
+}
+
+
+/*
+ * Disable the filter by removing the hooks from the IP input/output
+ * stream.
+ */
+int ipldetach()
+{
+ int s, i = FR_INQUE|FR_OUTQUE;
+
+ if (!ipl_inited)
+ {
+ printk("IP Filter: not initialized\n");
+ return 0;
+ }
+
+ fr_checkp = fr_savep;
+ frflush(IPL_LOGIPF, (caddr_t)&i);
+ ipl_inited = 0;
+
+ ipfr_unload();
+ ip_natunload();
+ fr_stateunload();
+ fr_authunload();
+
+ printk("IP Filter: unloaded\n");
+
+ return 0;
+}
+#endif /* _KERNEL */
+
+
+static int frzerostats(data)
+caddr_t data;
+{
+ struct friostat fio;
+ int error;
+
+ bcopy((char *)frstats, (char *)fio.f_st,
+ sizeof(struct filterstats) * 2);
+ fio.f_fin[0] = ipfilter[0][0];
+ fio.f_fin[1] = ipfilter[0][1];
+ fio.f_fout[0] = ipfilter[1][0];
+ fio.f_fout[1] = ipfilter[1][1];
+ fio.f_acctin[0] = ipacct[0][0];
+ fio.f_acctin[1] = ipacct[0][1];
+ fio.f_acctout[0] = ipacct[1][0];
+ fio.f_acctout[1] = ipacct[1][1];
+ fio.f_active = fr_active;
+ fio.f_froute[0] = ipl_frouteok[0];
+ fio.f_froute[1] = ipl_frouteok[1];
+ IWCOPY((caddr_t)&fio, data, sizeof(fio));
+ bzero((char *)frstats, sizeof(*frstats) * 2);
+ return error;
+}
+
+
+/*
+ * Filter ioctl interface.
+ */
+#if defined(_KERNEL)
+int iplioctl(struct inode *inode, struct file *file, u_int cmd, u_long arg)
+{
+ int s;
+ caddr_t data = (caddr_t)arg;
+
+ int mode = file->f_mode;
+#else
+int iplioctl(dev_t dev, int cmd, caddr_t data, int mode)
+{
+#endif
+ int error = 0, unit = 0;
+
+#ifdef _KERNEL
+ unit = GET_MINOR(inode->i_rdev);
+ if ((IPL_LOGMAX < unit) || (unit < 0))
+ return ENXIO;
+#endif
+
+ if (unit == IPL_LOGNAT) {
+ error = nat_ioctl(data, cmd, mode);
+ return error;
+ }
+ if (unit == IPL_LOGSTATE) {
+ error = fr_state_ioctl(data, cmd, mode);
+ return error;
+ }
+
+ switch (cmd) {
+ case FIONREAD :
+#ifdef IPFILTER_LOG
+ IWCOPY((caddr_t)&iplused[IPL_LOGIPF], data,
+ sizeof(iplused[IPL_LOGIPF]));
+#endif
+ break;
+#if !defined(IPFILTER_LKM) && defined(_KERNEL)
+ case SIOCFRENB :
+ {
+ u_int enable;
+
+ if (!(mode & FWRITE))
+ error = EPERM;
+ else {
+ IRCOPY(data, (caddr_t)&enable, sizeof(enable));
+ if (error)
+ break;
+ if (enable)
+ error = iplattach();
+ else
+ error = ipldetach();
+ }
+ break;
+ }
+#endif
+ case SIOCSETFF :
+ if (!(mode & FWRITE))
+ error = EPERM;
+ else
+ IRCOPY(data, (caddr_t)&fr_flags, sizeof(fr_flags));
+ break;
+ case SIOCGETFF :
+ IWCOPY((caddr_t)&fr_flags, data, sizeof(fr_flags));
+ break;
+ case SIOCINAFR :
+ case SIOCRMAFR :
+ case SIOCADAFR :
+ case SIOCZRLST :
+ if (!(mode & FWRITE))
+ error = EPERM;
+ else
+ error = frrequest(unit, cmd, data, fr_active);
+ break;
+ case SIOCINIFR :
+ case SIOCRMIFR :
+ case SIOCADIFR :
+ if (!(mode & FWRITE))
+ error = EPERM;
+ else
+ error = frrequest(unit, cmd, data, 1 - fr_active);
+ break;
+ case SIOCSWAPA :
+ if (!(mode & FWRITE))
+ error = EPERM;
+ else {
+ bzero((char *)frcache, sizeof(frcache[0]) * 2);
+ *(u_int *)data = fr_active;
+ fr_active = 1 - fr_active;
+ }
+ break;
+ case SIOCGETFS :
+ {
+ struct friostat fio;
+
+ bcopy((char *)frstats, (char *)fio.f_st,
+ sizeof(struct filterstats) * 2);
+ fio.f_fin[0] = ipfilter[0][0];
+ fio.f_fin[1] = ipfilter[0][1];
+ fio.f_fout[0] = ipfilter[1][0];
+ fio.f_fout[1] = ipfilter[1][1];
+ fio.f_acctin[0] = ipacct[0][0];
+ fio.f_acctin[1] = ipacct[0][1];
+ fio.f_acctout[0] = ipacct[1][0];
+ fio.f_acctout[1] = ipacct[1][1];
+ fio.f_auth = ipauth;
+ fio.f_active = fr_active;
+ fio.f_froute[0] = ipl_frouteok[0];
+ fio.f_froute[1] = ipl_frouteok[1];
+ IWCOPY((caddr_t)&fio, data, sizeof(fio));
+ break;
+ }
+ case SIOCFRZST :
+ if (!(mode & FWRITE))
+ error = EPERM;
+ else
+ frzerostats(data);
+ break;
+ case SIOCIPFFL :
+ if (!(mode & FWRITE))
+ error = EPERM;
+ else
+ frflush(unit, data);
+ break;
+#ifdef IPFILTER_LOG
+ case SIOCIPFFB :
+ if (!(mode & FWRITE))
+ error = EPERM;
+ else
+ *(int *)data = ipflog_clear(unit);
+ break;
+#endif /* IPFILTER_LOG */
+ case SIOCGFRST :
+ IWCOPY((caddr_t)ipfr_fragstats(), data, sizeof(ipfrstat_t));
+ break;
+ case SIOCAUTHW :
+ case SIOCAUTHR :
+ if (!(mode & FWRITE)) {
+ error = EPERM;
+ break;
+ }
+ case SIOCATHST :
+ error = fr_auth_ioctl(data, cmd, NULL, NULL);
+ break;
+ case SIOCFRSYN :
+ if (!(mode & FWRITE))
+ error = EPERM;
+ else {
+#if defined(_KERNEL) && defined(__sgi)
+ ipfsync();
+#endif
+ frsync();
+ }
+ break;
+ default :
+ error = EINVAL;
+ break;
+ }
+ return error;
+}
+
+
+static void frsync()
+{
+#ifdef _KERNEL
+ struct device *dev;
+
+ for (dev = dev_base; dev; dev = dev->next)
+ ip_natsync(dev);
+#endif
+}
+
+
+static void fixskip(listp, rp, addremove)
+frentry_t **listp, *rp;
+int addremove;
+{
+ frentry_t *fp;
+ int rules = 0, rn = 0;
+
+ for (fp = *listp; fp && (fp != rp); fp = fp->fr_next, rules++)
+ ;
+
+ if (!fp)
+ return;
+
+ for (fp = *listp; fp && (fp != rp); fp = fp->fr_next, rn++)
+ if (fp->fr_skip && (rn + fp->fr_skip >= rules))
+ fp->fr_skip += addremove;
+}
+
+
+static int frrequest(unit, req, data, set)
+int unit;
+u_long req;
+int set;
+caddr_t data;
+{
+ register frentry_t *fp, *f, **fprev;
+ register frentry_t **ftail;
+ frentry_t frd;
+ frdest_t *fdp;
+ frgroup_t *fg = NULL;
+ int error = 0, in, group;
+
+ fp = &frd;
+ IRCOPY(data, (caddr_t)fp, sizeof(*fp));
+ if (error)
+ return error;
+
+ /*
+ * Check that the group number does exist and that if a head group
+ * has been specified, doesn't exist.
+ */
+ if (fp->fr_grhead &&
+ fr_findgroup(fp->fr_grhead, fp->fr_flags, unit, set, NULL))
+ return EEXIST;
+ if (fp->fr_group &&
+ !fr_findgroup(fp->fr_group, fp->fr_flags, unit, set, NULL))
+ return ESRCH;
+
+ in = (fp->fr_flags & FR_INQUE) ? 0 : 1;
+
+ if (unit == IPL_LOGAUTH)
+ ftail = fprev = &ipauth;
+ else if (fp->fr_flags & FR_ACCOUNT)
+ ftail = fprev = &ipacct[in][set];
+ else if (fp->fr_flags & (FR_OUTQUE|FR_INQUE))
+ ftail = fprev = &ipfilter[in][set];
+ else
+ return ESRCH;
+
+ if ((group = fp->fr_group)) {
+ if (!(fg = fr_findgroup(group, fp->fr_flags, unit, set, NULL)))
+ return ESRCH;
+ ftail = fprev = fg->fg_start;
+ }
+
+ bzero((char *)frcache, sizeof(frcache[0]) * 2);
+
+ if (*fp->fr_ifname) {
+ fp->fr_ifa = GETUNIT(fp->fr_ifname);
+ if (!fp->fr_ifa)
+ fp->fr_ifa = (void *)-1;
+ }
+
+ fdp = &fp->fr_dif;
+ fp->fr_flags &= ~FR_DUP;
+ if (*fdp->fd_ifname) {
+ fdp->fd_ifp = GETUNIT(fdp->fd_ifname);
+ if (!fdp->fd_ifp)
+ fdp->fd_ifp = (struct ifnet *)-1;
+ else
+ fp->fr_flags |= FR_DUP;
+ }
+
+ fdp = &fp->fr_tif;
+ if (*fdp->fd_ifname) {
+ fdp->fd_ifp = GETUNIT(fdp->fd_ifname);
+ if (!fdp->fd_ifp)
+ fdp->fd_ifp = (struct ifnet *)-1;
+ }
+
+ /*
+ * Look for a matching filter rule, but don't include the next or
+ * interface pointer in the comparison (fr_next, fr_ifa).
+ */
+ for (; (f = *ftail); ftail = &f->fr_next)
+ if (bcmp((char *)&f->fr_ip, (char *)&fp->fr_ip,
+ FR_CMPSIZ) == 0)
+ break;
+
+ /*
+ * If zero'ing statistics, copy current to caller and zero.
+ */
+ if (req == SIOCZRLST) {
+ if (!f)
+ return ESRCH;
+ IWCOPY((caddr_t)f, data, sizeof(*f));
+ if (error)
+ return error;
+ f->fr_hits = 0;
+ f->fr_bytes = 0;
+ return 0;
+ }
+
+ if (!f) {
+ ftail = fprev;
+ if (req != SIOCINAFR && req != SIOCINIFR)
+ while ((f = *ftail))
+ ftail = &f->fr_next;
+ else if (fp->fr_hits)
+ while (--fp->fr_hits && (f = *ftail))
+ ftail = &f->fr_next;
+ f = NULL;
+ }
+
+ if (req == SIOCDELFR || req == SIOCRMIFR) {
+ if (!f)
+ error = ESRCH;
+ else {
+ if (f->fr_ref > 1)
+ return EBUSY;
+ if (fg && fg->fg_head)
+ fg->fg_head->fr_ref--;
+ if (unit == IPL_LOGAUTH)
+ return fr_auth_ioctl(data, req, f, ftail);
+ if (f->fr_grhead)
+ fr_delgroup(f->fr_grhead, fp->fr_flags, unit,
+ set);
+ fixskip(fprev, f, -1);
+ *ftail = f->fr_next;
+ KFREE(f);
+ }
+ } else {
+ if (f)
+ error = EEXIST;
+ else {
+ if (unit == IPL_LOGAUTH)
+ return fr_auth_ioctl(data, req, f, ftail);
+ KMALLOC(f, frentry_t *, sizeof(*f));
+ if (f != NULL) {
+ if (fg && fg->fg_head)
+ fg->fg_head->fr_ref++;
+ bcopy((char *)fp, (char *)f, sizeof(*f));
+ f->fr_ref = 1;
+ f->fr_hits = 0;
+ f->fr_next = *ftail;
+ *ftail = f;
+ if (req == SIOCINIFR || req == SIOCINAFR)
+ fixskip(fprev, f, 1);
+ f->fr_grp = NULL;
+ if ((group = f->fr_grhead))
+ fg = fr_addgroup(group, f, unit, set);
+ } else
+ error = ENOMEM;
+ }
+ }
+ return (error);
+}
+
+
+#ifdef _KERNEL
+/*
+ * routines below for saving IP headers to buffer
+ */
+int iplopen(struct inode *inode, struct file *file)
+{
+ u_int min = GET_MINOR(inode->i_rdev);
+
+ if (2 < min)
+ min = ENXIO;
+ else {
+ MOD_INC_USE_COUNT;
+ min = 0;
+ }
+ return min;
+}
+
+
+void iplclose(struct inode *inode, struct file *file)
+{
+ u_int min = GET_MINOR(inode->i_rdev);
+
+ if (2 >= min) {
+ MOD_DEC_USE_COUNT;
+ }
+}
+
+/*
+ * iplread/ipllog
+ * both of these must operate with at least splnet() lest they be
+ * called during packet processing and cause an inconsistancy to appear in
+ * the filter lists.
+ */
+int iplread(struct inode *inode, struct file *file, char *buf, int nbytes)
+{
+ struct uio uiob, *uio = &uiob;
+
+ uio->uio_buf = buf;
+ uio->uio_resid = nbytes;
+# ifdef IPFILTER_LOG
+ return ipflog_read(GET_MINOR(inode->i_rdev), uio);
+# else
+ return ENXIO;
+# endif
+}
+
+
+/*
+ * send_reset - this could conceivably be a call to tcp_respond(), but that
+ * requires a large amount of setting up and isn't any more efficient.
+ */
+int send_reset(ti)
+struct tcpiphdr *ti;
+{
+#if notyet
+ struct tcpiphdr *tp;
+ tcphdr_t *tcp;
+ seq_t seq;
+ int tlen = 0;
+ ip_t *ip;
+ mb_t *m;
+
+ if (ti->ti_flags & TH_RST)
+ return -1; /* feedback loop */
+ m = alloc_skb(MAX_HEADER + sizeof(*ti), GFP_ATOMIC);
+ if (m == NULL)
+ return -1;
+
+ if (ti->ti_flags & TH_SYN)
+ tlen = 1;
+ m->m_len = sizeof (struct tcpiphdr);
+ bzero(mtod(m, char *), sizeof(struct tcpiphdr));
+ ip = mtod(m, ip_t *);
+ tp = mtod(m, struct tcpiphdr *);
+ tcp = (tcphdr_t *)((char *)ip + sizeof(struct ip));
+
+ ip->ip_src.s_addr = ti->ti_dst.s_addr;
+ ip->ip_dst.s_addr = ti->ti_src.s_addr;
+ tcp->th_dport = ti->ti_sport;
+ tcp->th_sport = ti->ti_dport;
+ seq = ntohl(ti->ti_seq);
+ tcp->th_ack = htonl(seq + tlen);
+ tcp->th_off = sizeof(tcphdr_t) >> 2;
+ tcp->th_flags = TH_RST|TH_ACK;
+ tp->ti_pr = ((ip_t *)ti)->ip_p;
+ tp->ti_len = htons(sizeof(struct tcphdr));
+ tcp->th_sum = in_cksum(m, sizeof(struct tcpiphdr));
+
+ ip->ip_tos = ((ip_t *)ti)->ip_tos;
+ ip->ip_p = ((ip_t *)ti)->ip_p;
+ ip->ip_len = sizeof (struct tcpiphdr);
+ ip->ip_ttl = 255;
+
+ /*
+ * extra 0 in case of multicast
+ */
+ (void) ip_output(m, (mb_t *)0, 0, 0, 0);
+ return 0;
+#endif
+}
+
+
+size_t mbufchainlen(m0)
+register mb_t *m0;
+{
+ register size_t len = 0;
+
+ for (; m0; m0 = m0->m_next)
+ len += m0->m_len;
+ return len;
+}
+
+
+void ipfr_fastroute(m0, fin, fdp)
+mb_t *m0;
+fr_info_t *fin;
+frdest_t *fdp;
+{
+#if notyet
+ register ip_t *ip, *mhip;
+ register mb_t *m = m0;
+ register struct route *ro;
+ struct ifnet *ifp = fdp->fd_ifp;
+ int len, off, error = 0;
+ int hlen = fin->fin_hlen;
+ struct route iproute;
+ struct sockaddr_in *dst;
+
+ ip = mtod(m0, ip_t *);
+ /*
+ * Route packet.
+ */
+ ro = &iproute;
+ bzero((caddr_t)ro, sizeof (*ro));
+ dst = (struct sockaddr_in *)&ro->ro_dst;
+ dst->sin_family = AF_INET;
+ dst->sin_addr = fdp->fd_ip.s_addr ? fdp->fd_ip : ip->ip_dst;
+ /*
+ * XXX -allocate route here
+ */
+ if (!ifp) {
+ if (!(fin->fin_fr->fr_flags & FR_FASTROUTE)) {
+ error = -2;
+ goto bad;
+ }
+ if (ro->ro_rt == 0 || (ifp = ro->ro_rt->rt_ifp) == 0) {
+ if (in_localaddr(ip->ip_dst))
+ error = EHOSTUNREACH;
+ else
+ error = ENETUNREACH;
+ goto bad;
+ }
+ if (ro->ro_rt->rt_flags & RTF_GATEWAY)
+ dst = (struct sockaddr_in *)&ro->ro_rt->rt_gateway;
+ }
+ ro->ro_rt->rt_use++;
+
+ /*
+ * For input packets which are being "fastrouted", they won't
+ * go back through output filtering and miss their chance to get
+ * NAT'd.
+ */
+ (void) ip_natout(ip, hlen, fin);
+ if (fin->fin_out)
+ ip->ip_sum = 0;
+ /*
+ * If small enough for interface, can just send directly.
+ */
+ if (ip->ip_len <= ifp->if_mtu) {
+# ifndef sparc
+ ip->ip_id = htons(ip->ip_id);
+ ip->ip_len = htons(ip->ip_len);
+ ip->ip_off = htons(ip->ip_off);
+# endif
+ if (!ip->ip_sum)
+ ip->ip_sum = in_cksum(m, hlen);
+ error = (*ifp->hard_start_xmit)(m, ifp, m);
+ goto done;
+ }
+ /*
+ * Too large for interface; fragment if possible.
+ * Must be able to put at least 8 bytes per fragment.
+ */
+ if (ip->ip_off & IP_DF) {
+ error = EMSGSIZE;
+ goto bad;
+ }
+ len = (ifp->if_mtu - hlen) &~ 7;
+ if (len < 8) {
+ error = EMSGSIZE;
+ goto bad;
+ }
+
+ {
+ int mhlen, firstlen = len;
+ mb_t **mnext = &m->m_act;
+
+ /*
+ * Loop through length of segment after first fragment,
+ * make new header and copy data of each part and link onto chain.
+ */
+ m0 = m;
+ mhlen = sizeof (struct ip);
+ for (off = hlen + len; off < ip->ip_len; off += len) {
+ MGET(m, M_DONTWAIT, MT_HEADER);
+ if (m == 0) {
+ error = ENOBUFS;
+ goto bad;
+ }
+ m->m_data += max_linkhdr;
+ mhip = mtod(m, struct ip *);
+ bcopy((char *)ip, (char *)mhip, sizeof(*ip));
+ if (hlen > sizeof (struct ip)) {
+ mhlen = ip_optcopy(ip, mhip) + sizeof (struct ip);
+ mhip->ip_hl = mhlen >> 2;
+ }
+ m->m_len = mhlen;
+ mhip->ip_off = ((off - hlen) >> 3) + (ip->ip_off & ~IP_MF);
+ if (ip->ip_off & IP_MF)
+ mhip->ip_off |= IP_MF;
+ if (off + len >= ip->ip_len)
+ len = ip->ip_len - off;
+ else
+ mhip->ip_off |= IP_MF;
+ mhip->ip_len = htons((u_short)(len + mhlen));
+ m->m_next = m_copy(m0, off, len);
+ if (m->m_next == 0) {
+ error = ENOBUFS; /* ??? */
+ goto sendorfree;
+ }
+# ifndef sparc
+ mhip->ip_off = htons((u_short)mhip->ip_off);
+# endif
+ mhip->ip_sum = 0;
+ mhip->ip_sum = in_cksum(m, mhlen);
+ *mnext = m;
+ mnext = &m->m_act;
+ }
+ /*
+ * Update first fragment by trimming what's been copied out
+ * and updating header, then send each fragment (in order).
+ */
+ m_adj(m0, hlen + firstlen - ip->ip_len);
+ ip->ip_len = htons((u_short)(hlen + firstlen));
+ ip->ip_off = htons((u_short)(ip->ip_off | IP_MF));
+ ip->ip_sum = 0;
+ ip->ip_sum = in_cksum(m0, hlen);
+sendorfree:
+ for (m = m0; m; m = m0) {
+ m0 = m->m_act;
+ m->m_act = 0;
+ if (error == 0)
+ error = (*ifp->if_output)(ifp, m,
+ (struct sockaddr *)dst);
+ else
+ m_freem(m);
+ }
+ }
+done:
+ if (!error)
+ ipl_frouteok[0]++;
+ else
+ ipl_frouteok[1]++;
+
+ if (ro->ro_rt) {
+ RTFREE(ro->ro_rt);
+ }
+ return;
+bad:
+ m_freem(m);
+ goto done;
+# endif
+}
+
+
+/*
+ * Fake BSD uiomove() call.
+ */
+int uiomove(caddr_t src, size_t ssize, int rw, struct uio *uio)
+{
+ int error;
+ size_t mv = MIN(ssize, uio->uio_resid);
+
+ if (rw == UIO_READ) {
+ IWCOPY(src, (caddr_t)uio->uio_buf, mv);
+ } else if (rw == UIO_WRITE) {
+ IRCOPY((caddr_t)uio->uio_buf, src, mv);
+ } else
+ error = EINVAL;
+ if (!error) {
+ uio->uio_resid -= mv;
+ uio->uio_buf += mv;
+ }
+ return error;
+}
+
+# ifdef IPFILTER_LKM
+# ifndef IPL_MAJOR
+# define IPL_MAJOR 95
+# endif
+
+# ifndef IPL_NAME
+# define IPL_NAME "/dev/ipl"
+# endif
+
+static struct file_operations ipl_fops = {
+ NULL, /* lseek */
+ iplread, /* read */
+ NULL, /* write */
+ NULL, /* readdir */
+ NULL, /* select */
+ iplioctl, /* ioctl */
+ NULL, /* mmap */
+ iplopen, /* open */
+ iplclose, /* release */
+ NULL, /* fsync */
+ NULL, /* fasync */
+ NULL, /* check_media_change */
+ NULL, /* revalidate */
+};
+
+
+int init_module(void)
+{
+ int error = 0, major;
+
+ if (register_chrdev(IPL_MAJOR, "ipf", &ipl_fops)) {
+ printk("ipf: unable to get major number: %d\n", IPL_MAJOR);
+ return -EIO;
+ }
+
+ error = iplattach();
+ if (!error)
+ register_symtab(0);
+ return -error;
+}
+
+void cleanup_module(void)
+{
+ unregister_chrdev(IPL_MAJOR, "ipf");
+ (void) ipldetach();
+}
+# endif /* IPFILTER_LKM */
+#else /* #ifdef _KERNEL */
+
+
+static int no_output __P((mb_t *m, struct ifnet *ifp))
+{
+ return 0;
+}
+
+
+static int write_output __P((mb_t *m, struct ifnet *ifp))
+{
+ FILE *fp;
+ char fname[32];
+ ip_t *ip;
+
+ ip = mtod(m, ip_t *);
+ sprintf(fname, "/tmp/%s", ifp->name);
+ if ((fp = fopen(fname, "a"))) {
+ fwrite((char *)ip, ntohs(ip->ip_len), 1, fp);
+ fclose(fp);
+ }
+ return 0;
+}
+
+
+struct ifnet *get_unit(name)
+char *name;
+{
+ struct ifnet *ifp, **ifa;
+ char ifname[32], *s;
+
+ for (ifa = ifneta; ifa && (ifp = *ifa); ifa++) {
+ (void) sprintf(ifname, "%s", ifp->name);
+ if (!strcmp(name, ifname))
+ return ifp;
+ }
+
+ if (!ifneta) {
+ ifneta = (struct ifnet **)malloc(sizeof(ifp) * 2);
+ ifneta[1] = NULL;
+ ifneta[0] = (struct ifnet *)calloc(1, sizeof(*ifp));
+ nifs = 1;
+ } else {
+ nifs++;
+ ifneta = (struct ifnet **)realloc(ifneta,
+ (nifs + 1) * sizeof(*ifa));
+ ifneta[nifs] = NULL;
+ ifneta[nifs - 1] = (struct ifnet *)malloc(sizeof(*ifp));
+ }
+ ifp = ifneta[nifs - 1];
+
+ for (s = name; *s && !isdigit(*s); s++)
+ ;
+ if (*s && isdigit(*s)) {
+ ifp->name = (char *)malloc(s - name + 1);
+ strncpy(ifp->name, name, s - name);
+ ifp->name[s - name] = '\0';
+ } else {
+ ifp->name = strdup(name);
+ }
+ ifp->hard_start_xmit = no_output;
+ return ifp;
+}
+
+
+
+void init_ifp()
+{
+ FILE *fp;
+ struct ifnet *ifp, **ifa;
+ char fname[32];
+
+ for (ifa = ifneta; ifa && (ifp = *ifa); ifa++) {
+ ifp->hard_start_xmit = write_output;
+ sprintf(fname, "/tmp/%s", ifp->name);
+ if ((fp = fopen(fname, "w")))
+ fclose(fp);
+ }
+}
+
+
+void ipfr_fastroute(ip, fin, fdp)
+ip_t *ip;
+fr_info_t *fin;
+frdest_t *fdp;
+{
+ struct ifnet *ifp = fdp->fd_ifp;
+
+ if (!ifp)
+ return; /* no routing table out here */
+
+ ip->ip_len = htons((u_short)ip->ip_len);
+ ip->ip_off = htons((u_short)(ip->ip_off | IP_MF));
+ ip->ip_sum = 0;
+ (*ifp->hard_start_xmit)((mb_t *)ip, ifp);
+}
+
+
+int ipllog __P((void))
+{
+ verbose("l");
+ return 0;
+}
+
+
+int send_reset(ip, ifp)
+ip_t *ip;
+struct ifnet *ifp;
+{
+ verbose("- TCP RST sent\n");
+ return 0;
+}
+
+
+int icmp_error(ip, ifp)
+ip_t *ip;
+struct ifnet *ifp;
+{
+ verbose("- TCP RST sent\n");
+ return 0;
+}
+#endif /* _KERNEL */
diff --git a/contrib/ipfilter/ip_log.c b/contrib/ipfilter/ip_log.c
new file mode 100644
index 000000000000..6440124c6f91
--- /dev/null
+++ b/contrib/ipfilter/ip_log.c
@@ -0,0 +1,473 @@
+/*
+ * Copyright (C) 1997 by Darren Reed.
+ *
+ * Redistribution and use in source and binary forms are permitted
+ * provided that this notice is preserved and due credit is given
+ * to the original author and the contributors.
+ *
+ * $Id: ip_log.c,v 2.0.2.13.2.2 1997/11/12 10:52:21 darrenr Exp $
+ */
+#ifdef IPFILTER_LOG
+# ifndef SOLARIS
+# define SOLARIS (defined(sun) && (defined(__svr4__) || defined(__SVR4)))
+# endif
+
+# ifdef __FreeBSD__
+# if defined(KERNEL) && !defined(_KERNEL)
+# define _KERNEL
+# endif
+# if defined(_KERNEL) && !defined(IPFILTER_LKM)
+# include <sys/osreldate.h>
+# else
+# include <osreldate.h>
+# endif
+# endif
+# ifndef _KERNEL
+# include <stdio.h>
+# include <string.h>
+# include <stdlib.h>
+# include <ctype.h>
+# endif
+# include <sys/errno.h>
+# include <sys/types.h>
+# include <sys/param.h>
+# include <sys/file.h>
+# if __FreeBSD_version >= 220000 && defined(_KERNEL)
+# include <sys/fcntl.h>
+# include <sys/filio.h>
+# else
+# include <sys/ioctl.h>
+# endif
+# include <sys/time.h>
+# if defined(_KERNEL) && !defined(linux)
+# include <sys/systm.h>
+# endif
+# include <sys/uio.h>
+# if !SOLARIS
+# if (NetBSD > 199609) || (OpenBSD > 199603)
+# include <sys/dirent.h>
+# else
+# include <sys/dir.h>
+# endif
+# ifndef linux
+# include <sys/mbuf.h>
+# endif
+# else
+# include <sys/filio.h>
+# include <sys/cred.h>
+# include <sys/ddi.h>
+# include <sys/sunddi.h>
+# include <sys/ksynch.h>
+# include <sys/kmem.h>
+# include <sys/mkdev.h>
+# include <sys/dditypes.h>
+# include <sys/cmn_err.h>
+# endif
+# ifndef linux
+# include <sys/protosw.h>
+# endif
+# include <sys/socket.h>
+
+# include <net/if.h>
+# ifdef sun
+# include <net/af.h>
+# endif
+# if __FreeBSD_version >= 300000
+# include <net/if_var.h>
+# endif
+# include <net/route.h>
+# include <netinet/in.h>
+# ifdef __sgi
+# include <sys/ddi.h>
+# ifdef IFF_DRVRLOCK /* IRIX6 */
+# include <sys/hashing.h>
+# endif
+# endif
+# if !defined(linux) && !(defined(__sgi) && !defined(IFF_DRVRLOCK)) /*IRIX<6*/
+# include <netinet/in_var.h>
+# endif
+# include <netinet/in_systm.h>
+# include <netinet/ip.h>
+# include <netinet/tcp.h>
+# include <netinet/udp.h>
+# include <netinet/ip_icmp.h>
+# ifndef linux
+# include <netinet/ip_var.h>
+# endif
+# ifndef _KERNEL
+# include <syslog.h>
+# endif
+# include "netinet/ip_compat.h"
+# include <netinet/tcpip.h>
+# include "netinet/ip_fil.h"
+# include "netinet/ip_proxy.h"
+# include "netinet/ip_nat.h"
+# include "netinet/ip_frag.h"
+# include "netinet/ip_state.h"
+# include "netinet/ip_auth.h"
+# ifndef MIN
+# define MIN(a,b) (((a)<(b))?(a):(b))
+# endif
+
+
+# if SOLARIS || defined(__sgi)
+extern kmutex_t ipl_mutex;
+# if SOLARIS
+extern kcondvar_t iplwait;
+# endif
+# endif
+
+iplog_t **iplh[IPL_LOGMAX+1], *iplt[IPL_LOGMAX+1];
+int iplused[IPL_LOGMAX+1];
+u_long iplcrc[IPL_LOGMAX+1];
+u_long iplcrcinit;
+#ifdef linux
+static struct wait_queue *iplwait[IPL_LOGMAX+1];
+#endif
+
+
+/*
+ * Initialise log buffers & pointers. Also iniialised the CRC to a local
+ * secret for use in calculating the "last log checksum".
+ */
+void ipflog_init()
+{
+ struct timeval tv;
+ int i;
+
+ for (i = IPL_LOGMAX; i >= 0; i--) {
+ iplt[i] = NULL;
+ iplh[i] = &iplt[i];
+ iplused[i] = 0;
+ }
+# if BSD >= 199306 || defined(__FreeBSD__) || defined(__sgi)
+ microtime(&tv);
+# else
+ uniqtime(&tv);
+# endif
+ iplcrcinit = tv.tv_sec ^ (tv.tv_usec << 8) ^ tv.tv_usec;
+}
+
+
+/*
+ * ipflog
+ * Create a log record for a packet given that it has been triggered by a
+ * rule (or the default setting). Calculate the transport protocol header
+ * size using predetermined size of a couple of popular protocols and thus
+ * how much data to copy into the log, including part of the data body if
+ * requested.
+ */
+int ipflog(flags, ip, fin, m)
+u_int flags;
+ip_t *ip;
+fr_info_t *fin;
+mb_t *m;
+{
+ ipflog_t ipfl;
+ register int mlen, hlen;
+ u_long crc;
+ size_t sizes[2];
+ void *ptrs[2];
+ int types[2];
+# if SOLARIS
+ ill_t *ifp = fin->fin_ifp;
+# else
+ struct ifnet *ifp = fin->fin_ifp;
+# endif
+
+ /*
+ * calculate header size.
+ */
+ hlen = fin->fin_hlen;
+ if (ip->ip_p == IPPROTO_TCP)
+ hlen += MIN(sizeof(tcphdr_t), fin->fin_dlen);
+ else if (ip->ip_p == IPPROTO_UDP)
+ hlen += MIN(sizeof(udphdr_t), fin->fin_dlen);
+ else if (ip->ip_p == IPPROTO_ICMP) {
+ struct icmp *icmp = (struct icmp *)((char *)ip + hlen);
+
+ /*
+ * For ICMP, if the packet is an error packet, also include
+ * the information about the packet which caused the error.
+ */
+ switch (icmp->icmp_type)
+ {
+ case ICMP_UNREACH :
+ case ICMP_SOURCEQUENCH :
+ case ICMP_REDIRECT :
+ case ICMP_TIMXCEED :
+ case ICMP_PARAMPROB :
+ hlen += MIN(sizeof(struct icmp) + 8, fin->fin_dlen);
+ break;
+ default :
+ hlen += MIN(sizeof(struct icmp), fin->fin_dlen);
+ break;
+ }
+ }
+ /*
+ * Get the interface number and name to which this packet is
+ * currently associated.
+ */
+# if SOLARIS
+ ipfl.fl_unit = (u_char)ifp->ill_ppa;
+ bcopy(ifp->ill_name, ipfl.fl_ifname, MIN(ifp->ill_name_length, 4));
+ mlen = (flags & FR_LOGBODY) ? MIN(msgdsize(m) - hlen, 128) : 0;
+# else
+# if (defined(NetBSD) && (NetBSD <= 1991011) && (NetBSD >= 199603)) || \
+ (defined(OpenBSD) && (OpenBSD >= 199603))
+ strncpy(ipfl.fl_ifname, ifp->if_xname, IFNAMSIZ);
+# else
+# ifndef linux
+ ipfl.fl_unit = (u_char)ifp->if_unit;
+# endif
+ if ((ipfl.fl_ifname[0] = ifp->if_name[0]))
+ if ((ipfl.fl_ifname[1] = ifp->if_name[1]))
+ if ((ipfl.fl_ifname[2] = ifp->if_name[2]))
+ ipfl.fl_ifname[3] = ifp->if_name[3];
+# endif
+ mlen = (flags & FR_LOGBODY) ? MIN(ip->ip_len - hlen, 128) : 0;
+# endif
+ ipfl.fl_plen = (u_char)mlen;
+ ipfl.fl_hlen = (u_char)hlen;
+ ipfl.fl_rule = fin->fin_rule;
+ ipfl.fl_group = fin->fin_group;
+ ipfl.fl_flags = flags;
+ ptrs[0] = (void *)&ipfl;
+ sizes[0] = sizeof(ipfl);
+ types[0] = 0;
+#if SOLARIS
+ /*
+ * Are we copied from the mblk or an aligned array ?
+ */
+ if (ip == (ip_t *)m->b_rptr) {
+ ptrs[1] = m;
+ sizes[1] = hlen + mlen;
+ types[1] = 1;
+ } else {
+ ptrs[1] = ip;
+ sizes[1] = hlen + mlen;
+ types[1] = 0;
+ }
+#else
+ ptrs[1] = m;
+ sizes[1] = hlen + mlen;
+ types[1] = 1;
+#endif
+ crc = (ipf_cksum((u_short *)fin, FI_CSIZE) << 8) + iplcrcinit;
+ return ipllog(IPL_LOGIPF, crc, ptrs, sizes, types, 2);
+}
+
+
+/*
+ * ipllog
+ */
+int ipllog(dev, crc, items, itemsz, types, cnt)
+int dev;
+u_long crc;
+void **items;
+size_t *itemsz;
+int *types, cnt;
+{
+ iplog_t *ipl;
+ caddr_t buf, s;
+ int len, i;
+
+ /*
+ * Check to see if this log record has a CRC which matches the last
+ * record logged. If it does, just up the count on the previous one
+ * rather than create a new one.
+ */
+ if (crc) {
+ MUTEX_ENTER(&ipl_mutex);
+ if ((iplcrc[dev] == crc) && *iplh[dev]) {
+ (*iplh[dev])->ipl_count++;
+ MUTEX_EXIT(&ipl_mutex);
+ return 1;
+ }
+ iplcrc[dev] = crc;
+ MUTEX_EXIT(&ipl_mutex);
+ }
+
+ /*
+ * Get the total amount of data to be logged.
+ */
+ for (i = 0, len = sizeof(iplog_t); i < cnt; i++)
+ len += itemsz[i];
+
+ /*
+ * check that we have space to record this information and can
+ * allocate that much.
+ */
+ KMALLOC(buf, caddr_t, len);
+ if (!buf)
+ return 0;
+ MUTEX_ENTER(&ipl_mutex);
+ if ((iplused[dev] + len) > IPLLOGSIZE) {
+ MUTEX_EXIT(&ipl_mutex);
+ KFREES(buf, len);
+ return 0;
+ }
+ iplused[dev] += len;
+ MUTEX_EXIT(&ipl_mutex);
+
+ /*
+ * advance the log pointer to the next empty record and deduct the
+ * amount of space we're going to use.
+ */
+ ipl = (iplog_t *)buf;
+ ipl->ipl_magic = IPL_MAGIC;
+ ipl->ipl_count = 1;
+ ipl->ipl_next = NULL;
+ ipl->ipl_dsize = len;
+# if SOLARIS || defined(sun) || defined(linux)
+ uniqtime((struct timeval *)&ipl->ipl_sec);
+# else
+# if BSD >= 199306 || defined(__FreeBSD__) || defined(__sgi)
+ microtime((struct timeval *)&ipl->ipl_sec);
+# endif
+# endif
+
+ /*
+ * Loop through all the items to be logged, copying each one to the
+ * buffer. Use bcopy for normal data or the mb_t copyout routine.
+ */
+ for (i = 0, s = buf + sizeof(*ipl); i < cnt; i++) {
+ if (types[i] == 0)
+ bcopy(items[i], s, itemsz[i]);
+ else if (types[i] == 1) {
+# if SOLARIS
+ copyout_mblk(items[i], 0, itemsz[i], s);
+# else
+ m_copydata(items[i], 0, itemsz[i], s);
+# endif
+ }
+ s += itemsz[i];
+ }
+ MUTEX_ENTER(&ipl_mutex);
+ *iplh[dev] = ipl;
+ iplh[dev] = &ipl->ipl_next;
+# if SOLARIS
+ cv_signal(&iplwait);
+ mutex_exit(&ipl_mutex);
+# else
+ MUTEX_EXIT(&ipl_mutex);
+# ifdef linux
+ wake_up_interruptible(&iplwait[dev]);
+# else
+ wakeup(&iplh[dev]);
+# endif
+# endif
+ return 1;
+}
+
+
+int ipflog_read(unit, uio)
+int unit;
+struct uio *uio;
+{
+ iplog_t *ipl;
+ int error = 0, dlen, copied;
+# if defined(_KERNEL) && !SOLARIS
+ int s;
+# endif
+
+ /*
+ * Sanity checks. Make sure the minor # is valid and we're copying
+ * a valid chunk of data.
+ */
+ if ((IPL_LOGMAX < unit) || (unit < 0))
+ return ENXIO;
+ if (!uio->uio_resid)
+ return 0;
+ if ((uio->uio_resid < sizeof(iplog_t)) ||
+ (uio->uio_resid > IPLLOGSIZE))
+ return EINVAL;
+
+ /*
+ * Lock the log so we can snapshot the variables. Wait for a signal
+ * if the log is empty.
+ */
+ SPL_NET(s);
+ MUTEX_ENTER(&ipl_mutex);
+
+ while (!iplused[unit] || !iplt[unit]) {
+# if SOLARIS && defined(_KERNEL)
+ if (!cv_wait_sig(&iplwait, &ipl_mutex)) {
+ MUTEX_EXIT(&ipl_mutex);
+ return EINTR;
+ }
+# else
+# ifdef linux
+ interruptible_sleep_on(&iplwait[unit]);
+ if (current->signal & ~current->blocked)
+ return -EINTR;
+# else
+ MUTEX_EXIT(&ipl_mutex);
+ SPL_X(s);
+ error = SLEEP(&iplh[unit], "ipl sleep");
+ if (error)
+ return error;
+ SPL_NET(s);
+ MUTEX_ENTER(&ipl_mutex);
+# endif /* linux */
+# endif /* SOLARIS */
+ }
+
+# if BSD >= 199306 || defined(__FreeBSD__)
+ uio->uio_rw = UIO_READ;
+# endif
+
+ for (copied = 0; (ipl = iplt[unit]); copied += dlen) {
+ dlen = ipl->ipl_dsize;
+ if (dlen + sizeof(iplog_t) > uio->uio_resid)
+ break;
+ /*
+ * Don't hold the mutex over the uiomove call.
+ */
+ iplt[unit] = ipl->ipl_next;
+ MUTEX_EXIT(&ipl_mutex);
+ SPL_X(s);
+ error = UIOMOVE((caddr_t)ipl, ipl->ipl_dsize, UIO_READ, uio);
+ KFREES((caddr_t)ipl, ipl->ipl_dsize);
+ if (error)
+ break;
+ SPL_NET(s);
+ MUTEX_ENTER(&ipl_mutex);
+ iplused[unit] -= dlen;
+ }
+ if (!ipl) {
+ iplused[unit] = 0;
+ iplh[unit] = &iplt[unit];
+ }
+
+ if (!error) {
+ MUTEX_EXIT(&ipl_mutex);
+ SPL_X(s);
+ }
+#ifdef linux
+ if (!error)
+ return copied;
+ return -error;
+#else
+ return error;
+#endif
+}
+
+
+int ipflog_clear(unit)
+int unit;
+{
+ iplog_t *ipl;
+ int used;
+
+ while ((ipl = iplt[unit])) {
+ iplt[unit] = ipl->ipl_next;
+ KFREES((caddr_t)ipl, ipl->ipl_dsize);
+ }
+ iplh[unit] = &iplt[unit];
+ used = iplused[unit];
+ iplused[unit] = 0;
+ iplcrc[unit] = 0;
+ return used;
+}
+#endif /* IPFILTER_LOG */
diff --git a/contrib/ipfilter/ip_nat.c b/contrib/ipfilter/ip_nat.c
index 3c9476fe68d2..e1774b34bb05 100644
--- a/contrib/ipfilter/ip_nat.c
+++ b/contrib/ipfilter/ip_nat.c
@@ -1,5 +1,5 @@
/*
- * (C)opyright 1995-1996 by Darren Reed.
+ * Copyright (C) 1995-1997 by Darren Reed.
*
* Redistribution and use in source and binary forms are permitted
* provided that this notice is preserved and due credit is given
@@ -7,9 +7,9 @@
*
* Added redirect stuff and a LOT of bug fixes. (mcn@EnGarde.com)
*/
-#if !defined(lint) && defined(LIBC_SCCS)
-static char sccsid[] = "@(#)ip_nat.c 1.11 6/5/96 (C) 1995 Darren Reed";
-static char rcsid[] = "$Id: ip_nat.c,v 2.0.2.18 1997/05/24 07:34:44 darrenr Exp $";
+#if !defined(lint)
+static const char sccsid[] = "@(#)ip_nat.c 1.11 6/5/96 (C) 1995 Darren Reed";
+static const char rcsid[] = "@(#)$Id: ip_nat.c,v 2.0.2.44.2.3 1997/11/12 10:53:29 darrenr Exp $";
#endif
#if defined(__FreeBSD__) && defined(KERNEL) && !defined(_KERNEL)
@@ -28,19 +28,23 @@ static char rcsid[] = "$Id: ip_nat.c,v 2.0.2.18 1997/05/24 07:34:44 darrenr Exp
#include <sys/file.h>
#if defined(KERNEL) && (__FreeBSD_version >= 220000)
# include <sys/filio.h>
-# include <sys/fnctl.h>
+# include <sys/fcntl.h>
#else
# include <sys/ioctl.h>
#endif
#include <sys/fcntl.h>
#include <sys/uio.h>
-#include <sys/protosw.h>
+#ifndef linux
+# include <sys/protosw.h>
+#endif
#include <sys/socket.h>
-#ifdef _KERNEL
+#if defined(_KERNEL) && !defined(linux)
# include <sys/systm.h>
#endif
#if !defined(__SVR4) && !defined(__svr4__)
-# include <sys/mbuf.h>
+# ifndef linux
+# include <sys/mbuf.h>
+# endif
#else
# include <sys/filio.h>
# include <sys/byteorder.h>
@@ -63,18 +67,27 @@ static char rcsid[] = "$Id: ip_nat.c,v 2.0.2.18 1997/05/24 07:34:44 darrenr Exp
#include <netinet/in_systm.h>
#include <netinet/ip.h>
+#ifdef __sgi
+# ifdef IFF_DRVRLOCK /* IRIX6 */
+#include <sys/hashing.h>
+#include <netinet/in_var.h>
+# endif
+#endif
+
#ifdef RFC1825
#include <vpn/md5.h>
#include <vpn/ipsec.h>
extern struct ifnet vpnif;
#endif
-#include <netinet/ip_var.h>
+#ifndef linux
+# include <netinet/ip_var.h>
+#endif
#include <netinet/tcp.h>
#include <netinet/udp.h>
-#include <netinet/tcpip.h>
#include <netinet/ip_icmp.h>
#include "netinet/ip_compat.h"
+#include <netinet/tcpip.h>
#include "netinet/ip_fil.h"
#include "netinet/ip_proxy.h"
#include "netinet/ip_nat.h"
@@ -88,14 +101,32 @@ extern struct ifnet vpnif;
nat_t *nat_table[2][NAT_SIZE], *nat_instances = NULL;
ipnat_t *nat_list = NULL;
-u_long fr_defnatage = 1200;
+u_long fr_defnatage = 1200, /* 10 minutes (600 seconds) */
+ fr_defnaticmpage = 6; /* 3 seconds */
natstat_t nat_stats;
-#if SOLARIS && defined(_KERNEL)
+#if (SOLARIS || defined(__sgi)) && defined(_KERNEL)
extern kmutex_t ipf_nat;
-extern kmutex_t ipf_natfrag;
#endif
-static int flush_nattable __P((void)), clear_natlist __P((void));
+static int nat_flushtable __P((void));
+static int nat_clearlist __P((void));
+static void nat_delete __P((struct nat *));
+static int nat_ifpaddr __P((nat_t *, void *, struct in_addr *));
+
+
+#define LONG_SUM(in) (((in) & 0xffff) + ((in) >> 16))
+
+#define CALC_SUMD(s1, s2, sd) { \
+ /* Do it twice */ \
+ (s1) = ((s1) & 0xffff) + ((s1) >> 16); \
+ (s1) = ((s1) & 0xffff) + ((s1) >> 16); \
+ /* Do it twice */ \
+ (s2) = ((s2) & 0xffff) + ((s2) >> 16); \
+ (s2) = ((s2) & 0xffff) + ((s2) >> 16); \
+ /* Because ~1 == -2, We really need ~1 == -1 */ \
+ if ((s1) > (s2)) (s2)--; \
+ (sd) = (s2) - (s1); \
+ (sd) = ((sd) & 0xffff) + ((sd) >> 16); }
void fix_outcksum(sp, n)
u_short *sp;
@@ -104,11 +135,9 @@ u_long n;
register u_short sumshort;
register u_long sum1;
-#ifdef sparc
- sum1 = (~(*sp)) & 0xffff;
-#else
+ if (!n)
+ return;
sum1 = (~ntohs(*sp)) & 0xffff;
-#endif
sum1 += (n);
sum1 = (sum1 >> 16) + (sum1 & 0xffff);
/* Again */
@@ -125,6 +154,8 @@ u_long n;
register u_short sumshort;
register u_long sum1;
+ if (!n)
+ return;
#ifdef sparc
sum1 = (~(*sp)) & 0xffff;
#else
@@ -164,21 +195,33 @@ u_long n;
* Handle ioctls which manipulate the NAT.
*/
int nat_ioctl(data, cmd, mode)
+#if defined(__NetBSD__) || defined(__OpenBSD__)
+u_long cmd;
+#else
+int cmd;
+#endif
caddr_t data;
-int cmd, mode;
+int mode;
{
register ipnat_t *nat, *n = NULL, **np = NULL;
ipnat_t natd;
- int error = 0, ret, s;
+ int error = 0, ret;
+#if defined(_KERNEL) && !SOLARIS
+ int s;
+#endif
+
+ nat = NULL; /* XXX gcc -Wuninitialized */
/*
* For add/delete, look to see if the NAT entry is already present
*/
+ SPL_NET(s);
MUTEX_ENTER(&ipf_nat);
- SPLNET(s);
if ((cmd == SIOCADNAT) || (cmd == SIOCRMNAT)) {
IRCOPY(data, (char *)&natd, sizeof(natd));
nat = &natd;
+ nat->in_inip &= nat->in_inmsk;
+ nat->in_outip &= nat->in_outmsk;
for (np = &nat_list; (n = *np); np = &n->in_next)
if (!bcmp((char *)&nat->in_flags, (char *)&n->in_flags,
IPN_CMPSIZ))
@@ -201,8 +244,10 @@ int cmd, mode;
error = ENOMEM;
break;
}
- IRCOPY((char *)data, (char *)n, sizeof(*n));
+ bcopy((char *)nat, (char *)n, sizeof(*n));
n->in_ifp = (void *)GETUNIT(n->in_ifname);
+ if (!n->in_ifp)
+ n->in_ifp = (void *)-1;
n->in_apr = ap_match(n->in_p, n->in_plabel);
n->in_next = *np;
n->in_use = 0;
@@ -211,7 +256,7 @@ int cmd, mode;
n->in_space -= 2;
else
n->in_space = 1; /* single IP# mapping */
- if (n->in_outmsk != 0xffffffff)
+ if ((n->in_outmsk != 0xffffffff) && n->in_outmsk)
n->in_nip = ntohl(n->in_outip) + 1;
else
n->in_nip = ntohl(n->in_outip);
@@ -260,9 +305,9 @@ int cmd, mode;
IRCOPY((char *)data, (char *)&nl, sizeof(nl));
- if (nat_lookupredir(&nl))
+ if (nat_lookupredir(&nl)) {
IWCOPY((char *)&nl, (char *)data, sizeof(nl));
- else
+ } else
error = ESRCH;
break;
}
@@ -271,7 +316,7 @@ int cmd, mode;
error = EPERM;
break;
}
- ret = flush_nattable();
+ ret = nat_flushtable();
IWCOPY((caddr_t)&ret, data, sizeof(ret));
break;
case SIOCCNATL :
@@ -279,21 +324,25 @@ int cmd, mode;
error = EPERM;
break;
}
- ret = clear_natlist();
+ ret = nat_clearlist();
IWCOPY((caddr_t)&ret, data, sizeof(ret));
break;
case FIONREAD :
#ifdef IPFILTER_LOG
- *(int *)data = iplused[IPL_LOGNAT];
+ IWCOPY((caddr_t)&iplused[IPL_LOGNAT], (caddr_t)data,
+ sizeof(iplused[IPL_LOGNAT]));
#endif
break;
}
- SPLX(s);
MUTEX_EXIT(&ipf_nat);
+ SPL_X(s);
return error;
}
+/*
+ * Delete a nat entry from the various lists and table.
+ */
static void nat_delete(natd)
struct nat *natd;
{
@@ -314,6 +363,11 @@ struct nat *natd;
break;
}
+ /*
+ * If there is an active reference from the nat entry to its parent
+ * rule, decrement the rule's reference count and free it too if no
+ * longer being used.
+ */
if ((ipn = natd->nat_ptr)) {
ipn->in_space++;
ipn->in_use--;
@@ -324,18 +378,20 @@ struct nat *natd;
nat_stats.ns_rules--;
}
}
- MUTEX_ENTER(&ipf_natfrag);
- if (nat->nat_frag && nat->nat_frag->ipfr_data == nat)
- nat->nat_frag->ipfr_data = NULL;
- MUTEX_EXIT(&ipf_natfrag);
+
+ /*
+ * If there's a fragment table entry too for this nat entry, then
+ * dereference that as well.
+ */
+ ipfr_forget((void *)natd);
KFREE(natd);
}
/*
- * flush_nattable - clear the NAT table of all mapping entries.
+ * nat_flushtable - clear the NAT table of all mapping entries.
*/
-static int flush_nattable()
+static int nat_flushtable()
{
register nat_t *nat, **natp;
register int j = 0;
@@ -358,9 +414,9 @@ static int flush_nattable()
/*
- * clear_natlist - delete all entries in the active NAT mapping list.
+ * nat_clearlist - delete all entries in the active NAT mapping list.
*/
-static int clear_natlist()
+static int nat_clearlist()
{
register ipnat_t *n, **np = &nat_list;
int i = 0;
@@ -384,14 +440,89 @@ static int clear_natlist()
/*
+ * return the first IP Address associated with an interface
+ */
+static int nat_ifpaddr(nat, ifptr, inp)
+nat_t *nat;
+void *ifptr;
+struct in_addr *inp;
+{
+#if SOLARIS
+ ill_t *ill = ifptr;
+#else
+ struct ifnet *ifp = ifptr;
+#endif
+ struct in_addr in;
+
+#if SOLARIS
+ in.s_addr = ill->ill_ipif->ipif_local_addr;
+#else /* SOLARIS */
+# if linux
+ ;
+# else /* linux */
+ struct ifaddr *ifa;
+ struct sockaddr_in *sin;
+
+# if (__FreeBSD_version >= 300000)
+ ifa = TAILQ_FIRST(&ifp->if_addrhead);
+# else
+# if defined(__NetBSD__) || defined(__OpenBSD__)
+ ifa = ifp->if_addrlist.tqh_first;
+# else
+# if defined(__sgi) && defined(IFF_DRVRLOCK) /* IRIX 6 */
+ ifa = &((struct in_ifaddr *)ifp->in_ifaddr)->ia_ifa;
+# else
+ ifa = ifp->if_addrlist;
+# endif
+# endif /* __NetBSD__ || __OpenBSD__ */
+# endif /* __FreeBSD_version >= 300000 */
+# if (BSD < 199306) && !(/*IRIX6*/defined(__sgi) && defined(IFF_DRVRLOCK))
+ sin = (SOCKADDR_IN *)&ifa->ifa_addr;
+# else
+ sin = (SOCKADDR_IN *)ifa->ifa_addr;
+ while (sin && ifa &&
+ sin->sin_family != AF_INET) {
+# if (__FreeBSD_version >= 300000)
+ ifa = TAILQ_NEXT(ifa, ifa_link);
+# else
+# if defined(__NetBSD__) || defined(__OpenBSD__)
+ ifa = ifa->ifa_list.tqe_next;
+# else
+ ifa = ifa->ifa_next;
+# endif
+# endif /* __FreeBSD_version >= 300000 */
+ if (ifa)
+ sin = (SOCKADDR_IN *)ifa->ifa_addr;
+ }
+ if (!ifa)
+ sin = NULL;
+ if (!sin) {
+ KFREE(nat);
+ return -1;
+ }
+# endif /* (BSD < 199306) && (!__sgi && IFF_DRVLOCK) */
+ in = sin->sin_addr;
+ in.s_addr = ntohl(in.s_addr);
+# endif /* linux */
+#endif /* SOLARIS */
+ *inp = in;
+ return 0;
+}
+
+
+/*
* Create a new NAT table entry.
*/
+#ifdef __STDC__
+nat_t *nat_new(ipnat_t *np, ip_t *ip, fr_info_t *fin, u_short flags, int direction)
+#else
nat_t *nat_new(np, ip, fin, flags, direction)
ipnat_t *np;
ip_t *ip;
fr_info_t *fin;
u_short flags;
int direction;
+#endif
{
register u_long sum1, sum2, sumd;
u_short port = 0, sport = 0, dport = 0, nport = 0;
@@ -419,11 +550,6 @@ int direction;
* Search the current table for a match.
*/
if (direction == NAT_OUTBOUND) {
-#if SOLARIS
- ill_t *ill = fin->fin_ifp;
-#else
- struct ifnet *ifp = fin->fin_ifp;
-#endif
/*
* If it's an outbound packet which doesn't match any existing
* record, then create a new port
@@ -432,50 +558,13 @@ int direction;
port = 0;
in.s_addr = np->in_nip;
if (!in.s_addr && (np->in_outmsk == 0xffffffff)) {
-#if SOLARIS
- in.s_addr = ill->ill_ipif->ipif_local_addr;
-#else
- struct ifaddr *ifa;
- struct sockaddr_in *sin;
-
-# if (__FreeBSD_version >= 300000)
- ifa = TAILQ_FIRST(&ifp->if_addrhead);
-# else
-# ifdef __NetBSD__
- ifa = ifp->if_addrlist.tqh_first;
-# else
- ifa = ifp->if_addrlist;
-# endif
-# endif
-# if BSD < 199306
- sin = (SOCKADDR_IN *)&ifa->ifa_addr;
-# else
- sin = (SOCKADDR_IN *)ifa->ifa_addr;
- while (sin && ifa &&
- sin->sin_family != AF_INET) {
-# if (__FreeBSD_version >= 300000)
- ifa = TAILQ_NEXT(ifa, ifa_link);
-# else
-# ifdef __NetBSD__
- ifa = ifa->ifa_list.tqe_next;
-# else
- ifa = ifa->ifa_next;
-# endif
-# endif
- sin = (SOCKADDR_IN *)ifa->ifa_addr;
- }
- if (!ifa)
- sin = NULL;
- if (!sin) {
- KFREE(nat);
+ if (nat_ifpaddr(nat, fin->fin_ifp, &in) == -1)
return NULL;
- }
-# endif
- in = sin->sin_addr;
- in.s_addr = ntohl(in.s_addr);
-#endif
- }
- if (nflags & IPN_TCPUDP) {
+ } else if (!in.s_addr && !np->in_outmsk) {
+ in.s_addr = ntohl(ip->ip_src.s_addr);
+ if (nflags & IPN_TCPUDP)
+ port = sport;
+ } else if (nflags & IPN_TCPUDP) {
port = htons(np->in_pnext++);
if (np->in_pnext >= ntohs(np->in_pmax)) {
np->in_pnext = ntohs(np->in_pmin);
@@ -520,7 +609,7 @@ int direction;
* internal port.
*/
in.s_addr = ntohl(np->in_inip);
- if (!(nport = np->in_pnext))
+ if (!(nport = htons(np->in_pnext)))
nport = dport;
nat->nat_inip.s_addr = htonl(in.s_addr);
@@ -597,10 +686,10 @@ int direction;
nat->nat_dir = direction;
if (direction == NAT_OUTBOUND) {
if (flags & IPN_TCPUDP)
- tcp->th_sport = htons(port);
+ tcp->th_sport = port;
} else {
if (flags & IPN_TCPUDP)
- tcp->th_dport = htons(nport);
+ tcp->th_dport = nport;
}
nat_stats.ns_added++;
nat_stats.ns_inuse++;
@@ -609,6 +698,132 @@ int direction;
}
+nat_t *nat_icmpinlookup(ip, fin)
+ip_t *ip;
+fr_info_t *fin;
+{
+ icmphdr_t *icmp;
+ tcphdr_t *tcp = NULL;
+ ip_t *oip;
+ int flags = 0, type;
+
+ icmp = (icmphdr_t *)fin->fin_dp;
+ /*
+ * Does it at least have the return (basic) IP header ?
+ * Only a basic IP header (no options) should be with an ICMP error
+ * header.
+ */
+ if ((ip->ip_hl != 5) || (ip->ip_len < sizeof(*icmp) + sizeof(ip_t)))
+ return NULL;
+ type = icmp->icmp_type;
+ /*
+ * If it's not an error type, then return.
+ */
+ if ((type != ICMP_UNREACH) && (type != ICMP_SOURCEQUENCH) &&
+ (type != ICMP_REDIRECT) && (type != ICMP_TIMXCEED) &&
+ (type != ICMP_PARAMPROB))
+ return NULL;
+
+ oip = (ip_t *)((char *)fin->fin_dp + 8);
+ if (oip->ip_p == IPPROTO_TCP)
+ flags = IPN_TCP;
+ else if (oip->ip_p == IPPROTO_UDP)
+ flags = IPN_UDP;
+ if (flags & IPN_TCPUDP) {
+ tcp = (tcphdr_t *)((char *)oip + (oip->ip_hl << 2));
+ return nat_inlookup(fin->fin_ifp, flags, oip->ip_dst,
+ tcp->th_dport, oip->ip_src, tcp->th_sport);
+ }
+ return nat_inlookup(fin->fin_ifp, 0, oip->ip_src, 0, oip->ip_dst, 0);
+}
+
+
+/*
+ * This should *ONLY* be used for incoming packets to make sure a NAT'd ICMP
+ * packet gets correctly recognised.
+ */
+nat_t *nat_icmpin(ip, fin, nflags)
+ip_t *ip;
+fr_info_t *fin;
+int *nflags;
+{
+ icmphdr_t *icmp;
+ nat_t *nat;
+ ip_t *oip;
+ int flags = 0;
+
+ if (!(nat = nat_icmpinlookup(ip, fin)))
+ return NULL;
+
+ *nflags = IPN_ICMPERR;
+ icmp = (icmphdr_t *)fin->fin_dp;
+ oip = (ip_t *)((char *)icmp + 8);
+ if (oip->ip_p == IPPROTO_TCP)
+ flags = IPN_TCP;
+ else if (oip->ip_p == IPPROTO_UDP)
+ flags = IPN_UDP;
+ /*
+ * Need to adjust ICMP header to include the real IP#'s and
+ * port #'s. Only apply a checksum change relative to the
+ * IP address change is it will be modified again in ip_natout
+ * for both address and port. Two checksum changes are
+ * necessary for the two header address changes. Be careful
+ * to only modify the checksum once for the port # and twice
+ * for the IP#.
+ */
+ if (flags & IPN_TCPUDP) {
+ tcphdr_t *tcp = (tcphdr_t *)(oip + 1);
+ u_long sum1, sum2, sumd;
+ struct in_addr in;
+
+ if (nat->nat_dir == NAT_OUTBOUND) {
+ sum1 = LONG_SUM(ntohl(oip->ip_src.s_addr));
+ in = nat->nat_outip;
+ oip->ip_src = in;
+ tcp->th_sport = nat->nat_outport;
+ } else {
+ sum1 = LONG_SUM(ntohl(oip->ip_dst.s_addr));
+ in = nat->nat_inip;
+ oip->ip_dst = in;
+ tcp->th_dport = nat->nat_inport;
+ }
+
+ sum2 = LONG_SUM(in.s_addr);
+
+ CALC_SUMD(sum1, sum2, sumd);
+ sumd = (sumd & 0xffff) + (sumd >> 16);
+
+ if (nat->nat_dir == NAT_OUTBOUND) {
+ fix_incksum(&oip->ip_sum, sumd);
+ fix_incksum(&icmp->icmp_cksum, sumd);
+ } else {
+ fix_outcksum(&oip->ip_sum, sumd);
+ fix_outcksum(&icmp->icmp_cksum, sumd);
+ }
+
+ /*
+ * TCP checksum doesn't make it into the 1st eight
+ * bytes but UDP does.
+ */
+ if (ip->ip_p == IPPROTO_UDP) {
+ udphdr_t *udp = (udphdr_t *)tcp;
+
+ if (udp->uh_sum) {
+ if (nat->nat_dir == NAT_OUTBOUND)
+ fix_incksum(&udp->uh_sum,
+ nat->nat_sumd);
+ else
+ fix_outcksum(&udp->uh_sum,
+ nat->nat_sumd);
+ }
+ }
+ } else
+ ip->ip_dst = nat->nat_outip;
+ nat->nat_age = fr_defnaticmpage;
+ return nat;
+}
+
+
/*
* NB: these lookups don't lock access to the list, it assume it has already
* been done!
@@ -619,11 +834,15 @@ int direction;
* we're looking for a table entry, based on the destination address.
* NOTE: THE PACKET BEING CHECKED (IF FOUND) HAS A MAPPING ALREADY.
*/
+#ifdef __STDC__
+nat_t *nat_inlookup(void *ifp, int flags, struct in_addr src, u_short sport, struct in_addr mapdst, u_short mapdport)
+#else
nat_t *nat_inlookup(ifp, flags, src, sport, mapdst, mapdport)
void *ifp;
register int flags;
struct in_addr src , mapdst;
u_short sport, mapdport;
+#endif
{
register nat_t *nat;
@@ -648,24 +867,29 @@ u_short sport, mapdport;
* we're looking for a table entry, based on the source address.
* NOTE: THE PACKET BEING CHECKED (IF FOUND) HAS A MAPPING ALREADY.
*/
+#ifdef __STDC__
+nat_t *nat_outlookup(void *ifp, int flags, struct in_addr src, u_short sport, struct in_addr dst, u_short dport)
+#else
nat_t *nat_outlookup(ifp, flags, src, sport, dst, dport)
void *ifp;
register int flags;
struct in_addr src , dst;
u_short sport, dport;
+#endif
{
register nat_t *nat;
flags &= IPN_TCPUDP;
nat = nat_table[0][src.s_addr % NAT_SIZE];
- for (; nat; nat = nat->nat_hnext[0])
+ for (; nat; nat = nat->nat_hnext[0]) {
if ((!ifp || ifp == nat->nat_ifp) &&
nat->nat_inip.s_addr == src.s_addr &&
nat->nat_oip.s_addr == dst.s_addr &&
flags == nat->nat_flags && (!flags ||
(nat->nat_inport == sport && nat->nat_oport == dport)))
return nat;
+ }
return NULL;
}
@@ -675,11 +899,15 @@ u_short sport, dport;
* real destination address/port. We use this lookup when sending a packet
* out, we're looking for a table entry, based on the source address.
*/
+#ifdef __STDC__
+nat_t *nat_lookupmapip(void *ifp, int flags, struct in_addr mapsrc, u_short mapsport, struct in_addr dst, u_short dport)
+#else
nat_t *nat_lookupmapip(ifp, flags, mapsrc, mapsport, dst, dport)
void *ifp;
register int flags;
struct in_addr mapsrc , dst;
u_short mapsport, dport;
+#endif
{
register nat_t *nat;
@@ -710,10 +938,11 @@ register natlookup_t *np;
* If nl_inip is non null, this is a lookup based on the real
* ip address. Else, we use the fake.
*/
- if ((nat = nat_outlookup(NULL, IPN_TCPUDP, np->nl_inip, np->nl_inport,
- np->nl_outip, np->nl_outport))) {
- np->nl_inip = nat->nat_outip;
- np->nl_inport = nat->nat_outport;
+ if ((nat = nat_outlookup(NULL, np->nl_flags, np->nl_inip,
+ np->nl_inport, np->nl_outip,
+ np->nl_outport))) {
+ np->nl_realip = nat->nat_outip;
+ np->nl_realport = nat->nat_outport;
}
return nat;
}
@@ -731,10 +960,11 @@ fr_info_t *fin;
register ipnat_t *np;
register u_long ipa;
tcphdr_t *tcp = NULL;
- nat_t *nat;
u_short nflags = 0, sport = 0, dport = 0, *csump = NULL;
struct ifnet *ifp;
frentry_t *fr;
+ nat_t *nat;
+ int natadd = 1;
if ((fr = fin->fin_fr) && !(fr->fr_flags & FR_DUP) &&
fr->fr_tif.fd_ifp && fr->fr_tif.fd_ifp != (void *)-1)
@@ -757,11 +987,12 @@ fr_info_t *fin;
ipa = ip->ip_src.s_addr;
MUTEX_ENTER(&ipf_nat);
- if ((nat = ipfr_nat_knownfrag(ip, fin)))
- ;
- else if ((nat = nat_outlookup(fin->fin_ifp, nflags, ip->ip_src, sport,
+ if ((ip->ip_off & (IP_OFFMASK|IP_MF)) &&
+ (nat = ipfr_nat_knownfrag(ip, fin)))
+ natadd = 0;
+ else if ((nat = nat_outlookup(ifp, nflags, ip->ip_src, sport,
ip->ip_dst, dport)))
- np = nat->nat_ptr;
+ ;
else
/*
* If there is no current entry in the nat table for this IP#,
@@ -794,7 +1025,7 @@ fr_info_t *fin;
}
if (nat) {
- if (!nat->nat_frag && fin->fin_fi.fi_fl & FI_FRAG)
+ if (natadd && fin->fin_fi.fi_fl & FI_FRAG)
ipfr_nat_newfrag(ip, fin, 0, nat);
nat->nat_age = fr_defnatage;
ip->ip_src = nat->nat_outip;
@@ -805,7 +1036,7 @@ fr_info_t *fin;
* Fix up checksums, not by recalculating them, but
* simply computing adjustments.
*/
-#if SOLARIS
+#if SOLARIS || defined(__sgi)
if (nat->nat_dir == NAT_OUTBOUND)
fix_outcksum(&ip->ip_sum, nat->nat_ipsumd);
else
@@ -872,8 +1103,9 @@ fr_info_t *fin;
register struct in_addr in;
struct ifnet *ifp = fin->fin_ifp;
tcphdr_t *tcp = NULL;
- u_short sport = 0, dport = 0, nflags = 0, *csump = NULL;
+ u_short sport = 0, dport = 0, *csump = NULL;
nat_t *nat;
+ int nflags = 0, natadd = 1;
if (!(ip->ip_off & 0x1fff) && !(fin->fin_fi.fi_fl & FI_SHORT)) {
if (ip->ip_p == IPPROTO_TCP)
@@ -891,11 +1123,14 @@ fr_info_t *fin;
MUTEX_ENTER(&ipf_nat);
- if ((nat = ipfr_nat_knownfrag(ip, fin)))
+ if ((ip->ip_p == IPPROTO_ICMP) && (nat = nat_icmpin(ip, fin, &nflags)))
;
+ else if ((ip->ip_off & IP_OFFMASK) &&
+ (nat = ipfr_nat_knownfrag(ip, fin)))
+ natadd = 0;
else if ((nat = nat_inlookup(fin->fin_ifp, nflags, ip->ip_src, sport,
ip->ip_dst, dport)))
- np = nat->nat_ptr;
+ ;
else
/*
* If there is no current entry in the nat table for this IP#,
@@ -905,16 +1140,8 @@ fr_info_t *fin;
if ((np->in_ifp == ifp) &&
(!np->in_flags || (nflags & np->in_flags)) &&
((in.s_addr & np->in_outmsk) == np->in_outip) &&
- (np->in_redir & NAT_REDIRECT ||
- np->in_pmin == dport)) {
- /*
- * If this rule (np) is a redirection, rather
- * than a mapping, then do a nat_new.
- * Otherwise, if it's just a mapping, do a
- * continue;
- */
- if (!(np->in_redir & NAT_REDIRECT))
- continue;
+ (np->in_redir & NAT_REDIRECT) &&
+ (!np->in_pmin || np->in_pmin == dport)) {
if ((nat = nat_new(np, ip, fin, nflags,
NAT_INBOUND)))
#ifdef IPFILTER_LOG
@@ -925,10 +1152,13 @@ fr_info_t *fin;
break;
}
if (nat) {
- if (!nat->nat_frag && fin->fin_fi.fi_fl & FI_FRAG)
+ if (natadd && fin->fin_fi.fi_fl & FI_FRAG)
ipfr_nat_newfrag(ip, fin, 0, nat);
(void) ap_check(ip, tcp, fin, nat);
- nat->nat_age = fr_defnatage;
+
+ if (nflags != IPN_ICMPERR)
+ nat->nat_age = fr_defnatage;
+
ip->ip_dst = nat->nat_inip;
nat->nat_bytes += ip->ip_len;
nat->nat_pkts++;
@@ -937,13 +1167,13 @@ fr_info_t *fin;
* Fix up checksums, not by recalculating them, but
* simply computing adjustments.
*/
-#if SOLARIS
+#if SOLARIS || defined(__sgi)
if (nat->nat_dir == NAT_OUTBOUND)
fix_incksum(&ip->ip_sum, nat->nat_ipsumd);
else
fix_outcksum(&ip->ip_sum, nat->nat_ipsumd);
#endif
- if (nflags && !(ip->ip_off & 0x1fff) &&
+ if ((nflags & IPN_TCPUDP) && !(ip->ip_off & 0x1fff) &&
!(fin->fin_fi.fi_fl & FI_SHORT)) {
if (nat->nat_inport)
@@ -994,14 +1224,10 @@ fr_info_t *fin;
*/
void ip_natunload()
{
- int s;
-
MUTEX_ENTER(&ipf_nat);
- SPLNET(s);
- (void) clear_natlist();
- (void) flush_nattable();
+ (void) nat_clearlist();
+ (void) nat_flushtable();
(void) ap_unload();
- SPLX(s)
MUTEX_EXIT(&ipf_nat);
}
@@ -1013,10 +1239,12 @@ void ip_natunload()
void ip_natexpire()
{
register struct nat *nat, **natp;
+#if defined(_KERNEL) && !SOLARIS
int s;
+#endif
+ SPL_NET(s);
MUTEX_ENTER(&ipf_nat);
- SPLNET(s);
for (natp = &nat_instances; (nat = *natp); ) {
if (--nat->nat_age) {
natp = &nat->nat_next;
@@ -1029,34 +1257,83 @@ void ip_natexpire()
nat_delete(nat);
nat_stats.ns_expire++;
}
- SPLX(s);
MUTEX_EXIT(&ipf_nat);
+ SPL_X(s);
+}
+
+
+/*
+ */
+#ifdef __STDC__
+void ip_natsync(void *ifp)
+#else
+void ip_natsync(ifp)
+void *ifp;
+#endif
+{
+ register nat_t *nat;
+ register u_long sum1, sum2, sumd;
+ struct in_addr in;
+ ipnat_t *np;
+#if defined(_KERNEL) && !SOLARIS
+ int s;
+#endif
+
+ SPL_NET(s);
+ MUTEX_ENTER(&ipf_nat);
+ for (nat = nat_instances; nat; nat = nat->nat_next)
+ if ((ifp == nat->nat_ifp) && (np = nat->nat_ptr))
+ if ((np->in_outmsk == 0xffffffff) && !np->in_nip) {
+ /*
+ * Change the map-to address to be the same
+ * as the new one.
+ */
+ sum1 = nat->nat_outip.s_addr;
+ if (nat_ifpaddr(nat, ifp, &in) == -1)
+ nat->nat_outip.s_addr = htonl(in.s_addr);
+ sum2 = nat->nat_outip.s_addr;
+
+ /*
+ * Readjust the checksum adjustment to take
+ * into account the new IP#.
+ *
+ * Do it twice
+ */
+ sum1 = (sum1 & 0xffff) + (sum1 >> 16);
+ sum1 = (sum1 & 0xffff) + (sum1 >> 16);
+
+ /* Do it twice */
+ sum2 = (sum2 & 0xffff) + (sum2 >> 16);
+ sum2 = (sum2 & 0xffff) + (sum2 >> 16);
+
+ /* Because ~1 == -2, We really need ~1 == -1 */
+ if (sum1 > sum2)
+ sum2--;
+ sumd = sum2 - sum1;
+ sumd = (sumd & 0xffff) + (sumd >> 16);
+ sumd += nat->nat_sumd;
+ nat->nat_sumd = (sumd & 0xffff) + (sumd >> 16);
+ }
+ MUTEX_EXIT(&ipf_nat);
+ SPL_X(s);
}
#ifdef IPFILTER_LOG
+# ifdef __STDC__
+void nat_log(struct nat *nat, u_short type)
+# else
void nat_log(nat, type)
struct nat *nat;
u_short type;
+# endif
{
- struct ipnat *np;
- struct natlog natl;
- int rulen;
-
- if (iplused[IPL_LOGNAT] + sizeof(natl) > IPLLOGSIZE) {
- nat_stats.ns_logfail++;
- return;
- }
-
- if (iplh[IPL_LOGNAT] == iplbuf[IPL_LOGNAT] + IPLLOGSIZE)
- iplh[IPL_LOGNAT] = iplbuf[IPL_LOGNAT];
+ struct ipnat *np;
+ struct natlog natl;
+ void *items[1];
+ size_t sizes[1];
+ int rulen, types[1];
-# ifdef sun
- uniqtime(&natl);
-# endif
-# if BSD >= 199306 || defined(__FreeBSD__)
- microtime((struct timeval *)&natl);
-# endif
natl.nl_inip = nat->nat_inip;
natl.nl_outip = nat->nat_outip;
natl.nl_origip = nat->nat_oip;
@@ -1074,12 +1351,10 @@ u_short type;
break;
}
}
+ items[0] = &natl;
+ sizes[0] = sizeof(natl);
+ types[0] = 0;
- if (!fr_copytolog(IPL_LOGNAT, (char *)&natl, sizeof(natl))) {
- iplused[IPL_LOGNAT] += sizeof(natl);
- nat_stats.ns_logged++;
- } else
- nat_stats.ns_logfail++;
- wakeup(iplbuf[IPL_LOGNAT]);
+ (void) ipllog(IPL_LOGNAT, 0, items, sizes, types, 1);
}
#endif
diff --git a/contrib/ipfilter/ip_nat.h b/contrib/ipfilter/ip_nat.h
index add4a9a237e6..f0cb517bb007 100644
--- a/contrib/ipfilter/ip_nat.h
+++ b/contrib/ipfilter/ip_nat.h
@@ -1,21 +1,17 @@
/*
- * (C)opyright 1995-1997 by Darren Reed.
+ * Copyright (C) 1995-1997 by Darren Reed.
*
* Redistribution and use in source and binary forms are permitted
* provided that this notice is preserved and due credit is given
* to the original author and the contributors.
*
* @(#)ip_nat.h 1.5 2/4/96
- * $Id: ip_nat.h,v 2.0.2.12 1997/05/24 07:35:20 darrenr Exp $
+ * $Id: ip_nat.h,v 2.0.2.23.2.1 1997/11/05 11:08:18 darrenr Exp $
*/
#ifndef __IP_NAT_H__
#define __IP_NAT_H__
-#ifndef __IP_PROXY_H__
-#include "netinet/ip_proxy.h"
-#endif
-
#ifndef SOLARIS
#define SOLARIS (defined(sun) && (defined(__svr4__) || defined(__SVR4)))
#endif
@@ -29,7 +25,6 @@
#define SIOCGIPST _IOR('r', 85, struct ips_stat)
#define SIOCFLNAT _IOWR('r', 86, int)
#define SIOCCNATL _IOWR('r', 87, int)
-
#else
#define SIOCADNAT _IOW(r, 80, struct ipnat)
#define SIOCRMNAT _IOW(r, 81, struct ipnat)
@@ -42,13 +37,16 @@
#endif
#define NAT_SIZE 367
+#ifndef APR_LABELLEN
+#define APR_LABELLEN 16
+#endif
typedef struct nat {
u_long nat_age;
int nat_flags;
u_long nat_sumd;
u_long nat_ipsumd;
- struct ipfr *nat_frag;
+ void *nat_data;
struct in_addr nat_inip;
struct in_addr nat_outip;
struct in_addr nat_oip; /* other ip */
@@ -70,6 +68,7 @@ typedef struct nat {
typedef struct ipnat {
struct ipnat *in_next;
void *in_ifp;
+ void *in_apr;
u_int in_space;
u_int in_use;
struct in_addr in_nextip;
@@ -78,7 +77,6 @@ typedef struct ipnat {
u_short in_port[2];
struct in_addr in_in[2];
struct in_addr in_out[2];
- struct aproxy *in_apr;
int in_redir; /* 0 if it's a mapping, 1 if it's a hard redir */
char in_ifname[IFNAMSIZ];
char in_plabel[APR_LABELLEN]; /* proxy label */
@@ -102,13 +100,16 @@ typedef struct ipnat {
#define NAT_BIMAP (NAT_MAP|NAT_REDIRECT)
#define IPN_CMPSIZ (sizeof(struct in_addr) * 4 + sizeof(u_short) * 3 + \
- sizeof(int))
+ sizeof(int) + IFNAMSIZ + APR_LABELLEN + sizeof(char))
typedef struct natlookup {
struct in_addr nl_inip;
struct in_addr nl_outip;
+ struct in_addr nl_realip;
+ int nl_flags;
u_short nl_inport;
u_short nl_outport;
+ u_short nl_realport;
} natlookup_t;
typedef struct natstat {
@@ -128,10 +129,10 @@ typedef struct natstat {
#define IPN_UDP 0x02
#define IPN_TCPUDP 0x03
#define IPN_DELETE 0x04
+#define IPN_ICMPERR 0x08
typedef struct natlog {
- struct timeval nl_tv;
struct in_addr nl_origip;
struct in_addr nl_outip;
struct in_addr nl_inip;
@@ -150,22 +151,30 @@ typedef struct natlog {
#define NL_EXPIRE 0xffff
-extern u_long fr_defnatage;
-extern nat_t *nat_table[2][NAT_SIZE];
-extern int nat_ioctl __P((caddr_t, int, int));
-extern nat_t *nat_new __P((ipnat_t *, ip_t *, fr_info_t *, u_short, int));
-extern nat_t *nat_outlookup __P((void *, int, struct in_addr, u_short,
+extern void ip_natsync __P((void *));
+extern u_long fr_defnatage;
+extern u_long fr_defnaticmpage;
+extern nat_t *nat_table[2][NAT_SIZE];
+#if defined(__NetBSD__) || defined(__OpenBSD__)
+extern int nat_ioctl __P((caddr_t, u_long, int));
+#else
+extern int nat_ioctl __P((caddr_t, int, int));
+#endif
+extern nat_t *nat_new __P((ipnat_t *, ip_t *, fr_info_t *, u_short, int));
+extern nat_t *nat_outlookup __P((void *, int, struct in_addr, u_short,
struct in_addr, u_short));
-extern nat_t *nat_inlookup __P((void *, int, struct in_addr, u_short,
+extern nat_t *nat_inlookup __P((void *, int, struct in_addr, u_short,
struct in_addr, u_short));
-extern nat_t *nat_lookupredir __P((natlookup_t *));
-extern nat_t *nat_lookupmapip __P((void *, int, struct in_addr, u_short,
+extern nat_t *nat_lookupredir __P((natlookup_t *));
+extern nat_t *nat_lookupmapip __P((void *, int, struct in_addr, u_short,
struct in_addr, u_short));
-
-extern int ip_natout __P((ip_t *, int, fr_info_t *));
-extern int ip_natin __P((ip_t *, int, fr_info_t *));
-extern void ip_natunload __P((void)), ip_natexpire __P((void));
-extern void nat_log __P((struct nat *, u_short));
-extern void fix_incksum __P((u_short *, u_long));
-extern void fix_outcksum __P((u_short *, u_long));
+extern nat_t *nat_icmpinlookup __P((ip_t *, fr_info_t *));
+extern nat_t *nat_icmpin __P((ip_t *, fr_info_t *, int *));
+
+extern int ip_natout __P((ip_t *, int, fr_info_t *));
+extern int ip_natin __P((ip_t *, int, fr_info_t *));
+extern void ip_natunload __P((void)), ip_natexpire __P((void));
+extern void nat_log __P((struct nat *, u_short));
+extern void fix_incksum __P((u_short *, u_long));
+extern void fix_outcksum __P((u_short *, u_long));
#endif /* __IP_NAT_H__ */
diff --git a/contrib/ipfilter/ip_proxy.c b/contrib/ipfilter/ip_proxy.c
index 16e5fbe2cf44..cea27f6ca0cb 100644
--- a/contrib/ipfilter/ip_proxy.c
+++ b/contrib/ipfilter/ip_proxy.c
@@ -1,12 +1,12 @@
/*
- * (C)opyright 1997 by Darren Reed.
+ * Copyright (C) 1997 by Darren Reed.
*
* Redistribution and use in source and binary forms are permitted
* provided that this notice is preserved and due credit is given
* to the original author and the contributors.
*/
-#if !defined(lint) && defined(LIBC_SCCS)
-static char rcsid[] = "$Id: ip_proxy.c,v 2.0.2.3 1997/05/24 07:36:22 darrenr Exp $";
+#if !defined(lint)
+static const char rcsid[] = "@(#)$Id: ip_proxy.c,v 2.0.2.11.2.2 1997/11/12 10:54:11 darrenr Exp $";
#endif
#if defined(__FreeBSD__) && defined(KERNEL) && !defined(_KERNEL)
@@ -26,13 +26,21 @@ static char rcsid[] = "$Id: ip_proxy.c,v 2.0.2.3 1997/05/24 07:36:22 darrenr Exp
#include <sys/ioctl.h>
#include <sys/fcntl.h>
#include <sys/uio.h>
-#include <sys/protosw.h>
+#ifndef linux
+# include <sys/protosw.h>
+#endif
#include <sys/socket.h>
-#ifdef _KERNEL
-# include <sys/systm.h>
+#if defined(_KERNEL)
+# if !defined(linux)
+# include <sys/systm.h>
+# else
+# include <linux/string.h>
+# endif
#endif
#if !defined(__SVR4) && !defined(__svr4__)
-# include <sys/mbuf.h>
+# ifndef linux
+# include <sys/mbuf.h>
+# endif
#else
# include <sys/byteorder.h>
# include <sys/dditypes.h>
@@ -50,12 +58,14 @@ static char rcsid[] = "$Id: ip_proxy.c,v 2.0.2.3 1997/05/24 07:36:22 darrenr Exp
#include <netinet/in.h>
#include <netinet/in_systm.h>
#include <netinet/ip.h>
-#include <netinet/ip_var.h>
+#ifndef linux
+# include <netinet/ip_var.h>
+#endif
#include <netinet/tcp.h>
#include <netinet/udp.h>
-#include <netinet/tcpip.h>
#include <netinet/ip_icmp.h>
#include "netinet/ip_compat.h"
+#include <netinet/tcpip.h>
#include "netinet/ip_fil.h"
#include "netinet/ip_proxy.h"
#include "netinet/ip_nat.h"
@@ -71,7 +81,7 @@ static ap_session_t *ap_new_session __P((aproxy_t *, ip_t *, tcphdr_t *,
#define AP_SESS_SIZE 53
-#ifdef _KERNEL
+#if defined(_KERNEL) && !defined(linux)
#include "netinet/ip_ftp_pxy.c"
#endif
@@ -105,12 +115,15 @@ static ap_session_t *ap_find(ip, tcp)
ip_t *ip;
tcphdr_t *tcp;
{
- struct in_addr src = ip->ip_src, dst = ip->ip_dst;
+ struct in_addr src, dst;
register u_long hv;
register u_short sp, dp;
register ap_session_t *aps;
register u_char p = ip->ip_p;
+ src = ip->ip_src, dst = ip->ip_dst;
+ sp = dp = 0; /* XXX gcc -Wunitialized */
+
hv = ip->ip_src.s_addr ^ ip->ip_dst.s_addr;
hv *= 651733;
if (tcp) {
@@ -134,6 +147,12 @@ tcphdr_t *tcp;
return aps;
}
+
+/*
+ * Allocate a new application proxy structure and fill it in with the
+ * relevant details. call the init function once complete, prior to
+ * returning.
+ */
static ap_session_t *ap_new_session(apr, ip, tcp, fin, nat)
aproxy_t *apr;
ip_t *ip;
@@ -163,20 +182,13 @@ nat_t *nat;
KMALLOC(aps, ap_session_t *, sizeof(*aps));
if (!aps)
return NULL;
- bzero((char *)aps, sizeof(aps));
- apr->apr_ref++;
+ bzero((char *)aps, sizeof(*aps));
aps->aps_apr = apr;
aps->aps_src = ip->ip_src;
aps->aps_dst = ip->ip_dst;
aps->aps_p = ip->ip_p;
aps->aps_tout = 1200; /* XXX */
if (tcp) {
- if (ip->ip_p == IPPROTO_TCP) {
- aps->aps_seqoff = 0;
- aps->aps_ackoff = 0;
- aps->aps_state[0] = 0;
- aps->aps_state[1] = 0;
- }
aps->aps_sport = tcp->th_sport;
aps->aps_dport = tcp->th_dport;
}
@@ -189,6 +201,10 @@ nat_t *nat;
}
+/*
+ * check to see if a packet should be passed through an active proxy routine
+ * if one has been setup for it.
+ */
int ap_check(ip, tcp, fin, nat)
ip_t *ip;
tcphdr_t *tcp;
@@ -204,9 +220,20 @@ nat_t *nat;
if ((aps = ap_find(ip, tcp)) ||
(aps = ap_new_session(nat->nat_ptr->in_apr, ip, tcp, fin, nat))) {
- if (ip->ip_p == IPPROTO_TCP)
+ if (ip->ip_p == IPPROTO_TCP) {
+ /*
+ * verify that the checksum is correct. If not, then
+ * don't do anything with this packet.
+ */
+ if (tcp->th_sum != fr_tcpsum(*(mb_t **)fin->fin_mp,
+ ip, tcp)) {
+ frstats[fin->fin_out].fr_tcpbad++;
+ return -1;
+ }
fr_tcp_age(&aps->aps_tout, aps->aps_state, ip, fin,
tcp->th_sport == aps->aps_sport);
+ }
+
apr = aps->aps_apr;
err = 0;
if (fin->fin_out) {
@@ -219,7 +246,7 @@ nat_t *nat;
aps, nat);
}
if (err == 2) {
- tcp->th_sum = fr_tcpsum(fin->fin_mp, ip, tcp);
+ tcp->th_sum = fr_tcpsum(*(mb_t **)fin->fin_mp, ip, tcp);
err = 0;
}
return err;
@@ -229,15 +256,17 @@ nat_t *nat;
aproxy_t *ap_match(pr, name)
-char pr;
+u_char pr;
char *name;
{
aproxy_t *ap;
for (ap = ap_proxies; ap->apr_p; ap++)
if ((ap->apr_p == pr) &&
- !strncmp(name, ap->apr_label, sizeof(ap->apr_label)))
+ !strncmp(name, ap->apr_label, sizeof(ap->apr_label))) {
+ ap->apr_ref++;
return ap;
+ }
return NULL;
}
@@ -245,7 +274,7 @@ char *name;
void ap_free(ap)
aproxy_t *ap;
{
- KFREE(ap);
+ ap->apr_ref--;
}
@@ -264,7 +293,7 @@ void ap_unload()
int i;
for (i = 0; i < AP_SESS_SIZE; i++)
- while (aps = ap_sess_tab[i]) {
+ while ((aps = ap_sess_tab[i])) {
ap_sess_tab[i] = aps->aps_next;
aps_free(aps);
}
diff --git a/contrib/ipfilter/ip_proxy.h b/contrib/ipfilter/ip_proxy.h
index 2d7175491b39..2f71316a6800 100644
--- a/contrib/ipfilter/ip_proxy.h
+++ b/contrib/ipfilter/ip_proxy.h
@@ -1,11 +1,11 @@
/*
- * (C)opyright 1997 by Darren Reed.
+ * Copyright (C) 1997 by Darren Reed.
*
* Redistribution and use in source and binary forms are permitted
* provided that this notice is preserved and due credit is given
* to the original author and the contributors.
*
- * $Id: ip_proxy.h,v 2.0.2.2 1997/05/24 07:36:44 darrenr Exp $
+ * $Id: ip_proxy.h,v 2.0.2.10 1997/10/19 15:39:23 darrenr Exp $
*/
#ifndef __IP_PROXY_H__
@@ -15,18 +15,21 @@
#define SOLARIS (defined(sun) && (defined(__svr4__) || defined(__SVR4)))
#endif
+#ifndef APR_LABELLEN
#define APR_LABELLEN 16
+#endif
#define AP_SESS_SIZE 53
struct nat;
+struct ipnat;
typedef struct ap_tcp {
u_short apt_sport; /* source port */
u_short apt_dport; /* destination port */
- short apt_seqoff; /* sequence # difference */
- short apt_ackoff; /* ack # difference */
- tcp_seq apt_after; /* don't change seq-off until after this */
- char apt_state[2]; /* connection state */
+ short apt_sel; /* seqoff/after set selector */
+ short apt_seqoff[2]; /* sequence # difference */
+ tcp_seq apt_after[2]; /* don't change seq-off until after this */
+ u_char apt_state[2]; /* connection state */
} ap_tcp_t;
typedef struct ap_udp {
@@ -46,7 +49,7 @@ typedef struct ap_session {
u_int aps_flags;
QUAD_T aps_bytes; /* bytes sent */
QUAD_T aps_pkts; /* packets sent */
- time_t aps_tout; /* time left before expiring */
+ u_long aps_tout; /* time left before expiring */
void *aps_data; /* private data */
int aps_psiz; /* size of private data */
struct ap_session *aps_next;
@@ -54,16 +57,15 @@ typedef struct ap_session {
#define aps_sport aps_un.apu_tcp.apt_sport
#define aps_dport aps_un.apu_tcp.apt_dport
+#define aps_sel aps_un.apu_tcp.apt_sel
#define aps_seqoff aps_un.apu_tcp.apt_seqoff
-#define aps_ackoff aps_un.apu_tcp.apt_ackoff
-#define aps_sumoff aps_un.apu_tcp.apt_sumoff
-#define aps_state aps_un.apu_tcp.apt_state
#define aps_after aps_un.apu_tcp.apt_after
+#define aps_state aps_un.apu_tcp.apt_state
typedef struct aproxy {
char apr_label[APR_LABELLEN]; /* Proxy label # */
- char apr_p; /* protocol */
+ u_char apr_p; /* protocol */
int apr_ref; /* +1 per rule referencing it */
int apr_flags;
int (* apr_init) __P((fr_info_t *, ip_t *, tcphdr_t *,
@@ -80,10 +82,11 @@ typedef struct aproxy {
extern ap_session_t *ap_sess_tab[AP_SESS_SIZE];
extern aproxy_t ap_proxies[];
-extern void ap_unload __P((void));
-extern void ap_free __P((aproxy_t *));
-extern void aps_free __P((ap_session_t *));
-extern int ap_check __P((ip_t *, tcphdr_t *, fr_info_t *, struct nat *));
-extern aproxy_t *ap_match __P((char, char *));
+extern int ap_ok __P((ip_t *, tcphdr_t *, struct ipnat *));
+extern void ap_unload __P((void));
+extern void ap_free __P((aproxy_t *));
+extern void aps_free __P((ap_session_t *));
+extern int ap_check __P((ip_t *, tcphdr_t *, fr_info_t *, struct nat *));
+extern aproxy_t *ap_match __P((u_char, char *));
#endif /* __IP_PROXY_H__ */
diff --git a/contrib/ipfilter/ip_sfil.c b/contrib/ipfilter/ip_sfil.c
index 5a5a33090ba9..5192f93ece07 100644
--- a/contrib/ipfilter/ip_sfil.c
+++ b/contrib/ipfilter/ip_sfil.c
@@ -1,5 +1,5 @@
/*
- * (C)opyright 1993,1994,1995 by Darren Reed.
+ * Copyright (C) 1993-1997 by Darren Reed.
*
* Redistribution and use in source and binary forms are permitted
* provided that this notice is preserved and due credit is given
@@ -7,9 +7,9 @@
*
* I hate legaleese, don't you ?
*/
-#if !defined(lint) && defined(LIBC_SCCS)
-static char sccsid[] = "%W% %G% (C) 1993-1995 Darren Reed";
-static char rcsid[] = "$Id: ip_sfil.c,v 2.0.2.8 1997/05/24 07:42:56 darrenr Exp $";
+#if !defined(lint)
+static const char sccsid[] = "%W% %G% (C) 1993-1995 Darren Reed";
+static const char rcsid[] = "@(#)$Id: ip_sfil.c,v 2.0.2.25.2.3 1997/11/12 10:54:35 darrenr Exp $";
#endif
#include <sys/types.h>
@@ -46,6 +46,7 @@ static char rcsid[] = "$Id: ip_sfil.c,v 2.0.2.8 1997/05/24 07:42:56 darrenr Exp
#include "ip_state.h"
#include "ip_nat.h"
#include "ip_frag.h"
+#include "ip_auth.h"
#include <inet/ip_ire.h>
#ifndef MIN
#define MIN(a,b) (((a)<(b))?(a):(b))
@@ -55,33 +56,32 @@ extern fr_flags, fr_active;
int ipfr_timer_id = 0;
int ipl_unreach = ICMP_UNREACH_HOST;
-int send_reset __P((struct tcpiphdr *, qif_t *, queue_t *));
-u_short ipf_cksum __P((u_short *, int));
+u_long ipl_frouteok[2] = {0, 0};
static void frzerostats __P((caddr_t));
-#ifdef IPFILTER_LOG
-int ipllog __P((u_int, int, ip_t *, fr_info_t *, mblk_t *));
-static void frflush __P((caddr_t));
-char iplbuf[3][IPLLOGSIZE];
-caddr_t iplh[3], iplt[3];
-int iplused[3] = {0, 0, 0};
-#endif /* IPFILTER_LOG */
-static int frrequest __P((int, caddr_t, int));
+static int frrequest __P((int, int, caddr_t, int));
kmutex_t ipl_mutex, ipf_mutex, ipfs_mutex;
-kmutex_t ipf_frag, ipf_state, ipf_nat, ipf_natfrag;
-kcondvar_t iplwait;
+kmutex_t ipf_frag, ipf_state, ipf_nat, ipf_natfrag, ipf_auth;
+kcondvar_t iplwait, ipfauthwait;
int ipldetach()
{
- int i = FR_INQUE|FR_OUTQUE;
+ int i;
+#ifdef IPFDEBUG
+ cmn_err(CE_CONT, "ipldetach()\n");
+#endif
+ for (i = IPL_LOGMAX; i >= 0; i--)
+ ipflog_clear(i);
untimeout(ipfr_timer_id);
- frflush((caddr_t)&i);
+ i = FR_INQUE|FR_OUTQUE;
+ frflush(IPL_LOGIPF, (caddr_t)&i);
ipfr_unload();
fr_stateunload();
ip_natunload();
cv_destroy(&iplwait);
+ cv_destroy(&ipfauthwait);
mutex_destroy(&ipl_mutex);
mutex_destroy(&ipf_mutex);
mutex_destroy(&ipfs_mutex);
@@ -89,6 +89,7 @@ int ipldetach()
mutex_destroy(&ipf_state);
mutex_destroy(&ipf_natfrag);
mutex_destroy(&ipf_nat);
+ mutex_destroy(&ipf_auth);
return 0;
}
@@ -97,12 +98,11 @@ int iplattach __P((void))
{
int i;
- for (i = 0; i <= 2; i++) {
- iplt[i] = iplbuf[i];
- iplh[i] = iplbuf[i];
- }
-
- bzero((char *)nat_table, sizeof(nat_t *) * NAT_SIZE * 2);
+#ifdef IPFDEBUG
+ cmn_err(CE_CONT, "iplattach()\n");
+#endif
+ bzero((char *)nat_table, sizeof(nat_table));
+ bzero((char *)frcache, sizeof(frcache));
mutex_init(&ipl_mutex, "ipf log mutex", MUTEX_DRIVER, NULL);
mutex_init(&ipf_mutex, "ipf filter mutex", MUTEX_DRIVER, NULL);
mutex_init(&ipfs_mutex, "ipf solaris mutex", MUTEX_DRIVER, NULL);
@@ -110,8 +110,11 @@ int iplattach __P((void))
mutex_init(&ipf_state, "ipf IP state mutex", MUTEX_DRIVER, NULL);
mutex_init(&ipf_nat, "ipf IP NAT mutex", MUTEX_DRIVER, NULL);
mutex_init(&ipf_natfrag, "ipf IP NAT-Frag mutex", MUTEX_DRIVER, NULL);
+ mutex_init(&ipf_auth, "ipf IP User-Auth mutex", MUTEX_DRIVER, NULL);
cv_init(&iplwait, "ipl condvar", CV_DRIVER, NULL);
+ cv_init(&ipfauthwait, "ipf auth condvar", CV_DRIVER, NULL);
ipfr_timer_id = timeout(ipfr_slowtimer, NULL, drv_usectohz(500000));
+ ipflog_init();
return 0;
}
@@ -132,53 +135,13 @@ caddr_t data;
fio.f_acctout[0] = ipacct[1][0];
fio.f_acctout[1] = ipacct[1][1];
fio.f_active = fr_active;
+ fio.f_froute[0] = ipl_frouteok[0];
+ fio.f_froute[1] = ipl_frouteok[1];
IWCOPY((caddr_t)&fio, data, sizeof(fio));
bzero((char *)frstats, sizeof(*frstats) * 2);
}
-#ifdef IPFILTER_LOG
-static void frflush(data)
-caddr_t data;
-{
- struct frentry *f, **fp;
- int flags, flushed = 0, set = fr_active;
-
- IRCOPY(data, (caddr_t)&flags, sizeof(flags));
- bzero((char *)frcache, sizeof(frcache[0]) * 2);
-
- if (flags & FR_INACTIVE)
- set = 1 - set;
- if (flags & FR_OUTQUE) {
- for (fp = &ipfilter[1][set]; (f = *fp); ) {
- *fp = f->fr_next;
- KFREE(f);
- flushed++;
- }
- for (fp = &ipacct[1][set]; (f = *fp); ) {
- *fp = f->fr_next;
- KFREE(f);
- flushed++;
- }
- }
- if (flags & FR_INQUE) {
- for (fp = &ipfilter[0][set]; (f = *fp); ) {
- *fp = f->fr_next;
- KFREE(f);
- flushed++;
- }
- for (fp = &ipacct[0][set]; (f = *fp); ) {
- *fp = f->fr_next;
- KFREE(f);
- flushed++;
- }
- }
-
- IWCOPY((caddr_t)&flushed, data, sizeof(flushed));
-}
-#endif /* IPFILTER_LOG */
-
-
/*
* Filter ioctl interface.
*/
@@ -190,11 +153,15 @@ int mode;
cred_t *cp;
int *rp;
{
- int error = 0, unit;
+ int error = 0, unit, tmp;
+#ifdef IPFDEBUG
+ cmn_err(CE_CONT, "iplioctl(%x,%x,%x,%d,%x,%d)\n",
+ dev, cmd, data, mode, cp, rp);
+#endif
unit = getminor(dev);
- if ((2 < unit) || (unit < 0))
- return ENXIO;
+ if ((IPL_LOGMAX < unit) || (unit < 0))
+ return ENXIO;
if (unit == IPL_LOGNAT) {
error = nat_ioctl((caddr_t)data, cmd, mode);
@@ -232,7 +199,7 @@ int *rp;
if (!(mode & FWRITE))
return EPERM;
mutex_enter(&ipf_mutex);
- error = frrequest(cmd, (caddr_t)data, fr_active);
+ error = frrequest(unit, cmd, (caddr_t)data, fr_active);
mutex_exit(&ipf_mutex);
break;
case SIOCINIFR :
@@ -241,7 +208,7 @@ int *rp;
if (!(mode & FWRITE))
return EPERM;
mutex_enter(&ipf_mutex);
- error = frrequest(cmd, (caddr_t)data, 1 - fr_active);
+ error = frrequest(unit, cmd, (caddr_t)data, 1 - fr_active);
mutex_exit(&ipf_mutex);
break;
case SIOCSWAPA :
@@ -269,6 +236,8 @@ int *rp;
fio.f_acctout[0] = ipacct[1][0];
fio.f_acctout[1] = ipacct[1][1];
fio.f_active = fr_active;
+ fio.f_froute[0] = ipl_frouteok[0];
+ fio.f_froute[1] = ipl_frouteok[1];
mutex_exit(&ipf_mutex);
IWCOPY((caddr_t)&fio, (caddr_t)data, sizeof(fio));
break;
@@ -278,23 +247,19 @@ int *rp;
return EPERM;
frzerostats((caddr_t)data);
break;
-#ifdef IPFILTER_LOG
case SIOCIPFFL :
if (!(mode & FWRITE))
return EPERM;
mutex_enter(&ipf_mutex);
- frflush((caddr_t)data);
+ frflush(unit, (caddr_t)data);
mutex_exit(&ipf_mutex);
break;
+#ifdef IPFILTER_LOG
case SIOCIPFFB :
if (!(mode & FWRITE))
return EPERM;
- mutex_enter(&ipl_mutex);
- IWCOPY((caddr_t)&iplused[unit], (caddr_t)data,
- sizeof(iplused[unit]));
- iplh[unit] = iplt[unit] = iplbuf[unit];
- iplused[unit] = 0;
- mutex_exit(&ipl_mutex);
+ tmp = ipflog_clear(unit);
+ IWCOPY((caddr_t)&tmp, (caddr_t)data, sizeof(tmp));
break;
#endif /* IPFILTER_LOG */
case SIOCFRSYN :
@@ -302,27 +267,23 @@ int *rp;
return EPERM;
error = ipfsync();
break;
- case SIOCADNAT :
- case SIOCRMNAT :
- case SIOCGNATS :
- case SIOCGNATL :
- case SIOCFLNAT :
- case SIOCCNATL :
- error = nat_ioctl((caddr_t)data, cmd, mode);
- break;
case SIOCGFRST :
IWCOPY((caddr_t)ipfr_fragstats(), (caddr_t)data,
sizeof(ipfrstat_t));
break;
- case SIOCGIPST :
- IWCOPY((caddr_t)fr_statetstats(), (caddr_t)data,
- sizeof(ips_stat_t));
- break;
case FIONREAD :
#ifdef IPFILTER_LOG
- *(int *)data = iplused[IPL_LOGIPF];
+ IWCOPY((caddr_t)&iplused[IPL_LOGIPF], (caddr_t)data,
+ sizeof(iplused[IPL_LOGIPF]));
#endif
break;
+ case SIOCAUTHW :
+ case SIOCAUTHR :
+ if (!(mode & FWRITE))
+ return EPERM;
+ case SIOCATHST :
+ error = fr_auth_ioctl((caddr_t)data, cmd, NULL, NULL);
+ break;
default :
error = EINVAL;
break;
@@ -345,7 +306,27 @@ char *name;
}
-static int frrequest(req, data, set)
+static void fixskip(listp, rp, addremove)
+frentry_t **listp, *rp;
+int addremove;
+{
+ frentry_t *fp;
+ int rules = 0, rn = 0;
+
+ for (fp = *listp; fp && (fp != rp); fp = fp->fr_next, rules++)
+ ;
+
+ if (!fp)
+ return;
+
+ for (fp = *listp; fp && (fp != rp); fp = fp->fr_next, rn++)
+ if (fp->fr_skip && (rn + fp->fr_skip >= rules))
+ fp->fr_skip += addremove;
+}
+
+
+static int frrequest(unit, req, data, set)
+int unit;
int req, set;
caddr_t data;
{
@@ -353,7 +334,8 @@ caddr_t data;
register frentry_t **ftail;
frentry_t fr;
frdest_t *fdp;
- int error = 0, in;
+ frgroup_t *fg = NULL;
+ int error = 0, in, group;
ill_t *ill;
ipif_t *ipif;
ire_t *ire;
@@ -361,18 +343,38 @@ caddr_t data;
fp = &fr;
IRCOPY(data, (caddr_t)fp, sizeof(*fp));
- bzero((char *)frcache, sizeof(frcache[0]) * 2);
+ /*
+ * Check that the group number does exist and that if a head group
+ * has been specified, doesn't exist.
+ */
+ if (fp->fr_grhead &&
+ fr_findgroup(fp->fr_grhead, fp->fr_flags, unit, set, NULL))
+ return EEXIST;
+ if (fp->fr_group &&
+ !fr_findgroup(fp->fr_group, fp->fr_flags, unit, set, NULL))
+ return ESRCH;
in = (fp->fr_flags & FR_INQUE) ? 0 : 1;
- if (fp->fr_flags & FR_ACCOUNT)
+
+ if (unit == IPL_LOGAUTH)
+ ftail = fprev = &ipauth;
+ else if (fp->fr_flags & FR_ACCOUNT)
ftail = fprev = &ipacct[in][set];
else if (fp->fr_flags & (FR_OUTQUE|FR_INQUE))
ftail = fprev = &ipfilter[in][set];
else
return ESRCH;
+ if ((group = fp->fr_group)) {
+ if (!(fg = fr_findgroup(group, fp->fr_flags, unit, set, NULL)))
+ return ESRCH;
+ ftail = fprev = fg->fg_start;
+ }
+
+ bzero((char *)frcache, sizeof(frcache[0]) * 2);
+
if (*fp->fr_ifname) {
- fp->fr_ifa = (struct ifnet *)get_unit((char *)fp->fr_ifname);
+ fp->fr_ifa = (void *)get_unit((char *)fp->fr_ifname);
if (!fp->fr_ifa)
fp->fr_ifa = (struct ifnet *)-1;
}
@@ -385,7 +387,9 @@ caddr_t data;
ire = (ire_t *)-1;
else if ((ipif = ill->ill_ipif)) {
#if SOLARIS2 > 5
- ire = ipif_to_ire(ipif);
+ ire = ire_ctable_lookup(ipif->ipif_local_addr, 0,
+ IRE_LOCAL, NULL, NULL,
+ MATCH_IRE_TYPE);
#else
ire = ire_lookup_myaddr(ipif->ipif_local_addr);
#endif
@@ -404,7 +408,9 @@ caddr_t data;
ire = (ire_t *)-1;
else if ((ipif = ill->ill_ipif)) {
#if SOLARIS2 > 5
- ire = ipif_to_ire(ipif);
+ ire = ire_ctable_lookup(ipif->ipif_local_addr, 0,
+ IRE_LOCAL, NULL, NULL,
+ MATCH_IRE_TYPE);
#else
ire = ire_lookup_myaddr(ipif->ipif_local_addr);
#endif
@@ -450,6 +456,16 @@ caddr_t data;
if (!f)
error = ESRCH;
else {
+ if (f->fr_ref > 1)
+ return EBUSY;
+ if (fg && fg->fg_head)
+ fg->fg_head->fr_ref--;
+ if (unit == IPL_LOGAUTH)
+ return fr_auth_ioctl(data, req, f, ftail);
+ if (f->fr_grhead)
+ fr_delgroup(f->fr_grhead, fp->fr_flags, unit,
+ set);
+ fixskip(fprev, f, -1);
*ftail = f->fr_next;
KFREE(f);
}
@@ -457,12 +473,22 @@ caddr_t data;
if (f)
error = EEXIST;
else {
+ if (unit == IPL_LOGAUTH)
+ return fr_auth_ioctl(data, req, f, ftail);
KMALLOC(f, frentry_t *, sizeof(*f));
if (f != NULL) {
+ if (fg && fg->fg_head)
+ fg->fg_head->fr_ref++;
bcopy((char *)fp, (char *)f, sizeof(*f));
+ f->fr_ref = 1;
f->fr_hits = 0;
f->fr_next = *ftail;
*ftail = f;
+ if (req == SIOCINIFR || req == SIOCINAFR)
+ fixskip(fprev, f, 1);
+ f->fr_grp = NULL;
+ if ((group = f->fr_grhead))
+ fg = fr_addgroup(group, f, unit, set);
} else
error = ENOMEM;
}
@@ -481,6 +507,9 @@ cred_t *cred;
{
u_int min = getminor(*devp);
+#ifdef IPFDEBUG
+ cmn_err(CE_CONT, "iplopen(%x,%x,%x,%x)\n", devp, flags, otype, cred);
+#endif
if (!(otype & OTYP_CHR))
return ENXIO;
min = (2 < min || min < 0) ? ENXIO : 0;
@@ -495,6 +524,9 @@ cred_t *cred;
{
u_int min = getminor(dev);
+#ifdef IPFDEBUG
+ cmn_err(CE_CONT, "iplclose(%x,%x,%x,%x)\n", dev, flags, otype, cred);
+#endif
min = (2 < min || min < 0) ? ENXIO : 0;
return min;
}
@@ -511,147 +543,10 @@ dev_t dev;
register struct uio *uio;
cred_t *cp;
{
- register int ret;
- register size_t sz, sx;
- char *h, *t;
- int error, used, usedo, copied, unit;
-
- unit = getminor(dev);
-
- if (!uio->uio_resid)
- return 0;
- if ((uio->uio_resid < 0) || (uio->uio_resid > IPLLOGSIZE))
- return EINVAL;
-
- /*
- * Lock the log so we can snapshot the variables. Wait for a signal
- * if the log is empty.
- */
- mutex_enter(&ipl_mutex);
- while (!iplused[unit]) {
- error = cv_wait_sig(&iplwait, &ipl_mutex);
- if (!error) {
- mutex_exit(&ipl_mutex);
- return EINTR;
- }
- }
- h = iplh[unit];
- t = iplt[unit];
- used = iplused[unit];
- mutex_exit(&ipl_mutex);
- usedo = used;
-
- /*
- * Given up the mutex, the log can grow more, but we can't hold the
- * mutex across the uiomove's.
- */
- sx = sz = MIN(uio->uio_resid, used);
- if (h <= t)
- sz = MIN(sz, IPLLOGSIZE + iplbuf[unit] - t);
-
- if (!(ret = uiomove(t, sz, UIO_READ, uio))) {
- t += sz;
- sx -= sz;
- used -= sz;
- if ((h < t) && (t >= iplbuf[unit] + IPLLOGSIZE))
- t = iplbuf[unit];
-
- if (sx && !(ret = uiomove(t, sx, UIO_READ, uio)))
- used -= sx;
- }
-
- /*
- * copied all the data, now adjust variables to match this.
- */
- mutex_enter(&ipl_mutex);
- copied = usedo - used;
- iplused[unit] -= copied;
-
- if (!iplused[unit]) /* minimise wrapping around the end */
- iplh[unit] = iplt[unit] = iplbuf[unit];
- else {
- iplt[unit] += copied;
- if (iplt[unit] >= iplbuf[unit] + IPLLOGSIZE)
- iplt[unit] -= IPLLOGSIZE;
- if (iplt[unit] == iplbuf[unit] + IPLLOGSIZE)
- iplt[unit] = iplbuf[unit];
- }
- mutex_exit(&ipl_mutex);
- return ret;
-}
-
-
-int ipllog(flags, dev, ip, fin, m)
-u_int flags;
-int dev;
-ip_t *ip;
-fr_info_t *fin;
-mblk_t *m;
-{
- struct ipl_ci iplci;
- register int len, mlen, hlen;
- register u_char *s = (u_char *)ip;
- ill_t *il = fin->fin_ifp;
-
- hlen = fin->fin_hlen;
- if (ip->ip_p == IPPROTO_TCP || ip->ip_p == IPPROTO_UDP)
- hlen += MIN(sizeof(tcphdr_t), fin->fin_dlen);
- else if (ip->ip_p == IPPROTO_ICMP) {
- struct icmp *icmp = (struct icmp *)(s + hlen);
-
- switch (icmp->icmp_type) {
- case ICMP_UNREACH :
- case ICMP_SOURCEQUENCH :
- case ICMP_REDIRECT :
- case ICMP_TIMXCEED :
- case ICMP_PARAMPROB :
- hlen += MIN(sizeof(struct icmp) + 8, fin->fin_dlen);
- break;
- default :
- hlen += MIN(sizeof(struct icmp), fin->fin_dlen);
- break;
- }
- }
-
- mlen = (flags & FR_LOGBODY) ? MIN(msgdsize(m) - hlen, 128) : 0;
- len = hlen + sizeof(iplci) + mlen;
- mutex_enter(&ipl_mutex);
- if ((iplused[dev] + len) > IPLLOGSIZE) {
- mutex_exit(&ipl_mutex);
- return 0;
- }
- iplused[dev] += len;
-
- uniqtime((struct timeval *)&iplci);
- iplci.flags = flags;
- iplci.hlen = (u_char)hlen;
- iplci.plen = (u_char)mlen;
- iplci.rule = fin->fin_rule;
- iplci.unit = (u_char)il->ill_ppa;
- bcopy(il->ill_name, (char *)iplci.ifname, MIN(il->ill_name_length, 4));
-
- /*
- * Gauranteed to succeed from above
- */
- (void) fr_copytolog(dev, (char *)&iplci, sizeof(iplci));
- len -= sizeof(iplci);
-
- if (len && m) {
- s = m->b_rptr;
- do {
- if ((hlen = MIN(m->b_wptr - s, len))) {
- if (fr_copytolog(dev, s, hlen))
- break;
- len -= hlen;
- }
- if ((m = m->b_cont))
- s = m->b_rptr;
- } while (m && len);
- }
-
- cv_signal(&iplwait);
- mutex_exit(&ipl_mutex);
- return 1;
+#ifdef IPFDEBUG
+ cmn_err(CE_CONT, "iplread(%x,%x,%x)\n", dev, uio, cp);
+#endif
+ return ipflog_read(getminor(dev), uio);
}
#endif /* IPFILTER_LOG */
@@ -660,13 +555,14 @@ mblk_t *m;
* send_reset - this could conceivably be a call to tcp_respond(), but that
* requires a large amount of setting up and isn't any more efficient.
*/
-int send_reset(ti, qif, q)
-struct tcpiphdr *ti;
+int send_reset(iphdr, qif)
+ip_t *iphdr;
qif_t *qif;
-queue_t *q;
{
+ struct tcpiphdr *ti = (struct tcpiphdr *)iphdr;
struct ip *ip;
struct tcphdr *tcp;
+ queue_t *q = qif->qf_q;
mblk_t *m;
int tlen = 0;
@@ -708,17 +604,17 @@ queue_t *q;
}
-int icmp_error(q, ip, type, code, qif, src)
-queue_t *q;
+int icmp_error(ip, type, code, qif, src)
ip_t *ip;
int type, code;
qif_t *qif;
struct in_addr src;
{
- mblk_t *mb;
- struct icmp *icmp;
- ip_t *nip;
- int sz = sizeof(*nip) + sizeof(*icmp) + 8;
+ queue_t *q = qif->qf_q;
+ mblk_t *mb;
+ struct icmp *icmp;
+ ip_t *nip;
+ int sz = sizeof(*nip) + sizeof(*icmp) + 8;
if ((mb = (mblk_t *)allocb(sz, BPRI_HI)) == NULL)
return -1;
diff --git a/contrib/ipfilter/ip_state.c b/contrib/ipfilter/ip_state.c
index a6bda8a170ed..cc14c1a9d9e6 100644
--- a/contrib/ipfilter/ip_state.c
+++ b/contrib/ipfilter/ip_state.c
@@ -1,23 +1,27 @@
/*
- * (C)opyright 1995 by Darren Reed.
+ * Copyright (C) 1995-1997 by Darren Reed.
*
* Redistribution and use in source and binary forms are permitted
* provided that this notice is preserved and due credit is given
* to the original author and the contributors.
*/
-#if !defined(lint) && defined(LIBC_SCCS)
-static char sccsid[] = "@(#)ip_state.c 1.8 6/5/96 (C) 1993-1995 Darren Reed";
-static char rcsid[] = "$Id: ip_state.c,v 2.0.2.12 1997/05/24 07:34:10 darrenr Exp $";
+#if !defined(lint)
+static const char sccsid[] = "@(#)ip_state.c 1.8 6/5/96 (C) 1993-1995 Darren Reed";
+static const char rcsid[] = "@(#)$Id: ip_state.c,v 2.0.2.24.2.3 1997/11/12 10:55:34 darrenr Exp $";
#endif
-#if !defined(_KERNEL) && !defined(KERNEL)
+#if !defined(_KERNEL) && !defined(KERNEL) && !defined(__KERNEL__)
# include <stdlib.h>
# include <string.h>
+#else
+# ifdef linux
+# include <linux/kernel.h>
+# include <linux/module.h>
+# endif
#endif
#include <sys/errno.h>
#include <sys/types.h>
#include <sys/param.h>
-#include <sys/time.h>
#include <sys/file.h>
#if defined(KERNEL) && (__FreeBSD_version >= 220000)
# include <sys/filio.h>
@@ -25,14 +29,19 @@ static char rcsid[] = "$Id: ip_state.c,v 2.0.2.12 1997/05/24 07:34:10 darrenr Ex
#else
# include <sys/ioctl.h>
#endif
+#include <sys/time.h>
#include <sys/uio.h>
+#ifndef linux
#include <sys/protosw.h>
+#endif
#include <sys/socket.h>
-#ifdef _KERNEL
+#if defined(_KERNEL) && !defined(linux)
# include <sys/systm.h>
#endif
#if !defined(__SVR4) && !defined(__svr4__)
-# include <sys/mbuf.h>
+# ifndef linux
+# include <sys/mbuf.h>
+# endif
#else
# include <sys/filio.h>
# include <sys/byteorder.h>
@@ -49,15 +58,19 @@ static char rcsid[] = "$Id: ip_state.c,v 2.0.2.12 1997/05/24 07:34:10 darrenr Ex
#include <netinet/in.h>
#include <netinet/in_systm.h>
#include <netinet/ip.h>
-#include <netinet/ip_var.h>
#include <netinet/tcp.h>
-#include <netinet/tcp_fsm.h>
+#ifndef linux
+# include <netinet/ip_var.h>
+# include <netinet/tcp_fsm.h>
+#endif
#include <netinet/udp.h>
-#include <netinet/tcpip.h>
#include <netinet/ip_icmp.h>
#include "netinet/ip_compat.h"
+#include <netinet/tcpip.h>
#include "netinet/ip_fil.h"
#include "netinet/ip_nat.h"
+#include "netinet/ip_frag.h"
+#include "netinet/ip_proxy.h"
#include "netinet/ip_state.h"
#ifndef MIN
#define MIN(a,b) (((a)<(b))?(a):(b))
@@ -68,7 +81,7 @@ static char rcsid[] = "$Id: ip_state.c,v 2.0.2.12 1997/05/24 07:34:10 darrenr Ex
ipstate_t *ips_table[IPSTATE_SIZE];
int ips_num = 0;
ips_stat_t ips_stats;
-#if SOLARIS && defined(_KERNEL)
+#if (SOLARIS || defined(__sgi)) && defined(_KERNEL)
extern kmutex_t ipf_state;
#endif
@@ -92,25 +105,100 @@ ips_stat_t *fr_statetstats()
}
+/*
+ * flush state tables. two actions currently defined:
+ * which == 0 : flush all state table entries
+ * which == 1 : flush TCP connections which have started to close but are
+ * stuck for some reason.
+ */
+int fr_state_flush(which)
+int which;
+{
+ register int i;
+ register ipstate_t *is, **isp;
+#if defined(_KERNEL) && !SOLARIS
+ int s;
+#endif
+ int delete, removed = 0;
+
+ SPL_NET(s);
+ MUTEX_ENTER(&ipf_state);
+ for (i = 0; i < IPSTATE_SIZE; i++)
+ for (isp = &ips_table[i]; (is = *isp); ) {
+ delete = 0;
+
+ switch (which)
+ {
+ case 0 :
+ delete = 1;
+ break;
+ case 1 :
+ if ((is->is_p == IPPROTO_TCP) &&
+ ((is->is_state[0] <= TCPS_ESTABLISHED) &&
+ (is->is_state[1] > TCPS_ESTABLISHED)) ||
+ ((is->is_state[1] <= TCPS_ESTABLISHED) &&
+ (is->is_state[0] > TCPS_ESTABLISHED)))
+ delete = 1;
+ break;
+ }
+
+ if (delete) {
+ *isp = is->is_next;
+ if (is->is_p == IPPROTO_TCP)
+ ips_stats.iss_fin++;
+ else
+ ips_stats.iss_expire++;
+#ifdef IPFILTER_LOG
+ ipstate_log(is, ISL_FLUSH);
+#endif
+ KFREE(is);
+ ips_num--;
+ removed++;
+ } else
+ isp = &is->is_next;
+ }
+ MUTEX_EXIT(&ipf_state);
+ SPL_X(s);
+ return removed;
+}
+
+
int fr_state_ioctl(data, cmd, mode)
caddr_t data;
+#if defined(__NetBSD__) || defined(__OpenBSD__)
+u_long cmd;
+#else
int cmd;
+#endif
int mode;
{
+ int arg, ret, error = 0;
+
switch (cmd)
{
+ case SIOCIPFFL :
+ IRCOPY(data, (caddr_t)&arg, sizeof(arg));
+ if (arg == 0 || arg == 1) {
+ MUTEX_ENTER(&ipf_state);
+ ret = fr_state_flush(arg);
+ MUTEX_EXIT(&ipf_state);
+ IWCOPY((caddr_t)&ret, data, sizeof(ret));
+ } else
+ error = EINVAL;
+ break;
case SIOCGIPST :
IWCOPY((caddr_t)fr_statetstats(), data, sizeof(ips_stat_t));
break;
case FIONREAD :
#ifdef IPFILTER_LOG
- *(int *)data = iplused[IPL_LOGSTATE];
+ IWCOPY((caddr_t)&iplused[IPL_LOGSTATE], (caddr_t)data,
+ sizeof(iplused[IPL_LOGSTATE]));
#endif
break;
default :
- return -1;
+ return EINVAL;
}
- return 0;
+ return error;
}
@@ -183,7 +271,7 @@ u_int pass;
is->is_dwin = is->is_swin; /* start them the same */
ips_stats.iss_tcp++;
/*
- * If we're creating state for a starting connectoin, start the
+ * If we're creating state for a starting connection, start the
* timer on it as we'll never see an error if it fails to
* connect.
*/
@@ -255,17 +343,27 @@ u_short sport;
*/
seq = ntohl(tcp->th_seq);
ack = ntohl(tcp->th_ack);
- if (sport == is->is_sport) {
+ source = (sport == is->is_sport);
+
+ if (!(tcp->th_flags & TH_ACK)) /* Pretend an ack was sent */
+ ack = source ? is->is_ack : is->is_seq;
+
+ if (source) {
+ if (!is->is_seq)
+ /*
+ * Must be an outgoing SYN-ACK in reply to a SYN.
+ */
+ is->is_seq = seq;
seqskew = seq - is->is_seq;
ackskew = ack - is->is_ack;
} else {
- seqskew = ack - is->is_seq;
if (!is->is_ack)
/*
* Must be a SYN-ACK in reply to a SYN.
*/
is->is_ack = seq;
ackskew = seq - is->is_ack;
+ seqskew = ack - is->is_seq;
}
/*
@@ -281,7 +379,7 @@ u_short sport;
* window size of the connection, store these values and match
* the packet.
*/
- if ((source = (sport == is->is_sport))) {
+ if (source) {
swin = is->is_swin;
dwin = is->is_dwin;
} else {
@@ -440,16 +538,13 @@ void fr_stateunload()
{
register int i;
register ipstate_t *is, **isp;
- int s;
MUTEX_ENTER(&ipf_state);
- SPLNET(s);
for (i = 0; i < IPSTATE_SIZE; i++)
for (isp = &ips_table[i]; (is = *isp); ) {
*isp = is->is_next;
KFREE(is);
}
- SPLX(s);
MUTEX_EXIT(&ipf_state);
}
@@ -462,10 +557,12 @@ void fr_timeoutstate()
{
register int i;
register ipstate_t *is, **isp;
+#if defined(_KERNEL) && !SOLARIS
int s;
+#endif
+ SPL_NET(s);
MUTEX_ENTER(&ipf_state);
- SPLNET(s);
for (i = 0; i < IPSTATE_SIZE; i++)
for (isp = &ips_table[i]; (is = *isp); )
if (is->is_age && !--is->is_age) {
@@ -481,8 +578,8 @@ void fr_timeoutstate()
ips_num--;
} else
isp = &is->is_next;
- SPLX(s);
MUTEX_EXIT(&ipf_state);
+ SPL_X(s);
}
@@ -580,21 +677,10 @@ struct ipstate *is;
u_short type;
{
struct ipslog ipsl;
+ void *items[1];
+ size_t sizes[1];
+ int types[1];
- if (iplused[IPL_LOGSTATE] + sizeof(ipsl) > IPLLOGSIZE) {
- ips_stats.iss_logfail++;
- return;
- }
-
- if (iplh[IPL_LOGSTATE] == iplbuf[IPL_LOGSTATE] + IPLLOGSIZE)
- iplh[IPL_LOGSTATE] = iplbuf[IPL_LOGSTATE];
-
-# ifdef sun
- uniqtime(&ipsl);
-# endif
-# if BSD >= 199306 || defined(__FreeBSD__)
- microtime((struct timeval *)&ipsl);
-# endif
ipsl.isl_pkts = is->is_pkts;
ipsl.isl_bytes = is->is_bytes;
ipsl.isl_src = is->is_src;
@@ -611,12 +697,10 @@ u_short type;
ipsl.isl_ps.isl_filler[0] = 0;
ipsl.isl_ps.isl_filler[1] = 0;
}
+ items[0] = &ipsl;
+ sizes[0] = sizeof(ipsl);
+ types[0] = 0;
- if (!fr_copytolog(IPL_LOGSTATE, (char *)&ipsl, sizeof(ipsl))) {
- iplused[IPL_LOGSTATE] += sizeof(ipsl);
- ips_stats.iss_logged++;
- } else
- ips_stats.iss_logfail++;
- wakeup(iplbuf[IPL_LOGSTATE]);
+ (void) ipllog(IPL_LOGSTATE, 0, items, sizes, types, 1);
}
#endif
diff --git a/contrib/ipfilter/ip_state.h b/contrib/ipfilter/ip_state.h
index 930110157488..3d87a2186c6d 100644
--- a/contrib/ipfilter/ip_state.h
+++ b/contrib/ipfilter/ip_state.h
@@ -1,12 +1,12 @@
/*
- * (C)opyright 1995-1997 by Darren Reed.
+ * Copyright (C) 1995-1997 by Darren Reed.
*
* Redistribution and use in source and binary forms are permitted
* provided that this notice is preserved and due credit is given
* to the original author and the contributors.
*
* @(#)ip_state.h 1.3 1/12/96 (C) 1995 Darren Reed
- * $Id: ip_state.h,v 2.0.2.9 1997/05/24 07:35:11 darrenr Exp $
+ * $Id: ip_state.h,v 2.0.2.14.2.1 1997/11/06 21:23:15 darrenr Exp $
*/
#ifndef __IP_STATE_H__
#define __IP_STATE_H__
@@ -73,7 +73,6 @@ typedef struct ipstate {
typedef struct ipslog {
- struct timeval isl_tv;
U_QUAD_T isl_pkts;
U_QUAD_T isl_bytes;
struct in_addr isl_src;
@@ -94,6 +93,7 @@ typedef struct ipslog {
#define ISL_NEW 0
#define ISL_EXPIRE 0xffff
+#define ISL_FLUSH 0xfffe
typedef struct ips_stat {
@@ -113,21 +113,26 @@ typedef struct ips_stat {
} ips_stat_t;
-extern u_long fr_tcpidletimeout;
-extern u_long fr_tcpclosewait;
-extern u_long fr_tcplastack;
-extern u_long fr_tcptimeout;
-extern u_long fr_tcpclosed;
-extern u_long fr_udptimeout;
-extern u_long fr_icmptimeout;
-extern int fr_tcpstate __P((ipstate_t *, fr_info_t *, ip_t *,
+extern u_long fr_tcpidletimeout;
+extern u_long fr_tcpclosewait;
+extern u_long fr_tcplastack;
+extern u_long fr_tcptimeout;
+extern u_long fr_tcpclosed;
+extern u_long fr_udptimeout;
+extern u_long fr_icmptimeout;
+extern int fr_tcpstate __P((ipstate_t *, fr_info_t *, ip_t *,
tcphdr_t *, u_short));
-extern ips_stat_t *fr_statetstats __P((void));
-extern int fr_addstate __P((ip_t *, fr_info_t *, u_int));
-extern int fr_checkstate __P((ip_t *, fr_info_t *));
-extern void fr_timeoutstate __P((void));
-extern void fr_tcp_age __P((u_long *, u_char *, ip_t *, fr_info_t *, int));
-extern void fr_stateunload __P((void));
-extern void ipstate_log __P((struct ipstate *, u_short));
-extern int fr_state_ioctl __P((caddr_t, int, int));
+extern ips_stat_t *fr_statetstats __P((void));
+extern int fr_addstate __P((ip_t *, fr_info_t *, u_int));
+extern int fr_checkstate __P((ip_t *, fr_info_t *));
+extern void fr_timeoutstate __P((void));
+extern void fr_tcp_age __P((u_long *, u_char *, ip_t *, fr_info_t *, int));
+extern int fr_state_flush __P((int));
+extern void fr_stateunload __P((void));
+extern void ipstate_log __P((struct ipstate *, u_short));
+#if defined(__NetBSD__) || defined(__OpenBSD__)
+extern int fr_state_ioctl __P((caddr_t, u_long, int));
+#else
+extern int fr_state_ioctl __P((caddr_t, int, int));
+#endif
#endif /* __IP_STATE_H__ */
diff --git a/contrib/ipfilter/ipf.c b/contrib/ipfilter/ipf.c
index 326ffe38efbd..b4069e2ebcf1 100644
--- a/contrib/ipfilter/ipf.c
+++ b/contrib/ipfilter/ipf.c
@@ -1,5 +1,5 @@
/*
- * (C)opyright 1993,1994,1995 by Darren Reed.
+ * Copyright (C) 1993-1997 by Darren Reed.
*
* Redistribution and use in source and binary forms are permitted
* provided that this notice is preserved and due credit is given
@@ -38,13 +38,13 @@
#include "ip_fil.h"
#include "ipf.h"
-#if !defined(lint) && defined(LIBC_SCCS)
-static char sccsid[] = "@(#)ipf.c 1.23 6/5/96 (C) 1993-1995 Darren Reed";
-static char rcsid[] = "$Id: ipf.c,v 2.0.2.6 1997/04/30 13:59:59 darrenr Exp $";
+#if !defined(lint)
+static const char sccsid[] = "@(#)ipf.c 1.23 6/5/96 (C) 1993-1995 Darren Reed";
+static const char rcsid[] = "@(#)$Id: ipf.c,v 2.0.2.13.2.2 1997/11/06 21:23:36 darrenr Exp $";
#endif
-#if SOLARIS
static void frsync __P((void));
+#if SOLARIS
static void blockunknown __P((void));
#endif
#if !defined(__SVR4) && defined(__GNUC__)
@@ -63,27 +63,29 @@ static int fd = -1;
static void procfile __P((char *, char *)), flushfilter __P((char *));
static void set_state __P((u_int)), showstats __P((friostat_t *));
static void packetlogon __P((char *)), swapactive __P((void));
-static int opendevice __P((void));
+static int opendevice __P((char *));
+static void closedevice __P((void));
static char *getline __P((char *, size_t, FILE *));
+static char *ipfname = IPL_NAME;
int main(argc,argv)
int argc;
char *argv[];
{
- char c;
+ int c;
- while ((c = getopt(argc, argv, "AdDEf:F:Il:noprsUvyzZ")) != -1) {
+ while ((c = getopt(argc, argv, "AdDEf:F:Il:noPrsUvyzZ")) != -1) {
switch (c)
{
+ case 'A' :
+ opts &= ~OPT_INACTIVE;
+ break;
case 'E' :
set_state((u_int)1);
break;
case 'D' :
set_state((u_int)0);
break;
- case 'A' :
- opts &= ~OPT_INACTIVE;
- break;
case 'd' :
opts |= OPT_DEBUG;
break;
@@ -105,8 +107,8 @@ char *argv[];
case 'o' :
opts |= OPT_OUTQUE;
break;
- case 'p' :
- opts |= OPT_PRINTFR;
+ case 'P' :
+ ipfname = IPL_AUTH;
break;
case 'r' :
opts |= OPT_REMOVE;
@@ -122,11 +124,9 @@ char *argv[];
case 'v' :
opts |= OPT_VERBOSE;
break;
-#if SOLARIS
case 'y' :
frsync();
break;
-#endif
case 'z' :
opts |= OPT_ZERORULEST;
break;
@@ -144,23 +144,34 @@ char *argv[];
}
-static int opendevice()
+static int opendevice(ipfdev)
+char *ipfdev;
{
if (opts & OPT_DONOTHING)
return -2;
+ if (!ipfdev)
+ ipfdev = ipfname;
+
if (!(opts & OPT_DONOTHING) && fd == -1)
- if ((fd = open(IPL_NAME, O_RDWR)) == -1)
- if ((fd = open(IPL_NAME, O_RDONLY)) == -1)
+ if ((fd = open(ipfdev, O_RDWR)) == -1)
+ if ((fd = open(ipfname, O_RDONLY)) == -1)
perror("open device");
return fd;
}
+static void closedevice()
+{
+ close(fd);
+ fd = -1;
+}
+
+
static void set_state(enable)
u_int enable;
{
- if (opendevice() != -2)
+ if (opendevice(ipfname) != -2)
if (ioctl(fd, SIOCFRENB, &enable) == -1)
perror("SIOCFRENB");
return;
@@ -174,7 +185,7 @@ char *name, *file;
struct frentry *fr;
u_int add = SIOCADAFR, del = SIOCRMAFR;
- (void) opendevice();
+ (void) opendevice(ipfname);
if (opts & OPT_INACTIVE) {
add = SIOCADIFR;
@@ -270,14 +281,17 @@ size_t size;
FILE *file;
{
register char *p;
+ register int len;
do {
- for (p = str;; p+= strlen(p) - 1) {
+ for (p = str; ; p += strlen(p) - 1) {
if (!fgets(p, size, file))
return(NULL);
- p[strlen(p) -1] = '\0';
- if (p[strlen(p) - 1] != '\\')
+ len = strlen(p);
+ p[len - 1] = '\0';
+ if (p[len - 1] != '\\')
break;
+ size -= len;
}
} while (*str == '\0' || *str == '\n');
return(str);
@@ -314,7 +328,7 @@ char *opt;
printf("set log flag: block\n");
}
- if (opendevice() != -2 && (err = ioctl(fd, SIOCSETFF, &flag)))
+ if (opendevice(ipfname) != -2 && (err = ioctl(fd, SIOCSETFF, &flag)))
perror("ioctl(SIOCSETFF)");
if ((opts & (OPT_DONOTHING|OPT_VERBOSE)) == OPT_VERBOSE) {
@@ -333,6 +347,24 @@ char *arg;
if (!arg || !*arg)
return;
+ if (!strcmp(arg, "s") || !strcmp(arg, "S")) {
+ if (*arg == 'S')
+ fl = 0;
+ else
+ fl = 1;
+ rem = fl;
+
+ closedevice();
+ if (opendevice(IPL_STATE) != -2 &&
+ ioctl(fd, SIOCIPFFL, &fl) == -1)
+ perror("ioctl(SIOCIPFFL)");
+ if ((opts & (OPT_DONOTHING|OPT_VERBOSE)) == OPT_VERBOSE) {
+ printf("remove flags %s (%d)\n", arg, rem);
+ printf("removed %d filter rules\n", fl);
+ }
+ closedevice();
+ return;
+ }
if (strchr(arg, 'i') || strchr(arg, 'I'))
fl = FR_INQUE;
if (strchr(arg, 'o') || strchr(arg, 'O'))
@@ -342,7 +374,7 @@ char *arg;
fl |= (opts & FR_INACTIVE);
rem = fl;
- if (opendevice() != -2 && ioctl(fd, SIOCIPFFL, &fl) == -1)
+ if (opendevice(ipfname) != -2 && ioctl(fd, SIOCIPFFL, &fl) == -1)
perror("ioctl(SIOCIPFFL)");
if ((opts & (OPT_DONOTHING|OPT_VERBOSE)) == OPT_VERBOSE) {
printf("remove flags %s%s (%d)\n", (rem & FR_INQUE) ? "I" : "",
@@ -357,29 +389,27 @@ static void swapactive()
{
int in = 2;
- if (opendevice() != -2 && ioctl(fd, SIOCSWAPA, &in) == -1)
+ if (opendevice(ipfname) != -2 && ioctl(fd, SIOCSWAPA, &in) == -1)
perror("ioctl(SIOCSWAPA)");
else
printf("Set %d now inactive\n", in);
}
-#if defined(sun) && (defined(__SVR4) || defined(__svr4__))
static void frsync()
{
- if (opendevice() != -2 && ioctl(fd, SIOCFRSYN, 0) == -1)
+ if (opendevice(ipfname) != -2 && ioctl(fd, SIOCFRSYN, 0) == -1)
perror("SIOCFRSYN");
else
printf("filter sync'd\n");
}
-#endif
void zerostats()
{
friostat_t fio;
- if (opendevice() != -2) {
+ if (opendevice(ipfname) != -2) {
if (ioctl(fd, SIOCFRZST, &fio) == -1) {
perror("ioctl(SIOCFRZST)");
exit(-1);
@@ -427,7 +457,7 @@ static void blockunknown()
{
int flag;
- if (opendevice() == -1)
+ if (opendevice(ipfname) == -1)
return;
if ((opts & (OPT_DONOTHING|OPT_VERBOSE)) == OPT_VERBOSE) {
@@ -439,7 +469,7 @@ static void blockunknown()
flag ^= FF_BLOCKNONIP;
- if (opendevice() != -2 && ioctl(fd, SIOCSETFF, &flag))
+ if (opendevice(ipfname) != -2 && ioctl(fd, SIOCSETFF, &flag))
perror("ioctl(SIOCSETFF)");
if ((opts & (OPT_DONOTHING|OPT_VERBOSE)) == OPT_VERBOSE) {
diff --git a/contrib/ipfilter/ipf.h b/contrib/ipfilter/ipf.h
index 67554cb820b8..5c55502d2f81 100644
--- a/contrib/ipfilter/ipf.h
+++ b/contrib/ipfilter/ipf.h
@@ -1,12 +1,12 @@
/*
- * (C)opyright 1993-1997 by Darren Reed.
+ * Copyright (C) 1993-1997 by Darren Reed.
*
* Redistribution and use in source and binary forms are permitted
* provided that this notice is preserved and due credit is given
* to the original author and the contributors.
*
* @(#)ipf.h 1.12 6/5/96
- * $Id: ipf.h,v 2.0.2.6 1997/04/30 13:49:05 darrenr Exp $
+ * $Id: ipf.h,v 2.0.2.12 1997/09/28 07:11:50 darrenr Exp $
*/
#ifndef __IPF_H__
@@ -33,6 +33,8 @@
#define OPT_PRINTFR 0x08000
#define OPT_ZERORULEST 0x10000
#define OPT_SAVEOUT 0x20000
+#define OPT_AUTHSTATS 0x40000
+#define OPT_RAW 0x80000
#ifndef __P
# ifdef __STDC__
@@ -42,6 +44,10 @@
# endif
#endif
+#ifdef ultrix
+extern char *strdup __P((char *));
+#endif
+
extern struct frentry *parse __P((char *));
extern void printfr __P((struct frentry *));
@@ -57,10 +63,10 @@ struct ipopt_names {
};
-extern u_long buildopts __P((char *, char *));
-extern u_long hostnum __P((char *, int *));
-extern u_long optname __P((char ***, u_short *));
-extern void printpacket __P((struct ip *));
+extern u_32_t buildopts __P((char *, char *, int));
+extern u_32_t hostnum __P((char *, int *));
+extern u_32_t optname __P((char ***, u_short *));
+extern void printpacket __P((ip_t *));
#if SOLARIS
extern int inet_aton __P((const char *, struct in_addr *));
#endif
diff --git a/contrib/ipfilter/ipft_ef.c b/contrib/ipfilter/ipft_ef.c
index e1f228f90756..ee6e5c5dd40e 100644
--- a/contrib/ipfilter/ipft_ef.c
+++ b/contrib/ipfilter/ipft_ef.c
@@ -1,5 +1,5 @@
/*
- * (C)opyright 1993,1994,1995 by Darren Reed.
+ * Copyright (C) 1993-1997 by Darren Reed.
*
* Redistribution and use in source and binary forms are permitted
* provided that this notice is preserved and due credit is given
@@ -35,21 +35,23 @@ etherfind -n -t
#include <netinet/in.h>
#include <arpa/inet.h>
#include <netinet/in_systm.h>
+#ifndef linux
#include <netinet/ip_var.h>
+#endif
#include <netinet/ip.h>
#include <netinet/tcp.h>
#include <netinet/udp.h>
#include <netinet/ip_icmp.h>
-#include <netinet/tcpip.h>
#include <net/if.h>
#include <netdb.h>
#include "ip_compat.h"
+#include <netinet/tcpip.h>
#include "ipf.h"
#include "ipt.h"
-#if !defined(lint) && defined(LIBC_SCCS)
-static char sccsid[] = "@(#)ipft_ef.c 1.6 2/4/96 (C)1995 Darren Reed";
-static char rcsid[] = "$Id: ipft_ef.c,v 2.0.2.4 1997/04/30 13:55:06 darrenr Exp $";
+#if !defined(lint)
+static const char sccsid[] = "@(#)ipft_ef.c 1.6 2/4/96 (C)1995 Darren Reed";
+static const char rcsid[] = "@(#)$Id: ipft_ef.c,v 2.0.2.7.2.1 1997/11/12 10:56:06 darrenr Exp $";
#endif
static int etherf_open __P((char *));
@@ -90,7 +92,7 @@ char *buf, **ifn;
int cnt, *dir;
{
struct tcpiphdr pkt;
- struct ip *ip = (struct ip *)&pkt;
+ ip_t *ip = (ip_t *)&pkt;
struct protoent *p = NULL;
char src[16], dst[16], sprt[16], dprt[16];
char lbuf[128], len[8], prot[8], time[8], *s;
@@ -143,7 +145,7 @@ int cnt, *dir;
(void) inet_aton(src, &ip->ip_src);
(void) inet_aton(dst, &ip->ip_dst);
ip->ip_len = atoi(len);
- ip->ip_hl = sizeof(struct ip);
+ ip->ip_hl = sizeof(ip_t);
slen = ip->ip_hl + extra;
i = MIN(cnt, slen);
diff --git a/contrib/ipfilter/ipft_hx.c b/contrib/ipfilter/ipft_hx.c
index 30b3d6d93959..c7fcd92f872b 100644
--- a/contrib/ipfilter/ipft_hx.c
+++ b/contrib/ipfilter/ipft_hx.c
@@ -1,5 +1,5 @@
/*
- * (C)opyright 1995 by Darren Reed.
+ * Copyright (C) 1995-1997 by Darren Reed.
*
* Redistribution and use in source and binary forms are permitted
* provided that this notice is preserved and due credit is given
@@ -9,12 +9,12 @@
#include <ctype.h>
#include <assert.h>
#include <string.h>
+#include <sys/types.h>
#if !defined(__SVR4) && !defined(__svr4__)
#include <strings.h>
#else
#include <sys/byteorder.h>
#endif
-#include <sys/types.h>
#include <sys/param.h>
#include <sys/time.h>
#include <stdlib.h>
@@ -24,23 +24,25 @@
#include <sys/ioctl.h>
#include <netinet/in.h>
#include <netinet/in_systm.h>
+#ifndef linux
#include <netinet/ip_var.h>
+#endif
#include <netinet/ip.h>
#include <netinet/udp.h>
#include <netinet/tcp.h>
#include <netinet/ip_icmp.h>
-#include <netinet/tcpip.h>
#include <net/if.h>
#include <netdb.h>
#include <arpa/nameser.h>
#include <resolv.h>
#include "ip_compat.h"
+#include <netinet/tcpip.h>
#include "ipf.h"
#include "ipt.h"
-#if !defined(lint) && defined(LIBC_SCCS)
-static char sccsid[] = "@(#)ipft_hx.c 1.1 3/9/96 (C) 1996 Darren Reed";
-static char rcsid[] = "$Id: ipft_hx.c,v 2.0.2.4 1997/04/30 13:55:07 darrenr Exp $";
+#if !defined(lint)
+static const char sccsid[] = "@(#)ipft_hx.c 1.1 3/9/96 (C) 1996 Darren Reed";
+static const char rcsid[] = "@(#)$Id: ipft_hx.c,v 2.0.2.8.2.1 1997/11/12 10:56:07 darrenr Exp $";
#endif
extern int opts;
@@ -88,10 +90,10 @@ char *buf, **ifn;
int cnt, *dir;
{
register char *s, *t, *u;
- struct ip *ip;
char line[513];
+ ip_t *ip;
- ip = (struct ip *)buf;
+ ip = (ip_t *)buf;
while (fgets(line, sizeof(line)-1, tfp)) {
if ((s = index(line, '\n'))) {
if (s == line)
@@ -111,25 +113,30 @@ int cnt, *dir;
* interpret start of line as possibly "[ifname]" or
* "[in/out,ifname]".
*/
- *ifn = NULL;
- *dir = 0;
+ if (ifn)
+ *ifn = NULL;
+ if (dir)
+ *dir = 0;
if ((*buf == '[') && (s = index(line, ']'))) {
t = buf + 1;
if (t - s > 0) {
if ((u = index(t, ',')) && (u < s)) {
u++;
- *ifn = u;
- if (*t == 'i')
- *dir = 0;
- else if (*t == 'o')
- *dir = 1;
- } else
+ if (ifn)
+ *ifn = u;
+ if (dir) {
+ if (*t == 'i')
+ *dir = 0;
+ else if (*t == 'o')
+ *dir = 1;
+ }
+ } else if (ifn)
*ifn = t;
*s++ = '\0';
}
} else
s = line;
- ip = (struct ip *)readhex(s, (char *)ip);
+ ip = (ip_t *)readhex(s, (char *)ip);
}
return -1;
}
diff --git a/contrib/ipfilter/ipft_pc.c b/contrib/ipfilter/ipft_pc.c
index 948a8921ecf4..15241432a783 100644
--- a/contrib/ipfilter/ipft_pc.c
+++ b/contrib/ipfilter/ipft_pc.c
@@ -1,5 +1,5 @@
/*
- * (C)opyright 1993-1996 by Darren Reed.
+ * Copyright (C) 1993-1997 by Darren Reed.
*
* Redistribution and use in source and binary forms are permitted
* provided that this notice is preserved and due credit is given
@@ -20,18 +20,20 @@
#include <sys/param.h>
#include <netinet/in.h>
#include <netinet/in_systm.h>
+#ifndef linux
#include <netinet/ip_var.h>
+#endif
#include <netinet/ip.h>
#include <netinet/tcp.h>
-#include <netinet/tcpip.h>
#include <net/if.h>
#include "ip_compat.h"
+#include <netinet/tcpip.h>
#include "ipf.h"
#include "ipt.h"
#include "pcap.h"
-#if !defined(lint) && defined(LIBC_SCCS)
-static char rcsid[] = "$Id: ipft_pc.c,v 2.0.2.4 1997/04/30 13:55:09 darrenr Exp $";
+#if !defined(lint)
+static const char rcsid[] = "@(#)$Id: ipft_pc.c,v 2.0.2.6.2.1 1997/11/12 10:56:08 darrenr Exp $";
#endif
struct llc {
diff --git a/contrib/ipfilter/ipft_sn.c b/contrib/ipfilter/ipft_sn.c
index 11a878f767de..fc9183efd710 100644
--- a/contrib/ipfilter/ipft_sn.c
+++ b/contrib/ipfilter/ipft_sn.c
@@ -1,5 +1,5 @@
/*
- * (C)opyright 1993,1994,1995 by Darren Reed.
+ * Copyright (C) 1993-1997 by Darren Reed.
*
* Redistribution and use in source and binary forms are permitted
* provided that this notice is preserved and due credit is given
@@ -24,18 +24,20 @@
#include <sys/time.h>
#include <netinet/in.h>
#include <netinet/in_systm.h>
+#ifndef linux
#include <netinet/ip_var.h>
+#endif
#include <netinet/ip.h>
#include <netinet/tcp.h>
-#include <netinet/tcpip.h>
#include <net/if.h>
#include "ip_compat.h"
+#include <netinet/tcpip.h>
#include "ipf.h"
#include "ipt.h"
#include "snoop.h"
-#if !defined(lint) && defined(LIBC_SCCS)
-static char rcsid[] = "$Id: ipft_sn.c,v 2.0.2.4 1997/04/30 13:55:10 darrenr Exp $";
+#if !defined(lint)
+static const char rcsid[] = "@(#)$Id: ipft_sn.c,v 2.0.2.6.2.1 1997/11/12 10:56:09 darrenr Exp $";
#endif
struct llc {
diff --git a/contrib/ipfilter/ipft_td.c b/contrib/ipfilter/ipft_td.c
index f70a08fe6e4d..de22b94e08ea 100644
--- a/contrib/ipfilter/ipft_td.c
+++ b/contrib/ipfilter/ipft_td.c
@@ -1,5 +1,5 @@
/*
- * (C)opyright 1993,1994,1995 by Darren Reed.
+ * Copyright (C) 1993-1997 by Darren Reed.
*
* Redistribution and use in source and binary forms are permitted
* provided that this notice is preserved and due credit is given
@@ -44,21 +44,23 @@ tcpdump -nqte
#include <netinet/in.h>
#include <arpa/inet.h>
#include <netinet/in_systm.h>
+#ifndef linux
#include <netinet/ip_var.h>
+#endif
#include <netinet/ip.h>
#include <netinet/tcp.h>
#include <netinet/udp.h>
#include <netinet/ip_icmp.h>
-#include <netinet/tcpip.h>
#include <net/if.h>
#include <netdb.h>
#include "ip_compat.h"
+#include <netinet/tcpip.h>
#include "ipf.h"
#include "ipt.h"
-#if !defined(lint) && defined(LIBC_SCCS)
-static char sccsid[] = "@(#)ipft_td.c 1.8 2/4/96 (C)1995 Darren Reed";
-static char rcsid[] = "$Id: ipft_td.c,v 2.0.2.4 1997/04/30 13:55:12 darrenr Exp $";
+#if !defined(lint)
+static const char sccsid[] = "@(#)ipft_td.c 1.8 2/4/96 (C)1995 Darren Reed";
+static const char rcsid[] = "@(#)$Id: ipft_td.c,v 2.0.2.6.2.1 1997/11/12 10:56:10 darrenr Exp $";
#endif
static int tcpd_open __P((char *));
@@ -113,7 +115,7 @@ char *buf, **ifn;
int cnt, *dir;
{
struct tcpiphdr pkt;
- struct ip *ip = (struct ip *)&pkt;
+ ip_t *ip = (ip_t *)&pkt;
struct protoent *p;
char src[32], dst[32], misc[256], time[32], link1[32], link2[32];
char lbuf[160], *s;
@@ -156,7 +158,7 @@ int cnt, *dir;
(void) inet_aton(src, &ip->ip_src);
(void) inet_aton(src, &ip->ip_dst);
}
- ip->ip_len = ip->ip_hl = sizeof(struct ip);
+ ip->ip_len = ip->ip_hl = sizeof(ip_t);
s = strtok(misc, " :");
if ((p = getprotobyname(s))) {
diff --git a/contrib/ipfilter/ipft_tx.c b/contrib/ipfilter/ipft_tx.c
index 04e5e3f62b44..9be852b6619a 100644
--- a/contrib/ipfilter/ipft_tx.c
+++ b/contrib/ipfilter/ipft_tx.c
@@ -1,5 +1,5 @@
/*
- * (C)opyright 1995 by Darren Reed.
+ * Copyright (C) 1995-1997 by Darren Reed.
*
* Redistribution and use in source and binary forms are permitted
* provided that this notice is preserved and due credit is given
@@ -9,12 +9,12 @@
#include <ctype.h>
#include <assert.h>
#include <string.h>
+#include <sys/types.h>
#if !defined(__SVR4) && !defined(__svr4__)
#include <strings.h>
#else
#include <sys/byteorder.h>
#endif
-#include <sys/types.h>
#include <sys/param.h>
#include <sys/time.h>
#include <stdlib.h>
@@ -24,34 +24,35 @@
#include <sys/ioctl.h>
#include <netinet/in.h>
#include <netinet/in_systm.h>
+#ifndef linux
#include <netinet/ip_var.h>
+#endif
#include <netinet/ip.h>
#include <netinet/udp.h>
#include <netinet/tcp.h>
#include <netinet/ip_icmp.h>
-#include <netinet/tcpip.h>
#include <arpa/inet.h>
#include <net/if.h>
#include <netdb.h>
#include <arpa/nameser.h>
#include <resolv.h>
#include "ip_compat.h"
+#include <netinet/tcpip.h>
#include "ipf.h"
#include "ipt.h"
-#if !defined(lint) && defined(LIBC_SCCS)
-static char sccsid[] = "@(#)ipft_tx.c 1.7 6/5/96 (C) 1993 Darren Reed";
-static char rcsid[] = "$Id: ipft_tx.c,v 2.0.2.4 1997/04/30 13:55:13 darrenr Exp $";
+#if !defined(lint)
+static const char sccsid[] = "@(#)ipft_tx.c 1.7 6/5/96 (C) 1993 Darren Reed";
+static const char rcsid[] = "@(#)$Id: ipft_tx.c,v 2.0.2.11.2.1 1997/11/12 10:56:11 darrenr Exp $";
#endif
extern int opts;
-extern u_long buildopts __P((char *, char *));
static char *tx_proto = "";
static int text_open __P((char *)), text_close __P((void));
static int text_readip __P((char *, int, char **, int *));
-static int parseline __P((char *, struct ip *, char **, int *));
+static int parseline __P((char *, ip_t *, char **, int *));
static char tcp_flagset[] = "FSRPAU";
static u_char tcp_flags[] = { TH_FIN, TH_SYN, TH_RST, TH_PUSH,
@@ -90,7 +91,7 @@ int *resolved;
}
return np->n_net;
}
- return *(u_long *)hp->h_addr;
+ return *(u_32_t *)hp->h_addr;
}
@@ -136,8 +137,8 @@ char *name;
char *tx_icmptypes[] = {
"echorep", (char *)NULL, (char *)NULL, "unreach", "squench",
- "redir", (char *)NULL, (char *)NULL, "echo", (char *)NULL,
- (char *)NULL, "timex", "paramprob", "timest", "timestrep",
+ "redir", (char *)NULL, (char *)NULL, "echo", "routerad",
+ "routersol", "timex", "paramprob", "timest", "timestrep",
"inforeq", "inforep", "maskreq", "maskrep", "END"
};
@@ -175,10 +176,10 @@ char *buf, **ifn;
int cnt, *dir;
{
register char *s;
- struct ip *ip;
+ ip_t *ip;
char line[513];
- ip = (struct ip *)buf;
+ ip = (ip_t *)buf;
*ifn = NULL;
while (fgets(line, sizeof(line)-1, tfp)) {
if ((s = index(line, '\n')))
@@ -193,11 +194,11 @@ int cnt, *dir;
printf("input: %s\n", line);
*ifn = NULL;
*dir = 0;
- if (!parseline(line, (struct ip *)buf, ifn, dir))
+ if (!parseline(line, (ip_t *)buf, ifn, dir))
#if 0
return sizeof(struct tcpiphdr);
#else
- return sizeof(struct ip);
+ return sizeof(ip_t);
#endif
}
return -1;
@@ -205,7 +206,7 @@ int cnt, *dir;
static int parseline(line, ip, ifn, out)
char *line;
-struct ip *ip;
+ip_t *ip;
char **ifn;
int *out;
{
@@ -245,7 +246,7 @@ int *out;
}
c = **cpp;
- ip->ip_len = sizeof(struct ip);
+ ip->ip_len = sizeof(ip_t);
if (!strcasecmp(*cpp, "tcp") || !strcasecmp(*cpp, "udp") ||
!strcasecmp(*cpp, "icmp")) {
if (c == 't') {
@@ -327,7 +328,7 @@ int *out;
u_long olen;
cpp++;
- olen = buildopts(*cpp, ipopts);
+ olen = buildopts(*cpp, ipopts, (ip->ip_hl - 5) << 2);
if (olen) {
bcopy(ipopts, (char *)(ip + 1), olen);
ip->ip_hl += olen >> 2;
diff --git a/contrib/ipfilter/ipl.h b/contrib/ipfilter/ipl.h
index a7a582800b0c..3c5af92b263c 100644
--- a/contrib/ipfilter/ipl.h
+++ b/contrib/ipfilter/ipl.h
@@ -1,5 +1,5 @@
/*
- * (C)opyright 1993-1997 by Darren Reed.
+ * Copyright (C) 1993-1997 by Darren Reed.
*
* Redistribution and use in source and binary forms are permitted
* provided that this notice is preserved and due credit is given
@@ -11,6 +11,6 @@
#ifndef __IPL_H__
#define __IPL_H__
-#define IPL_VERSION "IP Filter v3.2alpha7"
+#define IPL_VERSION "IP Filter v3.2.1"
#endif
diff --git a/contrib/ipfilter/iplang/BNF b/contrib/ipfilter/iplang/BNF
new file mode 100644
index 000000000000..b5fb8d09ae2d
--- /dev/null
+++ b/contrib/ipfilter/iplang/BNF
@@ -0,0 +1,69 @@
+line ::= iface | arp | send | defrouter | ipv4line .
+
+iface ::= ifhdr "{" ifaceopts "}" ";" .
+ifhdr ::= "interface" | "iface" .
+ifaceopts ::= "ifname" name | "mtu" mtu | "v4addr" ipaddr |
+ "eaddr" eaddr .
+
+send ::= "send" ";" | "send" "{" sendbodyopts "}" ";" .
+sendbodyopts ::= sendbody [ sendbodyopts ] .
+sendbody ::= "ifname" name | "via" ipaddr .
+
+defrouter ::= "router" ipaddr .
+
+arp ::= "arp" "{" arpbodyopts "}" ";" .
+arpbodyopts ::= arpbody [ arpbodyopts ] .
+arpbody ::= "v4addr" ipaddr | "eaddr" eaddr .
+
+bodyline ::= ipv4line | tcpline | udpline | icmpline | dataline .
+
+ipv4line ::= "ipv4" "{" ipv4bodyopts "}" ";" .
+ipv4bodyopts ::= ipv4body [ ipv4bodyopts ] | bodyline .
+ipv4body ::= "proto" protocol | "src" ipaddr | "dst" ipaddr |
+ "off" number | "v" number | "hl" number| "id" number |
+ "ttl" number | "tos" number | "sum" number | "len" number |
+ "opt" "{" ipv4optlist "}" ";" .
+ipv4optlist ::= ipv4option [ ipv4optlist ] .
+ipv4optlist = "nop" | "rr" | "zsu" | "mtup" | "mtur" | "encode" | "ts" |
+ "tr" | "sec" | "lsrr" | "e-sec" | "cipso" | "satid" |
+ "ssrr" | "addext" | "visa" | "imitd" | "eip" | "finn" |
+ "secclass" ipv4secclass.
+ipv4secclass := "unclass" | "confid" | "reserv-1" | "reserv-2" |
+ "reserv-3" | "reserv-4" | "secret" | "topsecret" .
+
+tcpline ::= "tcp" "{" tcpbodyopts "}" ";" .
+tcpbodyopts ::= tcpbody [ tcpbodyopts ] | bodyline .
+tcpbody ::= "sport" port | "dport" port | "seq" number | "ack" number |
+ "off" number | "urp" number | "win" number | "sum" number |
+ "flags" tcpflags | data .
+
+udpline ::= "udp" "{" udpbodyopts "}" ";" .
+udpbodyopts ::= udpbody [ udpbodyopts ] | bodyline .
+udpbody ::= "sport" port | "dport" port | "len" number | "sum" number |
+ data .
+
+icmpline ::= "icmp" "{" icmpbodyopts "}" ";" .
+icmpbodyopts ::= icmpbody [ icmpbodyopts ] | bodyline .
+icmpbody ::= "type" icmptype [ "code" icmpcode ] .
+icmptype ::= "echorep" | "echorep" "{" echoopts "}" ";" | "unreach" |
+ "unreach" "{" unreachtype "}" ";" | "squench" | "redir" |
+ "redir" "{" redirtype "}" ";" | "echo" "{" echoopts "}" ";" |
+ "echo" | "routerad" | "routersol" | "timex" |
+ "timex" "{" timextype "}" ";" | "paramprob" |
+ "paramprob" "{" parapptype "}" ";" | "timest" | "timestrep" |
+ "inforeq" | "inforep" | "maskreq" | "maskrep" .
+
+echoopts ::= echoopts [ icmpechoopts ] .
+unreachtype ::= "net-unr" | "host-unr" | "proto-unr" | "port-unr" |
+ "needfrag" | "srcfail" | "net-unk" | "host-unk" | "isolate" |
+ "net-prohib" | "host-prohib" | "net-tos" | "host-tos" |
+ "filter-prohib" | "host-preced" | "cutoff-preced" .
+redirtype ::= "net-redir" | "host-redir" | "tos-net-redir" |
+ "tos-host-redir" .
+timextype ::= "intrans" | "reass" .
+paramptype ::= "optabsent" .
+
+data ::= "data" "{" databodyopts "}" ";" .
+databodyopts ::= "len" number | "value" string | "file" filename .
+
+icmpechoopts ::= "icmpseq" number | "icmpid" number .
diff --git a/contrib/ipfilter/iplang/Makefile b/contrib/ipfilter/iplang/Makefile
new file mode 100644
index 000000000000..4537e8dfb593
--- /dev/null
+++ b/contrib/ipfilter/iplang/Makefile
@@ -0,0 +1,30 @@
+#
+# Redistribution and use in source and binary forms are permitted
+# provided that this notice is preserved and due credit is given
+# to the original author and the contributors.
+#
+#CC=gcc -Wuninitialized -Wstrict-prototypes -Werror -O
+CFLAGS=-I..
+
+all: $(DESTDIR)/y.tab.o $(DESTDIR)/lex.yy.o y.tab.o lex.yy.o
+
+$(DESTDIR)/y.tab.o: y.tab.c
+ $(CC) $(DEBUG) -I. -I.. -I../ipsend $(CFLAGS) $(LINUX) -c y.tab.c -o $@
+
+$(DESTDIR)/lex.yy.o: lex.yy.c
+ $(CC) $(DEBUG) -I. -I.. -I../ipsend $(CFLAGS) $(LINUX) -c lex.yy.c -o $@
+
+y.tab.o: y.tab.c
+ $(CC) $(DEBUG) -I. -I.. -I../ipsend $(CFLAGS) $(LINUX) -c y.tab.c -o $@
+
+lex.yy.o: lex.yy.c
+ $(CC) $(DEBUG) -I. -I.. -I../ipsend $(CFLAGS) $(LINUX) -c lex.yy.c -o $@
+
+lex.yy.c: iplang_l.l y.tab.h
+ lex iplang_l.l
+
+y.tab.c y.tab.h: iplang_y.y
+ yacc -d iplang_y.y
+
+clean:
+ /bin/rm -f *.o lex.yy.c y.tab.c y.tab.h
diff --git a/contrib/ipfilter/iplang/iplang.h b/contrib/ipfilter/iplang/iplang.h
new file mode 100644
index 000000000000..a7a13f91503c
--- /dev/null
+++ b/contrib/ipfilter/iplang/iplang.h
@@ -0,0 +1,51 @@
+/*
+ * Copyright (C) 1997 by Darren Reed.
+ *
+ * Redistribution and use in source and binary forms are permitted
+ * provided that this notice is preserved and due credit is given
+ * to the original author and the contributors.
+ */
+typedef struct iface {
+ int if_MTU;
+ char *if_name;
+ struct in_addr if_addr;
+ struct ether_addr if_eaddr;
+ struct iface *if_next;
+ int if_fd;
+} iface_t;
+
+
+typedef struct send {
+ struct iface *snd_if;
+ struct in_addr snd_gw;
+} send_t;
+
+
+typedef struct arp {
+ struct in_addr arp_addr;
+ struct ether_addr arp_eaddr;
+ struct arp *arp_next;
+} arp_t;
+
+
+typedef struct aniphdr {
+ union {
+ ip_t *ahu_ip;
+ char *ahu_data;
+ tcphdr_t *ahu_tcp;
+ udphdr_t *ahu_udp;
+ icmphdr_t *ahu_icmp;
+ } ah_un;
+ int ah_optlen;
+ int ah_lastopt;
+ int ah_p;
+ size_t ah_len;
+ struct aniphdr *ah_next;
+ struct aniphdr *ah_prev;
+} aniphdr_t;
+
+#define ah_ip ah_un.ahu_ip
+#define ah_data ah_un.ahu_data
+#define ah_tcp ah_un.ahu_tcp
+#define ah_udp ah_un.ahu_udp
+#define ah_icmp ah_un.ahu_icmp
diff --git a/contrib/ipfilter/iplang/iplang.tst b/contrib/ipfilter/iplang/iplang.tst
new file mode 100644
index 000000000000..9a8c35e99507
--- /dev/null
+++ b/contrib/ipfilter/iplang/iplang.tst
@@ -0,0 +1,11 @@
+#
+interface { ifname le0; mtu 1500; }
+
+ipv4 {
+ src 1.1.1.1; dst 2.2.2.2;
+ tcp {
+ seq 12345; ack 0; sport 9999; dport 23; flags S;
+ data { value "abcdef"; } ;
+ }
+}
+send { via 10.1.1.1; }
diff --git a/contrib/ipfilter/iplang/iplang_l.l b/contrib/ipfilter/iplang/iplang_l.l
new file mode 100644
index 000000000000..c136e9108b1f
--- /dev/null
+++ b/contrib/ipfilter/iplang/iplang_l.l
@@ -0,0 +1,313 @@
+%e 1500
+%p 4000
+%a 4000
+%o 6000
+%{
+/*
+ * Copyright (C) 1997 by Darren Reed.
+ *
+ * Redistribution and use in source and binary forms are permitted
+ * provided that this notice is preserved and due credit is given
+ * to the original author and the contributors.
+ *
+ * $Id: iplang_l.l,v 2.0.2.15.2.1 1997/11/05 11:04:04 darrenr Exp $
+ */
+#include <stdio.h>
+#include <string.h>
+#include <sys/param.h>
+#if defined(__SVR4) || defined(__sysv__)
+#include <sys/stream.h>
+#endif
+#include <sys/types.h>
+#include <netinet/in_systm.h>
+#include <netinet/in.h>
+#include "y.tab.h"
+#include "ip_compat.h"
+#include "ipf.h"
+
+#ifndef __P
+# ifdef __STDC__
+# define __P(x) x
+# else
+# define __P(x) ()
+# endif
+#endif
+
+extern int opts;
+
+int lineNum = 0, proto = 0, oldproto = 0, next = -1, laststate = 0;
+int *prstack = NULL, numpr = 0, state = 0, token = 0;
+
+void yyerror __P((char *));
+void push_proto __P((void));
+void pop_proto __P((void));
+int next_state __P((int, int));
+int next_item __P((int));
+int save_token __P((void));
+void swallow __P((void));
+int yylex __P((void));
+%}
+
+%%
+[ \t\r] ;
+\n { lineNum++; swallow(); }
+interface |
+iface { return next_state(IL_INTERFACE, -1); }
+name |
+ifname { return next_state(IL_IFNAME, IL_TOKEN); }
+router { return next_state(IL_DEFROUTER, IL_TOKEN); }
+mtu { return next_state(IL_MTU, IL_NUMBER); }
+eaddr { return next_state(IL_EADDR, IL_TOKEN); }
+v4addr { return next_state(IL_V4ADDR, IL_TOKEN); }
+ipv4 { return next_state(IL_IPV4, -1); }
+v { return next_state(IL_V4V, IL_TOKEN); }
+proto { return next_state(IL_V4PROTO, IL_TOKEN); }
+hl { return next_state(IL_V4HL, IL_TOKEN); }
+id { return next_state(IL_V4ID, IL_TOKEN); }
+ttl { return next_state(IL_V4TTL, IL_TOKEN); }
+tos { return next_state(IL_V4TOS, IL_TOKEN); }
+src { return next_state(IL_V4SRC, IL_TOKEN); }
+dst { return next_state(IL_V4DST, IL_TOKEN); }
+opt { return next_state(IL_OPT, -1); }
+len { return next_state(IL_LEN, IL_TOKEN); }
+off { return next_state(IL_OFF, IL_TOKEN); }
+sum { return next_state(IL_SUM, IL_TOKEN); }
+tcp { return next_state(IL_TCP, -1); }
+sport { return next_state(IL_SPORT, IL_TOKEN); }
+dport { return next_state(IL_DPORT, IL_TOKEN); }
+seq { return next_state(IL_TCPSEQ, IL_TOKEN); }
+ack { return next_state(IL_TCPACK, IL_TOKEN); }
+flags { return next_state(IL_TCPFL, IL_TOKEN); }
+urp { return next_state(IL_TCPURP, IL_TOKEN); }
+win { return next_state(IL_TCPWIN, IL_TOKEN); }
+udp { return next_state(IL_UDP, -1); }
+send { return next_state(IL_SEND, -1); }
+via { return next_state(IL_VIA, IL_TOKEN); }
+arp { return next_state(IL_ARP, -1); }
+data { return next_state(IL_DATA, -1); }
+value { return next_state(IL_DVALUE, IL_TOKEN); }
+file { return next_state(IL_DFILE, IL_TOKEN); }
+nop { return next_state(IL_IPO_NOP, -1); }
+eol { return next_state(IL_IPO_EOL, -1); }
+rr { return next_state(IL_IPO_RR, -1); }
+zsu { return next_state(IL_IPO_ZSU, -1); }
+mtup { return next_state(IL_IPO_MTUP, -1); }
+mtur { return next_state(IL_IPO_MTUR, -1); }
+encode { return next_state(IL_IPO_ENCODE, -1); }
+ts { return next_state(IL_IPO_TS, -1); }
+tr { return next_state(IL_IPO_TR, -1); }
+sec { return next_state(IL_IPO_SEC, -1); }
+secclass { return next_state(IL_IPO_SECCLASS, IL_TOKEN); }
+lsrr { return next_state(IL_IPO_LSRR, -1); }
+esec { return next_state(IL_IPO_ESEC, -1); }
+cipso { return next_state(IL_IPO_CIPSO, -1); }
+satid { return next_state(IL_IPO_SATID, -1); }
+ssrr { return next_state(IL_IPO_SSRR, -1); }
+addext { return next_state(IL_IPO_ADDEXT, -1); }
+visa { return next_state(IL_IPO_VISA, -1); }
+imitd { return next_state(IL_IPO_IMITD, -1); }
+eip { return next_state(IL_IPO_EIP, -1); }
+finn { return next_state(IL_IPO_FINN, -1); }
+mss { return next_state(IL_TCPO_MSS, IL_TOKEN); }
+wscale { return next_state(IL_TCPO_MSS, IL_TOKEN); }
+reserv-4 { return next_state(IL_IPS_RESERV4, -1); }
+topsecret { return next_state(IL_IPS_TOPSECRET, -1); }
+secret { return next_state(IL_IPS_SECRET, -1); }
+reserv-3 { return next_state(IL_IPS_RESERV3, -1); }
+confid { return next_state(IL_IPS_CONFID, -1); }
+unclass { return next_state(IL_IPS_UNCLASS, -1); }
+reserv-2 { return next_state(IL_IPS_RESERV2, -1); }
+reserv-1 { return next_state(IL_IPS_RESERV1, -1); }
+icmp { return next_state(IL_ICMP, -1); }
+type { return next_state(IL_ICMPTYPE, -1); }
+code { return next_state(IL_ICMPCODE, -1); }
+echorep { return next_state(IL_ICMP_ECHOREPLY, -1); }
+unreach { return next_state(IL_ICMP_UNREACH, -1); }
+squench { return next_state(IL_ICMP_SOURCEQUENCH, -1); }
+redir { return next_state(IL_ICMP_REDIRECT, -1); }
+echo { return next_state(IL_ICMP_ECHO, -1); }
+routerad { return next_state(IL_ICMP_ROUTERADVERT, -1); }
+routersol { return next_state(IL_ICMP_ROUTERSOLICIT, -1); }
+timex { return next_state(IL_ICMP_TIMXCEED, -1); }
+paramprob { return next_state(IL_ICMP_PARAMPROB, -1); }
+timest { return next_state(IL_ICMP_TSTAMP, -1); }
+timestrep { return next_state(IL_ICMP_TSTAMPREPLY, -1); }
+inforeq { return next_state(IL_ICMP_IREQ, -1); }
+inforep { return next_state(IL_ICMP_IREQREPLY, -1); }
+maskreq { return next_state(IL_ICMP_MASKREQ, -1); }
+maskrep { return next_state(IL_ICMP_MASKREPLY, -1); }
+net-unr { return next_state(IL_ICMP_UNREACH_NET, -1); }
+host-unr { return next_state(IL_ICMP_UNREACH_HOST, -1); }
+proto-unr { return next_state(IL_ICMP_UNREACH_PROTOCOL, -1); }
+port-unr { return next_state(IL_ICMP_UNREACH_PORT, -1); }
+needfrag { return next_state(IL_ICMP_UNREACH_NEEDFRAG, -1); }
+srcfail { return next_state(IL_ICMP_UNREACH_SRCFAIL, -1); }
+net-unk { return next_state(IL_ICMP_UNREACH_NET_UNKNOWN, -1); }
+host-unk { return next_state(IL_ICMP_UNREACH_HOST_UNKNOWN, -1); }
+isolate { return next_state(IL_ICMP_UNREACH_ISOLATED, -1); }
+net-prohib { return next_state(IL_ICMP_UNREACH_NET_PROHIB, -1); }
+host-prohib { return next_state(IL_ICMP_UNREACH_HOST_PROHIB, -1); }
+net-tos { return next_state(IL_ICMP_UNREACH_TOSNET, -1); }
+host-tos { return next_state(IL_ICMP_UNREACH_TOSHOST, -1); }
+filter-prohib { return next_state(IL_ICMP_UNREACH_FILTER_PROHIB, -1); }
+host-preced { return next_state(IL_ICMP_UNREACH_HOST_PRECEDENCE, -1); }
+cutoff-preced { return next_state(IL_ICMP_UNREACH_PRECEDENCE_CUTOFF, -1); }
+net-redir { return next_state(IL_ICMP_REDIRECT_NET, -1); }
+host-redir { return next_state(IL_ICMP_REDIRECT_HOST, -1); }
+tos-net-redir { return next_state(IL_ICMP_REDIRECT_TOSNET, -1); }
+tos-host-redir { return next_state(IL_ICMP_REDIRECT_TOSHOST, -1); }
+intrans { return next_state(IL_ICMP_TIMXCEED_INTRANS, -1); }
+reass { return next_state(IL_ICMP_TIMXCEED_REASS, -1); }
+optabsent { return next_state(IL_ICMP_PARAMPROB_OPTABSENT, -1); }
+otime { return next_state(IL_ICMP_OTIME, -1); }
+rtime { return next_state(IL_ICMP_RTIME, -1); }
+ttime { return next_state(IL_ICMP_TTIME, -1); }
+icmpseq { return next_state(IL_ICMP_SEQ, -1); }
+icmpid { return next_state(IL_ICMP_SEQ, -1); }
+\{ { push_proto(); return next_item('{'); }
+\} { pop_proto(); return next_item('}'); }
+\. { return next_item(IL_DOT); }
+; { return next_item(';'); }
+[0-9]+ { return next_item(IL_NUMBER); }
+[0-9a-fA-F] { return next_item(IL_HEXDIGIT); }
+: { return next_item(IL_COLON); }
+#[^\n]* { return next_item(IL_COMMENT); }
+[^ {}\n\t;]* { return next_item(IL_TOKEN); }
+\"[^\"]*\" { return next_item(IL_TOKEN); }
+%%
+void yyerror(msg)
+char *msg;
+{
+ fprintf(stderr, "%s error at \"%s\", line %d\n", msg, yytext,
+ lineNum + 1);
+ exit(1);
+}
+
+
+void push_proto()
+{
+ numpr++;
+ if (!prstack)
+ prstack = (int *)malloc(sizeof(int));
+ else
+ prstack = (int *)realloc((char *)prstack, numpr * sizeof(int));
+ prstack[numpr - 1] = oldproto;
+}
+
+
+void pop_proto()
+{
+ numpr--;
+ proto = prstack[numpr];
+ if (!numpr) {
+ free(prstack);
+ prstack = NULL;
+ return;
+ }
+ prstack = (int *)realloc((char *)prstack, numpr * sizeof(int));
+}
+
+
+int save_token()
+{
+ static char *buf = NULL;
+
+ if (buf && (buf == yylval.str))
+ free(buf);
+ buf = yylval.str = strdup(yytext);
+ return IL_TOKEN;
+}
+
+
+int next_item(nstate)
+int nstate;
+{
+ if (next == IL_TOKEN) {
+ next = -1;
+ return save_token();
+ }
+ next = -1;
+ if (nstate == IL_NUMBER)
+ yylval.num = atoi(yytext);
+ token++;
+ return nstate;
+}
+
+
+int next_state(nstate, fornext)
+int nstate, fornext;
+{
+ token++;
+
+ if (next == IL_TOKEN) {
+ next = -1;
+ return save_token();
+ }
+
+ next = fornext;
+
+ switch (nstate)
+ {
+ case IL_IPV4 :
+ case IL_TCP :
+ case IL_UDP :
+ case IL_ICMP :
+ case IL_DATA :
+ case IL_INTERFACE :
+ case IL_ARP :
+ oldproto = proto;
+ proto = nstate;
+ break;
+ case IL_SUM :
+ if (proto == IL_IPV4)
+ nstate = IL_V4SUM;
+ else if (proto == IL_TCP)
+ nstate = IL_TCPSUM;
+ else if (proto == IL_UDP)
+ nstate = IL_UDPSUM;
+ break;
+ case IL_OPT :
+ if (proto == IL_IPV4)
+ nstate = IL_V4OPT;
+ else if (proto == IL_TCP)
+ nstate = IL_TCPOPT;
+ break;
+ case IL_IPO_NOP :
+ if (proto == IL_TCP)
+ nstate = IL_TCPO_NOP;
+ break;
+ case IL_IPO_EOL :
+ if (proto == IL_TCP)
+ nstate = IL_TCPO_EOL;
+ break;
+ case IL_IPO_TS :
+ if (proto == IL_TCP)
+ nstate = IL_TCPO_TS;
+ break;
+ case IL_OFF :
+ if (proto == IL_IPV4)
+ nstate = IL_V4OFF;
+ else if (proto == IL_TCP)
+ nstate = IL_TCPOFF;
+ break;
+ case IL_LEN :
+ if (proto == IL_IPV4)
+ nstate = IL_V4LEN;
+ else if (proto == IL_UDP)
+ nstate = IL_UDPLEN;
+ break;
+ }
+ return nstate;
+}
+
+
+void swallow()
+{
+ int c = input();
+
+ if (c == '#') {
+ while ((c != '\n') && (c != EOF))
+ c = input();
+ }
+ unput(c);
+}
diff --git a/contrib/ipfilter/iplang/iplang_y.y b/contrib/ipfilter/iplang/iplang_y.y
new file mode 100644
index 000000000000..6d56bc5047c9
--- /dev/null
+++ b/contrib/ipfilter/iplang/iplang_y.y
@@ -0,0 +1,1858 @@
+%{
+/*
+ * Copyright (C) 1997 by Darren Reed.
+ *
+ * Redistribution and use in source and binary forms are permitted
+ * provided that this notice is preserved and due credit is given
+ * to the original author and the contributors.
+ *
+ * $Id: iplang_y.y,v 2.0.2.18.2.2 1997/11/05 11:04:19 darrenr Exp $
+ */
+
+#include <stdio.h>
+#include <string.h>
+#include <fcntl.h>
+#if !defined(__SVR4) && !defined(__svr4__)
+#include <strings.h>
+#else
+#include <sys/byteorder.h>
+#endif
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <sys/param.h>
+#include <sys/time.h>
+#include <stdlib.h>
+#include <unistd.h>
+#include <stddef.h>
+#include <sys/socket.h>
+#include <netinet/in.h>
+#include <netinet/in_systm.h>
+#include <netinet/ip.h>
+#include <netinet/ip_icmp.h>
+#ifndef linux
+#include <netinet/ip_var.h>
+#endif
+#include <netinet/tcp.h>
+#include <netinet/udp.h>
+#include <net/if.h>
+#ifndef linux
+#include <netinet/if_ether.h>
+#endif
+#include <netdb.h>
+#include <arpa/nameser.h>
+#include <arpa/inet.h>
+#include <resolv.h>
+#include <ctype.h>
+#include "ipsend.h"
+#include "ip_compat.h"
+#include "ipf.h"
+#include "iplang.h"
+
+extern struct ether_addr *ether_aton __P((char *));
+
+extern int opts;
+extern struct ipopt_names ionames[];
+extern int state, state, lineNum, token;
+extern int yylineno;
+extern char yytext[];
+extern FILE *yyin;
+int yylex __P((void));
+#define YYDEBUG 1
+#if !defined(ultrix) && !defined(hpux)
+int yydebug = 1;
+#else
+extern int yydebug;
+#endif
+
+iface_t *iflist = NULL, **iftail = &iflist;
+iface_t *cifp = NULL;
+arp_t *arplist = NULL, **arptail = &arplist, *carp = NULL;
+struct in_addr defrouter;
+send_t sending;
+char *sclass = NULL;
+u_short c_chksum __P((u_short *, u_int, u_long));
+u_long p_chksum __P((u_short *, u_int));
+
+u_long ipbuffer[67584/sizeof(u_long)]; /* 66K */
+aniphdr_t *aniphead = NULL, *canip = NULL, **aniptail = &aniphead;
+ip_t *ip = NULL;
+udphdr_t *udp = NULL;
+tcphdr_t *tcp = NULL;
+icmphdr_t *icmp = NULL;
+
+struct statetoopt {
+ int sto_st;
+ int sto_op;
+};
+
+struct in_addr getipv4addr __P((char *arg));
+u_short getportnum __P((char *, char *));
+struct ether_addr *geteaddr __P((char *, struct ether_addr *));
+void *new_header __P((int));
+void free_aniplist __P((void));
+void inc_anipheaders __P((int));
+void new_data __P((void));
+void set_datalen __P((char **));
+void set_datafile __P((char **));
+void set_data __P((char **));
+void new_packet __P((void));
+void set_ipv4proto __P((char **));
+void set_ipv4src __P((char **));
+void set_ipv4dst __P((char **));
+void set_ipv4off __P((char **));
+void set_ipv4v __P((char **));
+void set_ipv4hl __P((char **));
+void set_ipv4ttl __P((char **));
+void set_ipv4tos __P((char **));
+void set_ipv4id __P((char **));
+void set_ipv4sum __P((char **));
+void set_ipv4len __P((char **));
+void new_tcpheader __P((void));
+void set_tcpsport __P((char **));
+void set_tcpdport __P((char **));
+void set_tcpseq __P((char **));
+void set_tcpack __P((char **));
+void set_tcpoff __P((char **));
+void set_tcpurp __P((char **));
+void set_tcpwin __P((char **));
+void set_tcpsum __P((char **));
+void set_tcpflags __P((char **));
+void set_tcpopt __P((int, char **));
+void end_tcpopt __P((void));
+void new_udpheader __P((void));
+void set_udplen __P((char **));
+void set_udpsum __P((char **));
+void prep_packet __P((void));
+void packet_done __P((void));
+void new_interface __P((void));
+void check_interface __P((void));
+void set_ifname __P((char **));
+void set_ifmtu __P((int));
+void set_ifv4addr __P((char **));
+void set_ifeaddr __P((char **));
+void new_arp __P((void));
+void set_arpeaddr __P((char **));
+void set_arpv4addr __P((char **));
+void reset_send __P((void));
+void set_sendif __P((char **));
+void set_sendvia __P((char **));
+void set_defaultrouter __P((char **));
+void new_icmpheader __P((void));
+void set_icmpcode __P((int));
+void set_icmptype __P((int));
+void set_icmpcodetok __P((char **));
+void set_icmptypetok __P((char **));
+void set_icmpid __P((int));
+void set_icmpseq __P((int));
+void set_icmpotime __P((int));
+void set_icmprtime __P((int));
+void set_icmpttime __P((int));
+void set_icmpmtu __P((int));
+void set_redir __P((int, char **));
+void new_ipv4opt __P((void));
+void set_icmppprob __P((int));
+void add_ipopt __P((int, void *));
+void end_ipopt __P((void));
+void set_secclass __P((char **));
+void free_anipheader __P((void));
+void end_ipv4 __P((void));
+void end_icmp __P((void));
+void end_udp __P((void));
+void end_tcp __P((void));
+void end_data __P((void));
+void yyerror __P((char *));
+void iplang __P((FILE *));
+int yyparse __P((void));
+%}
+%union {
+ char *str;
+ int num;
+}
+%token <num> IL_NUMBER
+%type <num> number digits optnumber
+%token <str> IL_TOKEN
+%type <str> token optoken
+%token IL_HEXDIGIT IL_COLON IL_DOT IL_EOF IL_COMMENT
+%token IL_INTERFACE IL_IFNAME IL_MTU IL_EADDR
+%token IL_IPV4 IL_V4PROTO IL_V4SRC IL_V4DST IL_V4OFF IL_V4V IL_V4HL IL_V4TTL
+%token IL_V4TOS IL_V4SUM IL_V4LEN IL_V4OPT IL_V4ID
+%token IL_TCP IL_SPORT IL_DPORT IL_TCPFL IL_TCPSEQ IL_TCPACK IL_TCPOFF
+%token IL_TCPWIN IL_TCPSUM IL_TCPURP IL_TCPOPT IL_TCPO_NOP IL_TCPO_EOL
+%token IL_TCPO_MSS IL_TCPO_WSCALE IL_TCPO_TS
+%token IL_UDP IL_UDPLEN IL_UDPSUM
+%token IL_ICMP IL_ICMPTYPE IL_ICMPCODE
+%token IL_SEND IL_VIA
+%token IL_ARP
+%token IL_DEFROUTER
+%token IL_SUM IL_OFF IL_LEN IL_V4ADDR IL_OPT
+%token IL_DATA IL_DLEN IL_DVALUE IL_DFILE
+%token IL_IPO_NOP IL_IPO_RR IL_IPO_ZSU IL_IPO_MTUP IL_IPO_MTUR IL_IPO_EOL
+%token IL_IPO_TS IL_IPO_TR IL_IPO_SEC IL_IPO_LSRR IL_IPO_ESEC
+%token IL_IPO_SATID IL_IPO_SSRR IL_IPO_ADDEXT IL_IPO_VISA IL_IPO_IMITD
+%token IL_IPO_EIP IL_IPO_FINN IL_IPO_SECCLASS IL_IPO_CIPSO IL_IPO_ENCODE
+%token IL_IPS_RESERV4 IL_IPS_TOPSECRET IL_IPS_SECRET IL_IPS_RESERV3
+%token IL_IPS_CONFID IL_IPS_UNCLASS IL_IPS_RESERV2 IL_IPS_RESERV1
+%token IL_ICMP_ECHOREPLY IL_ICMP_UNREACH IL_ICMP_UNREACH_NET
+%token IL_ICMP_UNREACH_HOST IL_ICMP_UNREACH_PROTOCOL IL_ICMP_UNREACH_PORT
+%token IL_ICMP_UNREACH_NEEDFRAG IL_ICMP_UNREACH_SRCFAIL
+%token IL_ICMP_UNREACH_NET_UNKNOWN IL_ICMP_UNREACH_HOST_UNKNOWN
+%token IL_ICMP_UNREACH_ISOLATED IL_ICMP_UNREACH_NET_PROHIB
+%token IL_ICMP_UNREACH_HOST_PROHIB IL_ICMP_UNREACH_TOSNET
+%token IL_ICMP_UNREACH_TOSHOST IL_ICMP_UNREACH_FILTER_PROHIB
+%token IL_ICMP_UNREACH_HOST_PRECEDENCE IL_ICMP_UNREACH_PRECEDENCE_CUTOFF
+%token IL_ICMP_SOURCEQUENCH IL_ICMP_REDIRECT IL_ICMP_REDIRECT_NET
+%token IL_ICMP_REDIRECT_HOST IL_ICMP_REDIRECT_TOSNET
+%token IL_ICMP_REDIRECT_TOSHOST IL_ICMP_ECHO IL_ICMP_ROUTERADVERT
+%token IL_ICMP_ROUTERSOLICIT IL_ICMP_TIMXCEED IL_ICMP_TIMXCEED_INTRANS
+%token IL_ICMP_TIMXCEED_REASS IL_ICMP_PARAMPROB IL_ICMP_PARAMPROB_OPTABSENT
+%token IL_ICMP_TSTAMP IL_ICMP_TSTAMPREPLY IL_ICMP_IREQ IL_ICMP_IREQREPLY
+%token IL_ICMP_MASKREQ IL_ICMP_MASKREPLY IL_ICMP_SEQ IL_ICMP_ID
+%token IL_ICMP_OTIME IL_ICMP_RTIME IL_ICMP_TTIME
+
+%%
+file: line
+ | line file
+ | IL_COMMENT
+ | IL_COMMENT file
+ ;
+
+line: iface
+ | arp
+ | send
+ | defrouter
+ | ipline
+ ;
+
+iface: ifhdr '{' ifaceopts '}' ';' { check_interface(); }
+ ;
+
+ifhdr: IL_INTERFACE { new_interface(); }
+ ;
+
+ifaceopts:
+ ifaceopt
+ | ifaceopt ifaceopts
+ ;
+
+ifaceopt:
+ IL_IFNAME token { set_ifname(&yylval.str); }
+ | IL_MTU number { set_ifmtu(yylval.num); }
+ | IL_V4ADDR token { set_ifv4addr(&yylval.str); }
+ | IL_EADDR token { set_ifeaddr(&yylval.str); }
+ ;
+
+send: sendhdr '{' sendbody '}' ';' { packet_done(); }
+ | sendhdr ';' { packet_done(); }
+ ;
+
+sendhdr:
+ IL_SEND { reset_send(); }
+ ;
+
+sendbody:
+ sendopt
+ | sendbody sendopt
+ ;
+
+sendopt:
+ IL_IFNAME token { set_sendif(&yylval.str); }
+ | IL_VIA token { set_sendvia(&yylval.str); }
+ ;
+
+arp: arphdr '{' arpbody '}' ';'
+ ;
+
+arphdr: IL_ARP { new_arp(); }
+ ;
+
+arpbody:
+ arpopt
+ | arpbody arpopt
+ ;
+
+arpopt: IL_V4ADDR token { set_arpv4addr(&yylval.str); }
+ | IL_EADDR token { set_arpeaddr(&yylval.str); }
+ ;
+
+defrouter:
+ IL_DEFROUTER token { set_defaultrouter(&yylval.str); }
+ ;
+
+bodyline:
+ ipline
+ | tcp tcpline
+ | udp udpline
+ | icmp icmpline
+ | data dataline
+ ;
+
+ipline: ipv4 '{' ipv4body '}' ';' { end_ipv4(); }
+ ;
+
+ipv4: IL_IPV4 { new_packet(); }
+
+ipv4body:
+ ipv4type
+ | ipv4type ipv4body
+ | bodyline
+ ;
+
+ipv4type:
+ IL_V4PROTO token { set_ipv4proto(&yylval.str); }
+ | IL_V4SRC token { set_ipv4src(&yylval.str); }
+ | IL_V4DST token { set_ipv4dst(&yylval.str); }
+ | IL_V4OFF token { set_ipv4off(&yylval.str); }
+ | IL_V4V token { set_ipv4v(&yylval.str); }
+ | IL_V4HL token { set_ipv4hl(&yylval.str); }
+ | IL_V4ID token { set_ipv4id(&yylval.str); }
+ | IL_V4TTL token { set_ipv4ttl(&yylval.str); }
+ | IL_V4TOS token { set_ipv4tos(&yylval.str); }
+ | IL_V4SUM token { set_ipv4sum(&yylval.str); }
+ | IL_V4LEN token { set_ipv4len(&yylval.str); }
+ | ipv4opt '{' ipv4optlist '}' ';' { end_ipopt(); }
+ ;
+
+tcp: IL_TCP { new_tcpheader(); }
+ ;
+
+tcpline:
+ '{' tcpheader '}' ';' { end_tcp(); }
+ ;
+
+tcpheader:
+ tcpbody tcpheader
+ | bodyline
+ ;
+
+tcpbody:
+ IL_SPORT token { set_tcpsport(&yylval.str); }
+ | IL_DPORT token { set_tcpdport(&yylval.str); }
+ | IL_TCPSEQ token { set_tcpseq(&yylval.str); }
+ | IL_TCPACK token { set_tcpack(&yylval.str); }
+ | IL_TCPOFF token { set_tcpoff(&yylval.str); }
+ | IL_TCPURP token { set_tcpurp(&yylval.str); }
+ | IL_TCPWIN token { set_tcpwin(&yylval.str); }
+ | IL_TCPSUM token { set_tcpsum(&yylval.str); }
+ | IL_TCPFL token { set_tcpflags(&yylval.str); }
+ | IL_TCPOPT '{' tcpopts '}' ';' { end_tcpopt(); }
+ ;
+
+tcpopts:
+ | tcpopt tcpopts
+ ;
+
+tcpopt: IL_TCPO_NOP ';' { set_tcpopt(IL_TCPO_NOP, NULL); }
+ | IL_TCPO_EOL ';' { set_tcpopt(IL_TCPO_EOL, NULL); }
+ | IL_TCPO_MSS optoken { set_tcpopt(IL_TCPO_MSS,&yylval.str);}
+ | IL_TCPO_WSCALE optoken { set_tcpopt(IL_TCPO_MSS,&yylval.str);}
+ | IL_TCPO_TS optoken { set_tcpopt(IL_TCPO_TS, &yylval.str);}
+ ;
+
+udp: IL_UDP { new_udpheader(); }
+ ;
+
+udpline:
+ '{' udpheader '}' ';' { end_udp(); }
+ ;
+
+
+udpheader:
+ udpbody
+ | udpbody udpheader
+ | bodyline
+ ;
+
+udpbody:
+ IL_SPORT token { set_tcpsport(&yylval.str); }
+ | IL_DPORT token { set_tcpdport(&yylval.str); }
+ | IL_UDPLEN token { set_udplen(&yylval.str); }
+ | IL_UDPSUM token { set_udpsum(&yylval.str); }
+ ;
+
+icmp: IL_ICMP { new_icmpheader(); }
+ ;
+
+icmpline:
+ '{' icmpbody '}' ';' { end_icmp(); }
+ ;
+
+icmpbody:
+ icmpheader
+ | icmpheader bodyline
+ ;
+
+icmpheader:
+ IL_ICMPTYPE icmptype
+ | IL_ICMPTYPE icmptype icmpcode
+ ;
+
+icmpcode:
+ IL_ICMPCODE token { set_icmpcodetok(&yylval.str); }
+ ;
+
+icmptype:
+ IL_ICMP_ECHOREPLY ';' { set_icmptype(ICMP_ECHOREPLY); }
+ | IL_ICMP_ECHOREPLY '{' icmpechoopts '}' ';'
+ | unreach
+ | IL_ICMP_SOURCEQUENCH ';' { set_icmptype(ICMP_SOURCEQUENCH); }
+ | redirect
+ | IL_ICMP_ROUTERADVERT ';' { set_icmptype(ICMP_ROUTERADVERT); }
+ | IL_ICMP_ROUTERSOLICIT ';' { set_icmptype(ICMP_ROUTERSOLICIT); }
+ | IL_ICMP_ECHO ';' { set_icmptype(ICMP_ECHO); }
+ | IL_ICMP_ECHO '{' icmpechoopts '}' ';'
+ | IL_ICMP_TIMXCEED ';' { set_icmptype(ICMP_TIMXCEED); }
+ | IL_ICMP_TIMXCEED '{' exceed '}' ';'
+ | IL_ICMP_TSTAMP ';' { set_icmptype(ICMP_TSTAMP); }
+ | IL_ICMP_TSTAMPREPLY ';' { set_icmptype(ICMP_TSTAMPREPLY); }
+ | IL_ICMP_TSTAMPREPLY '{' icmptsopts '}' ';'
+ | IL_ICMP_IREQ ';' { set_icmptype(ICMP_IREQ); }
+ | IL_ICMP_IREQREPLY ';' { set_icmptype(ICMP_IREQREPLY); }
+ | IL_ICMP_IREQREPLY '{' data dataline '}' ';'
+ | IL_ICMP_MASKREQ ';' { set_icmptype(ICMP_MASKREQ); }
+ | IL_ICMP_MASKREPLY ';' { set_icmptype(ICMP_MASKREPLY); }
+ | IL_ICMP_MASKREPLY '{' token '}' ';'
+ | IL_ICMP_PARAMPROB ';' { set_icmptype(ICMP_PARAMPROB); }
+ | IL_ICMP_PARAMPROB '{' paramprob '}' ';'
+ | IL_TOKEN ';' { set_icmptypetok(&yylval.str); }
+ ;
+
+icmpechoopts:
+ | icmpechoopts icmpecho
+ ;
+
+icmpecho:
+ IL_ICMP_SEQ number { set_icmpseq(yylval.num); }
+ | IL_ICMP_ID number { set_icmpid(yylval.num); }
+ ;
+
+icmptsopts:
+ | icmptsopts icmpts ';'
+ ;
+
+icmpts: IL_ICMP_OTIME number { set_icmpotime(yylval.num); }
+ | IL_ICMP_RTIME number { set_icmprtime(yylval.num); }
+ | IL_ICMP_TTIME number { set_icmpttime(yylval.num); }
+ ;
+
+unreach:
+ IL_ICMP_UNREACH
+ | IL_ICMP_UNREACH '{' unreachopts '}' ';'
+ ;
+
+unreachopts:
+ IL_ICMP_UNREACH_NET line
+ | IL_ICMP_UNREACH_HOST line
+ | IL_ICMP_UNREACH_PROTOCOL line
+ | IL_ICMP_UNREACH_PORT line
+ | IL_ICMP_UNREACH_NEEDFRAG number ';' { set_icmpmtu(yylval.num); }
+ | IL_ICMP_UNREACH_SRCFAIL line
+ | IL_ICMP_UNREACH_NET_UNKNOWN line
+ | IL_ICMP_UNREACH_HOST_UNKNOWN line
+ | IL_ICMP_UNREACH_ISOLATED line
+ | IL_ICMP_UNREACH_NET_PROHIB line
+ | IL_ICMP_UNREACH_HOST_PROHIB line
+ | IL_ICMP_UNREACH_TOSNET line
+ | IL_ICMP_UNREACH_TOSHOST line
+ | IL_ICMP_UNREACH_FILTER_PROHIB line
+ | IL_ICMP_UNREACH_HOST_PRECEDENCE line
+ | IL_ICMP_UNREACH_PRECEDENCE_CUTOFF line
+ ;
+
+redirect:
+ IL_ICMP_REDIRECT
+ | IL_ICMP_REDIRECT '{' redirectopts '}' ';'
+ ;
+
+redirectopts:
+ | IL_ICMP_REDIRECT_NET token { set_redir(0, &yylval.str); }
+ | IL_ICMP_REDIRECT_HOST token { set_redir(1, &yylval.str); }
+ | IL_ICMP_REDIRECT_TOSNET token { set_redir(2, &yylval.str); }
+ | IL_ICMP_REDIRECT_TOSHOST token { set_redir(3, &yylval.str); }
+ ;
+
+exceed:
+ IL_ICMP_TIMXCEED_INTRANS line
+ | IL_ICMP_TIMXCEED_REASS line
+ ;
+
+paramprob:
+ IL_ICMP_PARAMPROB_OPTABSENT
+ | IL_ICMP_PARAMPROB_OPTABSENT paraprobarg
+
+paraprobarg:
+ '{' number '}' ';' { set_icmppprob(yylval.num); }
+ ;
+
+ipv4opt: IL_V4OPT { new_ipv4opt(); }
+ ;
+
+ipv4optlist:
+ | ipv4opts ipv4optlist
+ ;
+
+ipv4opts:
+ IL_IPO_NOP ';' { add_ipopt(IL_IPO_NOP, NULL); }
+ | IL_IPO_RR optnumber { add_ipopt(IL_IPO_RR, &yylval.num); }
+ | IL_IPO_ZSU ';' { add_ipopt(IL_IPO_ZSU, NULL); }
+ | IL_IPO_MTUP ';' { add_ipopt(IL_IPO_MTUP, NULL); }
+ | IL_IPO_MTUR ';' { add_ipopt(IL_IPO_MTUR, NULL); }
+ | IL_IPO_ENCODE ';' { add_ipopt(IL_IPO_ENCODE, NULL); }
+ | IL_IPO_TS ';' { add_ipopt(IL_IPO_TS, NULL); }
+ | IL_IPO_TR ';' { add_ipopt(IL_IPO_TR, NULL); }
+ | IL_IPO_SEC ';' { add_ipopt(IL_IPO_SEC, NULL); }
+ | IL_IPO_SECCLASS secclass { add_ipopt(IL_IPO_SECCLASS, sclass); }
+ | IL_IPO_LSRR token { add_ipopt(IL_IPO_LSRR,&yylval.str); }
+ | IL_IPO_ESEC ';' { add_ipopt(IL_IPO_ESEC, NULL); }
+ | IL_IPO_CIPSO ';' { add_ipopt(IL_IPO_CIPSO, NULL); }
+ | IL_IPO_SATID optnumber { add_ipopt(IL_IPO_SATID,&yylval.num);}
+ | IL_IPO_SSRR token { add_ipopt(IL_IPO_SSRR,&yylval.str); }
+ | IL_IPO_ADDEXT ';' { add_ipopt(IL_IPO_ADDEXT, NULL); }
+ | IL_IPO_VISA ';' { add_ipopt(IL_IPO_VISA, NULL); }
+ | IL_IPO_IMITD ';' { add_ipopt(IL_IPO_IMITD, NULL); }
+ | IL_IPO_EIP ';' { add_ipopt(IL_IPO_EIP, NULL); }
+ | IL_IPO_FINN ';' { add_ipopt(IL_IPO_FINN, NULL); }
+ ;
+
+secclass:
+ IL_IPS_RESERV4 ';' { set_secclass(&yylval.str); }
+ | IL_IPS_TOPSECRET ';' { set_secclass(&yylval.str); }
+ | IL_IPS_SECRET ';' { set_secclass(&yylval.str); }
+ | IL_IPS_RESERV3 ';' { set_secclass(&yylval.str); }
+ | IL_IPS_CONFID ';' { set_secclass(&yylval.str); }
+ | IL_IPS_UNCLASS ';' { set_secclass(&yylval.str); }
+ | IL_IPS_RESERV2 ';' { set_secclass(&yylval.str); }
+ | IL_IPS_RESERV1 ';' { set_secclass(&yylval.str); }
+ ;
+
+data: IL_DATA { new_data(); }
+ ;
+
+dataline:
+ '{' databody '}' ';' { end_data(); }
+ ;
+
+databody: dataopts
+ | dataopts databody
+ ;
+
+dataopts:
+ IL_DLEN token { set_datalen(&yylval.str); }
+ | IL_DVALUE token { set_data(&yylval.str); }
+ | IL_DFILE token { set_datafile(&yylval.str); }
+ ;
+
+token: IL_TOKEN ';'
+ ;
+
+optoken: ';' { $$ = ""; }
+ | token
+ ;
+
+number: digits ';'
+ ;
+
+optnumber: ';' { $$ = 0; }
+ | number
+ ;
+
+digits: IL_NUMBER
+ | digits IL_NUMBER
+ ;
+%%
+
+struct statetoopt toipopts[] = {
+ { IL_IPO_NOP, IPOPT_NOP },
+ { IL_IPO_RR, IPOPT_RR },
+ { IL_IPO_ZSU, IPOPT_ZSU },
+ { IL_IPO_MTUP, IPOPT_MTUP },
+ { IL_IPO_MTUR, IPOPT_MTUR },
+ { IL_IPO_ENCODE, IPOPT_ENCODE },
+ { IL_IPO_TS, IPOPT_TS },
+ { IL_IPO_TR, IPOPT_TR },
+ { IL_IPO_SEC, IPOPT_SECURITY },
+ { IL_IPO_SECCLASS, IPOPT_SECURITY },
+ { IL_IPO_LSRR, IPOPT_LSRR },
+ { IL_IPO_ESEC, IPOPT_E_SEC },
+ { IL_IPO_CIPSO, IPOPT_CIPSO },
+ { IL_IPO_SATID, IPOPT_SATID },
+ { IL_IPO_SSRR, IPOPT_SSRR },
+ { IL_IPO_ADDEXT, IPOPT_ADDEXT },
+ { IL_IPO_VISA, IPOPT_VISA },
+ { IL_IPO_IMITD, IPOPT_IMITD },
+ { IL_IPO_EIP, IPOPT_EIP },
+ { IL_IPO_FINN, IPOPT_FINN },
+ { 0, 0 }
+};
+
+struct statetoopt tosecopts[] = {
+ { IL_IPS_RESERV4, IPSO_CLASS_RES4 },
+ { IL_IPS_TOPSECRET, IPSO_CLASS_TOPS },
+ { IL_IPS_SECRET, IPSO_CLASS_SECR },
+ { IL_IPS_RESERV3, IPSO_CLASS_RES3 },
+ { IL_IPS_CONFID, IPSO_CLASS_CONF },
+ { IL_IPS_UNCLASS, IPSO_CLASS_UNCL },
+ { IL_IPS_RESERV2, IPSO_CLASS_RES2 },
+ { IL_IPS_RESERV1, IPSO_CLASS_RES1 },
+ { 0, 0 }
+};
+
+#ifdef bsdi
+struct ether_addr *
+ether_aton(s)
+ char *s;
+{
+ static struct ether_addr n;
+ u_int i[6];
+
+ if (sscanf(s, " %x:%x:%x:%x:%x:%x ", &i[0], &i[1],
+ &i[2], &i[3], &i[4], &i[5]) == 6) {
+ n.ether_addr_octet[0] = (u_char)i[0];
+ n.ether_addr_octet[1] = (u_char)i[1];
+ n.ether_addr_octet[2] = (u_char)i[2];
+ n.ether_addr_octet[3] = (u_char)i[3];
+ n.ether_addr_octet[4] = (u_char)i[4];
+ n.ether_addr_octet[5] = (u_char)i[5];
+ return &n;
+ }
+ return NULL;
+}
+#endif
+
+#ifdef bsdi
+struct ether_addr *
+ether_aton(s)
+ char *s;
+{
+ static struct ether_addr n;
+ u_int i[6];
+
+ if (sscanf(s, " %x:%x:%x:%x:%x:%x ", &i[0], &i[1],
+ &i[2], &i[3], &i[4], &i[5]) == 6) {
+ n.ether_addr_octet[0] = (u_char)i[0];
+ n.ether_addr_octet[1] = (u_char)i[1];
+ n.ether_addr_octet[2] = (u_char)i[2];
+ n.ether_addr_octet[3] = (u_char)i[3];
+ n.ether_addr_octet[4] = (u_char)i[4];
+ n.ether_addr_octet[5] = (u_char)i[5];
+ return &n;
+ }
+ return NULL;
+}
+#endif
+
+
+struct in_addr getipv4addr(arg)
+char *arg;
+{
+ struct hostent *hp;
+ struct in_addr in;
+
+ in.s_addr = 0xffffffff;
+
+ if ((hp = gethostbyname(arg)))
+ bcopy(hp->h_addr, &in.s_addr, sizeof(struct in_addr));
+ else
+ in.s_addr = inet_addr(arg);
+ return in;
+}
+
+
+u_short getportnum(pr, name)
+char *pr, *name;
+{
+ struct servent *sp;
+
+ if (!(sp = getservbyname(name, pr)))
+ return atoi(name);
+ return sp->s_port;
+}
+
+
+struct ether_addr *geteaddr(arg, buf)
+char *arg;
+struct ether_addr *buf;
+{
+ struct ether_addr *e;
+
+#if !defined(hpux) && !defined(linux)
+ e = ether_aton(arg);
+ if (!e)
+ fprintf(stderr, "Invalid ethernet address: %s\n", arg);
+ else
+# ifdef __FreeBSD__
+ bcopy(e->octet, buf->octet, sizeof(e->octet));
+# else
+ bcopy(e->ether_addr_octet, buf->ether_addr_octet,
+ sizeof(e->ether_addr_octet));
+# endif
+ return e;
+#else
+ return NULL;
+#endif
+}
+
+
+void *new_header(type)
+int type;
+{
+ aniphdr_t *aip, *oip = canip;
+ int sz = 0;
+
+ aip = (aniphdr_t *)calloc(1, sizeof(*aip));
+ *aniptail = aip;
+ aniptail = &aip->ah_next;
+ aip->ah_p = type;
+ aip->ah_prev = oip;
+ canip = aip;
+
+ if (type == IPPROTO_UDP)
+ sz = sizeof(udphdr_t);
+ else if (type == IPPROTO_TCP)
+ sz = sizeof(tcphdr_t);
+ else if (type == IPPROTO_ICMP)
+ sz = sizeof(icmphdr_t);
+ else if (type == IPPROTO_IP)
+ sz = sizeof(ip_t);
+
+ if (oip)
+ canip->ah_data = oip->ah_data + oip->ah_len;
+ else
+ canip->ah_data = (char *)ipbuffer;
+
+ /*
+ * Increase the size fields in all wrapping headers.
+ */
+ for (aip = aniphead; aip; aip = aip->ah_next) {
+ aip->ah_len += sz;
+ if (aip->ah_p == IPPROTO_IP)
+ aip->ah_ip->ip_len += sz;
+ else if (aip->ah_p == IPPROTO_UDP)
+ aip->ah_udp->uh_ulen += sz;
+ }
+ return (void *)canip->ah_data;
+}
+
+
+void free_aniplist()
+{
+ aniphdr_t *aip, **aipp = &aniphead;
+
+ while ((aip = *aipp)) {
+ *aipp = aip->ah_next;
+ free(aip);
+ }
+ aniptail = &aniphead;
+}
+
+
+void inc_anipheaders(inc)
+int inc;
+{
+ aniphdr_t *aip;
+
+ for (aip = aniphead; aip; aip = aip->ah_next) {
+ aip->ah_len += inc;
+ if (aip->ah_p == IPPROTO_IP)
+ aip->ah_ip->ip_len += inc;
+ else if (aip->ah_p == IPPROTO_UDP)
+ aip->ah_udp->uh_ulen += inc;
+ }
+}
+
+
+void new_data()
+{
+ (void) new_header(-1);
+ canip->ah_len = 0;
+}
+
+
+void set_datalen(arg)
+char **arg;
+{
+ int len;
+
+ len = strtol(*arg, NULL, 0);
+ inc_anipheaders(len);
+ free(*arg);
+ *arg = NULL;
+}
+
+
+void set_data(arg)
+char **arg;
+{
+ u_char *s = (u_char *)*arg, *t = (u_char *)canip->ah_data, c;
+ int len = 0, todo = 0, quote = 0, val = 0;
+
+ while ((c = *s++)) {
+ if (todo) {
+ if (isdigit(c)) {
+ todo--;
+ if (c > '7') {
+ fprintf(stderr, "octal with %c!\n", c);
+ break;
+ }
+ val <<= 3;
+ val |= (c - '0');
+ }
+ if (!isdigit(c) || !todo) {
+ *t++ = (u_char)(val & 0xff);
+ todo = 0;
+ }
+ }
+ if (quote) {
+ if (isdigit(c)) {
+ todo = 2;
+ if (c > '7') {
+ fprintf(stderr, "octal with %c!\n", c);
+ break;
+ }
+ val = (c - '0');
+ } else {
+ switch (c)
+ {
+ case '\"' :
+ *t++ = '\"';
+ break;
+ case '\\' :
+ *t++ = '\\';
+ break;
+ case 'n' :
+ *t++ = '\n';
+ break;
+ case 'r' :
+ *t++ = '\r';
+ break;
+ case 't' :
+ *t++ = '\t';
+ break;
+ }
+ quote = 0;
+ }
+ continue;
+ }
+
+ if (c == '\\')
+ quote = 1;
+ else
+ *t++ = c;
+ }
+ if (quote)
+ *t++ = '\\';
+ len = t - (u_char *)canip->ah_data;
+ inc_anipheaders(len - canip->ah_len);
+ canip->ah_len = len;
+}
+
+
+void set_datafile(arg)
+char **arg;
+{
+ struct stat sb;
+ char *file = *arg;
+ int fd, len;
+
+ if ((fd = open(file, O_RDONLY)) == -1) {
+ perror("open");
+ exit(-1);
+ }
+
+ if (fstat(fd, &sb) == -1) {
+ perror("fstat");
+ exit(-1);
+ }
+
+ if ((sb.st_size + aniphead->ah_len ) > 65535) {
+ fprintf(stderr, "data file %s too big to include.\n", file);
+ close(fd);
+ return;
+ }
+ if ((len = read(fd, canip->ah_data, sb.st_size)) == -1) {
+ perror("read");
+ close(fd);
+ return;
+ }
+ inc_anipheaders(len);
+ canip->ah_len += len;
+ close(fd);
+}
+
+
+void new_packet()
+{
+ static u_short id = 0;
+
+ if (!aniphead)
+ bzero((char *)ipbuffer, sizeof(ipbuffer));
+
+ ip = (ip_t *)new_header(IPPROTO_IP);
+ ip->ip_v = IPVERSION;
+ ip->ip_hl = sizeof(ip_t) >> 2;
+ ip->ip_len = sizeof(ip_t);
+ ip->ip_ttl = 63;
+ ip->ip_id = htons(id++);
+}
+
+
+void set_ipv4proto(arg)
+char **arg;
+{
+ struct protoent *pr;
+
+ if ((pr = getprotobyname(*arg)))
+ ip->ip_p = pr->p_proto;
+ else
+ if (!(ip->ip_p = atoi(*arg)))
+ fprintf(stderr, "unknown protocol %s\n", *arg);
+ free(*arg);
+ *arg = NULL;
+}
+
+
+void set_ipv4src(arg)
+char **arg;
+{
+ ip->ip_src = getipv4addr(*arg);
+ free(*arg);
+ *arg = NULL;
+}
+
+
+void set_ipv4dst(arg)
+char **arg;
+{
+ ip->ip_dst = getipv4addr(*arg);
+ free(*arg);
+ *arg = NULL;
+}
+
+
+void set_ipv4off(arg)
+char **arg;
+{
+ ip->ip_off = strtol(*arg, NULL, 0);
+ free(*arg);
+ *arg = NULL;
+}
+
+
+void set_ipv4v(arg)
+char **arg;
+{
+ ip->ip_v = strtol(*arg, NULL, 0);
+ free(*arg);
+ *arg = NULL;
+}
+
+
+void set_ipv4hl(arg)
+char **arg;
+{
+ int newhl, inc;
+
+ newhl = strtol(*arg, NULL, 0);
+ inc = (newhl - ip->ip_hl) << 2;
+ ip->ip_len += inc;
+ ip->ip_hl = newhl;
+ canip->ah_len += inc;
+ free(*arg);
+ *arg = NULL;
+}
+
+
+void set_ipv4ttl(arg)
+char **arg;
+{
+ ip->ip_ttl = strtol(*arg, NULL, 0);
+ free(*arg);
+ *arg = NULL;
+}
+
+
+void set_ipv4tos(arg)
+char **arg;
+{
+ ip->ip_tos = strtol(*arg, NULL, 0);
+ free(*arg);
+ *arg = NULL;
+}
+
+
+void set_ipv4id(arg)
+char **arg;
+{
+ ip->ip_id = strtol(*arg, NULL, 0);
+ free(*arg);
+ *arg = NULL;
+}
+
+
+void set_ipv4sum(arg)
+char **arg;
+{
+ ip->ip_sum = strtol(*arg, NULL, 0);
+ free(*arg);
+ *arg = NULL;
+}
+
+
+void set_ipv4len(arg)
+char **arg;
+{
+ int len;
+
+ len = strtol(*arg, NULL, 0);
+ inc_anipheaders(len - ip->ip_len);
+ ip->ip_len = len;
+ free(*arg);
+ *arg = NULL;
+}
+
+
+void new_tcpheader()
+{
+
+ if ((ip->ip_p) && (ip->ip_p != IPPROTO_TCP)) {
+ fprintf(stderr, "protocol %d specified with TCP!\n", ip->ip_p);
+ return;
+ }
+ ip->ip_p = IPPROTO_TCP;
+
+ tcp = (tcphdr_t *)new_header(IPPROTO_TCP);
+ tcp->th_win = 4096;
+ tcp->th_off = sizeof(*tcp) >> 2;
+}
+
+
+void set_tcpsport(arg)
+char **arg;
+{
+ u_short *port;
+ char *pr;
+
+ if (ip->ip_p == IPPROTO_UDP) {
+ port = &udp->uh_sport;
+ pr = "udp";
+ } else {
+ port = &tcp->th_sport;
+ pr = "udp";
+ }
+
+ *port = getportnum(pr, *arg);
+ free(*arg);
+ *arg = NULL;
+}
+
+
+void set_tcpdport(arg)
+char **arg;
+{
+ u_short *port;
+ char *pr;
+
+ if (ip->ip_p == IPPROTO_UDP) {
+ port = &udp->uh_dport;
+ pr = "udp";
+ } else {
+ port = &tcp->th_dport;
+ pr = "udp";
+ }
+
+ *port = getportnum(pr, *arg);
+ free(*arg);
+ *arg = NULL;
+}
+
+
+void set_tcpseq(arg)
+char **arg;
+{
+ tcp->th_seq = strtol(*arg, NULL, 0);
+ free(*arg);
+ *arg = NULL;
+}
+
+
+void set_tcpack(arg)
+char **arg;
+{
+ tcp->th_ack = strtol(*arg, NULL, 0);
+ free(*arg);
+ *arg = NULL;
+}
+
+
+void set_tcpoff(arg)
+char **arg;
+{
+ int off;
+
+ off = strtol(*arg, NULL, 0);
+ inc_anipheaders((off - tcp->th_off) << 2);
+ tcp->th_off = off;
+ free(*arg);
+ *arg = NULL;
+}
+
+
+void set_tcpurp(arg)
+char **arg;
+{
+ tcp->th_urp = strtol(*arg, NULL, 0);
+ free(*arg);
+ *arg = NULL;
+}
+
+
+void set_tcpwin(arg)
+char **arg;
+{
+ tcp->th_win = strtol(*arg, NULL, 0);
+ free(*arg);
+ *arg = NULL;
+}
+
+
+void set_tcpsum(arg)
+char **arg;
+{
+ tcp->th_sum = strtol(*arg, NULL, 0);
+ free(*arg);
+ *arg = NULL;
+}
+
+
+void set_tcpflags(arg)
+char **arg;
+{
+ static char flags[] = "ASURPF";
+ static int flagv[] = { TH_ACK, TH_SYN, TH_URG, TH_RST, TH_PUSH,
+ TH_FIN } ;
+ char *s, *t;
+
+ for (s = *arg; *s; s++)
+ if (!(t = strchr(flags, *s))) {
+ if (s - *arg) {
+ fprintf(stderr, "unknown TCP flag %c\n", *s);
+ break;
+ }
+ tcp->th_flags = strtol(*arg, NULL, 0);
+ break;
+ } else
+ tcp->th_flags |= flagv[t - flags];
+ free(*arg);
+ *arg = NULL;
+}
+
+
+void set_tcpopt(state, arg)
+int state;
+char **arg;
+{
+ u_char *s;
+ int val, len, val2, pad, optval;
+
+ if (arg && *arg)
+ val = atoi(*arg);
+ else
+ val = 0;
+
+ s = (u_char *)tcp + sizeof(*tcp) + canip->ah_optlen;
+ switch (state)
+ {
+ case IL_TCPO_EOL :
+ optval = 0;
+ len = 1;
+ break;
+ case IL_TCPO_NOP :
+ optval = 1;
+ len = 1;
+ break;
+ case IL_TCPO_MSS :
+ optval = 2;
+ len = 4;
+ break;
+ case IL_TCPO_WSCALE :
+ optval = 3;
+ len = 3;
+ break;
+ case IL_TCPO_TS :
+ optval = 8;
+ len = 10;
+ break;
+ default :
+ optval = 0;
+ len = 0;
+ break;
+ }
+
+ if (len > 1) {
+ /*
+ * prepend padding - if required.
+ */
+ if (len & 3)
+ for (pad = 4 - (len & 3); pad; pad--) {
+ *s++ = 1;
+ canip->ah_optlen++;
+ }
+ /*
+ * build tcp option
+ */
+ *s++ = (u_char)optval;
+ *s++ = (u_char)len;
+ if (len > 2) {
+ if (len == 3) { /* 1 byte - char */
+ *s++ = (u_char)val;
+ } else if (len == 4) { /* 2 bytes - short */
+ *s++ = (u_char)((val >> 8) & 0xff);
+ *s++ = (u_char)(val & 0xff);
+ } else if (len >= 6) { /* 4 bytes - long */
+ val2 = htonl(val);
+ bcopy((char *)&val2, s, 4);
+ }
+ s += (len - 2);
+ }
+ } else
+ *s++ = (u_char)optval;
+
+ canip->ah_lastopt = optval;
+ canip->ah_optlen += len;
+
+ if (arg && *arg) {
+ free(*arg);
+ *arg = NULL;
+ }
+}
+
+
+void end_tcpopt()
+{
+ int pad;
+ char *s = (char *)tcp;
+
+ s += sizeof(*tcp) + canip->ah_optlen;
+ /*
+ * pad out so that we have a multiple of 4 bytes in size fo the
+ * options. make sure last byte is EOL.
+ */
+ if (canip->ah_optlen & 3) {
+ if (canip->ah_lastopt != 1) {
+ for (pad = 3 - (canip->ah_optlen & 3); pad; pad--) {
+ *s++ = 1;
+ canip->ah_optlen++;
+ }
+ canip->ah_optlen++;
+ } else {
+ s -= 1;
+
+ for (pad = 3 - (canip->ah_optlen & 3); pad; pad--) {
+ *s++ = 1;
+ canip->ah_optlen++;
+ }
+ }
+ *s++ = 0;
+ }
+ tcp->th_off = (sizeof(*tcp) + canip->ah_optlen) >> 2;
+ inc_anipheaders(canip->ah_optlen);
+}
+
+
+void new_udpheader()
+{
+ if ((ip->ip_p) && (ip->ip_p != IPPROTO_UDP)) {
+ fprintf(stderr, "protocol %d specified with UDP!\n", ip->ip_p);
+ return;
+ }
+ ip->ip_p = IPPROTO_UDP;
+
+ udp = (udphdr_t *)new_header(IPPROTO_UDP);
+ udp->uh_ulen = sizeof(*udp);
+}
+
+
+void set_udplen(arg)
+char **arg;
+{
+ int len;
+
+ len = strtol(*arg, NULL, 0);
+ inc_anipheaders(len - udp->uh_ulen);
+ udp->uh_ulen = len;
+ free(*arg);
+ *arg = NULL;
+}
+
+
+void set_udpsum(arg)
+char **arg;
+{
+ udp->uh_sum = strtol(*arg, NULL, 0);
+ free(*arg);
+ *arg = NULL;
+}
+
+
+void prep_packet()
+{
+ iface_t *ifp;
+ struct in_addr gwip;
+
+ ifp = sending.snd_if;
+ if (!ifp) {
+ fprintf(stderr, "no interface defined for sending!\n");
+ return;
+ }
+ if (ifp->if_fd == -1)
+ ifp->if_fd = initdevice(ifp->if_name, 0, 5);
+ gwip = sending.snd_gw;
+ if (!gwip.s_addr)
+ gwip = aniphead->ah_ip->ip_dst;
+ (void) send_ip(ifp->if_fd, ifp->if_MTU, (ip_t *)ipbuffer, gwip, 2);
+}
+
+
+void packet_done()
+{
+ char outline[80];
+ int i, j, k;
+ u_char *s = (u_char *)ipbuffer, *t = (u_char *)outline;
+
+ if (opts & OPT_VERBOSE) {
+ for (i = ip->ip_len, j = 0; i; i--, j++, s++) {
+ if (j && !(j & 0xf)) {
+ *t++ = '\n';
+ *t = '\0';
+ fputs(outline, stdout);
+ fflush(stdout);
+ t = (u_char *)outline;
+ *t = '\0';
+ }
+ sprintf((char *)t, "%02x", *s & 0xff);
+ t += 2;
+ if (!((j + 1) & 0xf)) {
+ s -= 15;
+ sprintf((char *)t, " ");
+ t += 8;
+ for (k = 16; k; k--, s++)
+ *t++ = (isprint(*s) ? *s : '.');
+ s--;
+ }
+
+ if ((j + 1) & 0xf)
+ *t++ = ' ';;
+ }
+
+ if (j & 0xf) {
+ for (k = 16 - (j & 0xf); k; k--) {
+ *t++ = ' ';
+ *t++ = ' ';
+ *t++ = ' ';
+ }
+ sprintf((char *)t, " ");
+ t += 7;
+ s -= j & 0xf;
+ for (k = j & 0xf; k; k--, s++)
+ *t++ = (isprint(*s) ? *s : '.');
+ *t++ = '\n';
+ *t = '\0';
+ }
+ fputs(outline, stdout);
+ fflush(stdout);
+ }
+
+ prep_packet();
+ free_aniplist();
+}
+
+
+void new_interface()
+{
+ cifp = (iface_t *)calloc(1, sizeof(iface_t));
+ *iftail = cifp;
+ iftail = &cifp->if_next;
+ cifp->if_fd = -1;
+}
+
+
+void check_interface()
+{
+ if (!cifp->if_name || !*cifp->if_name)
+ fprintf(stderr, "No interface name given!\n");
+ if (!cifp->if_MTU || !*cifp->if_name)
+ fprintf(stderr, "Interface %s has an MTU of 0!\n",
+ cifp->if_name);
+}
+
+
+void set_ifname(arg)
+char **arg;
+{
+ cifp->if_name = *arg;
+ *arg = NULL;
+}
+
+
+void set_ifmtu(arg)
+int arg;
+{
+ cifp->if_MTU = arg;
+}
+
+
+void set_ifv4addr(arg)
+char **arg;
+{
+ cifp->if_addr = getipv4addr(*arg);
+ free(*arg);
+ *arg = NULL;
+}
+
+
+void set_ifeaddr(arg)
+char **arg;
+{
+ (void) geteaddr(*arg, &cifp->if_eaddr);
+ free(*arg);
+ *arg = NULL;
+}
+
+
+void new_arp()
+{
+ carp = (arp_t *)calloc(1, sizeof(arp_t));
+ *arptail = carp;
+ arptail = &carp->arp_next;
+}
+
+
+void set_arpeaddr(arg)
+char **arg;
+{
+ (void) geteaddr(*arg, &carp->arp_eaddr);
+ free(*arg);
+ *arg = NULL;
+}
+
+
+void set_arpv4addr(arg)
+char **arg;
+{
+ carp->arp_addr = getipv4addr(*arg);
+ free(*arg);
+ *arg = NULL;
+}
+
+
+void reset_send()
+{
+ sending.snd_if = iflist;
+ sending.snd_gw = defrouter;
+}
+
+
+void set_sendif(arg)
+char **arg;
+{
+ iface_t *ifp;
+
+ for (ifp = iflist; ifp; ifp = ifp->if_next)
+ if (ifp->if_name && !strcmp(ifp->if_name, *arg))
+ break;
+ sending.snd_if = ifp;
+ if (!ifp)
+ fprintf(stderr, "couldn't find interface %s\n", *arg);
+ free(*arg);
+ *arg = NULL;
+}
+
+
+void set_sendvia(arg)
+char **arg;
+{
+ sending.snd_gw = getipv4addr(*arg);
+ free(*arg);
+ *arg = NULL;
+}
+
+
+void set_defaultrouter(arg)
+char **arg;
+{
+ defrouter = getipv4addr(*arg);
+ free(*arg);
+ *arg = NULL;
+}
+
+
+void new_icmpheader()
+{
+ if ((ip->ip_p) && (ip->ip_p != IPPROTO_ICMP)) {
+ fprintf(stderr, "protocol %d specified with ICMP!\n",
+ ip->ip_p);
+ return;
+ }
+ ip->ip_p = IPPROTO_ICMP;
+ icmp = (icmphdr_t *)new_header(IPPROTO_ICMP);
+}
+
+
+void set_icmpcode(code)
+int code;
+{
+ icmp->icmp_code = code;
+}
+
+
+void set_icmptype(type)
+int type;
+{
+ icmp->icmp_type = type;
+}
+
+
+static char *icmpcodes[] = {
+ "net-unr", "host-unr", "proto-unr", "port-unr", "needfrag", "srcfail",
+ "net-unk", "host-unk", "isolate", "net-prohib", "host-prohib",
+ "net-tos", "host-tos", NULL };
+
+void set_icmpcodetok(code)
+char **code;
+{
+ char *s;
+ int i;
+
+ for (i = 0; (s = icmpcodes[i]); i++)
+ if (!strcmp(s, *code)) {
+ icmp->icmp_code = i;
+ break;
+ }
+ if (!s)
+ fprintf(stderr, "unknown ICMP code %s\n", *code);
+ free(*code);
+ *code = NULL;
+}
+
+
+static char *icmptypes[] = {
+ "echorep", (char *)NULL, (char *)NULL, "unreach", "squench",
+ "redir", (char *)NULL, (char *)NULL, "echo", (char *)NULL,
+ (char *)NULL, "timex", "paramprob", "timest", "timestrep",
+ "inforeq", "inforep", "maskreq", "maskrep", "END"
+};
+
+void set_icmptypetok(type)
+char **type;
+{
+ char *s;
+ int i, done = 0;
+
+ for (i = 0; !(s = icmptypes[i]) || strcmp(s, "END"); i++)
+ if (s && !strcmp(s, *type)) {
+ icmp->icmp_type = i;
+ done = 1;
+ break;
+ }
+ if (!done)
+ fprintf(stderr, "unknown ICMP type %s\n", *type);
+ free(*type);
+ *type = NULL;
+}
+
+
+void set_icmpid(arg)
+int arg;
+{
+ icmp->icmp_id = arg;
+}
+
+
+void set_icmpseq(arg)
+int arg;
+{
+ icmp->icmp_seq = arg;
+}
+
+
+void set_icmpotime(arg)
+int arg;
+{
+ icmp->icmp_otime = arg;
+}
+
+
+void set_icmprtime(arg)
+int arg;
+{
+ icmp->icmp_rtime = arg;
+}
+
+
+void set_icmpttime(arg)
+int arg;
+{
+ icmp->icmp_ttime = arg;
+}
+
+
+void set_icmpmtu(arg)
+int arg;
+{
+#if BSD >= 199306
+ icmp->icmp_nextmtu = arg;
+#endif
+}
+
+
+void set_redir(redir, arg)
+int redir;
+char **arg;
+{
+ icmp->icmp_code = redir;
+ icmp->icmp_gwaddr = getipv4addr(*arg);
+ free(*arg);
+ *arg = NULL;
+}
+
+
+void set_icmppprob(num)
+int num;
+{
+ icmp->icmp_pptr = num;
+}
+
+
+void new_ipv4opt()
+{
+ new_header(-2);
+}
+
+
+void add_ipopt(state, ptr)
+int state;
+void *ptr;
+{
+ struct ipopt_names *io;
+ struct statetoopt *sto;
+ char numbuf[16], *arg, **param = ptr;
+ int inc, hlen;
+
+ if (state == IL_IPO_RR || state == IL_IPO_SATID) {
+ if (param)
+ sprintf(numbuf, "%d", *(int *)param);
+ else
+ strcpy(numbuf, "0");
+ arg = numbuf;
+ } else
+ arg = param ? *param : NULL;
+
+ if (canip->ah_next) {
+ fprintf(stderr, "cannot specify options after data body\n");
+ return;
+ }
+ for (sto = toipopts; sto->sto_st; sto++)
+ if (sto->sto_st == state)
+ break;
+ if (!sto || !sto->sto_st) {
+ fprintf(stderr, "No mapping for state %d to IP option\n",
+ state);
+ return;
+ }
+
+ hlen = sizeof(ip_t) + canip->ah_optlen;
+ for (io = ionames; io->on_name; io++)
+ if (io->on_value == sto->sto_op)
+ break;
+ canip->ah_lastopt = io->on_value;
+
+ if (io->on_name) {
+ inc = addipopt((char *)ip + hlen, io, hlen - sizeof(ip_t),arg);
+ if (inc > 0) {
+ while (inc & 3) {
+ ((char *)ip)[sizeof(*ip) + inc] = IPOPT_NOP;
+ canip->ah_lastopt = IPOPT_NOP;
+ inc++;
+ }
+ hlen += inc;
+ }
+ }
+
+ canip->ah_optlen = hlen - sizeof(ip_t);
+
+ if (state != IL_IPO_RR && state != IL_IPO_SATID)
+ if (param && *param) {
+ free(*param);
+ *param = NULL;
+ }
+ sclass = NULL;
+}
+
+
+void end_ipopt()
+{
+ int pad;
+ char *s, *buf = (char *)ip;
+
+ /*
+ * pad out so that we have a multiple of 4 bytes in size fo the
+ * options. make sure last byte is EOL.
+ */
+ if (canip->ah_lastopt == IPOPT_NOP) {
+ buf[sizeof(*ip) + canip->ah_optlen - 1] = IPOPT_EOL;
+ } else if (canip->ah_lastopt != IPOPT_EOL) {
+ s = buf + sizeof(*ip) + canip->ah_optlen;
+
+ for (pad = 3 - (canip->ah_optlen & 3); pad; pad--) {
+ *s++ = IPOPT_NOP;
+ *s = IPOPT_EOL;
+ canip->ah_optlen++;
+ }
+ canip->ah_optlen++;
+ } else {
+ s = buf + sizeof(*ip) + canip->ah_optlen - 1;
+
+ for (pad = 3 - (canip->ah_optlen & 3); pad; pad--) {
+ *s++ = IPOPT_NOP;
+ *s = IPOPT_EOL;
+ canip->ah_optlen++;
+ }
+ }
+ ip->ip_hl = (sizeof(*ip) + canip->ah_optlen) >> 2;
+ inc_anipheaders(canip->ah_optlen);
+ free_anipheader();
+}
+
+
+void set_secclass(arg)
+char **arg;
+{
+ sclass = *arg;
+ *arg = NULL;
+}
+
+
+void free_anipheader()
+{
+ aniphdr_t *aip;
+
+ aip = canip;
+ if ((canip = aip->ah_prev)) {
+ canip->ah_next = NULL;
+ aniptail = &canip->ah_next;
+ }
+ free(aip);
+}
+
+
+void end_ipv4()
+{
+ aniphdr_t *aip;
+
+ ip->ip_sum = 0;
+ ip->ip_sum = chksum((u_short *)ip, ip->ip_hl << 2);
+ free_anipheader();
+ for (aip = aniphead, ip = NULL; aip; aip = aip->ah_next)
+ if (aip->ah_p == IPPROTO_IP)
+ ip = aip->ah_ip;
+}
+
+
+void end_icmp()
+{
+ aniphdr_t *aip;
+
+ icmp->icmp_cksum = 0;
+ icmp->icmp_cksum = chksum((u_short *)icmp, canip->ah_len);
+ free_anipheader();
+ for (aip = aniphead, icmp = NULL; aip; aip = aip->ah_next)
+ if (aip->ah_p == IPPROTO_ICMP)
+ icmp = aip->ah_icmp;
+}
+
+
+void end_udp()
+{
+ u_long sum;
+ aniphdr_t *aip;
+ ip_t iptmp;
+
+ bzero((char *)&iptmp, sizeof(iptmp));
+ iptmp.ip_p = ip->ip_p;
+ iptmp.ip_src = ip->ip_src;
+ iptmp.ip_dst = ip->ip_dst;
+ iptmp.ip_len = ip->ip_len - (ip->ip_hl << 2);
+ sum = p_chksum((u_short *)&iptmp, (u_int)sizeof(iptmp));
+ udp->uh_sum = c_chksum((u_short *)udp, (u_int)iptmp.ip_len, sum);
+ free_anipheader();
+ for (aip = aniphead, udp = NULL; aip; aip = aip->ah_next)
+ if (aip->ah_p == IPPROTO_UDP)
+ udp = aip->ah_udp;
+}
+
+
+void end_tcp()
+{
+ u_long sum;
+ aniphdr_t *aip;
+ ip_t iptmp;
+
+ bzero((char *)&iptmp, sizeof(iptmp));
+ iptmp.ip_p = ip->ip_p;
+ iptmp.ip_src = ip->ip_src;
+ iptmp.ip_dst = ip->ip_dst;
+ iptmp.ip_len = ip->ip_len - (ip->ip_hl << 2);
+ sum = p_chksum((u_short *)&iptmp, (u_int)sizeof(iptmp));
+ tcp->th_sum = 0;
+ tcp->th_sum = c_chksum((u_short *)tcp, (u_int)iptmp.ip_len, sum);
+ free_anipheader();
+ for (aip = aniphead, tcp = NULL; aip; aip = aip->ah_next)
+ if (aip->ah_p == IPPROTO_TCP)
+ tcp = aip->ah_tcp;
+}
+
+
+void end_data()
+{
+ free_anipheader();
+}
+
+
+void iplang(fp)
+FILE *fp;
+{
+ yyin = fp;
+
+ yydebug = (opts & OPT_DEBUG) ? 1 : 0;
+
+ while (!feof(fp))
+ yyparse();
+}
+
+
+u_short c_chksum(buf, len, init)
+u_short *buf;
+u_int len;
+u_long init;
+{
+ u_long sum = init;
+ int nwords = len >> 1;
+
+ for(; nwords > 0; nwords--)
+ sum += *buf++;
+ sum = (sum>>16) + (sum & 0xffff);
+ sum += (sum >>16);
+ return (~sum);
+}
+
+
+u_long p_chksum(buf,len)
+u_short *buf;
+u_int len;
+{
+ u_long sum = 0;
+ int nwords = len >> 1;
+
+ for(; nwords > 0; nwords--)
+ sum += *buf++;
+ return sum;
+}
diff --git a/contrib/ipfilter/ipmon.c b/contrib/ipfilter/ipmon.c
index f8b339d3012e..f86c2df5da6e 100644
--- a/contrib/ipfilter/ipmon.c
+++ b/contrib/ipfilter/ipmon.c
@@ -1,16 +1,21 @@
/*
- * (C)opyright 1993-1996 by Darren Reed.
+ * Copyright (C) 1993-1997 by Darren Reed.
*
* Redistribution and use in source and binary forms are permitted
* provided that this notice is preserved and due credit is given
* to the original author and the contributors.
*/
+#if !defined(lint)
+static const char sccsid[] = "@(#)ipmon.c 1.21 6/5/96 (C)1993-1997 Darren Reed";
+static const char rcsid[] = "@(#)$Id: ipmon.c,v 2.0.2.29.2.3 1997/11/12 10:57:25 darrenr Exp $";
+#endif
#include <stdio.h>
#include <unistd.h>
#include <string.h>
#include <fcntl.h>
#include <errno.h>
+#include <sys/types.h>
#if !defined(__SVR4) && !defined(__svr4__)
#include <strings.h>
#include <sys/dir.h>
@@ -18,10 +23,10 @@
#include <sys/filio.h>
#include <sys/byteorder.h>
#endif
-#include <sys/types.h>
#include <sys/stat.h>
#include <sys/param.h>
#include <sys/file.h>
+#include <sys/time.h>
#include <stdlib.h>
#include <stddef.h>
#include <sys/socket.h>
@@ -36,26 +41,31 @@
#include <resolv.h>
#include <sys/uio.h>
-#include <sys/protosw.h>
-#include <sys/user.h>
+#ifndef linux
+# include <sys/protosw.h>
+# include <sys/user.h>
+# include <netinet/ip_var.h>
+#endif
-#include <netinet/ip_var.h>
#include <netinet/tcp.h>
-#include <netinet/tcpip.h>
#include <netinet/ip_icmp.h>
#include <ctype.h>
#include <syslog.h>
-#include "ip_compat.h"
-#include "ip_fil.h"
-#include "ip_proxy.h"
-#include "ip_nat.h"
-#include "ip_state.h"
+#include "netinet/ip_compat.h"
+#include <netinet/tcpip.h>
+#include "netinet/ip_fil.h"
+#include "netinet/ip_proxy.h"
+#include "netinet/ip_nat.h"
+#include "netinet/ip_state.h"
+
-#if !defined(lint) && defined(LIBC_SCCS)
-static char sccsid[] = "@(#)ipmon.c 1.21 6/5/96 (C)1993-1996 Darren Reed";
-static char rcsid[] = "$Id: ipmon.c,v 2.0.2.9 1997/04/30 13:54:10 darrenr Exp $";
+#if defined(sun) && !defined(SOLARIS2)
+#define STRERROR(x) sys_errlist[x]
+extern char *sys_errlist[];
+#else
+#define STRERROR(x) strerror(x)
#endif
@@ -78,24 +88,17 @@ struct flags tcpfl[] = {
static char line[2048];
static int opts = 0;
static void usage __P((char *));
+static void flushlogs __P((char *, FILE *));
+static void print_log __P((int, FILE *, char *, int));
static void print_ipflog __P((FILE *, char *, int));
static void print_natlog __P((FILE *, char *, int));
static void print_statelog __P((FILE *, char *, int));
static void dumphex __P((FILE *, u_char *, int));
-static void printiplci __P((struct ipl_ci *));
-static void resynclog __P((int, struct ipl_ci *, FILE *));
-static int read_ipflog __P((int, int *, char *, int, FILE *));
-static int read_natlog __P((int, int *, char *, int, FILE *));
-static int read_statelog __P((int, int *, char *, int, FILE *));
+static int read_log __P((int, int *, char *, int, FILE *));
char *hostname __P((int, struct in_addr));
char *portname __P((int, char *, u_short));
int main __P((int, char *[]));
-static int (*readfunc[3]) __P((int, int *, char *, int, FILE *)) =
- { read_ipflog, read_natlog, read_statelog };
-static void (*printfunc[3]) __P((FILE *, char *, int)) =
- { print_ipflog, print_natlog, print_statelog };
-
#define OPT_SYSLOG 0x001
#define OPT_RESOLVE 0x002
@@ -111,211 +114,20 @@ static void (*printfunc[3]) __P((FILE *, char *, int)) =
#define LOGFAC LOG_LOCAL0
#endif
-static void printiplci(icp)
-struct ipl_ci *icp;
-{
- printf("sec %ld usec %ld hlen %d plen %d\n", icp->sec, icp->usec,
- icp->hlen, icp->plen);
-}
-
-
-void resynclog(fd, iplcp, log)
-int fd;
-struct ipl_ci *iplcp;
-FILE *log;
-{
- time_t now;
- char *s = NULL;
- int len, nr = 0;
-
- do {
- if (s) {
- s = (char *)&iplcp->sec;
- if (opts & OPT_SYSLOG) {
- syslog(LOG_INFO, "Sync bytes:");
- syslog(LOG_INFO, " %02x %02x %02x %02x",
- *s, *(s+1), *(s+2), *(s+3));
- syslog(LOG_INFO, " %02x %02x %02x %02x\n",
- *(s+4), *(s+5), *(s+6), *(s+7));
- } else {
- fprintf(log, "Sync bytes:");
- fprintf(log, " %02x %02x %02x %02x",
- *s, *(s+1), *(s+2), *(s+3));
- fprintf(log, " %02x %02x %02x %02x\n",
- *(s+4), *(s+5), *(s+6), *(s+7));
- }
- }
- do {
- s = (char *)&iplcp->sec;
- len = sizeof(iplcp->sec);
- while (len) {
- switch ((nr = read(fd, s, len)))
- {
- case -1:
- case 0:
- return;
- default :
- s += nr;
- len -= nr;
- now = time(NULL);
- break;
- }
- }
- } while ((now < iplcp->sec) ||
- ((iplcp->sec - now) > (86400*5)));
-
- len = sizeof(iplcp->usec);
- while (len) {
- switch ((nr = read(fd, s, len)))
- {
- case -1:
- case 0:
- return;
- default :
- s += nr;
- len -= nr;
- break;
- }
- }
- } while (iplcp->usec > 1000000);
- len = sizeof(*iplcp) - sizeof(iplcp->sec) - sizeof(iplcp->usec);
- while (len) {
- switch ((nr = read(fd, s, len)))
- {
- case -1:
- case 0:
- return;
- default :
- s += nr;
- len -= nr;
- break;
- }
- }
-}
-
-
-static int read_natlog(fd, lenp, buf, bufsize, log)
+static int read_log(fd, lenp, buf, bufsize, log)
int fd, bufsize, *lenp;
char *buf;
FILE *log;
{
- int len, avail = 0, want = sizeof(struct natlog);
+ int nr;
- *lenp = 0;
-
- if (ioctl(fd, FIONREAD, &avail) == -1) {
- perror("ioctl(FIONREAD");
- return 1;
- }
-
- if (avail < want)
+ nr = read(fd, buf, bufsize);
+ if (!nr)
return 2;
-
- while (want) {
- len = read(fd, buf, want);
- if (len > 0)
- want -= len;
- else
- break;
- }
-
- if (!want) {
- *lenp = sizeof(struct natlog);
- return 0;
- }
- return !len ? 2 : -1;
-}
-
-
-static int read_statelog(fd, lenp, buf, bufsize, log)
-int fd, bufsize, *lenp;
-char *buf;
-FILE *log;
-{
- int len, avail = 0, want = sizeof(struct ipslog);
-
- *lenp = 0;
-
- if (ioctl(fd, FIONREAD, &avail) == -1) {
- perror("ioctl(FIONREAD");
- return 1;
- }
-
- if (avail < want)
- return 2;
-
- while (want) {
- len = read(fd, buf, want);
- if (len > 0)
- want -= len;
- else
- break;
- }
-
- if (!want) {
- *lenp = sizeof(struct ipslog);
- return 0;
- }
- return !len ? 2 : -1;
-}
-
-
-static int read_ipflog(fd, lenp, buf, bufsize, log)
-int fd, bufsize, *lenp;
-char *buf;
-FILE *log;
-{
- struct ipl_ci *icp = (struct ipl_ci *)buf;
- time_t now;
- char *s;
- int len, n = bufsize, tr = sizeof(struct ipl_ci), nr;
-
- if (bufsize < tr)
- return 1;
- for (s = buf; (n > 0) && (tr > 0); s += nr, n -= nr) {
- nr = read(fd, s, tr);
- if (nr > 0)
- tr -= nr;
- else
- return -1;
- }
-
- now = time(NULL);
- if ((icp->hlen > 92) || (now < icp->sec) ||
- ((now - icp->sec) > (86400*5))) {
- if (opts & OPT_SYSLOG)
- syslog(LOG_INFO, "Out of sync! (1,%lx)\n", now);
- else
- fprintf(log, "Out of sync! (1,%lx)\n", now);
- dumphex(log, buf, sizeof(struct ipl_ci));
- resynclog(fd, icp, log);
- }
-
-
- len = (int)((u_int)icp->plen);
- if (len > 128 || len < 0) {
- if (opts & OPT_SYSLOG)
- syslog(LOG_INFO, "Out of sync! (2,%d)\n", len);
- else
- fprintf(log, "Out of sync! (2,%d)\n", len);
- dumphex(log, buf, sizeof(struct ipl_ci));
- resynclog(fd, icp, log);
- }
-
-
- tr = icp->hlen + icp->plen;
- if (n < tr)
- return 1;
-
- for (; (n > 0) && (tr > 0); s += nr, n-= nr) {
- nr = read(fd, s, tr);
- if (nr > 0)
- tr -= nr;
- else
- return -1;
- }
- *lenp = s - buf;
+ if ((nr < 0) && (errno != EINTR))
+ return -1;
+ *lenp = nr;
return 0;
}
@@ -366,15 +178,18 @@ int len;
if (j && !(j & 0xf)) {
*t++ = '\n';
*t = '\0';
- fputs(line, stdout);
+ if (!(opts & OPT_SYSLOG))
+ fputs(line, stdout);
+ else
+ syslog(LOG_INFO, "%s", line);
t = (u_char *)line;
*t = '\0';
}
- sprintf(t, "%02x", *s & 0xff);
+ sprintf((char *)t, "%02x", *s & 0xff);
t += 2;
if (!((j + 1) & 0xf)) {
s -= 15;
- sprintf(t, " ");
+ sprintf((char *)t, " ");
t += 8;
for (k = 16; k; k--, s++)
*t++ = (isprint(*s) ? *s : '.');
@@ -391,7 +206,7 @@ int len;
*t++ = ' ';
*t++ = ' ';
}
- sprintf(t, " ");
+ sprintf((char *)t, " ");
t += 7;
s -= j & 0xf;
for (k = j & 0xf; k; k--, s++)
@@ -399,31 +214,35 @@ int len;
*t++ = '\n';
*t = '\0';
}
- fputs(line, stdout);
- fflush(stdout);
+ if (!(opts & OPT_SYSLOG)) {
+ fputs(line, stdout);
+ fflush(stdout);
+ } else
+ syslog(LOG_INFO, "%s", line);
}
-
static void print_natlog(log, buf, blen)
FILE *log;
char *buf;
int blen;
{
- struct natlog *nl = (struct natlog *)buf;
+ struct natlog *nl;
+ iplog_t *ipl = (iplog_t *)buf;
char *t = line;
struct tm *tm;
int res;
+ nl = (struct natlog *)((char *)ipl + sizeof(*ipl));
res = (opts & OPT_RESOLVE) ? 1 : 0;
- tm = localtime((time_t *)&nl->nl_tv.tv_sec);
+ tm = localtime((time_t *)&ipl->ipl_sec);
if (!(opts & OPT_SYSLOG)) {
(void) sprintf(t, "%2d/%02d/%4d ",
tm->tm_mday, tm->tm_mon + 1, tm->tm_year + 1900);
t += strlen(t);
}
(void) sprintf(t, "%02d:%02d:%02d.%-.6ld @%hd ",
- tm->tm_hour, tm->tm_min, tm->tm_sec, nl->nl_tv.tv_usec,
- nl->nl_rule);
+ tm->tm_hour, tm->tm_min, tm->tm_sec, ipl->ipl_usec,
+ nl->nl_rule+1);
t += strlen(t);
if (nl->nl_type == NL_NEWMAP)
@@ -469,21 +288,23 @@ FILE *log;
char *buf;
int blen;
{
- struct ipslog *sl = (struct ipslog *)buf;
+ struct ipslog *sl;
+ iplog_t *ipl = (iplog_t *)buf;
struct protoent *pr;
char *t = line, *proto, pname[6];
struct tm *tm;
int res;
+ sl = (struct ipslog *)((char *)ipl + sizeof(*ipl));
res = (opts & OPT_RESOLVE) ? 1 : 0;
- tm = localtime((time_t *)&sl->isl_tv.tv_sec);
+ tm = localtime((time_t *)&ipl->ipl_sec);
if (!(opts & OPT_SYSLOG)) {
(void) sprintf(t, "%2d/%02d/%4d ",
tm->tm_mday, tm->tm_mon + 1, tm->tm_year + 1900);
t += strlen(t);
}
(void) sprintf(t, "%02d:%02d:%02d.%-.6ld ",
- tm->tm_hour, tm->tm_min, tm->tm_sec, sl->isl_tv.tv_usec);
+ tm->tm_hour, tm->tm_min, tm->tm_sec, ipl->ipl_usec);
t += strlen(t);
if (sl->isl_type == ISL_NEW)
@@ -535,6 +356,40 @@ int blen;
}
+static void print_log(logtype, log, buf, blen)
+FILE *log;
+char *buf;
+int logtype, blen;
+{
+ iplog_t *ipl;
+ int psize;
+
+ while (blen > 0) {
+ ipl = (iplog_t *)buf;
+ if (ipl->ipl_magic != IPL_MAGIC) {
+ /* invalid data or out of sync */
+ return;
+ }
+ psize = ipl->ipl_dsize;
+ switch (logtype)
+ {
+ case IPL_LOGIPF :
+ print_ipflog(log, buf, psize);
+ break;
+ case IPL_LOGNAT :
+ print_natlog(log, buf, psize);
+ break;
+ case IPL_LOGSTATE :
+ print_statelog(log, buf, psize);
+ break;
+ }
+
+ blen -= psize;
+ buf += psize;
+ }
+}
+
+
static void print_ipflog(log, buf, blen)
FILE *log;
char *buf;
@@ -543,44 +398,54 @@ int blen;
struct protoent *pr;
struct tcphdr *tp;
struct icmp *ic;
- struct ip *ipc;
struct tm *tm;
char c[3], pname[8], *t, *proto;
u_short hl, p;
- int i, lvl, res;
-#if !SOLARIS && !(defined(NetBSD) && (NetBSD <= 1991011) && (NetBSD >= 199603))
- int len;
-#endif
- struct ip *ip;
- struct ipl_ci *lp;
-
- lp = (struct ipl_ci *)buf;
- ip = (struct ip *)(buf + sizeof(*lp));
+ int i, lvl, res, len;
+ ip_t *ipc, *ip;
+ iplog_t *ipl;
+ ipflog_t *ipf;
+
+ ipl = (iplog_t *)buf;
+ ipf = (ipflog_t *)((char *)buf + sizeof(*ipl));
+ ip = (ip_t *)((char *)ipf + sizeof(*ipf));
res = (opts & OPT_RESOLVE) ? 1 : 0;
t = line;
*t = '\0';
hl = (ip->ip_hl << 2);
p = (u_short)ip->ip_p;
- tm = localtime((time_t *)&lp->sec);
+ tm = localtime((time_t *)&ipl->ipl_sec);
+#ifdef linux
+ ip->ip_len = ntohs(ip->ip_len);
+#endif
+
if (!(opts & OPT_SYSLOG)) {
(void) sprintf(t, "%2d/%02d/%4d ",
tm->tm_mday, tm->tm_mon + 1, tm->tm_year + 1900);
t += strlen(t);
}
-#if SOLARIS || (defined(NetBSD) && (NetBSD <= 1991011) && (NetBSD >= 199603))
- (void) sprintf(t, "%02d:%02d:%02d.%-.6ld %.*s @%hd ",
- tm->tm_hour, tm->tm_min, tm->tm_sec, lp->usec,
- (int)sizeof(lp->ifname), lp->ifname, lp->rule);
+ (void) sprintf(t, "%02d:%02d:%02d.%-.6ld ", tm->tm_hour, tm->tm_min,
+ tm->tm_sec, ipl->ipl_usec);
+ t += strlen(t);
+ if (ipl->ipl_count > 1) {
+ (void) sprintf(t, "%dx ", ipl->ipl_count);
+ t += strlen(t);
+ }
+#if (SOLARIS || \
+ (defined(NetBSD) && (NetBSD <= 1991011) && (NetBSD >= 199603)) || \
+ (defined(OpenBSD) && (OpenBSD >= 199603))) || defined(linux)
+ len = (int)sizeof(ipf->fl_ifname);
+ (void) sprintf(t, "%*.*s", len, len, ipf->fl_ifname);
#else
for (len = 0; len < 3; len++)
- if (!lp->ifname[len])
+ if (!ipf->fl_ifname[len])
break;
- if (lp->ifname[len])
+ if (ipf->fl_ifname[len])
len++;
- (void) sprintf(t, "%02d:%02d:%02d.%-.6ld %*.*s%ld @%hd ",
- tm->tm_hour, tm->tm_min, tm->tm_sec, lp->usec,
- len, len, lp->ifname, lp->unit, lp->rule);
+ (void) sprintf(t, "%*.*s%u", len, len, ipf->fl_ifname, ipf->fl_unit);
#endif
+ t += strlen(t);
+ (void) sprintf(t, " @%hu:%hu ", ipf->fl_group, ipf->fl_rule + 1);
pr = getprotobynumber((int)p);
if (!pr) {
proto = pname;
@@ -588,22 +453,22 @@ int blen;
} else
proto = pr->p_name;
- if (lp->flags & (FI_SHORT << 20)) {
+ if (ipf->fl_flags & FF_SHORT) {
c[0] = 'S';
lvl = LOG_ERR;
- } else if (lp->flags & FR_PASS) {
- if (lp->flags & FR_LOGP)
+ } else if (ipf->fl_flags & FR_PASS) {
+ if (ipf->fl_flags & FR_LOGP)
c[0] = 'p';
else
c[0] = 'P';
lvl = LOG_NOTICE;
- } else if (lp->flags & FR_BLOCK) {
- if (lp->flags & FR_LOGB)
+ } else if (ipf->fl_flags & FR_BLOCK) {
+ if (ipf->fl_flags & FR_LOGB)
c[0] = 'b';
else
c[0] = 'B';
lvl = LOG_WARNING;
- } else if (lp->flags & FF_LOGNOMATCH) {
+ } else if (ipf->fl_flags & FF_LOGNOMATCH) {
c[0] = 'n';
lvl = LOG_NOTICE;
} else {
@@ -617,7 +482,7 @@ int blen;
if ((p == IPPROTO_TCP || p == IPPROTO_UDP) && !(ip->ip_off & 0x1fff)) {
tp = (struct tcphdr *)((char *)ip + hl);
- if (!(lp->flags & (FI_SHORT << 16))) {
+ if (!(ipf->fl_flags & (FI_SHORT << 16))) {
(void) sprintf(t, "%s,%s -> ",
hostname(res, ip->ip_src),
portname(res, proto, tp->th_sport));
@@ -654,7 +519,7 @@ int blen;
t += strlen(t);
(void) sprintf(t, "%s PR icmp len %hu (%hu) icmp %d/%d",
hostname(res, ip->ip_dst), hl,
- ip->ip_len, ic->icmp_type, ic->icmp_code);
+ ntohs(ip->ip_len), ic->icmp_type, ic->icmp_code);
if (ic->icmp_type == ICMP_UNREACH ||
ic->icmp_type == ICMP_SOURCEQUENCH ||
ic->icmp_type == ICMP_PARAMPROB ||
@@ -695,12 +560,12 @@ int blen;
}
t += strlen(t);
- if (lp->flags & FR_KEEPSTATE) {
+ if (ipf->fl_flags & FR_KEEPSTATE) {
(void) strcpy(t, " K-S");
t += strlen(t);
}
- if (lp->flags & FR_KEEPFRAG) {
+ if (ipf->fl_flags & FR_KEEPFRAG) {
(void) strcpy(t, " K-F");
t += strlen(t);
}
@@ -712,13 +577,13 @@ int blen;
else
(void) fprintf(log, "%s", line);
if (opts & OPT_HEXHDR)
- dumphex(log, buf, sizeof(struct ipl_ci));
+ dumphex(log, (u_char *)buf, sizeof(iplog_t));
if (opts & OPT_HEXBODY)
- dumphex(log, (u_char *)ip, lp->plen + lp->hlen);
+ dumphex(log, (u_char *)ip, ipf->fl_plen + ipf->fl_hlen);
}
-void static usage(prog)
+static void usage(prog)
char *prog;
{
fprintf(stderr, "%s: [-NFhstvxX] [-f <logfile>]\n", prog);
@@ -726,15 +591,14 @@ char *prog;
}
-void flushlogs(file, log)
+static void flushlogs(file, log)
char *file;
FILE *log;
{
int fd, flushed = 0;
if ((fd = open(file, O_RDWR)) == -1) {
- (void) fprintf(stderr, "%s: ", file);
- perror("open");
+ (void) fprintf(stderr, "%s: open: %s", file, STRERROR(errno));
exit(-1);
}
@@ -750,7 +614,7 @@ FILE *log;
if (opts & OPT_SYSLOG)
syslog(LOG_INFO, "%d bytes flushed from log\n",
flushed);
- else
+ else if (log != stdout)
fprintf(log, "%d bytes flushed from log\n", flushed);
}
}
@@ -760,15 +624,20 @@ int main(argc, argv)
int argc;
char *argv[];
{
- struct stat stat;
- FILE *log = NULL;
- int fd[3] = {-1, -1, -1}, flushed = 0, doread, n, i, nfd = 1;
- int tr, nr, regular;
- int fdt[3] = {IPL_LOGIPF, IPL_LOGNAT, IPL_LOGSTATE};
- char buf[512], c, *iplfile = IPL_NAME;
+ struct stat sb;
+ FILE *log = stdout;
+ int fd[3], doread, n, i, nfd = 1;
+ int tr, nr, regular, c;
+ int fdt[3];
+ char buf[512], *iplfile = IPL_NAME;
extern int optind;
extern char *optarg;
+ fd[0] = fd[1] = fd[2] = -1;
+ fdt[0] = IPL_LOGIPF;
+ fdt[1] = IPL_LOGNAT;
+ fdt[2] = IPL_LOGSTATE;
+
while ((c = getopt(argc, argv, "?af:FhnNsStvxX")) != -1)
switch (c)
{
@@ -794,8 +663,7 @@ char *argv[];
case 'N' :
opts |= OPT_NAT;
fdt[0] = IPL_LOGNAT;
- readfunc[0] = read_natlog;
- printfunc[0] = print_natlog;
+ iplfile = IPL_NAT;
break;
case 's' :
openlog(argv[0], LOG_NDELAY|LOG_PID, LOGFAC);
@@ -804,8 +672,7 @@ char *argv[];
case 'S' :
opts |= OPT_STATE;
fdt[0] = IPL_LOGSTATE;
- readfunc[0] = read_statelog;
- printfunc[0] = print_statelog;
+ iplfile = IPL_STATE;
break;
case 't' :
opts |= OPT_TAIL;
@@ -826,36 +693,42 @@ char *argv[];
}
if ((fd[0] == -1) && (fd[0] = open(iplfile, O_RDONLY)) == -1) {
- (void) fprintf(stderr, "%s: ", iplfile);
- perror("open");
+ (void) fprintf(stderr, "%s: open: %s", iplfile,
+ STRERROR(errno));
exit(-1);
}
if ((opts & OPT_ALL)) {
if ((fd[1] = open(IPL_NAT, O_RDONLY)) == -1) {
- (void) fprintf(stderr, "%s: ", IPL_NAT);
- perror("open");
+ (void) fprintf(stderr, "%s: open: %s", IPL_NAT,
+ STRERROR(errno));
exit(-1);
}
if ((fd[2] = open(IPL_STATE, O_RDONLY)) == -1) {
- (void) fprintf(stderr, "%s: ", IPL_STATE);
- perror("open");
+ (void) fprintf(stderr, "%s: open: %s", IPL_STATE,
+ STRERROR(errno));
exit(-1);
}
}
if (!(opts & OPT_SYSLOG)) {
log = argv[optind] ? fopen(argv[optind], "a") : stdout;
+ if (log == NULL) {
+
+ (void) fprintf(stderr, "%s: fopen: %s", argv[optind],
+ STRERROR(errno));
+ exit(-1);
+ }
setvbuf(log, NULL, _IONBF, 0);
}
- if (fstat(fd[0], &stat) == -1) {
- fprintf(stderr, "%s :", iplfile);
- perror("fstat");
+ if (stat(iplfile, &sb) == -1) {
+ (void) fprintf(stderr, "%s: stat: %s", iplfile,
+ STRERROR(errno));
exit(-1);
}
- regular = !S_ISCHR(stat.st_mode);
+ regular = !S_ISCHR(sb.st_mode);
for (doread = 1; doread; ) {
nr = 0;
@@ -868,16 +741,15 @@ char *argv[];
exit(-1);
}
} else {
- tr = (lseek(fd[i], 0, SEEK_CUR) <
- stat.st_size);
+ tr = (lseek(fd[i], 0, SEEK_CUR) < sb.st_size);
if (!tr && !(opts & OPT_TAIL))
doread = 0;
}
- if (!tr)
+ if (!tr && nfd != 1)
continue;
nr += tr;
- tr = (*readfunc[i])(fd[i], &n, buf, sizeof(buf), log);
+ tr = read_log(fd[i], &n, buf, sizeof(buf), log);
switch (tr)
{
case -1 :
@@ -898,14 +770,14 @@ char *argv[];
break;
case 0 :
if (n > 0) {
- (*printfunc[i])(log, buf, n);
+ print_log(fdt[i], log, buf, n);
if (!(opts & OPT_SYSLOG))
fflush(log);
}
break;
}
}
- if (!nr && regular && (opts & OPT_TAIL))
+ if (!nr && ((opts & OPT_TAIL) || !regular))
sleep(1);
}
exit(0);
diff --git a/contrib/ipfilter/ipnat.c b/contrib/ipfilter/ipnat.c
index 189640252c96..a97d1a3ff540 100644
--- a/contrib/ipfilter/ipnat.c
+++ b/contrib/ipfilter/ipnat.c
@@ -1,5 +1,5 @@
/*
- * (C)opyright 1993,1994,1995 by Darren Reed.
+ * Copyright (C) 1993-1997 by Darren Reed.
*
* Redistribution and use in source and binary forms are permitted
* provided that this notice is preserved and due credit is given
@@ -19,12 +19,12 @@
#include <stdio.h>
#include <string.h>
#include <fcntl.h>
+#include <sys/types.h>
#if !defined(__SVR4) && !defined(__svr4__)
#include <strings.h>
#else
#include <sys/byteorder.h>
#endif
-#include <sys/types.h>
#include <sys/time.h>
#include <sys/param.h>
#include <stdlib.h>
@@ -46,18 +46,18 @@
#include <arpa/inet.h>
#include <resolv.h>
#include <ctype.h>
-#include "ip_compat.h"
-#include "ip_fil.h"
-#include "ip_proxy.h"
-#include "ip_nat.h"
+#include "netinet/ip_compat.h"
+#include "netinet/ip_fil.h"
+#include "netinet/ip_proxy.h"
+#include "netinet/ip_nat.h"
#include "kmem.h"
-
-#if !defined(lint) && defined(LIBC_SCCS)
-static char sccsid[] ="@(#)ipnat.c 1.9 6/5/96 (C) 1993 Darren Reed";
-static char rcsid[] = "$Id: ipnat.c,v 2.0.2.9 1997/05/05 14:03:55 darrenr Exp $";
+#if !defined(lint)
+static const char sccsid[] ="@(#)ipnat.c 1.9 6/5/96 (C) 1993 Darren Reed";
+static const char rcsid[] = "@(#)$Id: ipnat.c,v 2.0.2.21.2.1 1997/11/08 04:55:55 darrenr Exp $";
#endif
+
#if SOLARIS
#define bzero(a,b) memset(a,0,b)
#endif
@@ -97,8 +97,8 @@ int main(argc, argv)
int argc;
char *argv[];
{
- char *file = NULL, c;
- int fd, opts = 1;
+ char *file = NULL;
+ int fd = -1, opts = 1, c;
while ((c = getopt(argc, argv, "CFf:lnrsv")) != -1)
switch (c)
@@ -182,11 +182,12 @@ int verbose;
void *ptr;
{
int bits;
+ struct protoent *pr;
switch (np->in_redir)
{
case NAT_REDIRECT :
- printf("redir ");
+ printf("rdr ");
break;
case NAT_MAP :
printf("map ");
@@ -212,11 +213,11 @@ void *ptr;
printf("-> %s", inet_ntoa(np->in_in[0]));
if (np->in_pnext)
printf(" port %d", ntohs(np->in_pnext));
- if (np->in_flags & IPN_TCPUDP)
+ if ((np->in_flags & IPN_TCPUDP) == IPN_TCPUDP)
printf(" tcp/udp");
- else if (np->in_flags & IPN_TCP)
+ else if ((np->in_flags & IPN_TCP) == IPN_TCP)
printf(" tcp");
- else if (np->in_flags & IPN_UDP)
+ else if ((np->in_flags & IPN_UDP) == IPN_UDP)
printf(" udp");
printf("\n");
if (verbose)
@@ -238,11 +239,15 @@ void *ptr;
else
printf("%s", inet_ntoa(np->in_out[1]));
if (*np->in_plabel) {
- printf(" proxy");
+ printf(" proxy port");
if (np->in_dport)
printf(" %hu", ntohs(np->in_dport));
- printf(" %.*s/%d", sizeof(np->in_plabel),
- np->in_plabel, np->in_p);
+ printf(" %.*s/", (int)sizeof(np->in_plabel),
+ np->in_plabel);
+ if ((pr = getprotobynumber(np->in_p)))
+ fputs(pr->p_name, stdout);
+ else
+ printf("%d", np->in_p);
} else if (np->in_pmin || np->in_pmax) {
printf(" portmap");
if ((np->in_flags & IPN_TCPUDP) == IPN_TCPUDP)
@@ -452,7 +457,7 @@ int *resolved;
}
return np->n_net;
}
- return *(u_long *)hp->h_addr;
+ return *(u_32_t *)hp->h_addr;
}
@@ -654,8 +659,12 @@ char *line;
ipn.in_pnext = portnum(tport, proto); /* target port */
s = NULL; /* That's all she wrote! */
}
+ ipn.in_inip &= ipn.in_inmsk;
+ ipn.in_outip &= ipn.in_outmsk;
+
if (!s)
return &ipn;
+
if (ipn.in_redir == NAT_BIMAP) {
fprintf(stderr, "extra words at the end of bimap line: %s\n",
s);
@@ -749,9 +758,12 @@ int opts;
FILE *fp;
int linenum = 1;
- if (strcmp(file, "-"))
- fp = fopen(file, "r");
- else
+ if (strcmp(file, "-")) {
+ if (!(fp = fopen(file, "r"))) {
+ perror(file);
+ exit(1);
+ }
+ } else
fp = stdin;
while (fgets(line, sizeof(line) - 1, fp)) {
@@ -773,7 +785,8 @@ int opts;
}
linenum++;
}
- fclose(stdin);
+ if (fp != stdin)
+ fclose(fp);
}
diff --git a/contrib/ipfilter/ipsd/Makefile b/contrib/ipfilter/ipsd/Makefile
index eb1986e1c9b2..37f0327154b3 100644
--- a/contrib/ipfilter/ipsd/Makefile
+++ b/contrib/ipfilter/ipsd/Makefile
@@ -1,9 +1,9 @@
#
-# (C)opyright 1993-1996 by Darren Reed.
+# Copyright (C) 1993-1997 by Darren Reed.
#
-# This code may be freely distributed as long as it retains this notice
-# and is not changed in any way. The author accepts no responsibility
-# for the use of this software. I hate legaleese, don't you ?
+# Redistribution and use in source and binary forms are permitted
+# provided that this notice is preserved and due credit is given
+# to the original author and the contributors.
#
OBJS=ipsd.o
BINDEST=/usr/local/bin
@@ -17,7 +17,7 @@ LINUX=slinux.o
SUNOS5=dlcommon.o sdlpi.o
CC=gcc
-CFLAGS=-g -I..
+CFLAGS=-g -I.. -I../ipsend
all:
@echo "Use one of these targets:"
diff --git a/contrib/ipfilter/ipsd/ipsd.c b/contrib/ipfilter/ipsd/ipsd.c
index 96364dda483e..d72c93291283 100644
--- a/contrib/ipfilter/ipsd/ipsd.c
+++ b/contrib/ipfilter/ipsd/ipsd.c
@@ -1,8 +1,9 @@
/*
- * (C)opyright December 1995 Darren Reed.
+ * (C)opyright 1995-1997 Darren Reed.
*
- * This software may be freely distributed as long as it is not altered
- * in any way and that this messagge always accompanies it.
+ * Redistribution and use in source and binary forms are permitted
+ * provided that this notice is preserved and due credit is given
+ * to the original author and the contributors.
*
* The author of this software makes no garuntee about the
* performance of this package or its suitability to fulfill any purpose.
@@ -35,7 +36,8 @@
#include "ipsd.h"
#ifndef lint
-static char sccsid[] = "@(#)ipsd.c 1.3 12/3/95 (C)1995 Darren Reed";
+static const char sccsid[] = "@(#)ipsd.c 1.3 12/3/95 (C)1995 Darren Reed";
+static const char rcsid[] = "@(#)$Id: ipsd.c,v 2.0.2.4 1997/09/28 07:13:17 darrenr Exp $";
#endif
extern char *optarg;
@@ -247,8 +249,8 @@ main(argc, argv)
int argc;
char *argv[];
{
- char c, *name = argv[0], *dev = NULL;
- int fd, writeafter = 10000, angelic = 0;
+ char *name = argv[0], *dev = NULL;
+ int fd, writeafter = 10000, angelic = 0, c;
while ((c = getopt(argc, argv, "ad:n:")) != -1)
switch (c)
diff --git a/contrib/ipfilter/ipsd/ipsd.h b/contrib/ipfilter/ipsd/ipsd.h
index a9f3920b4c55..27d55ce2a334 100644
--- a/contrib/ipfilter/ipsd/ipsd.h
+++ b/contrib/ipfilter/ipsd/ipsd.h
@@ -1,8 +1,9 @@
/*
- * (C)opyright December 1995 Darren Reed.
+ * (C)opyright 1995-1997 Darren Reed.
*
- * This software may be freely distributed as long as it is not altered
- * in any way and that this messagge always accompanies it.
+ * Redistribution and use in source and binary forms are permitted
+ * provided that this notice is preserved and due credit is given
+ * to the original author and the contributors.
*
* The author of this software makes no garuntee about the
* performance of this package or its suitability to fulfill any purpose.
diff --git a/contrib/ipfilter/ipsd/ipsdr.c b/contrib/ipfilter/ipsd/ipsdr.c
index b3bf95765a94..e814bd418166 100644
--- a/contrib/ipfilter/ipsd/ipsdr.c
+++ b/contrib/ipfilter/ipsd/ipsdr.c
@@ -1,8 +1,9 @@
/*
- * (C)opyright December 1995 Darren Reed.
+ * (C)opyright 1995-1997 Darren Reed.
*
- * This software may be freely distributed as long as it is not altered
- * in any way and that this messagge always accompanies it.
+ * Redistribution and use in source and binary forms are permitted
+ * provided that this notice is preserved and due credit is given
+ * to the original author and the contributors.
*
* The author of this software makes no garuntee about the
* performance of this package or its suitability to fulfill any purpose.
@@ -36,7 +37,8 @@
#include "ipsd.h"
#ifndef lint
-static char sccsid[] = "@(#)ipsdr.c 1.3 12/3/95 (C)1995 Darren Reed";
+static const char sccsid[] = "@(#)ipsdr.c 1.3 12/3/95 (C)1995 Darren Reed";
+static const char rcsid[] = "@(#)$Id: ipsdr.c,v 2.0.2.3 1997/09/28 07:13:18 darrenr Exp $";
#endif
extern char *optarg;
diff --git a/contrib/ipfilter/ipsd/linux.h b/contrib/ipfilter/ipsd/linux.h
index 7eb382b4b7e1..b5e710f3295e 100644
--- a/contrib/ipfilter/ipsd/linux.h
+++ b/contrib/ipfilter/ipsd/linux.h
@@ -1,9 +1,9 @@
/*
- * (C)opyright 1995 by Darren Reed.
+ * Copyright (C) 1997 by Darren Reed.
*
- * This code may be freely distributed as long as it retains this notice
- * and is not changed in any way. The author accepts no responsibility
- * for the use of this software. I hate legaleese, don't you ?
+ * Redistribution and use in source and binary forms are permitted
+ * provided that this notice is preserved and due credit is given
+ * to the original author and the contributors.
*
* @(#)linux.h 1.1 8/19/95
*/
diff --git a/contrib/ipfilter/ipsd/sbpf.c b/contrib/ipfilter/ipsd/sbpf.c
index d008a5f00d25..5cb520b56b1e 100644
--- a/contrib/ipfilter/ipsd/sbpf.c
+++ b/contrib/ipfilter/ipsd/sbpf.c
@@ -1,8 +1,9 @@
/*
- * (C)opyright October 1995 Darren Reed. (from tcplog)
+ * (C)opyright 1995-1997 Darren Reed. (from tcplog)
*
- * This software may be freely distributed as long as it is not altered
- * in any way and that this messagge always accompanies it.
+ * Redistribution and use in source and binary forms are permitted
+ * provided that this notice is preserved and due credit is given
+ * to the original author and the contributors.
*
*/
#include <stdio.h>
diff --git a/contrib/ipfilter/ipsd/sdlpi.c b/contrib/ipfilter/ipsd/sdlpi.c
index 1d0e41d7f66f..c06aa5f884eb 100644
--- a/contrib/ipfilter/ipsd/sdlpi.c
+++ b/contrib/ipfilter/ipsd/sdlpi.c
@@ -1,11 +1,9 @@
/*
- * (C)opyright October 1992 Darren Reed. (from tcplog)
+ * (C)opyright 1992-1997 Darren Reed. (from tcplog)
*
- * This software may be freely distributed as long as it is not altered
- * in any way and that this messagge always accompanies it.
- *
- * The author of this software makes no garuntee about the
- * performance of this package or its suitability to fulfill any purpose.
+ * Redistribution and use in source and binary forms are permitted
+ * provided that this notice is preserved and due credit is given
+ * to the original author and the contributors.
*
*/
diff --git a/contrib/ipfilter/ipsd/slinux.c b/contrib/ipfilter/ipsd/slinux.c
index 1115b86954ec..29c7c414b82a 100644
--- a/contrib/ipfilter/ipsd/slinux.c
+++ b/contrib/ipfilter/ipsd/slinux.c
@@ -1,8 +1,9 @@
/*
- * (C)opyright October 1992 Darren Reed. (from tcplog)
+ * (C)opyright 1992-1997 Darren Reed. (from tcplog)
*
- * This software may be freely distributed as long as it is not altered
- * in any way and that this messagge always accompanies it.
+ * Redistribution and use in source and binary forms are permitted
+ * provided that this notice is preserved and due credit is given
+ * to the original author and the contributors.
*
* The author of this software makes no garuntee about the
* performance of this package or its suitability to fulfill any purpose.
@@ -30,7 +31,7 @@
#include "tcpip.h"
#ifndef lint
-static char sccsid[] = "@(#)slinux.c 1.1 12/3/95 (C) 1995 Darren Reed";
+static const char sccsid[] = "@(#)slinux.c 1.1 12/3/95 (C) 1995 Darren Reed";
#endif
#define BUFSPACE 32768
diff --git a/contrib/ipfilter/ipsd/snit.c b/contrib/ipfilter/ipsd/snit.c
index 4b5fd0346b2a..ba097f048616 100644
--- a/contrib/ipfilter/ipsd/snit.c
+++ b/contrib/ipfilter/ipsd/snit.c
@@ -1,8 +1,9 @@
/*
- * (C)opyright October 1992 Darren Reed. (from tcplog)
+ * (C)opyright 1992-1997 Darren Reed. (from tcplog)
*
- * This software may be freely distributed as long as it is not altered
- * in any way and that this messagge always accompanies it.
+ * Redistribution and use in source and binary forms are permitted
+ * provided that this notice is preserved and due credit is given
+ * to the original author and the contributors.
*
* The author of this software makes no garuntee about the
* performance of this package or its suitability to fulfill any purpose.
diff --git a/contrib/ipfilter/ipsend/44arp.c b/contrib/ipfilter/ipsend/44arp.c
index f46bc55430b9..290e676d514c 100644
--- a/contrib/ipfilter/ipsend/44arp.c
+++ b/contrib/ipfilter/ipsend/44arp.c
@@ -22,6 +22,9 @@
#include <netinet/in.h>
#include <netinet/ip_var.h>
#include <netinet/tcp.h>
+#if __FreeBSD_version >= 300000
+# include <net/if_var.h>
+#endif
#include "ipsend.h"
diff --git a/contrib/ipfilter/ipsend/Crashable b/contrib/ipfilter/ipsend/Crashable
index dbe1b87c1174..c7ffcde38c32 100644
--- a/contrib/ipfilter/ipsend/Crashable
+++ b/contrib/ipfilter/ipsend/Crashable
@@ -10,6 +10,7 @@ Test 1:
HP-UX 9.0
HP-UX 10.1
LivingstonsComOS
+ MacOS 7.x, 8.x
Test 6:
SunOS 4.1.x
diff --git a/contrib/ipfilter/ipsend/Makefile b/contrib/ipfilter/ipsend/Makefile
index df650aa7af2d..49fdb676490f 100644
--- a/contrib/ipfilter/ipsend/Makefile
+++ b/contrib/ipfilter/ipsend/Makefile
@@ -1,34 +1,64 @@
#
-# (C)opyright 1993-1996 by Darren Reed.
+# Copyright (C) 1993-1997 by Darren Reed.
#
-# This code may be freely distributed as long as it retains this notice
-# and is not changed in any way. The author accepts no responsibility
-# for the use of this software. I hate legaleese, don't you ?
+# Redistribution and use in source and binary forms are permitted
+# provided that this notice is preserved and due credit is given
+# to the original author and the contributors.
#
-OBJS=ipsend.o ip.o ipsopt.o
-ROBJS=ipresend.o ip.o resend.o
+IPFT=ipft_ef.o ipft_hx.o ipft_pc.o ipft_sn.o ipft_td.o ipft_tx.o opt.o
+OBJS=ipsend.o ip.o ipsopt.o y.tab.o lex.yy.o
+ROBJS=ipresend.o ip.o resend.o $(IPFT)
TOBJS=iptest.o iptests.o ip.o
BPF=sbpf.o
NIT=snit.o
-SUNOS4=sock.o arp.o
+SUNOS4=sock.o arp.o inet_addr.o
BSD=sock.o 44arp.o
LINUX=lsock.o slinux.o larp.o
LINUXK=
TOP=..
-SUNOS5=dlcommon.o sdlpi.o arp.o
-
-CC=gcc
-CFLAGS=-g -I.. -DNO_IPF
+SUNOS5=dlcommon.o sdlpi.o arp.o inet_addr.o
+ULTRIX=ultrix.o sock.o arp.o inet_addr.o
+HPUX=hpux.o sock.o arp.o inet_addr.o
+#CC=gcc
+DEBUG=-g
+CFLAGS=$(DEBUG) -I. -Iipf
+#
+MFLAGS="BINDEST=$(BINDEST)" "SBINDEST=$(SBINDEST)" "MANDIR=$(MANDIR)" \
+ "IPFLKM=$(IPFLKM)" \
+ "IPFLOG=$(IPFLOG)" "LOGFAC=$(LOGFAC)" "POLICY=$(POLICY)" \
+ "SOLARIS2=$(SOLARIS2)" "DEBUG=$(DEBUG)" "DCPU=$(CPU)" \
+ "CPUDIR=$(CPUDIR)"
+#
all:
@echo "Use one of these targets:"
@echo " sunos4-nit (standard SunOS 4.1.x)"
@echo " sunos4-bpf (SunOS4.1.x with BPF in the kernel)"
@echo " bsd-bpf (4.4BSD variant with BPF in the kernel)"
@echo " linux10 (Linux 1.0 kernels)"
+ @echo " linux12 (Linux 1.2 kernels)"
@echo " linux20 (Linux 2.0 kernels)"
@echo " sunos5 (Solaris 2.x)"
+ipf:
+ -if [ ! -d iplang ] ; then ln -s ../iplang iplang; fi
+ -if [ ! -d netinet ] ; then ln -s ../netinet netinet; fi
+ -if [ ! -d ipf ] ; then ln -s .. ipf; fi
+
+y.tab.o: iplang/iplang_y.y
+ -if [ -h iplang ] ; then \
+ (cd iplang; ${MAKE} $(MFLAGS) 'DESTDIR=../ipsend' ) \
+ else \
+ (cd iplang; ${MAKE} $(MFLAGS) 'DESTDIR=..' ) \
+ fi
+
+lex.yy.o: iplang/iplang_l.l
+ -if [ -h iplang ] ; then \
+ (cd iplang; ${MAKE} $(MFLAGS) 'DESTDIR=../ipsend' ) \
+ else \
+ (cd iplang; ${MAKE} $(MFLAGS) 'DESTDIR=..' ) \
+ fi
+
.c.o:
$(CC) $(CFLAGS) $(LINUXK) -c $< -o $@
@@ -37,7 +67,7 @@ install:
bpf sunos4-bpf :
make ipsend "OBJS=$(OBJS)" "UNIXOBJS=$(BPF) $(SUNOS4)" "CC=$(CC)" \
- "CFLAGS=$(CFLAGS) -DDOSOCKET"
+ "CFLAGS=$(CFLAGS) -DDOSOCKET" "LLIB=-ll"
make ipresend "ROBJS=$(ROBJS)" "UNIXOBJS=$(BPF) $(SUNOS4)" "CC=$(CC)" \
"CFLAGS=$(CFLAGS) -DDOSOCKET"
make iptest "TOBJS=$(TOBJS)" "UNIXOBJS=$(BPF) $(SUNOS4)" "CC=$(CC)" \
@@ -45,7 +75,7 @@ bpf sunos4-bpf :
nit sunos4 sunos4-nit :
make ipsend "OBJS=$(OBJS)" "UNIXOBJS=$(NIT) $(SUNOS4)" "CC=$(CC)" \
- "CFLAGS=$(CFLAGS) -DDOSOCKET"
+ "CFLAGS=$(CFLAGS) -DDOSOCKET" "LLIB=-ll"
make ipresend "ROBJS=$(ROBJS)" "UNIXOBJS=$(NIT) $(SUNOS4)" "CC=$(CC)" \
"CFLAGS=$(CFLAGS) -DDOSOCKET"
make iptest "TOBJS=$(TOBJS)" "UNIXOBJS=$(NIT) $(SUNOS4)" "CC=$(CC)" \
@@ -53,7 +83,7 @@ nit sunos4 sunos4-nit :
dlpi sunos5 :
make ipsend "OBJS=$(OBJS)" "UNIXOBJS=$(SUNOS5)" "CC=$(CC)" \
- CFLAGS="$(CFLAGS) -Dsolaris" "LIBS=-lsocket -lnsl"
+ CFLAGS="$(CFLAGS) -Dsolaris" "LIBS=-lsocket -lnsl" "LLIB=-ll"
make ipresend "ROBJS=$(ROBJS)" "UNIXOBJS=$(SUNOS5)" "CC=$(CC)" \
CFLAGS="$(CFLAGS) -Dsolaris" "LIBS=-lsocket -lnsl"
make iptest "TOBJS=$(TOBJS)" "UNIXOBJS=$(SUNOS5)" "CC=$(CC)" \
@@ -61,7 +91,7 @@ dlpi sunos5 :
bsd-bpf :
make ipsend "OBJS=$(OBJS)" "UNIXOBJS=$(BPF) $(BSD)" "CC=$(CC)" \
- "CFLAGS=$(CFLAGS) -DDOSOCKET"
+ "CFLAGS=$(CFLAGS) -DDOSOCKET" "LLIB=-ll"
make ipresend "ROBJS=$(ROBJS)" "UNIXOBJS=$(BPF) $(BSD)" "CC=$(CC)" \
"CFLAGS=$(CFLAGS) -DDOSOCKET"
make iptest "TOBJS=$(TOBJS)" "UNIXOBJS=$(BPF) $(BSD)" "CC=$(CC)" \
@@ -69,26 +99,78 @@ bsd-bpf :
linuxrev :
make ipsend "OBJS=$(OBJS)" "UNIXOBJS=$(LINUX)" "CC=$(CC)" \
- CFLAGS="$(CFLAGS) -I/usr/src/linux/include -DDOSOCKET" $(LINUXK)
+ CFLAGS="$(CFLAGS) $(INC) -DDOSOCKET" $(LINUXK)
make ipresend "ROBJS=$(ROBJS)" "UNIXOBJS=$(LINUX)" "CC=$(CC)" \
- CFLAGS="$(CFLAGS) -I/usr/src/linux/include -DDOSOCKET" $(LINUXK)
+ CFLAGS="$(CFLAGS) $(INC) -DDOSOCKET" $(LINUXK)
make iptest "TOBJS=$(TOBJS)" "UNIXOBJS=$(LINUX)" "CC=$(CC)" \
- CFLAGS="$(CFLAGS) -I/usr/src/linux/include -DDOSOCKET" $(LINUXK)
+ CFLAGS="$(CFLAGS) $(INC) -DDOSOCKET" $(LINUXK)
linux10:
- make linuxrev 'LINUXK="LINUXK=-DLINUX=0100"'
+ make linuxrev 'LINUXK="LINUXK=-DLINUX=0100"' \
+ "INC=-I/usr/src/linux/include" "LLIB=-lfl"
+
+linux12:
+ make linuxrev 'LINUXK="LINUXK=-DLINUX=0102"' "INC=-I/usr/src/linux" \
+ "LLIB=-lfl"
linux20:
- make linuxrev 'LINUXK="LINUXK=-DLINUX=0200"'
+ make linuxrev 'LINUXK="LINUXK=-DLINUX=0200"' \
+ "INC=-I/usr/src/linux/include" "LLIB=-lfl" "ELIB=-lelf"
-ipsend: $(OBJS) $(UNIXOBJS)
- $(CC) $(OBJS) $(UNIXOBJS) -o $@ $(LIBS)
+ultrix :
+ make ipsend "OBJS=$(OBJS)" "UNIXOBJS=$(ULTRIX)" "CC=$(CC)" \
+ CFLAGS="$(CFLAGS)" "LIBS=" "LLIB=-ll"
+ make ipresend "ROBJS=$(ROBJS)" "UNIXOBJS=$(ULTRIX)" "CC=$(CC)" \
+ CFLAGS="$(CFLAGS)" "LIBS="
+ make iptest "TOBJS=$(TOBJS)" "UNIXOBJS=$(ULTRIX)" "CC=$(CC)" \
+ CFLAGS="$(CFLAGS)" "LIBS="
+
+hpux9 :
+ make ipsend "OBJS=$(OBJS)" "UNIXOBJS=$(HPUX)" "CC=$(CC)" \
+ CFLAGS="$(CFLAGS)" "LIBS="
+ make ipresend "ROBJS=$(ROBJS)" "UNIXOBJS=$(HPUX)" "CC=$(CC)" \
+ CFLAGS="$(CFLAGS)" "LIBS="
+ make iptest "TOBJS=$(TOBJS)" "UNIXOBJS=$(HPUX)" "CC=$(CC)" \
+ CFLAGS="$(CFLAGS)" "LIBS="
+
+ipsend: ipf $(OBJS) $(UNIXOBJS)
+ $(CC) $(OBJS) $(UNIXOBJS) -o $@ $(LIBS) $(LLIB) $(ELIB)
ipresend: $(ROBJS) $(UNIXOBJS)
- $(CC) $(ROBJS) $(UNIXOBJS) -o $@ $(LIBS)
+ $(CC) $(ROBJS) $(UNIXOBJS) -o $@ $(LIBS) $(ELIB)
iptest: $(TOBJS) $(UNIXOBJS)
- $(CC) $(TOBJS) $(UNIXOBJS) -o $@ $(LIBS)
+ $(CC) $(TOBJS) $(UNIXOBJS) -o $@ $(LIBS) $(ELIB)
+
+ipft_ef.o: ipf/ipft_ef.c ipf/ipt.h ipf/ipf.h ipf/ip_compat.h
+ $(CC) $(CFLAGS) $(LINUXK) -c ipf/ipft_ef.c -o $@
+
+ipft_hx.o: ipf/ipft_hx.c ipf/ipt.h ipf/ipf.h ipf/ip_compat.h
+ $(CC) $(CFLAGS) $(LINUXK) -c ipf/ipft_hx.c -o $@
+
+ipft_pc.o: ipf/ipft_pc.c ipf/ipt.h ipf/ipf.h ipf/ip_compat.h
+ $(CC) $(CFLAGS) $(LINUXK) -c ipf/ipft_pc.c -o $@
+
+ipft_sn.o: ipf/ipft_sn.c ipf/ipt.h ipf/ipf.h ipf/ip_compat.h
+ $(CC) $(CFLAGS) $(LINUXK) -c ipf/ipft_sn.c -o $@
+
+ipft_td.o: ipf/ipft_td.c ipf/ipt.h ipf/ipf.h ipf/ip_compat.h
+ $(CC) $(CFLAGS) $(LINUXK) -c ipf/ipft_td.c -o $@
+
+ipft_tx.o: ipf/ipft_tx.c ipf/ipt.h ipf/ipf.h ipf/ip_compat.h
+ $(CC) $(CFLAGS) $(LINUXK) -c ipf/ipft_tx.c -o $@
+
+opt.o: ipf/opt.c ipf/ipt.h ipf/ipf.h ipf/ip_compat.h
+ $(CC) $(CFLAGS) $(LINUXK) -c ipf/opt.c -o $@
+
+inet_addr.o: ipf/inet_addr.c
+ $(CC) $(CFLAGS) $(LINUXK) -c ipf/inet_addr.c -o $@
clean:
rm -rf *.o *core a.out ipsend ipresend iptest
+ if [ -d iplang ]; then (cd iplang; $(MAKE) $(MFLAGS) clean); fi
+ if [ -d $(TOP)/iplang ]; then (cd $(TOP)/iplang; $(MAKE) $(MFLAGS) clean); fi
+
+do-cvs:
+ find . -type d -name CVS -print | xargs /bin/rm -rf
+ find . -type f -name .cvsignore -print | xargs /bin/rm -f
diff --git a/contrib/ipfilter/ipsend/README b/contrib/ipfilter/ipsend/README
new file mode 100644
index 000000000000..6898cdd44b37
--- /dev/null
+++ b/contrib/ipfilter/ipsend/README
@@ -0,0 +1,8 @@
+
+This distribution contains *ONLY* the code required to build the 'ipsend'
+directory of programs (including man pages) found in the IP Filter package:
+http://coombs.anu.edu.au/~avalon/ip-filter.html
+
+Patches, bugs, etc, please send to:
+
+darrenr@cyber.com.au
diff --git a/contrib/ipfilter/ipsend/arp.c b/contrib/ipfilter/ipsend/arp.c
index 10f27cd7995f..27a27c3ce966 100644
--- a/contrib/ipfilter/ipsend/arp.c
+++ b/contrib/ipfilter/ipsend/arp.c
@@ -1,25 +1,28 @@
/*
- * arp.c (C) 1995 Darren Reed
+ * arp.c (C) 1995-1997 Darren Reed
*
- * The author provides this program as-is, with no gaurantee for its
- * suitability for any specific purpose. The author takes no responsibility
- * for the misuse/abuse of this program and provides it for the sole purpose
- * of testing packet filter policies. This file maybe distributed freely
- * providing it is not modified and that this notice remains in tact.
+ * Redistribution and use in source and binary forms are permitted
+ * provided that this notice is preserved and due credit is given
+ * to the original author and the contributors.
*/
-#if !defined(lint) && defined(LIBC_SCCS)
-static char sccsid[] = "@(#)arp.c 1.4 1/11/96 (C)1995 Darren Reed";
+#if !defined(lint)
+static const char sccsid[] = "@(#)arp.c 1.4 1/11/96 (C)1995 Darren Reed";
+static const char rcsid[] = "@(#)$Id: arp.c,v 2.0.2.6 1997/09/28 07:13:25 darrenr Exp $";
#endif
#include <stdio.h>
#include <errno.h>
#include <sys/types.h>
#include <sys/socket.h>
+#if !defined(ultrix) && !defined(hpux)
#include <sys/sockio.h>
+#endif
#include <sys/ioctl.h>
#include <netdb.h>
#include <netinet/in.h>
#include <net/if.h>
+#ifndef ultrix
#include <net/if_arp.h>
+#endif
#include <netinet/in.h>
#include <netinet/ip_var.h>
#include <netinet/tcp.h>
@@ -77,9 +80,11 @@ char *ether;
sin = (struct sockaddr_in *)&ar.arp_pa;
sin->sin_family = AF_INET;
bcopy(ip, (char *)&sin->sin_addr.s_addr, 4);
+#ifndef hpux
if ((hp = gethostbyaddr(ip, 4, AF_INET)))
if (!(ether_hostton(hp->h_name, ether)))
goto savearp;
+#endif
if (sfd == -1)
if ((sfd = socket(AF_INET, SOCK_DGRAM, 0)) == -1)
diff --git a/contrib/ipfilter/ipsend/hpux.c b/contrib/ipfilter/ipsend/hpux.c
new file mode 100644
index 000000000000..e4e5dc32e496
--- /dev/null
+++ b/contrib/ipfilter/ipsend/hpux.c
@@ -0,0 +1,112 @@
+/*
+ * (C)opyright 1997 Darren Reed. (from tcplog)
+ *
+ * Redistribution and use in source and binary forms are permitted
+ * provided that this notice is preserved and due credit is given
+ * to the original author and the contributors.
+ */
+#include <stdio.h>
+#include <strings.h>
+#include <unistd.h>
+#include <stdlib.h>
+#include <sys/types.h>
+#include <sys/param.h>
+#include <sys/socket.h>
+#include <sys/file.h>
+#include <sys/ioctl.h>
+
+
+int initdevice(device, sport, tout)
+char *device;
+int sport, tout;
+{
+ int fd;
+
+ if ((fd = socket(AF_DLI, SOCK_RAW, 0)) == -1)
+ perror("socket");
+ return fd;
+}
+
+
+/*
+ * output an IP packet onto a fd opened for /dev/bpf
+ */
+int sendip(fd, pkt, len)
+int fd, len;
+char *pkt;
+{
+ if (send(fd, pkt, len, 0) == -1)
+ {
+ perror("send");
+ return -1;
+ }
+
+ return len;
+}
+
+
+char *strdup(str)
+char *str;
+{
+ char *s;
+
+ if ((s = (char *)malloc(strlen(str) + 1)))
+ return strcpy(s, str);
+ return NULL;
+}
+/*
+ * (C)opyright 1997 Darren Reed. (from tcplog)
+ *
+ * Redistribution and use in source and binary forms are permitted
+ * provided that this notice is preserved and due credit is given
+ * to the original author and the contributors.
+ */
+#include <stdio.h>
+#include <strings.h>
+#include <unistd.h>
+#include <stdlib.h>
+#include <sys/types.h>
+#include <sys/param.h>
+#include <sys/socket.h>
+#include <sys/file.h>
+#include <sys/ioctl.h>
+
+
+int initdevice(device, sport, tout)
+char *device;
+int sport, tout;
+{
+ int fd;
+
+ if ((fd = socket(AF_DLI, SOCK_RAW, 0)) == -1)
+ perror("socket");
+ return fd;
+}
+
+
+/*
+ * output an IP packet onto a fd opened for /dev/bpf
+ */
+int sendip(fd, pkt, len)
+int fd, len;
+char *pkt;
+{
+ if (send(fd, pkt, len, 0) == -1)
+ {
+ perror("send");
+ return -1;
+ }
+
+ return len;
+}
+
+
+char *strdup(str)
+char *str;
+{
+ char *s;
+
+ if ((s = (char *)malloc(strlen(str) + 1)))
+ return strcpy(s, str);
+ return NULL;
+}
diff --git a/contrib/ipfilter/ipsend/ip.c b/contrib/ipfilter/ipsend/ip.c
index 1b0822221a74..0f8d19b29fc4 100644
--- a/contrib/ipfilter/ipsend/ip.c
+++ b/contrib/ipfilter/ipsend/ip.c
@@ -1,14 +1,13 @@
/*
- * ip.c (C) 1995 Darren Reed
+ * ip.c (C) 1995-1997 Darren Reed
*
- * The author provides this program as-is, with no gaurantee for its
- * suitability for any specific purpose. The author takes no responsibility
- * for the misuse/abuse of this program and provides it for the sole purpose
- * of testing packet filter policies. This file maybe distributed freely
- * providing it is not modified and that this notice remains in tact.
+ * Redistribution and use in source and binary forms are permitted
+ * provided that this notice is preserved and due credit is given
+ * to the original author and the contributors.
*/
-#if !defined(lint) && defined(LIBC_SCCS)
-static char sccsid[] = "%W% %G% (C)1995";
+#if !defined(lint)
+static const char sccsid[] = "%W% %G% (C)1995";
+static const char rcsid[] = "@(#)$Id: ip.c,v 2.0.2.11 1997/10/23 11:42:44 darrenr Exp $";
#endif
#include <errno.h>
#include <stdio.h>
@@ -24,9 +23,13 @@ static char sccsid[] = "%W% %G% (C)1995";
#include <netinet/tcp.h>
#include <netinet/udp.h>
#include <netinet/ip_icmp.h>
+#include <sys/param.h>
#ifndef linux
-#include <netinet/if_ether.h>
-#include <netinet/ip_var.h>
+# include <netinet/if_ether.h>
+# include <netinet/ip_var.h>
+# if __FreeBSD_version >= 300000
+# include <net/if_var.h>
+# endif
#endif
#include "ipsend.h"
@@ -67,13 +70,13 @@ struct in_addr gwip;
bcopy((char *)buf, s + sizeof(*eh), len);
if (gwip.s_addr == last_gw.s_addr)
- bcopy(last_arp, (char *)&eh->ether_dhost, 6);
- else if (arp((char *)&gwip, (char *)&eh->ether_dhost) == -1)
+ bcopy(last_arp, (char *)A_A eh->ether_dhost, 6);
+ else if (arp((char *)&gwip, (char *)A_A eh->ether_dhost) == -1)
{
perror("arp");
return -2;
}
- eh->ether_type = ETHERTYPE_IP;
+ eh->ether_type = htons(ETHERTYPE_IP);
last_gw.s_addr = gwip.s_addr;
err = sendip(nfd, s, sizeof(*eh) + len);
return err;
@@ -99,27 +102,29 @@ int frag;
ipbuf = (char *)malloc(65536);
eh = (ether_header_t *)ipbuf;
- bzero((char *)&eh->ether_shost, sizeof(eh->ether_shost));
+ bzero((char *)A_A eh->ether_shost, sizeof(eh->ether_shost));
if (last_gw.s_addr && (gwip.s_addr == last_gw.s_addr))
- bcopy(last_arp, (char *)&eh->ether_dhost, 6);
- else if (arp((char *)&gwip, (char *)&eh->ether_dhost) == -1)
+ bcopy(last_arp, (char *)A_A eh->ether_dhost, 6);
+ else if (arp((char *)&gwip, (char *)A_A eh->ether_dhost) == -1)
{
perror("arp");
return -2;
}
- bcopy((char *)&eh->ether_dhost, last_arp, sizeof(last_arp));
- eh->ether_type = ETHERTYPE_IP;
+ bcopy((char *)A_A eh->ether_dhost, last_arp, sizeof(last_arp));
+ eh->ether_type = htons(ETHERTYPE_IP);
bcopy((char *)ip, (char *)&ipsv, sizeof(*ip));
last_gw.s_addr = gwip.s_addr;
ip->ip_len = htons(ip->ip_len);
ip->ip_off = htons(ip->ip_off);
- if (!ip->ip_v)
- ip->ip_v = IPVERSION;
- if (!ip->ip_id)
- ip->ip_id = htons(id++);
- if (!ip->ip_ttl)
- ip->ip_ttl = 60;
+ if (!(frag & 2)) {
+ if (!ip->ip_v)
+ ip->ip_v = IPVERSION;
+ if (!ip->ip_id)
+ ip->ip_id = htons(id++);
+ if (!ip->ip_ttl)
+ ip->ip_ttl = 60;
+ }
if (!frag || (sizeof(*eh) + ntohs(ip->ip_len) < mtu))
{
diff --git a/contrib/ipfilter/ipsend/ipresend.1 b/contrib/ipfilter/ipsend/ipresend.1
new file mode 100644
index 000000000000..40f98256209f
--- /dev/null
+++ b/contrib/ipfilter/ipsend/ipresend.1
@@ -0,0 +1,107 @@
+.TH IPRESEND 1
+.SH NAME
+ipresend \- resend IP packets out to network
+.SH SYNOPSIS
+.B ipsend
+[
+.B \-EHPRSTX
+] [
+.B \-d
+<device>
+] [
+.B \-g
+<\fIgateway\fP>
+] [
+.B \-m
+<\fIMTU\fP>
+] [
+.B \-r
+<\fIfilename\fP>
+]
+.SH DESCRIPTION
+.PP
+\fBipresend\fP was designed to allow packets to be resent, once captured,
+back out onto the network for use in testing. \fIipresend\fP supports a
+number of different file formats as input, including saved snoop/tcpdump
+binary data.
+.SH OPTIONS
+.TP
+.BR \-d \0<interface>
+Set the interface name to be the name supplied. This is useful with the
+\fB\-P, \-S, \-T\fP and \fB\-E\fP options, where it is not otherwise possible
+to associate a packet with an interface. Normal "text packets" can override
+this setting.
+.TP
+.BR \-g \0<gateway>
+Specify the hostname of the gateway through which to route packets. This
+is required whenever the destination host isn't directly attached to the
+same network as the host from which you're sending.
+.TP
+.BR \-m \0<MTU>
+Specify the MTU to be used when sending out packets. This option allows you
+to set a fake MTU, allowing the simulation of network interfaces with small
+MTU's without setting them so.
+.TP
+.BR \-r \0<filename>
+Specify the filename from which to take input. Default is stdin.
+.B \-E
+The input file is to be text output from etherfind. The text formats which
+are currently supported are those which result from the following etherfind
+option combinations:
+.PP
+.nf
+ etherfind -n
+ etherfind -n -t
+.fi
+.LP
+.TP
+.B \-H
+The input file is to be hex digits, representing the binary makeup of the
+packet. No length correction is made, if an incorrect length is put in
+the IP header.
+.TP
+.B \-P
+The input file specified by \fB\-i\fP is a binary file produced using libpcap
+(i.e., tcpdump version 3). Packets are read from this file as being input
+(for rule purposes).
+.TP
+.B \-R
+When sending packets out, send them out "raw" (the way they came in). The
+only real significance here is that it will expect the link layer (i.e.
+ethernet) headers to be prepended to the IP packet being output.
+.TP
+.B \-S
+The input file is to be in "snoop" format (see RFC 1761). Packets are read
+from this file and used as input from any interface. This is perhaps the
+most useful input type, currently.
+.TP
+.B \-T
+The input file is to be text output from tcpdump. The text formats which
+are currently supported are those which result from the following tcpdump
+option combinations:
+.PP
+.nf
+ tcpdump -n
+ tcpdump -nq
+ tcpdump -nqt
+ tcpdump -nqtt
+ tcpdump -nqte
+.fi
+.LP
+.TP
+.B \-X
+The input file is composed of text descriptions of IP packets.
+.TP
+.SH FILES
+.DT
+.SH SEE ALSO
+snoop(1m), tcpdump(8), etherfind(8c), ipftest(1), ipresend(1), iptest(1), bpf(4), dlpi(7p)
+.SH DIAGNOSTICS
+.PP
+Needs to be run as root.
+.SH BUGS
+.PP
+Not all of the input formats are sufficiently capable of introducing a
+wide enough variety of packets for them to be all useful in testing.
+If you find any, please send email to me at darrenr@cyber.com.au
+
diff --git a/contrib/ipfilter/ipsend/ipresend.c b/contrib/ipfilter/ipsend/ipresend.c
index 9402104a6d22..4de8e418a9b8 100644
--- a/contrib/ipfilter/ipsend/ipresend.c
+++ b/contrib/ipfilter/ipsend/ipresend.c
@@ -1,21 +1,18 @@
/*
- * ipsend.c (C) 1995 Darren Reed
+ * ipresend.c (C) 1995-1997 Darren Reed
*
* This was written to test what size TCP fragments would get through
* various TCP/IP packet filters, as used in IP firewalls. In certain
* conditions, enough of the TCP header is missing for unpredictable
* results unless the filter is aware that this can happen.
*
- * The author provides this program as-is, with no gaurantee for its
- * suitability for any specific purpose. The author takes no responsibility
- * for the misuse/abuse of this program and provides it for the sole purpose
- * of testing packet filter policies. This file maybe distributed freely
- * providing it is not modified and that this notice remains in tact.
- *
- * This was written and tested (successfully) on SunOS 4.1.x.
+ * Redistribution and use in source and binary forms are permitted
+ * provided that this notice is preserved and due credit is given
+ * to the original author and the contributors.
*/
-#if !defined(lint) && defined(LIBC_SCCS)
-static char sccsid[] = "%W% %G% (C)1995 Darren Reed";
+#if !defined(lint)
+static const char sccsid[] = "%W% %G% (C)1995 Darren Reed";
+static const char rcsid[] = "@(#)$Id: ipresend.c,v 2.0.2.9 1997/10/12 09:48:37 darrenr Exp $";
#endif
#include <stdio.h>
#include <stdlib.h>
@@ -58,7 +55,11 @@ char default_device[] = "ln0";
# ifdef __bsdi__
char default_device[] = "ef0";
# else
+# ifdef __sgi
+char default_device[] = "ec0";
+# else
char default_device[] = "lan0";
+# endif
# endif
# endif
# endif
@@ -94,10 +95,10 @@ char **argv;
struct in_addr gwip;
struct ipread *ipr = NULL;
char *name = argv[0], *gateway = NULL, *dev = NULL;
- char c, *resend = NULL;
- int mtu = 1500;
+ char *resend = NULL;
+ int mtu = 1500, c;
- while ((c = getopt(argc, argv, "EHPSTXd:g:m:r:")) != -1)
+ while ((c = getopt(argc, argv, "EHPRSTXd:g:m:r:")) != -1)
switch (c)
{
case 'd' :
@@ -116,6 +117,9 @@ char **argv;
case 'r' :
resend = optarg;
break;
+ case 'R' :
+ opts |= OPT_RAW;
+ break;
#ifndef NO_IPF
case 'E' :
ipr = &etherf;
diff --git a/contrib/ipfilter/ipsend/ipsend.1 b/contrib/ipfilter/ipsend/ipsend.1
new file mode 100644
index 000000000000..d99038ddca77
--- /dev/null
+++ b/contrib/ipfilter/ipsend/ipsend.1
@@ -0,0 +1,109 @@
+.TH IPSEND 1
+.SH NAME
+ipsend \- sends IP packets
+.SH SYNOPSIS
+.B ipsend
+[
+.B \-dITUv
+] [
+.B \-i
+<interface>
+] [
+.B \-f
+<\fIoffset\fP>
+] [
+.B \-g
+<\fIgateway\fP>
+] [
+.B \-m
+<\fIMTU\fP>
+] [
+.B \-o
+<\fIoption\fP>
+] [
+.B \-P
+<protocol>
+] [
+.B \-s
+<\fIsource\fP>
+] [
+.B \-t
+<\fIdest. port\fP>
+] [
+.B \-w
+<\fIwindow\fP>
+] <destination> [TCP-flags]
+.SH DESCRIPTION
+.PP
+\fBipsend\fP can be compiled in two ways. The first is used to send one-off
+packets to a destination host, using command line options to specify various
+attributes present in the headers. The \fIdestination\fP must be given as
+the last command line option, except for when TCP flags are specified as
+a combination of A, S, F, U, P and R, last.
+.PP
+The other way it may be compiled, with DOSOCKET defined, is to allow an
+attempt at making a TCP connection using a with ipsend resending the SYN
+packet as per the command line options.
+.SH OPTIONS
+.TP
+.BR \-d
+enable debugging mode.
+.TP
+.BR \-f \0<offset>
+The \fI-f\fP allows the IP offset field in the IP header to be set to an
+arbitrary value, which can be specified in decimal or hexidecimal.
+.TP
+.BR \-g \0<gateway>
+Specify the hostname of the gateway through which to route packets. This
+is required whenever the destination host isn't directly attached to the
+same network as the host from which you're sending.
+.TP
+.BR \-i \0<interface>
+Set the interface name to be the name supplied.
+.TP
+.TP
+.BR \-m \0<MTU>
+Specify the MTU to be used when sending out packets. This option allows you
+to set a fake MTU, allowing the simulation of network interfaces with small
+MTU's without setting them so.
+.TP
+.BR \-o \0<option>
+Specify options to be included at the end of the IP header. An EOL option
+is automatically appended and need not be given. If an option would also
+have data associated with it (source as an IP# for a lsrr option), then
+this will not be initialised.
+.TP
+.BR \-s \0<source>
+Set the source address in the packet to that provided - maybe either a
+hostname or IP#.
+.TP
+.BR \-t \0<dest. port>
+Set the destination port for TCP/UDP packets.
+.TP
+.BR \-w \0<window>
+Set the window size for TCP packets.
+.TP
+.B \-I
+Set the protocol to ICMP.
+.TP
+.B \-P <protocol>
+Set the protocol to the value given. If the parameter is a name, the name
+is looked up in the \fI/etc/protocols\fP file.
+.TP
+.B \-T
+Set the protocol to TCP.
+.TP
+.B \-U
+Set the protocol to UDP.
+.TP
+.BR \-d
+enable verbose mode.
+.DT
+.SH SEE ALSO
+ipsend(1), ipresend(1), iptest(1), protocols(4), bpf(4), dlpi(7p)
+.SH DIAGNOSTICS
+.PP
+Needs to be run as root.
+.SH BUGS
+.PP
+If you find any, please send email to me at darrenr@cyber.com.au
diff --git a/contrib/ipfilter/ipsend/ipsend.5 b/contrib/ipfilter/ipsend/ipsend.5
new file mode 100644
index 000000000000..b6a3e0496775
--- /dev/null
+++ b/contrib/ipfilter/ipsend/ipsend.5
@@ -0,0 +1,398 @@
+.TH IPSEND 5
+.SH NAME
+ipsend \- IP packet description language
+.SH DESCRIPTION
+The \fBipsend\fP program expects, with the \fB-L\fP option, input to be a
+text file which fits the grammar described below. The purpose of this
+grammar is to allow IP packets to be described in an arbitary way which
+also allows encapsulation to be so done to an arbitary level.
+.SH GRAMMAR
+.LP
+.nf
+line ::= iface | arp | send | defrouter | ipv4line .
+
+iface ::= ifhdr "{" ifaceopts "}" ";" .
+ifhdr ::= "interface" | "iface" .
+ifaceopts ::= "ifname" name | "mtu" mtu | "v4addr" ipaddr |
+ "eaddr" eaddr .
+
+send ::= "send" ";" | "send" "{" sendbodyopts "}" ";" .
+sendbodyopts ::= sendbody [ sendbodyopts ] .
+sendbody ::= "ifname" name | "via" ipaddr .
+
+defrouter ::= "router" ipaddr .
+
+arp ::= "arp" "{" arpbodyopts "}" ";" .
+arpbodyopts ::= arpbody [ arpbodyopts ] .
+arpbody ::= "v4addr" ipaddr | "eaddr" eaddr .
+
+bodyline ::= ipv4line | tcpline | udpline | icmpline | dataline .
+
+ipv4line ::= "ipv4" "{" ipv4bodyopts "}" ";" .
+ipv4bodyopts ::= ipv4body [ ipv4bodyopts ] | bodyline .
+ipv4body ::= "proto" protocol | "src" ipaddr | "dst" ipaddr |
+ "off" number | "v" number | "hl" number| "id" number |
+ "ttl" number | "tos" number | "sum" number | "len" number |
+ "opt" "{" ipv4optlist "}" ";" .
+ipv4optlist ::= ipv4option [ ipv4optlist ] .
+ipv4optlist = "nop" | "rr" | "zsu" | "mtup" | "mtur" | "encode" | "ts" |
+ "tr" | "sec" | "lsrr" | "e-sec" | "cipso" | "satid" |
+ "ssrr" | "addext" | "visa" | "imitd" | "eip" | "finn" |
+ "secclass" ipv4secclass.
+ipv4secclass := "unclass" | "confid" | "reserv-1" | "reserv-2" |
+ "reserv-3" | "reserv-4" | "secret" | "topsecret" .
+
+tcpline ::= "tcp" "{" tcpbodyopts "}" ";" .
+tcpbodyopts ::= tcpbody [ tcpbodyopts ] | bodyline .
+tcpbody ::= "sport" port | "dport" port | "seq" number | "ack" number |
+ "off" number | "urp" number | "win" number | "sum" number |
+ "flags" tcpflags | data .
+
+udpline ::= "udp" "{" udpbodyopts "}" ";" .
+udpbodyopts ::= udpbody [ udpbodyopts ] | bodyline .
+udpbody ::= "sport" port | "dport" port | "len" number | "sum" number |
+ data .
+
+icmpline ::= "icmp" "{" icmpbodyopts "}" ";" .
+icmpbodyopts ::= icmpbody [ icmpbodyopts ] | bodyline .
+icmpbody ::= "type" icmptype [ "code" icmpcode ] .
+icmptype ::= "echorep" | "echorep" "{" echoopts "}" ";" | "unreach" |
+ "unreach" "{" unreachtype "}" ";" | "squench" | "redir" |
+ "redir" "{" redirtype "}" ";" | "echo" "{" echoopts "}" ";" |
+ "echo" | "routerad" | "routersol" | "timex" |
+ "timex" "{" timextype "}" ";" | "paramprob" |
+ "paramprob" "{" parapptype "}" ";" | "timest" | "timestrep" |
+ "inforeq" | "inforep" | "maskreq" | "maskrep" .
+
+echoopts ::= echoopts [ icmpechoopts ] .
+unreachtype ::= "net-unr" | "host-unr" | "proto-unr" | "port-unr" |
+ "needfrag" | "srcfail" | "net-unk" | "host-unk" | "isolate" |
+ "net-prohib" | "host-prohib" | "net-tos" | "host-tos" |
+ "filter-prohib" | "host-preced" | "cutoff-preced" .
+redirtype ::= "net-redir" | "host-redir" | "tos-net-redir" |
+ "tos-host-redir" .
+timextype ::= "intrans" | "reass" .
+paramptype ::= "optabsent" .
+
+data ::= "data" "{" databodyopts "}" ";" .
+databodyopts ::= "len" number | "value" string | "file" filename .
+
+icmpechoopts ::= "icmpseq" number | "icmpid" number .
+.fi
+.SH COMMANDS
+.PP
+Before sending any packets or defining any packets, it is necessary to
+describe the interface(s) which will be used to send packets out.
+.TP
+.B interface
+is used to describe a network interface. The description included need
+not match the actual configuration currently employed by the operating
+system.
+.TP
+.B send
+is used to actually send out a packet across the network. If the
+destination is not specified, it will attempt to send the packet
+directly out on the network to the destination without routing it.
+.TP
+.B router
+configures the default router for ipsend, as distinct from the default
+route installed in the kernel.
+.TP
+.B ipv4
+is used to describe an IP (version 4) packet. IP header fields can be
+specified, including options, followed by a data section which may contain
+further protocol headers.
+.SH IPV4
+.TP
+.B hl <number>
+manually specifies the IP header length (automatically adjusts with the
+presence of IP options and defaults to 5);
+.TP
+.B v <number>
+set the IP version. Default is 4.
+.TP
+.B tos <number>
+set the type of service (TOS) field in the IP header. Default is 0.
+.TP
+.B len <number>
+manually specifies the length of the IP packet. The length will automatically
+be adjusted to accomodate data or further protocol headers.
+.TP
+.B off <number>
+sets the fragment offset field of the IP packet. Default is 0.
+.TP
+.B ttl <number>
+sets the time to live (TTL) field of the IP header. Default is 60.
+.TP
+.B proto <protocol>
+sets the protocol field of the IP header. The protocol can either be a
+number or a name found in \fB/etc/protocols\fP.
+.TP
+.B sum
+manually specifies the checksum for the IP header. If left unset (0), it
+will be calculated prior to being sent.
+.TP
+.B src
+manually specifies the source address of the IP header. If left unset, it
+will default to the host's IP address.
+.TP
+.B dst
+sets the destination of the IP packet. The default is 0.0.0.0.
+.TP
+.B opt
+is used to include IP options in the IP header.
+.TP
+.B tcp
+is used to indicate the a TCP protocol header is to follow. See the \fBTCP\fP
+section for TCP header options.
+.TP
+.B udp
+is used to indicate the a UDP protocol header is to follow. See the \fBUDP\fP
+section for UDP header options.
+.TP
+.B icmp
+is used to indicate the a ICMP protocol header is to follow. See the
+\fBICMP\fP section for ICMP header options.
+.TP
+.B data
+is used to indicate that raw data is to be included in the IP packet. See the
+\fBDATA\fP section for details on options available.
+.SH "IPv4 Options"
+these keywords indicate that the releveant IP option should be added to the
+IP header (the header length field will be adjusted appropriately).
+.TP
+.B nop
+No Operation [RFC 791] (space filler).
+.TP
+.B rr <number>
+Record Router [RFC 791]. The number given specifies the number of
+\fBbytes\fP to be used for storage. This should be a multiple of 4 for
+proper operation.
+.TP
+.B zsu
+Experimental Measurement.
+.TP
+.B mtup [RFC 1191].
+MTU Probe.
+.TP
+.B mtur [RFC 1191].
+MTU Ready.
+.TP
+.B encode
+.TP
+.B ts
+Timestamp [RFC 791].
+.TP
+.B tr
+Traceroute [RFC 1393].
+.TP
+.B "sec-class <security-level>, sec"
+Security [RFC 1108]. This option specifies the security label for the packet.
+Using \fBsec\fP sets up the framework of the security option but unless
+\fBsec-class\fP is given, the level may not be set.
+.TP
+.B "lsrr <ip-address>"
+Loose Source Route [RFC 791].
+.TP
+.B e-sec
+Extended Security [RFC 1108].
+.TP
+.B cipso
+Commercial Security.
+.TP
+.B satid
+Stream ID [RFC 791].
+.TP
+.B "ssrr <ip-address>"
+Strict Source Route [RFC 791].
+.TP
+.B addext
+Address Extension
+.TP
+.B visa
+Expermental Access Control.
+.TP
+.B imitd
+IMI Traffic Descriptor.
+.TP
+.B eip
+[RFC 1358].
+.TP
+.B finn
+Experimental Flow Control.
+.SH TCP
+.TP
+.B sport <port>
+sets the source port to the number/name given. Default is 0.
+.TP
+.B dport <port>
+sets the destination port to the number/name given. Default is 0.
+.TP
+.B seq <number>
+sets the sequence number to the number specified. Default is 0.
+.TP
+.B ack <number>
+sets the acknowledge number to the number specified. Default is 0.
+.TP
+.B off <number>
+sets the offset value for the start of data to the number specified. This
+implies the size of the TCP header. It is automatically adjusted if TCP
+options are included and defaults to 5.
+.TP
+.B urp <number>
+sets the value of the urgent data pointer to the number specified. Default
+is 0.
+.TP
+.B win <number>
+sets the size of the TCP window to the number specified. Default is 4096.
+.TP
+.B sum <number>
+manually specifies the checksum for the TCP pseudo-header and data. If left
+unset, it defaults to 0 and is automatically calculated.
+.TP
+.B flags <tcp-flags>
+sets the TCP flags field to match the flags specified. Valid flags are
+"S" (SYN), "A" (ACK), "R" (RST), "F" (FIN), "U" (URG), "P" (PUSH).
+.TP
+.B opt
+indicates that TCP header options follow. As TCP options are added to the
+TCP header, the \fBoff\fP field is updated to match.
+.TP
+.B data
+indicates that a data section is to follow and is to be included as raw
+data, being appended to the header.
+.SH "TCP options"
+With a TCP header, it is possible to append a number of header options.
+The TCP header offset will be updated automatically to reflect the change
+in size. The valid options are: \fBnop\fP No Operation,
+\fBeol\fP End Of (option) List, \fBmss [ size ]\fP Maximum Segment Size - this
+sets the maximum receivable size of a packet containing data,
+\fBwscale\fP Window Scale, \fBts\fP Timestamp.
+.SH UDP
+.TP
+.B sport <port>
+sets the source port to the number/name given. Default is 0.
+.TP
+.B dport <port>
+sets the destination port to the number/name given. Default is 0.
+.TP
+.B len <number>
+manually specifies the length of the UDP header and data. If left unset,
+it is automatically adjusted to match the header presence and any data if
+present.
+.TP
+.B sum <number>
+manually specifies the checksum for the UDP pseudo-header and data. If left
+unset, it defaults to 0 and is automatically calculated.
+.TP
+.B data
+indicates that a data section is to follow and is to be included as raw
+data, being appended to the header.
+.SH ICMP
+.TP
+.B type <icmptype>
+sets the ICMP type according the to the icmptype tag. This may either be
+a number or one of the recognised tags (see the \fBICMP TYPES\fP section for a
+list of names recognised).
+.TP
+.B code <icmpcode>
+sets the ICMP code.
+.TP
+.B data
+indicates that a data section is to follow and is to be included as raw
+data, being appended to the header.
+.SH DATA
+Each of the following extend the packet in a different way. \fBLen\fP just
+increases the length (without adding any content), \fBvalue\fP uses a string
+and \fBfile\fP a file.
+.TP
+.B len <number>
+extend the length of the packet by \fBnumber\fP bytes (without filling those
+bytes with any particular data).
+.TP
+.B value <string>
+indicates that the string provided should be added to the current packet as
+data. A string may be a consecutive list of characters and numbers (with
+no white spaces) or bounded by "'s (may not contain them, even if \\'d).
+The \\ charcater is recognised with the appropriate C escaped values, including
+octal numbers.
+.TP
+.B file <filename>
+reads data in from the specified file and appends it to the current packet.
+If the new total length would exceed 64k, an error will be reported.
+.SH "ICMP TYPES"
+.TP
+.B echorep
+Eecho Reply.
+.TP
+.B "unreach [ unreachable-code ]"
+Generic Unreachable error. This is used to indicate that an error has
+occurred whilst trying to send the packet across the network and that the
+destination cannot be reached. The unreachable code names are:
+\fBnet-unr\fP network unreachable, \fBhost-unr\fP host unreachable,
+\fBproto-unr\fP protocol unreachable, \fBport-unr\fP port unreachable,
+\fBneedfrag\fP, \fBsrcfail\fP source route failed,
+\fBnet-unk\fP network unknown, \fBhost-unk\fP host unknown,
+\fBisolate\fP, \fBnet-prohib\fP administratively prohibited contact with
+network,
+\fBhost-prohib\fP administratively prohibited contact with host,
+\fBnet-tos\fP network unreachable with given TOS,
+\fBhost-tos\fP host unreachable with given TOS,
+\fBfilter-prohib\fP packet prohibited by packet filter,
+\fBhost-preced\fP,
+\fBcutoff-preced\fP.
+.TP
+.B squench
+Source Quence.
+.TP
+.B "redir [ redirect-code ]"
+Redirect (routing). This is used to indicate that the route being chosen
+for forwarding the packet is suboptimal and that the sender of the packet
+should be routing packets via another route. The redirect code names are:
+\fBnet-redir\fP redirect packets for a network,
+\fBhost-redir\fP redirect packets for a host,
+\fBtos-net-redir\fP redirect packets for a network with a given TOS,
+\fBtos-host-redir\fP redirect packets for a host with a given TOS.
+.TP
+.B echo
+Echo.
+.TP
+.B routerad
+Router Advertisment.
+.TP
+.B routersol
+Router solicitation.
+.TP
+.B "timex [ timexceed-code ]"
+Time Exceeded. This is used to indicate that the packet failed to reach the
+destination because it was in transit too long (i.e. ttl reached 0). The
+valid code names are: \fBintrans\fP,
+\fBreass\fP could not reassemble packet from fragments within a given time.
+.TP
+.B "paramprob [ paramprob-code ]"
+Parameter problem. There is only one available parameter problem code name:
+\fBoptabsent\fP.
+.TP
+.B timest
+Time stamp request.
+.TP
+.B "timestrep [ { timestamp-code } ]"
+Time stamp reply. In a timestamp reply, it is possible to supply the
+following values: \fBrtime\fP, \fBotime\fP, \fBttime\fP.
+.TP
+.B inforeq
+Information request.
+.TP
+.B inforep
+Information reply.
+.TP
+.B maskreq
+Address mask request.
+.TP
+.B maskrep
+Address mask reply.
+.SH FILES
+/etc/protocols
+/etc/services
+/etc/hosts
+.SH SEE ALSO
diff --git a/contrib/ipfilter/ipsend/ipsend.c b/contrib/ipfilter/ipsend/ipsend.c
index ecc64737ce46..1f47466f7366 100644
--- a/contrib/ipfilter/ipsend/ipsend.c
+++ b/contrib/ipfilter/ipsend/ipsend.c
@@ -1,21 +1,18 @@
/*
- * ipsend.c (C) 1995 Darren Reed
+ * ipsend.c (C) 1995-1997 Darren Reed
*
* This was written to test what size TCP fragments would get through
* various TCP/IP packet filters, as used in IP firewalls. In certain
* conditions, enough of the TCP header is missing for unpredictable
* results unless the filter is aware that this can happen.
*
- * The author provides this program as-is, with no gaurantee for its
- * suitability for any specific purpose. The author takes no responsibility
- * for the misuse/abuse of this program and provides it for the sole purpose
- * of testing packet filter policies. This file maybe distributed freely
- * providing it is not modified and that this notice remains in tact.
- *
- * This was written and tested (successfully) on SunOS 4.1.x.
+ * Redistribution and use in source and binary forms are permitted
+ * provided that this notice is preserved and due credit is given
+ * to the original author and the contributors.
*/
-#if !defined(lint) && defined(LIBC_SCCS)
-static char sccsid[] = "@(#)ipsend.c 1.5 12/10/95 (C)1995 Darren Reed";
+#if !defined(lint)
+static const char sccsid[] = "@(#)ipsend.c 1.5 12/10/95 (C)1995 Darren Reed";
+static const char rcsid[] = "@(#)$Id: ipsend.c,v 2.0.2.19 1997/10/12 09:48:38 darrenr Exp $";
#endif
#include <stdio.h>
#include <stdlib.h>
@@ -36,12 +33,15 @@ static char sccsid[] = "@(#)ipsend.c 1.5 12/10/95 (C)1995 Darren Reed";
#include <netinet/ip_var.h>
#endif
#include "ipsend.h"
+#include "ipf.h"
extern char *optarg;
extern int optind;
+extern void iplang __P((FILE *));
char options[68];
+int opts;
#ifdef linux
char default_device[] = "eth0";
#else
@@ -54,7 +54,11 @@ char default_device[] = "ln0";
# ifdef __bsdi__
char default_device[] = "ef0";
# else
+# ifdef __sgi
+char default_device[] = "ec0";
+# else
char default_device[] = "lan0";
+# endif
# endif
# endif
# endif
@@ -71,7 +75,8 @@ char *prog;
{
fprintf(stderr, "Usage: %s [options] dest [flags]\n\
\toptions:\n\
-\t\t-d device\tSend out on this device\n\
+\t\t-d\tdebug mode\n\
+\t\t-i device\tSend out on this device\n\
\t\t-f fragflags\tcan set IP_MF or IP_DF\n\
\t\t-g gateway\tIP gateway to use if non-local dest.\n\
\t\t-I code,type[,gw[,dst[,src]]]\tSet ICMP protocol\n\
@@ -81,12 +86,20 @@ char *prog;
\t\t-T\t\tSet TCP protocol\n\
\t\t-t port\t\tdestination port\n\
\t\t-U\t\tSet UDP protocol\n\
+\t\t-v\tverbose mode\n\
+\t\t-w <window>\tSet the TCP window size\n\
+", prog);
+ fprintf(stderr, "Usage: %s [-dv] -L <filename>\n\
+\toptions:\n\
+\t\t-d\tdebug mode\n\
+\t\t-L filename\tUse IP language for sending packets\n\
+\t\t-v\tverbose mode\n\
", prog);
exit(1);
}
-void do_icmp(ip, args)
+static void do_icmp(ip, args)
ip_t *ip;
char *args;
{
@@ -158,13 +171,14 @@ int main(argc, argv)
int argc;
char **argv;
{
+ FILE *langfile = NULL;
struct tcpiphdr *ti;
struct in_addr gwip;
tcphdr_t *tcp;
ip_t *ip;
char *name = argv[0], host[64], *gateway = NULL, *dev = NULL;
- char *src = NULL, *dst, c, *s;
- int mtu = 1500, olen = 0;
+ char *src = NULL, *dst, *s;
+ int mtu = 1500, olen = 0, c, nonl = 0;
/*
* 65535 is maximum packet size...you never know...
@@ -175,10 +189,11 @@ char **argv;
ip->ip_len = sizeof(*ip);
ip->ip_hl = sizeof(*ip) >> 2;
- while ((c = (char)getopt(argc, argv, "IP:TUd:f:g:m:o:s:t:")) != -1)
+ while ((c = getopt(argc, argv, "I:L:P:TUdf:i:g:m:o:s:t:vw:")) != -1)
switch (c)
{
case 'I' :
+ nonl++;
if (ip->ip_p)
{
fprintf(stderr, "Protocol already set: %d\n",
@@ -187,10 +202,26 @@ char **argv;
}
do_icmp(ip, optarg);
break;
+ case 'L' :
+ if (nonl) {
+ fprintf(stderr,
+ "Incorrect usage of -L option.\n");
+ usage(name);
+ }
+ if (!strcmp(optarg, "-"))
+ langfile = stdin;
+ else if (!(langfile = fopen(optarg, "r"))) {
+ fprintf(stderr, "can't open file %s\n",
+ optarg);
+ exit(1);
+ }
+ iplang(langfile);
+ return 0;
case 'P' :
{
struct protoent *p;
+ nonl++;
if (ip->ip_p)
{
fprintf(stderr, "Protocol already set: %d\n",
@@ -205,6 +236,7 @@ char **argv;
break;
}
case 'T' :
+ nonl++;
if (ip->ip_p)
{
fprintf(stderr, "Protocol already set: %d\n",
@@ -215,6 +247,7 @@ char **argv;
ip->ip_len += sizeof(tcphdr_t);
break;
case 'U' :
+ nonl++;
if (ip->ip_p)
{
fprintf(stderr, "Protocol already set: %d\n",
@@ -225,15 +258,22 @@ char **argv;
ip->ip_len += sizeof(udphdr_t);
break;
case 'd' :
- dev = optarg;
+ opts |= OPT_DEBUG;
break;
case 'f' :
+ nonl++;
ip->ip_off = strtol(optarg, NULL, 0);
break;
case 'g' :
+ nonl++;
gateway = optarg;
break;
+ case 'i' :
+ nonl++;
+ dev = optarg;
+ break;
case 'm' :
+ nonl++;
mtu = atoi(optarg);
if (mtu < 28)
{
@@ -242,16 +282,23 @@ char **argv;
}
break;
case 'o' :
- olen = optname(optarg, options);
+ nonl++;
+ olen = buildopts(optarg, options, (ip->ip_hl - 5) << 2);
break;
case 's' :
+ nonl++;
src = optarg;
break;
case 't' :
+ nonl++;
if (ip->ip_p == IPPROTO_TCP || ip->ip_p == IPPROTO_UDP)
tcp->th_dport = htons(atoi(optarg));
break;
+ case 'v' :
+ opts |= OPT_VERBOSE;
+ break;
case 'w' :
+ nonl++;
if (ip->ip_p == IPPROTO_TCP)
tcp->th_win = atoi(optarg);
else
@@ -262,7 +309,7 @@ char **argv;
usage(name);
}
- if (argc - optind < 2)
+ if (argc - optind < 1)
usage(name);
dst = argv[optind++];
@@ -292,6 +339,23 @@ char **argv;
exit(2);
}
+ if (olen)
+ {
+ caddr_t ipo = (caddr_t)ip;
+
+ printf("Options: %d\n", olen);
+ ti = (struct tcpiphdr *)malloc(olen + ip->ip_len);
+ bcopy((char *)ip, (char *)ti, sizeof(*ip));
+ ip = (ip_t *)ti;
+ ip->ip_hl = (olen >> 2);
+ bcopy(options, (char *)(ip + 1), olen);
+ bcopy((char *)tcp, (char *)(ip + 1) + olen, sizeof(*tcp));
+ ip->ip_len += olen;
+ bcopy((char *)ip, (char *)ipo, ip->ip_len);
+ ip = (ip_t *)ipo;
+ tcp = (tcphdr_t *)((char *)(ip + 1) + olen);
+ }
+
if (ip->ip_p == IPPROTO_TCP)
for (s = argv[optind]; (c = *s); s++)
switch(c)
@@ -326,19 +390,6 @@ char **argv;
printf("Flags: %#x\n", tcp->th_flags);
printf("mtu: %d\n", mtu);
- if (olen)
- {
- printf("Options: %d\n", olen);
- ti = (struct tcpiphdr *)malloc(olen + ip->ip_len);
- bcopy((char *)ip, (char *)ti, sizeof(*ip));
- ip = (ip_t *)ti;
- ip->ip_hl += (olen >> 2);
- bcopy(options, (char *)(ip + 1), olen);
- bcopy((char *)tcp, (char *)(ip + 1) + olen, sizeof(*tcp));
- tcp = (tcphdr_t *)((char *)(ip + 1) + olen);
- ip->ip_len += olen;
- }
-
#ifdef DOSOCKET
if (tcp->th_dport)
return do_socket(dev, mtu, ti, gwip);
diff --git a/contrib/ipfilter/ipsend/ipsend.h b/contrib/ipfilter/ipsend/ipsend.h
index 362e273aa02a..a2ff49cf5f40 100644
--- a/contrib/ipfilter/ipsend/ipsend.h
+++ b/contrib/ipfilter/ipsend/ipsend.h
@@ -27,6 +27,7 @@
#endif
#include "tcpip.h"
#include "ipt.h"
+#include "ipf.h"
extern int resolve __P((char *, char *));
extern int arp __P((char *, char *));
@@ -39,7 +40,8 @@ extern int send_icmp __P((int, int, ip_t *, struct in_addr));
extern int send_packet __P((int, int, ip_t *, struct in_addr));
extern int send_packets __P((char *, int, ip_t *, struct in_addr));
extern u_short seclevel __P((char *));
-extern u_long optname __P((char *, char *));
+extern u_32_t buildopts __P((char *, char *, int));
+extern int addipopt __P((char *, struct ipopt_names *, int, char *));
extern int initdevice __P((char *, int, int));
extern int sendip __P((int, char *, int));
#ifdef linux
@@ -57,8 +59,9 @@ extern void ip_test5 __P((char *, int, ip_t *, struct in_addr, int));
extern void ip_test6 __P((char *, int, ip_t *, struct in_addr, int));
extern void ip_test7 __P((char *, int, ip_t *, struct in_addr, int));
extern int do_socket __P((char *, int, struct tcpiphdr *, struct in_addr));
-
extern int openkmem __P((void));
extern int kmemcpy __P((char *, void *, int));
#define KMCPY(a,b,c) kmemcpy((char *)(a), (void *)(b), (int)(c))
+
+#define OPT_RAW 0x80000
diff --git a/contrib/ipfilter/ipsend/ipsopt.c b/contrib/ipfilter/ipsend/ipsopt.c
index 8313559bc45e..3c9a21dec134 100644
--- a/contrib/ipfilter/ipsend/ipsopt.c
+++ b/contrib/ipfilter/ipsend/ipsopt.c
@@ -1,22 +1,29 @@
/*
- * (C)opyright 1995 by Darren Reed.
+ * Copyright (C) 1995-1997 by Darren Reed.
*
- * This code may be freely distributed as long as it retains this notice
- * and is not changed in any way. The author accepts no responsibility
- * for the use of this software. I hate legaleese, don't you ?
+ * Redistribution and use in source and binary forms are permitted
+ * provided that this notice is preserved and due credit is given
+ * to the original author and the contributors.
*/
-#if !defined(lint) && defined(LIBC_SCCS)
-static char sccsid[] = "@(#)ipsopt.c 1.2 1/11/96 (C)1995 Darren Reed";
+#if !defined(lint)
+static const char sccsid[] = "@(#)ipsopt.c 1.2 1/11/96 (C)1995 Darren Reed";
+static const char rcsid[] = "@(#)$Id: ipsopt.c,v 2.0.2.10 1997/09/28 07:13:28 darrenr Exp $";
#endif
#include <stdio.h>
#include <string.h>
+#include <stdlib.h>
#include <sys/types.h>
#include <sys/time.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <netinet/in_systm.h>
#include <netinet/ip.h>
-#include "ip_compat.h"
+#ifndef linux
+#include <netinet/ip_var.h>
+#endif
+#include <netinet/tcp.h>
+#include <arpa/inet.h>
+#include "ipsend.h"
#ifndef __P
@@ -28,17 +35,10 @@ static char sccsid[] = "@(#)ipsopt.c 1.2 1/11/96 (C)1995 Darren Reed";
#endif
-struct ipopt_names {
- int on_value;
- int on_bit;
- int on_siz;
- char *on_name;
-};
-
struct ipopt_names ionames[] = {
{ IPOPT_EOL, 0x01, 1, "eol" },
{ IPOPT_NOP, 0x02, 1, "nop" },
- { IPOPT_RR, 0x04, 7, "rr" }, /* 1 route */
+ { IPOPT_RR, 0x04, 3, "rr" }, /* 1 route */
{ IPOPT_TS, 0x08, 8, "ts" }, /* 1 TS */
{ IPOPT_SECURITY, 0x08, 11, "sec-level" },
{ IPOPT_LSRR, 0x10, 7, "lsrr" }, /* 1 route */
@@ -59,10 +59,6 @@ struct ipopt_names secnames[] = {
};
-u_short seclevel __P((char *));
-u_long optname __P((char *, char *));
-
-
u_short seclevel(slevel)
char *slevel;
{
@@ -80,14 +76,82 @@ char *slevel;
}
-u_long optname(cp, op)
+int addipopt(op, io, len, class)
+char *op;
+struct ipopt_names *io;
+int len;
+char *class;
+{
+ struct in_addr ipadr;
+ int olen = len, srr = 0;
+ u_short val;
+ u_char lvl;
+ char *s = op, *t;
+
+ if ((len + io->on_siz) > 48) {
+ fprintf(stderr, "options too long\n");
+ return 0;
+ }
+ len += io->on_siz;
+ *op++ = io->on_value;
+ if (io->on_siz > 1) {
+ /*
+ * Allow option to specify RR buffer length in bytes.
+ */
+ if (io->on_value == IPOPT_RR) {
+ val = (class && *class) ? atoi(class) : 4;
+ *op++ = val + io->on_siz;
+ len += val;
+ } else
+ *op++ = io->on_siz;
+ *op++ = IPOPT_MINOFF;
+
+ while (class && *class) {
+ t = NULL;
+ switch (io->on_value)
+ {
+ case IPOPT_SECURITY :
+ lvl = seclevel(class);
+ *(op - 1) = lvl;
+ break;
+ case IPOPT_LSRR :
+ case IPOPT_SSRR :
+ if ((t = strchr(class, ',')))
+ *t = '\0';
+ ipadr.s_addr = inet_addr(class);
+ srr++;
+ bcopy((char *)&ipadr, op, sizeof(ipadr));
+ op += sizeof(ipadr);
+ break;
+ case IPOPT_SATID :
+ val = atoi(class);
+ bcopy((char *)&val, op, 2);
+ break;
+ }
+
+ if (t)
+ *t++ = ',';
+ class = t;
+ }
+ if (srr)
+ s[IPOPT_OLEN] = IPOPT_MINOFF - 1 + 4 * srr;
+ if (io->on_value == IPOPT_RR)
+ op += val;
+ else
+ op += io->on_siz - 3;
+ }
+ return len - olen;
+}
+
+
+u_32_t buildopts(cp, op, len)
char *cp, *op;
+int len;
{
struct ipopt_names *io;
- u_short lvl;
- u_long msk = 0;
+ u_32_t msk = 0;
char *s, *t;
- int len = 0;
+ int inc, lastop = -1;
for (s = strtok(cp, ","); s; s = strtok(NULL, ",")) {
if ((t = strchr(s, '=')))
@@ -95,21 +159,10 @@ char *cp, *op;
for (io = ionames; io->on_name; io++) {
if (strcasecmp(s, io->on_name) || (msk & io->on_bit))
continue;
- if ((len + io->on_siz) > 48) {
- fprintf(stderr, "options too long\n");
- return 0;
- }
- len += io->on_siz;
- *op++ = io->on_value;
- if (io->on_siz > 1) {
- *op++ = io->on_siz;
- *op++ = IPOPT_MINOFF;
-
- if (t && !strcasecmp(s, "sec-level")) {
- lvl = seclevel(t);
- bcopy(&lvl, op, sizeof(lvl));
- }
- op += io->on_siz - 3;
+ lastop = io->on_value;
+ if ((inc = addipopt(op, io, len, t))) {
+ op += inc;
+ len += inc;
}
msk |= io->on_bit;
break;
@@ -119,7 +172,24 @@ char *cp, *op;
return 0;
}
}
- *op++ = IPOPT_EOL;
- len++;
+
+ if (len & 3) {
+ while (len & 3) {
+ *op++ = ((len & 3) == 3) ? IPOPT_EOL : IPOPT_NOP;
+ len++;
+ }
+ } else {
+ if (lastop != IPOPT_EOL) {
+ if (lastop == IPOPT_NOP)
+ *(op - 1) = IPOPT_EOL;
+ else {
+ *op++ = IPOPT_NOP;
+ *op++ = IPOPT_NOP;
+ *op++ = IPOPT_NOP;
+ *op = IPOPT_EOL;
+ len += 4;
+ }
+ }
+ }
return len;
}
diff --git a/contrib/ipfilter/ipsend/iptest.1 b/contrib/ipfilter/ipsend/iptest.1
new file mode 100644
index 000000000000..3c98a4caab42
--- /dev/null
+++ b/contrib/ipfilter/ipsend/iptest.1
@@ -0,0 +1,101 @@
+.TH IPTEST 1
+.SH NAME
+iptest \- automatically generate a packets to test IP functionality
+.SH SYNOPSIS
+.B iptest
+[
+.B \-1234567
+] [
+.B \-d
+<device>
+] [
+.B \-g
+<gateway>
+] [
+.B \-m
+<\fIMTU\fP>
+] [
+.B \-p
+<\fIpointtest\fP>
+] [
+.B \-s
+<\fIsource\fP>
+] <destination>
+.SH DESCRIPTION
+.PP
+\fBiptest\fP ...
+.SH OPTIONS
+.TP
+.B \-1
+Run IP test group #1. This group of tests generates packets with the IP
+header fields set to invalid values given other packet characteristics.
+The point tests are: 1 (ip_hl < ip_len), 2 (ip_hl > ip_len),
+3 (ip_v < 4), 4 (ip_v > 4), 5 (ip_len < packetsize, long packets),
+6 (ip_len > packet size, short packets), 7 (Zero length fragments),
+8 (packet > 64k after reassembly), 9 (IP offset with MSB set), 10 (ttl
+variations).
+.TP
+.B \-2
+Run IP test group #2. This group of tests generates packets with the IP
+options constructed with invalud values given other packet characteristics.
+The point tests are: 1 (option length > packet length), 2 (option length = 0).
+.TP
+.B \-3
+Run IP test group #3. This group of tests generates packets with the ICMP
+header fields set to non-standard values. The point tests are: 1 (ICMP types
+0-31 & 255), 2 (type 3 & code 0 - 31), 3 (type 4 & code 0, 127, 128, 255),
+4 (type 5 & code 0, 127, 128, 255), 5 (types 8-10,13-18 with codes 0, 127,
+128 and 255), 6 (type 12 & code 0, 127, 128, 129, 255) and 7 (type 3 & codes
+9-10, 13-14 and 17-18 - shortened packets).
+.TP
+.B \-4
+Run IP test group #4. This group of tests generates packets with the UDP
+header fields set to non-standard values. The point tests are: 1 (UDP length
+> packet size), 2 (UDP length < packetsize), 3 (sport = 0, 1, 32767, 32768,
+65535), 4 (dport = 0, 1, 32767, 32768, 65535) and 5 (sizeof(struct ip) <= MTU
+<= sizeof(struct udphdr) + sizeof(struct ip)).
+.TP
+.B \-5
+Run IP test group #5. This group of tests generates packets with the TCP
+header fields set to non-standard values. The point tests are: 1 (TCP flags
+variations, all combinations), 2 (seq = 0, 0x7fffffff, 0x8000000, 0xa0000000,
+0xffffffff), 3 (ack = 0, 0x7fffffff, 0x8000000, 0xa0000000, 0xffffffff),
+4 (SYN packet with window of 0, 32768, 65535), 5 (set urgent pointer to 1,
+0x7fff, 0x8000, 0xffff), 6 (data offset), 7 (sport = 0, 1, 32767, 32768,
+65535) and 8 (dport = 0, 1, 32767, 32768, 65535).
+.TP
+.B \-6
+Run IP test group #6. This test generates a large number of fragments in
+an attempt to exhaust the network buffers used for holding packets for later
+reassembly. WARNING: this may crash or cause serious performance degradation
+to the target host.
+.TP
+.B \-7
+Run IP test group #7. This test generates 1024 random IP packets with only
+the IP version, checksum, length and IP offset field correct.
+.TP
+.BR \-d \0<interface>
+Set the interface name to be the name supplied.
+.TP
+.BR \-g \0<gateway>
+Specify the hostname of the gateway through which to route packets. This
+is required whenever the destination host isn't directly attached to the
+same network as the host from which you're sending.
+.TP
+.BR \-m \0<MTU>
+Specify the MTU to be used when sending out packets. This option allows you
+to set a fake MTU, allowing the simulation of network interfaces with small
+MTU's without setting them so.
+.TP
+.B \-p <test>
+Run a...
+.DT
+.SH SEE ALSO
+ipsend(1), ipresend(1), bpf(4), dlpi(7p)
+.SH DIAGNOSTICS
+Only one of the numeric test options may be given when \fIiptest\fP is run.
+.PP
+Needs to be run as root.
+.SH BUGS
+.PP
+If you find any, please send email to me at darrenr@cyber.com.au
diff --git a/contrib/ipfilter/ipsend/iptest.c b/contrib/ipfilter/ipsend/iptest.c
index 93d7f4ab74f6..6b3cf2374dd1 100644
--- a/contrib/ipfilter/ipsend/iptest.c
+++ b/contrib/ipfilter/ipsend/iptest.c
@@ -1,21 +1,18 @@
/*
- * ipsend.c (C) 1995 Darren Reed
+ * ipsend.c (C) 1995-1997 Darren Reed
*
* This was written to test what size TCP fragments would get through
* various TCP/IP packet filters, as used in IP firewalls. In certain
* conditions, enough of the TCP header is missing for unpredictable
* results unless the filter is aware that this can happen.
*
- * The author provides this program as-is, with no gaurantee for its
- * suitability for any specific purpose. The author takes no responsibility
- * for the misuse/abuse of this program and provides it for the sole purpose
- * of testing packet filter policies. This file maybe distributed freely
- * providing it is not modified and that this notice remains in tact.
- *
- * This was written and tested (successfully) on SunOS 4.1.x.
+ * Redistribution and use in source and binary forms are permitted
+ * provided that this notice is preserved and due credit is given
+ * to the original author and the contributors.
*/
-#if !defined(lint) && defined(LIBC_SCCS)
-static char sccsid[] = "%W% %G% (C)1995 Darren Reed";
+#if !defined(lint)
+static const char sccsid[] = "%W% %G% (C)1995 Darren Reed";
+static const char rcsid[] = "@(#)$Id: iptest.c,v 2.0.2.8 1997/10/12 09:48:39 darrenr Exp $";
#endif
#include <stdio.h>
#include <netdb.h>
@@ -57,7 +54,11 @@ char default_device[] = "ln0";
# ifdef __bsdi__
char default_device[] = "ef0";
# else
+# ifdef __sgi
+char default_device[] = "ec0";
+# else
char default_device[] = "lan0";
+# endif
# endif
# endif
# endif
@@ -97,8 +98,8 @@ char **argv;
struct in_addr gwip;
ip_t *ip;
char *name = argv[0], host[64], *gateway = NULL, *dev = NULL;
- char *src = NULL, *dst, c;
- int mtu = 1500, tests = 0, pointtest = 0;
+ char *src = NULL, *dst;
+ int mtu = 1500, tests = 0, pointtest = 0, c;
/*
* 65535 is maximum packet size...you never know...
@@ -108,8 +109,7 @@ char **argv;
ip->ip_len = sizeof(*ip);
ip->ip_hl = sizeof(*ip) >> 2;
- while ((c = (char)getopt(argc, argv,
- "1234567IP:TUd:f:g:m:o:p:s:t:")) != -1)
+ while ((c = getopt(argc, argv, "1234567d:g:m:p:s:")) != -1)
switch (c)
{
case '1' :
diff --git a/contrib/ipfilter/ipsend/iptests.c b/contrib/ipfilter/ipsend/iptests.c
index 6b5ecb9a2cd0..f9382721ae44 100644
--- a/contrib/ipfilter/ipsend/iptests.c
+++ b/contrib/ipfilter/ipsend/iptests.c
@@ -1,12 +1,13 @@
/*
- * (C)opyright 1993, 1994, 1995 by Darren Reed.
+ * Copyright (C) 1993-1997 by Darren Reed.
*
- * This code may be freely distributed as long as it retains this notice
- * and is not changed in any way. The author accepts no responsibility
- * for the use of this software. I hate legaleese, don't you ?
+ * Redistribution and use in source and binary forms are permitted
+ * provided that this notice is preserved and due credit is given
+ * to the original author and the contributors.
*/
-#if !defined(lint) && defined(LIBC_SCCS)
-static char sccsid[] = "%W% %G% (C)1995 Darren Reed";
+#if !defined(lint)
+static const char sccsid[] = "%W% %G% (C)1995 Darren Reed";
+static const char rcsid[] = "@(#)$Id: iptests.c,v 2.0.2.13 1997/10/23 11:42:45 darrenr Exp $";
#endif
#include <stdio.h>
#include <unistd.h>
@@ -15,7 +16,7 @@ static char sccsid[] = "%W% %G% (C)1995 Darren Reed";
#include <sys/types.h>
#include <sys/time.h>
#include <sys/param.h>
-#if !defined(solaris)
+#if !defined(solaris) && !defined(linux) && !defined(__sgi)
# define _KERNEL
# define KERNEL
# include <sys/file.h>
@@ -25,8 +26,12 @@ static char sccsid[] = "%W% %G% (C)1995 Darren Reed";
# include <sys/user.h>
# include <sys/proc.h>
#endif
-#include <kvm.h>
-#include <sys/socket.h>
+#if !defined(ultrix) && !defined(hpux) && !defined(linux) && !defined(__sgi)
+# include <kvm.h>
+#endif
+#ifndef ultrix
+# include <sys/socket.h>
+#endif
#if defined(solaris)
# include <sys/stream.h>
#endif
@@ -36,28 +41,37 @@ static char sccsid[] = "%W% %G% (C)1995 Darren Reed";
#include <sys/session.h>
#endif
#if BSD >= 199103
-#include <sys/sysctl.h>
-#include <sys/filedesc.h>
-#include <paths.h>
+# include <sys/sysctl.h>
+# include <sys/filedesc.h>
+# include <paths.h>
#endif
#include <netinet/in_systm.h>
#include <sys/socket.h>
#include <net/if.h>
-#include <net/route.h>
+#if defined(linux) && (LINUX >= 0200)
+# include <asm/atomic.h>
+#endif
+#if !defined(linux)
+# include <net/route.h>
+#else
+# define __KERNEL__ /* because there's a macro not wrapped by this */
+# include <net/route.h> /* in this file :-/ */
+#endif
#include <netinet/in.h>
#include <arpa/inet.h>
#include <netinet/ip.h>
#include <netinet/tcp.h>
#include <netinet/udp.h>
#include <netinet/ip_icmp.h>
-#include <netinet/if_ether.h>
-#include <netinet/ip_var.h>
-#include <netinet/in_pcb.h>
-#include <netinet/tcp_timer.h>
-#include <netinet/tcp_var.h>
-# if defined(__SVR4) || defined(__svr4__)
-#include <sys/sysmacros.h>
-# endif
+#ifndef linux
+# include <netinet/ip_var.h>
+# include <netinet/in_pcb.h>
+# include <netinet/tcp_timer.h>
+# include <netinet/tcp_var.h>
+#endif
+#if defined(__SVR4) || defined(__svr4__) || defined(__sgi)
+# include <sys/sysmacros.h>
+#endif
#include "ipsend.h"
@@ -74,7 +88,7 @@ int ptest;
{
struct timeval tv;
udphdr_t *u;
- int nfd, i, len, id = getpid();
+ int nfd, i = 0, len, id = getpid();
ip->ip_hl = sizeof(*ip) >> 2;
ip->ip_v = IPVERSION;
@@ -705,7 +719,7 @@ struct in_addr gwip;
int ptest;
{
struct timeval tv;
- struct udphdr *u;
+ udphdr_t *u;
int nfd, i;
@@ -836,10 +850,10 @@ int ptest;
PAUSE();
}
- if (!ptest || (ptest == 4)) {
+ if (!ptest || (ptest == 5)) {
/*
- * Test 5: sizeof(struct ip) <= MTU <= sizeof(struct udphdr) +
- * sizeof(struct ip)
+ * Test 5: sizeof(ip_t) <= MTU <= sizeof(udphdr_t) +
+ * sizeof(ip_t)
*/
printf("4.5 UDP 20 <= MTU <= 32\n");
for (i = sizeof(*ip); i <= u->uh_ulen; i++) {
@@ -867,7 +881,9 @@ int ptest;
int nfd, i;
t = (tcphdr_t *)((char *)ip + (ip->ip_hl << 2));
+#ifndef linux
t->th_x2 = 0;
+#endif
t->th_off = 0;
t->th_sport = 1;
t->th_dport = 1;
@@ -1005,7 +1021,7 @@ int ptest;
PAUSE();
}
-#if !defined(linux) && !defined(__SVR4) && !defined(__svr4__)
+#if !defined(linux) && !defined(__SVR4) && !defined(__svr4__) && !defined(__sgi)
{
struct tcpcb *t, tcb;
struct tcpiphdr ti;
diff --git a/contrib/ipfilter/ipsend/larp.c b/contrib/ipfilter/ipsend/larp.c
index 1eb4b2fe3e7a..7d38ddf63ab8 100644
--- a/contrib/ipfilter/ipsend/larp.c
+++ b/contrib/ipfilter/ipsend/larp.c
@@ -1,14 +1,13 @@
/*
- * larp.c (C) 1995 Darren Reed
+ * larp.c (C) 1995-1997 Darren Reed
*
- * The author provides this program as-is, with no gaurantee for its
- * suitability for any specific purpose. The author takes no responsibility
- * for the misuse/abuse of this program and provides it for the sole purpose
- * of testing packet filter policies. This file maybe distributed freely
- * providing it is not modified and that this notice remains in tact.
+ * Redistribution and use in source and binary forms are permitted
+ * provided that this notice is preserved and due credit is given
+ * to the original author and the contributors.
*/
-#if !defined(lint) && defined(LIBC_SCCS)
-static char sccsid[] = "@(#)larp.c 1.1 8/19/95 (C)1995 Darren Reed";
+#if !defined(lint)
+static const char sccsid[] = "@(#)larp.c 1.1 8/19/95 (C)1995 Darren Reed";
+static const char rcsid[] = "@(#)$Id: larp.c,v 2.0.2.3 1997/09/28 07:13:31 darrenr Exp $";
#endif
#include <stdio.h>
#include <errno.h>
diff --git a/contrib/ipfilter/ipsend/linux.h b/contrib/ipfilter/ipsend/linux.h
index 7eb382b4b7e1..c7bb5a58d7c6 100644
--- a/contrib/ipfilter/ipsend/linux.h
+++ b/contrib/ipfilter/ipsend/linux.h
@@ -1,5 +1,5 @@
/*
- * (C)opyright 1995 by Darren Reed.
+ * Copyright (C) 1995-1997 by Darren Reed.
*
* This code may be freely distributed as long as it retains this notice
* and is not changed in any way. The author accepts no responsibility
diff --git a/contrib/ipfilter/ipsend/lsock.c b/contrib/ipfilter/ipsend/lsock.c
index 5cc3122b75bc..db81dfd68041 100644
--- a/contrib/ipfilter/ipsend/lsock.c
+++ b/contrib/ipfilter/ipsend/lsock.c
@@ -1,14 +1,13 @@
/*
- * lsock.c (C) 1995 Darren Reed
+ * lsock.c (C) 1995-1997 Darren Reed
*
- * The author provides this program as-is, with no gaurantee for its
- * suitability for any specific purpose. The author takes no responsibility
- * for the misuse/abuse of this program and provides it for the sole purpose
- * of testing packet filter policies. This file maybe distributed freely
- * providing it is not modified and that this notice remains in tact.
+ * Redistribution and use in source and binary forms are permitted
+ * provided that this notice is preserved and due credit is given
+ * to the original author and the contributors.
*/
-#if !defined(lint) && defined(LIBC_SCCS)
-static char sccsid[] = "@(#)lsock.c 1.2 1/11/96 (C)1995 Darren Reed";
+#if !defined(lint)
+static const char sccsid[] = "@(#)lsock.c 1.2 1/11/96 (C)1995 Darren Reed";
+static const char rcsid[] = "@(#)$Id: lsock.c,v 2.0.2.7 1997/09/28 07:13:32 darrenr Exp $";
#endif
#include <stdio.h>
#include <unistd.h>
@@ -45,7 +44,7 @@ static char sccsid[] = "@(#)lsock.c 1.2 1/11/96 (C)1995 Darren Reed";
#include <netinet/in.h>
#include <netinet/in_systm.h>
#include <net/if.h>
-#if LINUX < 0103
+#if LINUX < 0200
#include <net/inet/sock.h>
#endif
#include "ipsend.h"
@@ -188,12 +187,11 @@ struct tcpiphdr *ti;
return i->u.socket_i.data;
}
-int do_socket(dev, mtu, ti, gwip, flags)
+int do_socket(dev, mtu, ti, gwip)
char *dev;
int mtu;
struct tcpiphdr *ti;
struct in_addr gwip;
-int flags;
{
struct sockaddr_in rsin, lsin;
struct sock *s, sk;
@@ -227,7 +225,7 @@ int flags;
(void) getsockname(fd, (struct sockaddr *)&lsin, &len);
ti->ti_sport = lsin.sin_port;
printf("sport %d\n", ntohs(lsin.sin_port));
- nfd = initdevice(dev, ntohs(lsin.sin_port));
+ nfd = initdevice(dev, ntohs(lsin.sin_port), 0);
if (!(s = find_tcp(fd, ti)))
return -1;
@@ -247,8 +245,9 @@ int flags;
ti->ti_win = sk.window;
ti->ti_seq = sk.sent_seq - 1;
ti->ti_ack = sk.rcv_ack_seq;
+ ti->ti_flags = TH_SYN;
- if (send_tcp(nfd, mtu, ti, gwip, TH_SYN) == -1)
+ if (send_tcp(nfd, mtu, (ip_t *)ti, gwip) == -1)
return -1;
(void)write(fd, "Hello World\n", 12);
sleep(2);
diff --git a/contrib/ipfilter/ipsend/resend.c b/contrib/ipfilter/ipsend/resend.c
index 84d3215ac18e..dcf7cc77c9d6 100644
--- a/contrib/ipfilter/ipsend/resend.c
+++ b/contrib/ipfilter/ipsend/resend.c
@@ -1,14 +1,18 @@
/*
- * resend.c (C) 1995 Darren Reed
+ * resend.c (C) 1995-1997 Darren Reed
*
* This was written to test what size TCP fragments would get through
* various TCP/IP packet filters, as used in IP firewalls. In certain
* conditions, enough of the TCP header is missing for unpredictable
* results unless the filter is aware that this can happen.
*
+ * Redistribution and use in source and binary forms are permitted
+ * provided that this notice is preserved and due credit is given
+ * to the original author and the contributors.
*/
-#if !defined(lint) && defined(LIBC_SCCS)
-static char sccsid[] = "@(#)resend.c 1.3 1/11/96 (C)1995 Darren Reed";
+#if !defined(lint)
+static const char sccsid[] = "@(#)resend.c 1.3 1/11/96 (C)1995 Darren Reed";
+static const char rcsid[] = "@(#)$Id: resend.c,v 2.0.2.12 1997/10/23 11:42:46 darrenr Exp $";
#endif
#include <stdio.h>
#include <netdb.h>
@@ -27,17 +31,21 @@ static char sccsid[] = "@(#)resend.c 1.3 1/11/96 (C)1995 Darren Reed";
#include <netinet/udp.h>
#include <netinet/ip_icmp.h>
#ifndef linux
-#include <netinet/ip_var.h>
-#include <netinet/if_ether.h>
+# include <netinet/ip_var.h>
+# include <netinet/if_ether.h>
+# if __FreeBSD_version >= 300000
+# include <net/if_var.h>
+# endif
#endif
#include "ipsend.h"
+extern int opts;
static u_char buf[65536]; /* 1 big packet */
-static void printpacket __P((ip_t *));
+void printpacket __P((ip_t *));
-static void printpacket(ip)
+void printpacket(ip)
ip_t *ip;
{
tcphdr_t *t;
@@ -90,7 +98,7 @@ char *datain;
ip = (struct ip *)buf;
eh = (ether_header_t *)malloc(sizeof(*eh));
- bzero(&eh->ether_shost, sizeof(eh->ether_shost));
+ bzero((char *)A_A eh->ether_shost, sizeof(eh->ether_shost));
if (gwip.s_addr && (arp((char *)&gwip, dhost) == -1))
{
perror("arp");
@@ -99,21 +107,31 @@ char *datain;
while ((i = (*r->r_readip)(buf, sizeof(buf), NULL, NULL)) > 0)
{
- len = ntohs(ip->ip_len);
- eh = (ether_header_t *)realloc((char *)eh, sizeof(*eh) + len);
- eh->ether_type = htons((u_short)ETHERTYPE_IP);
- if (!gwip.s_addr) {
- if (arp((char *)&gwip,
- (char *)&eh->ether_dhost) == -1) {
- perror("arp");
- continue;
- }
- } else
- bcopy(dhost, (char *)&eh->ether_dhost, sizeof(dhost));
- bcopy(ip, (char *)(eh + 1), len);
- printpacket(ip);
+ if (!(opts & OPT_RAW)) {
+ len = ntohs(ip->ip_len);
+ eh = (ether_header_t *)realloc((char *)eh, sizeof(*eh) + len);
+ eh->ether_type = htons((u_short)ETHERTYPE_IP);
+ if (!gwip.s_addr) {
+ if (arp((char *)&gwip,
+ (char *)A_A eh->ether_dhost) == -1) {
+ perror("arp");
+ continue;
+ }
+ } else
+ bcopy(dhost, (char *)A_A eh->ether_dhost,
+ sizeof(dhost));
+ if (!ip->ip_sum)
+ ip->ip_sum = chksum((u_short *)ip,
+ ip->ip_hl << 2);
+ bcopy(ip, (char *)(eh + 1), len);
+ len += sizeof(*eh);
+ printpacket(ip);
+ } else {
+ eh = (ether_header_t *)buf;
+ len = i;
+ }
- if (sendip(wfd, (char *)eh, sizeof(*eh) + len) == -1)
+ if (sendip(wfd, (char *)eh, len) == -1)
{
perror("send_packet");
break;
diff --git a/contrib/ipfilter/ipsend/sbpf.c b/contrib/ipfilter/ipsend/sbpf.c
index dd781ab4145c..d3df96fcf4fc 100644
--- a/contrib/ipfilter/ipsend/sbpf.c
+++ b/contrib/ipfilter/ipsend/sbpf.c
@@ -1,9 +1,9 @@
/*
- * (C)opyright October 1995 Darren Reed. (from tcplog)
- *
- * This software may be freely distributed as long as it is not altered
- * in any way and that this messagge always accompanies it.
+ * (C)opyright 1995-1997 Darren Reed. (from tcplog)
*
+ * Redistribution and use in source and binary forms are permitted
+ * provided that this notice is preserved and due credit is given
+ * to the original author and the contributors.
*/
#include <stdio.h>
#include <netdb.h>
@@ -31,15 +31,15 @@
#include <netinet/in.h>
#include <netinet/in_systm.h>
#include <netinet/ip.h>
-#include <netinet/if_ether.h>
#include <netinet/ip_var.h>
#include <netinet/udp.h>
#include <netinet/udp_var.h>
#include <netinet/tcp.h>
#include "ipsend.h"
-#if !defined(lint) && defined(LIBC_SCCS)
-static char sbpf[] = "@(#)sbpf.c 1.3 8/25/95 (C)1995 Darren Reed";
+#if !defined(lint)
+static const char sccsid[] = "@(#)sbpf.c 1.3 8/25/95 (C)1995 Darren Reed";
+static const char rcsid[] = "@(#)$Id: sbpf.c,v 2.0.2.7 1997/10/23 11:42:47 darrenr Exp $";
#endif
/*
diff --git a/contrib/ipfilter/ipsend/sdlpi.c b/contrib/ipfilter/ipsend/sdlpi.c
index 94d71ae9e864..1f181c2824d6 100644
--- a/contrib/ipfilter/ipsend/sdlpi.c
+++ b/contrib/ipfilter/ipsend/sdlpi.c
@@ -1,12 +1,9 @@
/*
- * (C)opyright October 1992 Darren Reed. (from tcplog)
- *
- * This software may be freely distributed as long as it is not altered
- * in any way and that this messagge always accompanies it.
- *
- * The author of this software makes no garuntee about the
- * performance of this package or its suitability to fulfill any purpose.
+ * (C)opyright 1992-1997 Darren Reed. (from tcplog)
*
+ * Redistribution and use in source and binary forms are permitted
+ * provided that this notice is preserved and due credit is given
+ * to the original author and the contributors.
*/
#include <stdio.h>
@@ -23,8 +20,10 @@
#include <sys/ioctl.h>
#include <sys/stropts.h>
+#ifdef sun
#include <sys/pfmod.h>
#include <sys/bufmod.h>
+#endif
#include <sys/dlpi.h>
#include <net/if.h>
@@ -39,8 +38,9 @@
#include "ipsend.h"
-#if !defined(lint) && defined(LIBC_SCCS)
-static char snitid[] = "@(#)sdlpi.c 1.3 10/30/95 (C)1995 Darren Reed";
+#if !defined(lint)
+static const char sccsid[] = "@(#)sdlpi.c 1.3 10/30/95 (C)1995 Darren Reed";
+static const char rcsid[] = "@(#)$Id: sdlpi.c,v 2.0.2.6 1997/10/15 14:49:14 darrenr Exp $";
#endif
#define CHUNKSIZE 8192
@@ -90,11 +90,15 @@ int sport, tout;
/*
* write full headers
*/
+#ifdef sun /* we require RAW DLPI mode, which is a Sun extension */
if (strioctl(fd, DLIOCRAW, -1, 0, NULL) == -1)
{
fprintf(stderr, "DLIOCRAW error\n");
exit(-1);
}
+#else
+you lose
+#endif
return fd;
}
diff --git a/contrib/ipfilter/ipsend/sirix.c b/contrib/ipfilter/ipsend/sirix.c
new file mode 100644
index 000000000000..a1933e0382f9
--- /dev/null
+++ b/contrib/ipfilter/ipsend/sirix.c
@@ -0,0 +1,94 @@
+/*
+ * (C)opyright 1992-1997 Darren Reed.
+ * (C)opyright 1997 Marc Boucher.
+ *
+ * Redistribution and use in source and binary forms are permitted
+ * provided that this notice is preserved and due credit is given
+ * to the original author and the contributors.
+ */
+#include <stdio.h>
+#include <sys/types.h>
+#include <string.h>
+#include <unistd.h>
+#include <stdlib.h>
+#include <errno.h>
+#include <sys/socket.h>
+#include <sys/ioctl.h>
+
+#include <net/if.h>
+#include <net/raw.h>
+#include <netinet/in.h>
+#include <netinet/in_systm.h>
+#include <netinet/ip.h>
+#include <netinet/if_ether.h>
+#include <netinet/ip_var.h>
+#include <netinet/udp.h>
+#include <netinet/udp_var.h>
+#include <netinet/tcp.h>
+#include "ipsend.h"
+
+#if !defined(lint) && defined(LIBC_SCCS)
+static char sirix[] = "@(#)sirix.c 1.0 10/9/97 (C)1997 Marc Boucher";
+#endif
+
+
+int initdevice(char *device, int sport, int tout)
+{
+ int fd;
+ struct sockaddr_raw sr;
+
+ if ((fd = socket(PF_RAW, SOCK_RAW, RAWPROTO_DRAIN)) < 0)
+ {
+ perror("socket(PF_RAW, SOCK_RAW, RAWPROTO_DRAIN)");
+ return -1;
+ }
+
+ memset(&sr, 0, sizeof(sr));
+ sr.sr_family = AF_RAW;
+ sr.sr_port = ETHERTYPE_IP;
+ strncpy(sr.sr_ifname, device, sizeof(sr.sr_ifname));
+ if (bind(fd, &sr, sizeof(sr)) < 0)
+ {
+ perror("bind AF_RAW");
+ close(fd);
+ return -1;
+ }
+ return fd;
+}
+
+
+/*
+ * output an IP packet
+ */
+int sendip(int fd, char *pkt, int len)
+{
+ struct sockaddr_raw sr;
+ int srlen = sizeof(sr);
+ struct ifreq ifr;
+ struct ether_header *eh = (struct ether_header *)pkt;
+
+ if (getsockname(fd, &sr, &srlen) == -1)
+ {
+ perror("getsockname");
+ return -1;
+ }
+
+ memset(&ifr, 0, sizeof(ifr));
+ strncpy(ifr.ifr_name, sr.sr_ifname, sizeof ifr.ifr_name);
+
+ if (ioctl(fd, SIOCGIFADDR, &ifr) == -1)
+ {
+ perror("ioctl SIOCGIFADDR");
+ return -1;
+ }
+
+ memcpy(eh->ether_shost, ifr.ifr_addr.sa_data, sizeof(eh->ether_shost));
+
+ if (write(fd, pkt, len) == -1)
+ {
+ perror("send");
+ return -1;
+ }
+
+ return len;
+}
diff --git a/contrib/ipfilter/ipsend/slinux.c b/contrib/ipfilter/ipsend/slinux.c
index 7e4c7bf7d069..29dbcd9f3343 100644
--- a/contrib/ipfilter/ipsend/slinux.c
+++ b/contrib/ipfilter/ipsend/slinux.c
@@ -1,12 +1,9 @@
/*
- * (C)opyright October 1992 Darren Reed. (from tcplog)
- *
- * This software may be freely distributed as long as it is not altered
- * in any way and that this messagge always accompanies it.
- *
- * The author of this software makes no garuntee about the
- * performance of this package or its suitability to fulfill any purpose.
+ * (C)opyright 1992-1997 Darren Reed. (from tcplog)
*
+ * Redistribution and use in source and binary forms are permitted
+ * provided that this notice is preserved and due credit is given
+ * to the original author and the contributors.
*/
#include <stdio.h>
@@ -30,8 +27,9 @@
#include <netinet/tcp.h>
#include "ipsend.h"
-#if !defined(lint) && defined(LIBC_SCCS)
-static char sccsid[] = "@(#)slinux.c 1.2 8/25/95";
+#if !defined(lint)
+static const char sccsid[] = "@(#)slinux.c 1.2 8/25/95";
+static const char rcsid[] = "@(#)$Id: slinux.c,v 2.0.2.6 1997/09/28 07:13:35 darrenr Exp $";
#endif
#define CHUNKSIZE 8192
@@ -46,9 +44,9 @@ static int timeout;
static char *eth_dev = NULL;
-int initdevice(dev, sport, tout)
+int initdevice(dev, sport, spare)
char *dev;
-int sport, tout;
+int sport, spare;
{
int fd;
diff --git a/contrib/ipfilter/ipsend/snit.c b/contrib/ipfilter/ipsend/snit.c
index e738fdb5ccd4..65b8e67941cf 100644
--- a/contrib/ipfilter/ipsend/snit.c
+++ b/contrib/ipfilter/ipsend/snit.c
@@ -1,12 +1,9 @@
/*
- * (C)opyright October 1992 Darren Reed. (from tcplog)
- *
- * This software may be freely distributed as long as it is not altered
- * in any way and that this messagge always accompanies it.
- *
- * The author of this software makes no garuntee about the
- * performance of this package or its suitability to fulfill any purpose.
+ * (C)opyright 1992-1997 Darren Reed. (from tcplog)
*
+ * Redistribution and use in source and binary forms are permitted
+ * provided that this notice is preserved and due credit is given
+ * to the original author and the contributors.
*/
#include <stdio.h>
@@ -41,8 +38,9 @@
#include "ipsend.h"
-#if !defined(lint) && defined(LIBC_SCCS)
-static char snitid[] = "@(#)snit.c 1.5 1/11/96 (C)1995 Darren Reed";
+#if !defined(lint)
+static const char sccsid[] = "@(#)snit.c 1.5 1/11/96 (C)1995 Darren Reed";
+static const char rcsid[] = "@(#)$Id: snit.c,v 2.0.2.4 1997/09/28 07:13:36 darrenr Exp $";
#endif
#define CHUNKSIZE 8192
diff --git a/contrib/ipfilter/ipsend/sock.c b/contrib/ipfilter/ipsend/sock.c
index b75342691440..92e4a24b8bfa 100644
--- a/contrib/ipfilter/ipsend/sock.c
+++ b/contrib/ipfilter/ipsend/sock.c
@@ -1,14 +1,13 @@
/*
- * sock.c (C) 1995 Darren Reed
+ * sock.c (C) 1995-1997 Darren Reed
*
- * The author provides this program as-is, with no gaurantee for its
- * suitability for any specific purpose. The author takes no responsibility
- * for the misuse/abuse of this program and provides it for the sole purpose
- * of testing packet filter policies. This file maybe distributed freely
- * providing it is not modified and that this notice remains in tact.
+ * Redistribution and use in source and binary forms are permitted
+ * provided that this notice is preserved and due credit is given
+ * to the original author and the contributors.
*/
-#if !defined(lint) && defined(LIBC_SCCS)
-static char sccsid[] = "@(#)sock.c 1.2 1/11/96 (C)1995 Darren Reed";
+#if !defined(lint)
+static const char sccsid[] = "@(#)sock.c 1.2 1/11/96 (C)1995 Darren Reed";
+static const char rcsid[] = "@(#)$Id: sock.c,v 2.0.2.9 1997/09/28 07:13:37 darrenr Exp $";
#endif
#include <stdio.h>
#include <unistd.h>
@@ -20,10 +19,16 @@ static char sccsid[] = "@(#)sock.c 1.2 1/11/96 (C)1995 Darren Reed";
#include <sys/time.h>
#include <sys/param.h>
#include <sys/stat.h>
+#ifndef ultrix
#include <fcntl.h>
+#endif
#include <sys/dir.h>
#define _KERNEL
#define KERNEL
+#ifdef ultrix
+# undef LOCORE
+# include <sys/smp_lock.h>
+#endif
#include <sys/file.h>
#undef _KERNEL
#undef KERNEL
@@ -32,7 +37,9 @@ static char sccsid[] = "@(#)sock.c 1.2 1/11/96 (C)1995 Darren Reed";
#include <sys/socket.h>
#include <sys/socketvar.h>
#include <sys/proc.h>
-#include <kvm.h>
+#if !defined(ultrix) && !defined(hpux)
+# include <kvm.h>
+#endif
#ifdef sun
#include <sys/systm.h>
#include <sys/session.h>
@@ -89,11 +96,12 @@ void *pos;
int n;
{
static int kfd = -1;
+ off_t offset = (u_long)pos;
if (kfd == -1)
kfd = open(KMEM, O_RDONLY);
- if (lseek(kfd, (off_t)pos, SEEK_SET) == -1)
+ if (lseek(kfd, offset, SEEK_SET) == -1)
{
perror("lseek");
return -1;
@@ -106,9 +114,14 @@ int n;
return n;
}
-struct nlist names[3] = {
+struct nlist names[4] = {
{ "_proc" },
{ "_nproc" },
+#ifdef ultrix
+ { "_u" },
+#else
+ { NULL },
+#endif
{ NULL }
};
@@ -170,26 +183,35 @@ struct tcpiphdr *ti;
if (!(p = getproc()))
return NULL;
-
+printf("fl %x ty %x cn %d mc %d\n",
+f->f_flag, f->f_type, f->f_count, f->f_msgcount);
up = (struct user *)malloc(sizeof(*up));
+#ifndef ultrix
if (KMCPY(up, p->p_uarea, sizeof(*up)) == -1)
{
fprintf(stderr, "read(%#x,%#x) failed\n", p, p->p_uarea);
return NULL;
}
+#else
+ if (KMCPY(up, names[2].n_value, sizeof(*up)) == -1)
+ {
+ fprintf(stderr, "read(%#x,%#x) failed\n", p, names[2].n_value);
+ return NULL;
+ }
+#endif
o = (struct file **)calloc(1, sizeof(*o) * (up->u_lastfile + 1));
if (KMCPY(o, up->u_ofile, (up->u_lastfile + 1) * sizeof(*o)) == -1)
{
fprintf(stderr, "read(%#x,%#x,%d) - u_ofile - failed\n",
- up->u_ofile_arr, o, sizeof(*o));
+ up->u_ofile, o, sizeof(*o));
return NULL;
}
f = (struct file *)calloc(1, sizeof(*f));
if (KMCPY(f, o[fd], sizeof(*f)) == -1)
{
fprintf(stderr, "read(%#x,%#x,%d) - o[fd] - failed\n",
- up->u_ofile_arr[fd], f, sizeof(*f));
+ up->u_ofile[fd], f, sizeof(*f));
return NULL;
}
@@ -223,7 +245,8 @@ static struct kinfo_proc *getproc()
{
static struct kinfo_proc kp;
pid_t pid = getpid();
- int n, mib[4];
+ int mib[4];
+ size_t n;
mib[0] = CTL_KERN;
mib[1] = KERN_PROC;
@@ -265,39 +288,39 @@ struct tcpiphdr *ti;
o = (struct file **)calloc(1, sizeof(*o) * (fd->fd_lastfile + 1));
if (KMCPY(o, fd->fd_ofiles, (fd->fd_lastfile + 1) * sizeof(*o)) == -1)
{
- fprintf(stderr, "read(%#lx,%#lx,%d) - u_ofile - failed\n",
- (u_long)fd->fd_ofiles, (u_long)o, sizeof(*o));
+ fprintf(stderr, "read(%#lx,%#lx,%lu) - u_ofile - failed\n",
+ (u_long)fd->fd_ofiles, (u_long)o, (u_long)sizeof(*o));
return NULL;
}
f = (struct file *)calloc(1, sizeof(*f));
if (KMCPY(f, o[tfd], sizeof(*f)) == -1)
{
- fprintf(stderr, "read(%#lx,%#lx,%d) - o[tfd] - failed\n",
- (u_long)o[tfd], (u_long)f, sizeof(*f));
+ fprintf(stderr, "read(%#lx,%#lx,%lu) - o[tfd] - failed\n",
+ (u_long)o[tfd], (u_long)f, (u_long)sizeof(*f));
return NULL;
}
s = (struct socket *)calloc(1, sizeof(*s));
if (KMCPY(s, f->f_data, sizeof(*s)) == -1)
{
- fprintf(stderr, "read(%#lx,%#lx,%d) - f_data - failed\n",
- (u_long)f->f_data, (u_long)s, sizeof(*s));
+ fprintf(stderr, "read(%#lx,%#lx,%lu) - f_data - failed\n",
+ (u_long)f->f_data, (u_long)s, (u_long)sizeof(*s));
return NULL;
}
i = (struct inpcb *)calloc(1, sizeof(*i));
if (KMCPY(i, s->so_pcb, sizeof(*i)) == -1)
{
- fprintf(stderr, "kvm_read(%#lx,%#lx,%d) - so_pcb - failed\n",
- (u_long)s->so_pcb, (u_long)i, sizeof(*i));
+ fprintf(stderr, "kvm_read(%#lx,%#lx,%lu) - so_pcb - failed\n",
+ (u_long)s->so_pcb, (u_long)i, (u_long)sizeof(*i));
return NULL;
}
t = (struct tcpcb *)calloc(1, sizeof(*t));
if (KMCPY(t, i->inp_ppcb, sizeof(*t)) == -1)
{
- fprintf(stderr, "read(%#lx,%#lx,%d) - inp_ppcb - failed\n",
- (u_long)i->inp_ppcb, (u_long)t, sizeof(*t));
+ fprintf(stderr, "read(%#lx,%#lx,%lu) - inp_ppcb - failed\n",
+ (u_long)i->inp_ppcb, (u_long)t, (u_long)sizeof(*t));
return NULL;
}
return (struct tcpcb *)i->inp_ppcb;
diff --git a/contrib/ipfilter/ipsend/tcpip.h b/contrib/ipfilter/ipsend/tcpip.h
index 78f274f00664..d92d9f8b0ea1 100644
--- a/contrib/ipfilter/ipsend/tcpip.h
+++ b/contrib/ipfilter/ipsend/tcpip.h
@@ -1,22 +1,75 @@
-/* @(#)tcpip.h 1.7 88/08/19 SMI; from UCB 7.1 6/5/85 */
-
/*
- * Copyright (c) 1982, 1986 Regents of the University of California.
- * All rights reserved. The Berkeley software License Agreement
- * specifies the terms and conditions for redistribution.
+ * Copyright (c) 1982, 1986, 1993
+ * The Regents of the University of California. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by the University of
+ * California, Berkeley and its contributors.
+ * 4. Neither the name of the University nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ * @(#)tcpip.h 8.1 (Berkeley) 6/10/93
+ * $Id: tcpip.h,v 2.0.2.3.2.1 1997/11/12 11:01:12 darrenr Exp $
*/
+#ifndef _NETINET_TCPIP_H_
+#define _NETINET_TCPIP_H_
+
+# if defined(linux) && !defined(LINUX_IPOVLY)
+# define LINUX_IPOVLY
+struct ipovly {
+ caddr_t ih_next, ih_prev; /* for protocol sequence q's */
+ u_char ih_x1; /* (unused) */
+ u_char ih_pr; /* protocol */
+ short ih_len; /* protocol length */
+ struct in_addr ih_src; /* source internet address */
+ struct in_addr ih_dst; /* destination internet address */
+};
+# endif
+
/*
* Tcp+ip header, after ip options removed.
*/
-
-#ifndef _netinet_tcpip_h
-#define _netinet_tcpip_h
-
struct tcpiphdr {
struct ipovly ti_i; /* overlaid ip structure */
- tcphdr_t ti_t; /* tcp header */
+#ifdef linux
+ tcphdr_t ti_t;
+#else
+ struct tcphdr ti_t; /* tcp header */
+#endif
+};
+#ifdef notyet
+/*
+ * Tcp+ip header, after ip options removed but including TCP options.
+ */
+struct full_tcpiphdr {
+ struct ipovly ti_i; /* overlaid ip structure */
+ struct tcphdr ti_t; /* tcp header */
+ char ti_o[TCP_MAXOLEN]; /* space for tcp options */
};
+#endif /* notyet */
#define ti_next ti_i.ih_next
#define ti_prev ti_i.ih_prev
#define ti_x1 ti_i.ih_x1
@@ -35,4 +88,4 @@ struct tcpiphdr {
#define ti_sum ti_t.th_sum
#define ti_urp ti_t.th_urp
-#endif /*!_netinet_tcpip_h*/
+#endif
diff --git a/contrib/ipfilter/ipsend/ultrix.c b/contrib/ipfilter/ipsend/ultrix.c
new file mode 100644
index 000000000000..186d2698237e
--- /dev/null
+++ b/contrib/ipfilter/ipsend/ultrix.c
@@ -0,0 +1,86 @@
+/*
+ * (C)opyright 1997 Darren Reed. (from tcplog)
+ *
+ * Redistribution and use in source and binary forms are permitted
+ * provided that this notice is preserved and due credit is given
+ * to the original author and the contributors.
+ */
+#include <stdio.h>
+#include <strings.h>
+#include <unistd.h>
+#include <stdlib.h>
+#include <ctype.h>
+#include <sys/types.h>
+#include <sys/param.h>
+#include <sys/socket.h>
+#include <sys/file.h>
+#include <sys/ioctl.h>
+#include <net/if.h>
+#include <netinet/in.h>
+#include <netinet/if_ether.h>
+#include <netdnet/dli_var.h>
+
+
+static struct dli_devid dli_devid;
+
+
+int initdevice(device, sport, tout)
+char *device;
+int sport, tout;
+{
+ u_char *s;
+ int fd;
+
+ fd = socket(AF_DLI, SOCK_DGRAM, 0);
+ if (fd == -1)
+ perror("socket(AF_DLI,SOCK_DGRAM)");
+ else {
+ strncpy(dli_devid.dli_devname, device, DLI_DEVSIZE);
+ dli_devid.dli_devname[DLI_DEVSIZE] ='\0';
+ for (s = dli_devid.dli_devname; *s && isalpha((char)*s); s++)
+ ;
+ if (*s && isdigit((char)*s)) {
+ dli_devid.dli_devnumber = atoi(s);
+ }
+ }
+ return fd;
+}
+
+
+/*
+ * output an IP packet onto a fd opened for /dev/bpf
+ */
+int sendip(fd, pkt, len)
+int fd, len;
+char *pkt;
+{
+ struct sockaddr_dl dl;
+ struct sockaddr_edl *edl = &dl.choose_addr.dli_eaddr;
+
+ dl.dli_family = AF_DLI;
+ dl.dli_substructype = DLI_ETHERNET;
+ bcopy((char *)&dli_devid, (char *)&dl.dli_device, sizeof(dli_devid));
+ bcopy(pkt, edl->dli_target, DLI_EADDRSIZE);
+ bcopy(pkt, edl->dli_dest, DLI_EADDRSIZE);
+ bcopy(pkt + DLI_EADDRSIZE * 2, (char *)&edl->dli_protype, 2);
+ edl->dli_ioctlflg = 0;
+
+ if (sendto(fd, pkt, len, 0, (struct sockaddr *)&dl, sizeof(dl)) == -1)
+ {
+ perror("send");
+ return -1;
+ }
+
+ return len;
+}
+
+
+char *strdup(str)
+char *str;
+{
+ char *s;
+
+ if ((s = (char *)malloc(strlen(str) + 1)))
+ return strcpy(s, str);
+ return NULL;
+}
diff --git a/contrib/ipfilter/ipt.c b/contrib/ipfilter/ipt.c
index cc0c223743a4..adf0f91d070d 100644
--- a/contrib/ipfilter/ipt.c
+++ b/contrib/ipfilter/ipt.c
@@ -1,5 +1,5 @@
/*
- * (C)opyright 1993-1996 by Darren Reed.
+ * Copyright (C) 1993-1997 by Darren Reed.
*
* Redistribution and use in source and binary forms are permitted
* provided that this notice is preserved and due credit is given
@@ -11,13 +11,15 @@
#include <stdio.h>
#include <assert.h>
#include <string.h>
-#if !defined(__SVR4) && !defined(__svr4__)
+#include <sys/types.h>
+#if !defined(__SVR4) && !defined(__svr4__) && !defined(__sgi)
#include <strings.h>
#else
+#if !defined(__sgi)
#include <sys/byteorder.h>
+#endif
#include <sys/file.h>
#endif
-#include <sys/types.h>
#include <sys/param.h>
#include <sys/time.h>
#include <stdlib.h>
@@ -27,12 +29,13 @@
#include <sys/ioctl.h>
#include <netinet/in.h>
#include <netinet/in_systm.h>
+#ifndef linux
#include <netinet/ip_var.h>
+#endif
#include <netinet/ip.h>
#include <netinet/udp.h>
#include <netinet/tcp.h>
#include <netinet/ip_icmp.h>
-#include <netinet/tcpip.h>
#include <net/if.h>
#if __FreeBSD_version >= 300000
# include <net/if_var.h>
@@ -43,13 +46,14 @@
#include <resolv.h>
#include <ctype.h>
#include "ip_compat.h"
+#include <netinet/tcpip.h>
#include "ip_fil.h"
#include "ipf.h"
#include "ipt.h"
-#if !defined(lint) && defined(LIBC_SCCS)
-static char sccsid[] = "@(#)ipt.c 1.19 6/3/96 (C) 1993-1996 Darren Reed";
-static char rcsid[] = "$Id: ipt.c,v 2.0.2.5 1997/04/30 13:59:39 darrenr Exp $";
+#if !defined(lint)
+static const char sccsid[] = "@(#)ipt.c 1.19 6/3/96 (C) 1993-1996 Darren Reed";
+static const char rcsid[] = "@(#)$Id: ipt.c,v 2.0.2.12.2.1 1997/11/12 10:58:10 darrenr Exp $";
#endif
extern char *optarg;
@@ -66,14 +70,13 @@ int argc;
char *argv[];
{
struct ipread *r = &iptext;
- struct ip *ip;
u_long buf[64];
struct ifnet *ifp;
- char c;
char *rules = NULL, *datain = NULL, *iface = NULL;
- int fd, i, dir = 0;
+ ip_t *ip;
+ int fd, i, dir = 0, c;
- while ((c = (char)getopt(argc, argv, "bdEHi:I:oPr:STvX")) != -1)
+ while ((c = getopt(argc, argv, "bdEHi:I:oPr:STvX")) != -1)
switch (c)
{
case 'b' :
@@ -157,10 +160,11 @@ char *argv[];
if (!(fr = parse(line)))
continue;
/* fake an `ioctl' call :) */
- i = iplioctl(0, SIOCADDFR, (caddr_t)fr, FWRITE|FREAD);
+ i = IPL_EXTERN(ioctl)(0, SIOCADDFR, (caddr_t)fr, FWRITE|FREAD);
if (opts & OPT_DEBUG)
fprintf(stderr,
- "iplioctl(SIOCADDFR,%x,1) = %d\n", i);
+ "iplioctl(SIOCADDFR,%p,1) = %d\n",
+ fr, i);
}
(void)fclose(fp);
}
@@ -176,14 +180,17 @@ char *argv[];
if (fd < 0)
exit(-1);
- ip = (struct ip *)buf;
+ ip = (ip_t *)buf;
while ((i = (*r->r_readip)((char *)buf, sizeof(buf),
&iface, &dir)) > 0) {
ifp = iface ? get_unit(iface) : NULL;
ip->ip_off = ntohs(ip->ip_off);
ip->ip_len = ntohs(ip->ip_len);
- switch (fr_check(ip, ip->ip_hl << 2, ifp, dir, (char *)buf))
+ switch (fr_check(ip, ip->ip_hl << 2, ifp, dir, (mb_t **)&buf))
{
+ case -2 :
+ (void)printf("auth");
+ break;
case -1 :
(void)printf("block");
break;
@@ -196,11 +203,17 @@ char *argv[];
}
if (!(opts & OPT_BRIEF)) {
putchar(' ');
- printpacket((struct ip *)buf);
+ printpacket((ip_t *)buf);
printf("--------------");
}
+#ifndef linux
if (dir && ifp && ip->ip_v)
+# ifdef __sgi
+ (*ifp->if_output)(ifp, (void *)buf, NULL);
+# else
(*ifp->if_output)(ifp, (void *)buf, NULL, 0);
+# endif
+#endif
putchar('\n');
dir = 0;
}
diff --git a/contrib/ipfilter/ipt.h b/contrib/ipfilter/ipt.h
index f7cc61f52416..650700cf9bd6 100644
--- a/contrib/ipfilter/ipt.h
+++ b/contrib/ipfilter/ipt.h
@@ -1,10 +1,10 @@
/*
- * (C)opyright 1993-1997 by Darren Reed.
+ * Copyright (C) 1993-1997 by Darren Reed.
*
* Redistribution and use in source and binary forms are permitted
* provided that this notice is preserved and due credit is given
* to the original author and the contributors.
- * $Id: ipt.h,v 2.0.2.6 1997/04/30 13:49:22 darrenr Exp $
+ * $Id: ipt.h,v 2.0.2.7 1997/09/28 07:12:00 darrenr Exp $
*/
#ifndef __IPT_H__
diff --git a/contrib/ipfilter/kmem.c b/contrib/ipfilter/kmem.c
index 33b6595fe90e..75d8a80320d4 100644
--- a/contrib/ipfilter/kmem.c
+++ b/contrib/ipfilter/kmem.c
@@ -1,5 +1,5 @@
/*
- * (C)opyright 1993,1994,1995 by Darren Reed.
+ * Copyright (C) 1993-1997 by Darren Reed.
*
* Redistribution and use in source and binary forms are permitted
* provided that this notice is preserved and due credit is given
@@ -18,9 +18,9 @@
#include <sys/file.h>
#include "kmem.h"
-#if !defined(lint) && defined(LIBC_SCCS)
-static char sccsid[] = "@(#)kmem.c 1.4 1/12/96 (C) 1992 Darren Reed";
-static char rcsid[] = "$Id: kmem.c,v 2.0.2.3 1997/03/10 08:10:37 darrenr Exp $";
+#if !defined(lint)
+static const char sccsid[] = "@(#)kmem.c 1.4 1/12/96 (C) 1992 Darren Reed";
+static const char rcsid[] = "@(#)$Id: kmem.c,v 2.0.2.5 1997/10/23 14:50:53 darrenr Exp $";
#endif
static int kmemfd = -1;
diff --git a/contrib/ipfilter/kmem.h b/contrib/ipfilter/kmem.h
index d98f391c27a9..13e1f3c43bab 100644
--- a/contrib/ipfilter/kmem.h
+++ b/contrib/ipfilter/kmem.h
@@ -1,10 +1,10 @@
/*
- * (C)opyright 1993-1997 by Darren Reed.
+ * Copyright (C) 1993-1997 by Darren Reed.
*
* Redistribution and use in source and binary forms are permitted
* provided that this notice is preserved and due credit is given
* to the original author and the contributors.
- * $Id: kmem.h,v 2.0.2.5 1997/04/30 13:49:35 darrenr Exp $
+ * $Id: kmem.h,v 2.0.2.6 1997/09/28 07:12:02 darrenr Exp $
*/
#ifndef __KMEM_H__
diff --git a/contrib/ipfilter/linux.h b/contrib/ipfilter/linux.h
index 75aec954baed..63f400a05e38 100644
--- a/contrib/ipfilter/linux.h
+++ b/contrib/ipfilter/linux.h
@@ -1,5 +1,5 @@
/*
- * (C)opyright 1993-1997 by Darren Reed.
+ * Copyright (C) 1993-1997 by Darren Reed.
*
* Redistribution and use in source and binary forms are permitted
* provided that this notice is preserved and due credit is given
@@ -7,7 +7,7 @@
* responsibility and is not changed in any way.
*
* I hate legaleese, don't you ?
- * $Id: linux.h,v 2.0.2.3 1997/04/07 09:59:01 darrenr Exp $
+ * $Id: linux.h,v 2.0.2.4 1997/09/28 07:12:03 darrenr Exp $
*/
#include <linux/config.h>
diff --git a/contrib/ipfilter/man/Makefile b/contrib/ipfilter/man/Makefile
index c62e54c74497..972fbf52005b 100644
--- a/contrib/ipfilter/man/Makefile
+++ b/contrib/ipfilter/man/Makefile
@@ -1,14 +1,14 @@
#
-# (C)opyright 1993, 1994, 1995 by Darren Reed.
+# Copyright (C) 1993-1997 by Darren Reed.
+#
+# Redistribution and use in source and binary forms are permitted
+# provided that this notice is preserved and due credit is given
+# to the original author and the contributors.
#
-# This code may be freely distributed as long as it retains this notice
-# and is not changed in any way. The author accepts no responsibility
-# for the use of this software. I hate legaleese, don't you ?
all:
install:
- $(INSTALL) -m 0644 -c -o root -g bin ipf.1 $(MANDIR)/man1
$(INSTALL) -m 0644 -c -o root -g bin ipftest.1 $(MANDIR)/man1
$(INSTALL) -m 0644 -c -o root -g bin ipnat.1 $(MANDIR)/man1
$(INSTALL) -m 0644 -c -o root -g bin ipf.4 $(MANDIR)/man4
@@ -16,6 +16,7 @@ install:
$(INSTALL) -m 0644 -c -o root -g bin ipnat.4 $(MANDIR)/man4
$(INSTALL) -m 0644 -c -o root -g bin ipf.5 $(MANDIR)/man5
$(INSTALL) -m 0644 -c -o root -g bin ipnat.5 $(MANDIR)/man5
+ $(INSTALL) -m 0644 -c -o root -g bin ipf.8 $(MANDIR)/man8
$(INSTALL) -m 0644 -c -o root -g bin ipmon.8 $(MANDIR)/man8
$(INSTALL) -m 0644 -c -o root -g bin ipfstat.8 $(MANDIR)/man8
@echo "Remember to rebuild the whatis database."
diff --git a/contrib/ipfilter/man/ipf.4 b/contrib/ipfilter/man/ipf.4
index ebeacebb0b16..6cf9f204ef89 100644
--- a/contrib/ipfilter/man/ipf.4
+++ b/contrib/ipfilter/man/ipf.4
@@ -2,7 +2,8 @@
.SH NAME
ipf \- packet filtering kernel interface
.SH SYNOPSIS
-#include <sys/ip_fil.h>
+#include <netinet/ip_compat.h>
+#include <netinet/ip_fil.h>
.SH IOCTLS
.PP
To add and delete rules to the filter list, three 'basic' ioctls are provided
@@ -41,10 +42,17 @@ which it is inserted is stored in the "fr_hits" field, below.
.nf
typedef struct frentry {
struct frentry *fr_next;
+ u_short fr_group; /* group to which this rule belongs */
+ u_short fr_head; /* group # which this rule starts */
+ struct frentry *fr_grp;
+ int fr_ref; /* reference count - for grouping */
struct ifnet *fr_ifa;
- u_long fr_hits;
- u_long fr_bytes; /* this is only incremented when a packet */
- /* stops matching on this rule */
+ /*
+ * These are only incremented when a packet matches this rule and
+ * it is the last match
+ */
+ U_QUAD_T fr_hits;
+ U_QUAD_T fr_bytes;
/*
* Fields after this may not change whilst in the kernel.
*/
@@ -64,6 +72,7 @@ typedef struct frentry {
u_short fr_stop; /* top port for <> and >< */
u_short fr_dtop; /* top port for <> and >< */
u_long fr_flags; /* per-rule flags && options (see below) */
+ int fr_skip; /* # of rules to skip */
int (*fr_func)(); /* call this function */
char fr_icode; /* return ICMP code */
char fr_ifname[IFNAMSIZ];
@@ -81,26 +90,31 @@ be put in the "fr_hits" field (the first rule is number 0).
Flags which are recognised in fr_pass:
.nf
- FR_BLOCK 0x00001 /* do not allow packet to pass */
- FR_PASS 0x00002 /* allow packet to pass */
- FR_OUTQUE 0x00004 /* outgoing packets */
- FR_INQUE 0x00008 /* ingoing packets */
- FR_LOG 0x00010 /* Log */
- FR_LOGP 0x00011 /* Log-pass */
- FR_LOGB 0x00012 /* Log-fail */
- FR_LOGBODY 0x00020 /* log the body of packets too */
- FR_LOGFIRST 0x00040 /* log only the first packet to match */
- FR_RETRST 0x00080 /* return a TCP RST packet if blocked */
- FR_RETICMP 0x00100 /* return an ICMP packet if blocked */
- FR_NOMATCH 0x00200 /* no match occured */
- FR_ACCOUNT 0x00400 /* count packet bytes */
- FR_KEEPFRAG 0x00800
- FR_KEEPSTATE 0x01000 /* keep packet flow state information */
- FR_INACTIVE 0x02000
- FR_QUICK 0x04000 /* quick-match and return */
- FR_FASTROUTE 0x08000
- FR_CALLNOW 0x10000
- FR_DUP 0x20000 /* duplicate the packet (not Solaris2)
+ FR_BLOCK 0x000001 /* do not allow packet to pass */
+ FR_PASS 0x000002 /* allow packet to pass */
+ FR_OUTQUE 0x000004 /* outgoing packets */
+ FR_INQUE 0x000008 /* ingoing packets */
+ FR_LOG 0x000010 /* Log */
+ FR_LOGP 0x000011 /* Log-pass */
+ FR_LOGB 0x000012 /* Log-fail */
+ FR_LOGBODY 0x000020 /* log the body of packets too */
+ FR_LOGFIRST 0x000040 /* log only the first packet to match */
+ FR_RETRST 0x000080 /* return a TCP RST packet if blocked */
+ FR__RETICMP 0x000100 /* return an ICMP packet if blocked */
+ FR_NOMATCH 0x000200 /* no match occured */
+ FR_ACCOUNT 0x000400 /* count packet bytes */
+ FR_KEEPFRAG 0x000800 /* keep fragment information */
+ FR_KEEPSTATE 0x001000 /* keep `connection' state information */
+ FR_INACTIVE 0x002000
+ FR_QUICK 0x004000 /* match & stop processing list */
+ FR_FASTROUTE 0x008000 /* bypass normal routing */
+ FR_CALLNOW 0x010000 /* call another function (fr_func) if matches */
+ FR_DUP 0x020000 /* duplicate the packet */
+ FR_LOGORBLOCK 0x040000 /* block the packet if it can't be logged */
+ FR_NOTSRCIP 0x080000 /* not the src IP# */
+ FR_NOTDSTIP 0x100000 /* not the dst IP# */
+ FR_AUTH 0x200000 /* use authentication */
+ FR_PREAUTH 0x400000 /* require preauthentication */
.fi
.PP
@@ -134,8 +148,10 @@ Takes an unsigned integer as the parameter. The flags are then set to
those provided (clearing/setting all in one).
.nf
- FF_LOGPASS 1
- FF_LOGBLOCK 2
+ FF_LOGPASS 0x10000000
+ FF_LOGBLOCK 0x20000000
+ FF_LOGNOMATCH 0x40000000
+ FF_BLOCKNONIP 0x80000000 /* Solaris 2.x only */
.fi
.IP SIOCGETFF 16
Takes a pointer to an unsigned integer as the parameter. A copy of the
@@ -149,10 +165,14 @@ through the kernel. To retrieve this structure, use this ioctl:
ioctl(fd, SIOCGETFS, struct friostat *)
-struct friostat {
- struct filterstats f_st[2];
- struct frentry *f_fin;
- struct frentry *f_fout;
+struct friostat {
+ struct filterstats f_st[2];
+ struct frentry *f_fin[2];
+ struct frentry *f_fout[2];
+ struct frentry *f_acctin[2];
+ struct frentry *f_acctout[2];
+ struct frentry *f_auth;
+ int f_active;
};
struct filterstats {
@@ -172,6 +192,7 @@ struct filterstats {
u_long fr_bads; /* bad attempts to allocate packet state */
u_long fr_ads; /* new packet state kept */
u_long fr_chit; /* cached hit */
+ u_long fr_pull[2]; /* good and bad pullup attempts */
#if SOLARIS
u_long fr_bad; /* bad IP packets to the filter */
u_long fr_notip; /* packets passed through no on ip queue */
diff --git a/contrib/ipfilter/man/ipf.5 b/contrib/ipfilter/man/ipf.5
index f8ceedd65c54..c202be71f6a0 100644
--- a/contrib/ipfilter/man/ipf.5
+++ b/contrib/ipfilter/man/ipf.5
@@ -18,27 +18,26 @@ The format used by \fBipf\fP for construction of filtering rules can be
described using the following grammar in BNF:
\fC
.nf
-filter-rule = [ insert ] action in-out [ options ] [ match ] [ keep ]
+filter-rule = [ insert ] action in-out [ options ] [ tos ] [ ttl ]
+ [ proto ] [ ip ] [ group ].
insert = "@" decnumber .
-action = block | "pass" | log | "count" | call .
+action = block | "pass" | log | "count" | skip | auth | call .
in-out = "in" | "out" .
options = [ log ] [ "quick" ] [ "on" interface-name [ dup ] [ froute ] ] .
-match = [ tos ] [ ttl ] [ proto ] [ ip ] .
-keep = "keep state" | "keep frags" .
+tos = "tos" decnumber | "tos" hexnumber .
+ttl = "ttl" decnumber .
+proto = "proto" protocol .
+ip = srcdst [ flags ] [ with withopt ] [ icmp ] [ keep ] .
+group = [ "head" decnumber ] [ "group" decnumber ] .
block = "block" [ "return-icmp"[return-code] | "return-rst" ] .
-log = "log" [ "body" ] [ "first" ] [ "or-block" ] .
-call = "call" [ "now" ] function-name .
-
-dup = "dup-to" interface-name[":"ipaddr] .
+auth = "auth" | "preauth" .
+log = "log" [ "body" ] [ "first" ] [ "or-block" ] .
+call = "call" [ "now" ] function-name .
+skip = "skip" decnumber .
+dup = "dup-to" interface-name[":"ipaddr] .
froute = "fastroute" | "to" interface-name .
-
-tos = "tos" decnumber | "tos" hexnumber .
-ttl = "ttl" decnumber .
-proto = "proto" protocol .
-ip = srcdst [ flags ] [ with withopt ] [ icmp ] [ keep ] .
-
protocol = "tcp/udp" | "udp" | "tcp" | "icmp" | decnumber .
srcdst = "all" | fromto .
fromto = "from" object "to" object .
@@ -47,11 +46,11 @@ object = addr [ port-comp | port-range ] .
addr = "any" | nummask | host-name [ "mask" ipaddr | "mask" hexnumber ] .
port-comp = "port" compare port-num .
port-range = "port" port-num range port-num .
-
flags = "flags" flag { flag } [ "/" flag { flag } ] .
with = "with" | "and" .
icmp = "icmp-type" icmp-type [ "code" decnumber ] .
return-code = "("icmp-code")" .
+keep = "keep" "state" | "keep" "frags" .
nummask = host-name [ "/" decnumber ] .
host-name = ipaddr | hostname | "any" .
@@ -72,16 +71,16 @@ icmp-type = "unreach" | "echo" | "echorep" | "squench" | "redir" |
icmp-code = decumber | "net-unr" | "host-unr" | "proto-unr" | "port-unr" |
"needfrag" | "srcfail" | "net-unk" | "host-unk" | "isolate" |
"net-prohib" | "host-prohib" | "net-tos" | "host-tos" .
-optlist = "nop" | "rr" | "zsu" | "mtup" | "mtur" | "encode" | "ts" | "tr" |
- "sec" | "lsrr" | "e-sec" | "cipso" | "satid" | "ssrr" | "addext" |
- "visa" | "imitd" | "eip" | "finn" .
+optlist = "nop" | "rr" | "zsu" | "mtup" | "mtur" | "encode" | "ts" |
+ "tr" | "sec" | "lsrr" | "e-sec" | "cipso" | "satid" | "ssrr" |
+ "addext" | "visa" | "imitd" | "eip" | "finn" .
hexnumber = "0" "x" hexstring .
hexstring = hexdigit [ hexstring ] .
decnumber = digit [ decnumber ] .
-compare = "=" | "!=" | "<" | ">" | "<=" | ">=" | "eq" | "ne" | "lt" | "gt" |
- "le" | "ge" .
+compare = "=" | "!=" | "<" | ">" | "<=" | ">=" | "eq" | "ne" | "lt" |
+ "gt" | "le" | "ge" .
range = "<>" | "><" .
hexdigit = digit | "a" | "b" | "c" | "d" | "e" | "f" .
digit = "0" | "1" | "2" | "3" | "4" | "5" | "6" | "7" | "8" | "9" .
@@ -95,18 +94,9 @@ not make sense (such as tcp \fBflags\fP for non-TCP packets).
.PP
The "briefest" valid rules are (currently) no-ops and are of the form:
.nf
- block in
- pass in
- log in
- count in
-.fi
-.PP
-These are supposed to be the same as, but currently differ from:
-.\" XXX How, why do they differ??
-.nf
block in all
- pass in from any to any
- log in all
+ pass in all
+ log out all
count in all
.fi
.PP
@@ -153,6 +143,12 @@ must conform to a specific calling interface. Customised actions and
semantics can thus be implemented to supplement those available. This
feature is for use by knowledgeable hackers, and is not currently
documented.
+.TP
+.B "skip <n>"
+.TP
+.B auth
+.TP
+.B preauth
.PP
The next word must be either \fBin\fP or \fBout\fP. Each packet
moving through the kernel is either inbound (just been received on an
@@ -221,7 +217,6 @@ packets with different Type-Of-Service values can be filtered.
Individual service levels or combinations can be filtered upon. The
value for the TOS mask can either be represented as a hex number or a
decimal integer value.
-.\" XXX TOS mask?? not in grammar!
.TP
.B ttl
packets may also be selected by their Time-To-Live value. The value given in
@@ -356,8 +351,9 @@ with which they are associated can be used. The most important from
a security point of view is the ICMP redirect.
.SH KEEP HISTORY
.PP
-The last parameter which can be set for a filter rule is whether on not to
-record historical information for that packet, and what sort to keep. The following information can be kept:
+The second last parameter which can be set for a filter rule is whether on not
+to record historical information for that packet, and what sort to keep. The
+following information can be kept:
.TP
.B state
keeps information about the flow of a communication session. State can
@@ -369,6 +365,23 @@ fragments.
.PP
allowing packets which match these to flow straight through, rather
than going through the access control list.
+.SH GROUPS
+The last pair of parameters control filter rule "grouping". By default, all
+filter rules are placed in group 0 if no other group is specified. To add a
+rule to a non-default group, the group must first be started by creating a
+group \fIhead\fP. If a packet matches a rule which is the \fIhead\fP of a
+group, the filter processing then switches to the group, using that rule as
+the default for the group. If \fBquick\fP is used with a \fBhead\fP rule, rule
+processing isn't stopped until it has returned from processing the group.
+.PP
+A rule may be both the head for a new group and a member of a non-default
+group (\fBhead\fP and \fBgroup\fP may be used together in a rule).
+.TP
+.B "head <n>"
+indicates that a new group (number n) should be created.
+.TP
+.B "group <n>"
+indicates that the rule should be put in group (number n) rather than group 0.
.SH LOGGING
.PP
When a packet is logged, with either the \fBlog\fP action or option,
@@ -427,7 +440,42 @@ rule such as:
pass in quick from any to any port < 1024
.fi
.PP
-would be needed before the first block.
+would be needed before the first block. To create a new group for
+processing all inbould packets on le0/le1/lo0, with the default being to block
+all inbound packets, we would do something like:
+.LP
+.nf
+ block in all
+ block in on le0 quick all head 100
+ block in on le1 quick all head 200
+ block in on lo0 quick all head 300
+.fi
+.PP
+
+and to then allow ICMP packets in on le0, only, we would do:
+.LP
+.nf
+ pass in proto icmp all group 100
+.fi
+.PP
+Note that because only inbound packets on le0 are used processed by group 100,
+there is no need to respecify the interface name. Likewise, we could further
+breakup processing of TCP, etc, as follows:
+.LP
+.nf
+ block in proto tcp all head 110 group 100
+ pass in from any to any port = 23 group 110
+.fi
+.PP
+and so on. The last line, if written without the groups would be:
+.LP
+.nf
+ pass in on le0 proto tcp from any to any port = telnet
+.fi
+.PP
+Note, that if we wanted to say "port = telnet", "proto tcp" would
+need to be specified as the parser interprets each rule on its own and
+qualifies all service/port names with the protocol specified.
.SH FILES
/etc/services
.br
diff --git a/contrib/ipfilter/man/ipf.8 b/contrib/ipfilter/man/ipf.8
new file mode 100644
index 000000000000..b13e2ddb2f05
--- /dev/null
+++ b/contrib/ipfilter/man/ipf.8
@@ -0,0 +1,109 @@
+.TH IPF 8
+.SH NAME
+ipf \- alters packet filtering lists for IP packet input and output
+.SH SYNOPSIS
+.B ipf
+[
+.B \-AdDEInorsUvyzZ
+] [
+.B \-l
+<block|pass|nomatch>
+] [
+.B \-F
+<i|o|a>
+]
+.B \-f
+<\fIfilename\fP>
+[
+.B \-f
+<\fIfilename\fP>
+[...]]
+.SH DESCRIPTION
+.PP
+\fBipf\fP opens the filenames listed (treating "\-" as stdin) and parses the
+file for a set of rules which are to be added or removed from the packet
+filter rule set.
+.PP
+Each rule processed by \fBipf\fP
+is added to the kernel's internal lists if there are no parsing problems.
+Rules are added to the end of the internal lists, matching the order in
+which they appear when given to \fBipf\fP.
+.SH OPTIONS
+.TP
+.B \-A
+Set the list to make changes to the active list (default).
+.TP
+.B \-d
+Turn debug mode on. Causes a hexdump of filter rules to be generated as
+it processes each one.
+.TP
+.B \-D
+Disable the filter (if enabled). Not effective for loadable kernel versions.
+.TP
+.B \-E
+Enable the filter (if disabled). Not effective for loadable kernel versions.
+.TP
+.BR \-F \0<param>
+This option specifies which filter list to flush. The parameter should
+either be "i" (input), "o" (output) or "a" (remove all filter rules).
+Either a single letter or an entire word starting with the appropriate
+letter maybe used. This option maybe before, or after, any other with
+the order on the command line being that used to execute options.
+.TP
+.BR \-f \0<filename>
+This option specifies which files
+\fBipf\fP should use to get input from for modifying the packet filter rule
+lists.
+.TP
+.B \-I
+Set the list to make changes to the inactive list.
+.TP
+.B \-l \0<param>
+Use of the \fB-l\fP flag toggles default logging of packets. Valid
+arguments to this option are \fBpass\fP, \fBblock\fP and \fBnomatch\fP.
+When an option is set, any packet which exits filtering and matches the
+set category is logged. This is most useful for causing all packets
+which don't match any of the loaded rules to be logged.
+.TP
+.B \-n
+This flag (no-change) prevents \fBipf\fP from actually making any ioctl
+calls or doing anything which would alter the currently running kernel.
+.TP
+.B \-o
+Force rules by default to be added/deleted to/from the output list, rather
+than the (default) input list.
+.TP
+.B \-r
+Remove matching filter rules rather than add them to the internal lists
+.TP
+.B \-s
+Swap the active filter list in use to be the "other" one.
+.TP
+.B \-U
+(SOLARIS 2 ONLY) Block packets travelling along the data stream which aren't
+recognised as IP packets. They will be printed out on the console.
+.TP
+.B \-v
+Turn verbose mode on. Displays information relating to rule processing.
+.TP
+.B \-y
+Manually resync the in-kernel interface list maintained by IP Filter with
+the current interface status list.
+.TP
+.B \-z
+For each rule in the input file, reset the statistics for it to zero and
+display the statistics prior to them being zero'd.
+.TP
+.B \-Z
+Zero global statistics held in the kernel for filtering only (this doesn't
+affect fragment or state statistics).
+.DT
+.SH SEE ALSO
+ipfstat(1), ipftest(1), ipf(5), mkfilters(1)
+.SH DIAGNOSTICS
+.PP
+Needs to be run as root for the packet filtering lists to actually
+be affected inside the kernel.
+.SH BUGS
+.PP
+If you find any, please send email to me at darrenr@cyber.com.au
diff --git a/contrib/ipfilter/man/ipfstat.8 b/contrib/ipfilter/man/ipfstat.8
index db23e39eed71..c8679f1c0a21 100644
--- a/contrib/ipfilter/man/ipfstat.8
+++ b/contrib/ipfilter/man/ipfstat.8
@@ -4,7 +4,7 @@ ipfstat \- reports on packet filter statistics and filter list
.SH SYNOPSIS
.B ipfstat
[
-.B \-hIinov
+.B \-aAfhIinosv
] [
.B \-d
<device>
@@ -24,6 +24,9 @@ accumulated over time as the kernel has put packets through the filter.
.B \-a
Display the accounting filter list and show bytes counted against each rule.
.TP
+.B \-A
+Display packet authentication statistics.
+.TP
.BR \-d \0<device>
Use a device other than \fB/dev/ipl\fP for interfacing with the kernel.
.TP
@@ -68,6 +71,6 @@ kernel.
.br
/vmunix
.SH SEE ALSO
-ipf(1), ipfstat(1)
+ipf(1)
.SH BUGS
none known.
diff --git a/contrib/ipfilter/man/ipl.4 b/contrib/ipfilter/man/ipl.4
index 0e58a50fa1d0..26aa604e7e44 100644
--- a/contrib/ipfilter/man/ipl.4
+++ b/contrib/ipfilter/man/ipl.4
@@ -6,50 +6,67 @@ The \fBipl\fP pseudo device's purpose is to provide an easy way to gather
packet headers of packets you wish to log. If a packet header is to be
logged, the entire header is logged (including any IP options \- TCP/UDP
options are not included when it calculates header size) or not at all.
-The packet contents are also logged after the header.
+The packet contents are also logged after the header. If the log reader
+is busy or otherwise unable to read log records, upto IPLLOGSIZE (8192 is the
+default) bytes of data are stored.
.PP
Prepending every packet header logged is a structure containing information
relevant to the packet following and why it was logged. The structure's
format is as follows:
.LP
.nf
-struct ipl_ci {
- u_long sec; /* time when the packet was logged */
- u_long usec;
- u_long plen; /* length of packet data logged */
- u_short hlen; /* length of headers logged */
- u_short rule; /* rule number (for log ...) or 0 if result = log */
- u_long flags:24; /* XXX FIXME do we care about the extra bytes? */
-#if (defined(NetBSD) && (NetBSD <= 1991011) && (NetBSD >= 199606))
- u_long filler:8; /* XXX FIXME do we care? */
- u_char ifname[IFNAMSIZ];
+/*
+ * Log structure. Each packet header logged is prepended by one of these.
+ * Following this in the log records read from the device will be an ipflog
+ * structure which is then followed by any packet data.
+ */
+typedef struct iplog {
+ u_long ipl_sec;
+ u_long ipl_usec;
+ u_int ipl_len;
+ u_int ipl_count;
+ size_t ipl_dsize;
+ struct iplog *ipl_next;
+} iplog_t;
+
+
+typedef struct ipflog {
+#if (defined(NetBSD) && (NetBSD <= 1991011) && (NetBSD >= 199603))
+ u_char fl_ifname[IFNAMSIZ];
#else
- u_long unit:8;
- u_char ifname[4];
+ u_int fl_unit;
+ u_char fl_ifname[4];
#endif
-};
+ u_char fl_plen; /* extra data after hlen */
+ u_char fl_hlen; /* length of IP headers saved */
+ u_short fl_rule; /* assume never more than 64k rules, total */
+ u_32_t fl_flags;
+} ipflog_t;
+
.fi
.PP
-In the case of the header causing the buffer to finish on a non-32bit
-boundary, padding will be `appended' to ensure that the next log entry
-is aligned to a 32bit boundary.
-.LP
+When reading from the \fBipl\fP device, it is necessary to call read(2) with
+a buffer big enough to hold at least 1 complete log record - reading of partial
+log records is not supported.
+.PP
+If the packet contents is more then 128 bytes when \fBlog body\fP is used,
+then only 128 bytes of the packet contents is logged.
+.PP
+Although it is only possible to read from the \fBipl\fP device, opening it
+for writing is required when using an ioctl which changes any kernel data.
.PP
-If the packet contents is more then 128 bytes, then only 128 bytes of the
-packet contents is logged. Should the packet contents finish on a non-32bit
-boundary, then the last few bytes are not logged to ensure the log entry
-is aligned to a 32bit boundary.
-
-\fBipl\fP is a read-only (sequential) character pseudo-device.
-
The ioctls which are loaded with this device can be found under \fBipf(4)\fP.
-The only ioctl which is used for logging and doesn't affect the filter is:
+The ioctls which are for use with logging and don't affect the filter are:
.LP
.nf
ioctl(fd, SIOCIPFFB, int *)
+ ioctl(fd, FIONREAD, int *)
.fi
.PP
-This ioctl flushes the log buffer and returns the number of bytes flushed.
+The SIOCIPFFB ioctl flushes the log buffer and returns the number of bytes
+flushed. FIONREAD returns the number of bytes currently used for storing
+log data. If IPFILTER_LOG is not defined when compiling, SIOCIPFFB is not
+available and FIONREAD will return but not do anything.
.PP
There is currently no support for non-blocking IO with this device, meaning
all read operations should be considered blocking in nature (if there is no
diff --git a/contrib/ipfilter/man/ipmon.8 b/contrib/ipfilter/man/ipmon.8
index e793352a60e5..32f4cbdfc549 100644
--- a/contrib/ipfilter/man/ipmon.8
+++ b/contrib/ipfilter/man/ipmon.8
@@ -4,9 +4,11 @@ ipmon \- monitors /dev/ipl for logged packets
.SH SYNOPSIS
.B ipmon
[
-.B \-asfnSN
+.B \-aFhnNsStvxX
] [
-<filename>
+.B "\-f <device>"
+] [
+.B <filename>
]
.SH DESCRIPTION
.LP
@@ -20,6 +22,24 @@ via syslog have the day, month and year removed from the message, but the
time (including microseconds), as recorded in the log, is still included.
.SH OPTIONS
.TP
+.B \-a
+Open all of the device logfiles for reading log entries from. All entries
+are displayed to the same output 'device' (stderr or syslog).
+.TP
+.B "\-f <device>"
+specify an alternative device/file from which to read the log information.
+.TP
+.B \-F
+Flush the current packet log buffer. The number of bytes flushed is displayed,
+even should the result be zero.
+.TP
+.B \-n
+IP addresses and port numbers will be mapped, where possible, back into
+hostnames and service names.
+.TP
+.B \-N
+Treat the logfile as being composed of NAT log records.
+.TP
.B \-s
Packet information read in will be sent through syslogd rather than
saved to a file. The following levels are used:
@@ -38,22 +58,17 @@ than pass or block.
\- packets which have been logged and which can be considered
"short".
.TP
-.B \-a
-Open all of the device logfiles for reading log entries from.
+.B \-S
+Treat the logfile as being composed of state log records.
.TP
-.B \-f
-Flush the current packet log buffer. The number of bytes flushed is displayed,
-even should the result be zero.
+.B \-t
+read the input file/device in a manner akin to tail(1).
.TP
-.B \-n
-IP addresses and port numbers will be mapped, where possible, back into
-hostnames and service names.
-.TP
-.B \-N
-Treat the logfile as being composed of NAT log records.
+.B \-x
+show the packet data in hex.
.TP
-.B \-S
-Treat the logfile as being composed of state log records.
+.B \-X
+show the log header record data in hex.
.SH DIAGNOSTICS
\fBipmon\fP expects data that it reads to be consistant with how it should be
saved and will abort if it fails an assertion which detects an anomoly in the
diff --git a/contrib/ipfilter/man/ipnat.4 b/contrib/ipfilter/man/ipnat.4
index 3346ef973029..ea789365ffd8 100644
--- a/contrib/ipfilter/man/ipnat.4
+++ b/contrib/ipfilter/man/ipnat.4
@@ -2,7 +2,10 @@
.SH NAME
ipnat \- Network Address Translation kernel interface
.SH SYNOPSIS
-#include <sys/ip_fil.h>
+#include <netinet/ip_compat.h>
+#include <netinet/ip_fil.h>
+#include <netinet/ip_proxy.h>
+#include <netinet/ip_nat.h>
.SH IOCTLS
.PP
To add and delete rules to the NAT list, two 'basic' ioctls are provided
diff --git a/contrib/ipfilter/misc.c b/contrib/ipfilter/misc.c
index 3ff46ba14474..082b5d6d0c0c 100644
--- a/contrib/ipfilter/misc.c
+++ b/contrib/ipfilter/misc.c
@@ -1,5 +1,5 @@
/*
- * (C)opyright 1993,1994,1995 by Darren Reed.
+ * Copyright (C) 1993-1997 by Darren Reed.
*
* Redistribution and use in source and binary forms are permitted
* provided that this notice is preserved and due credit is given
@@ -8,12 +8,12 @@
#include <stdio.h>
#include <assert.h>
#include <string.h>
+#include <sys/types.h>
#if !defined(__SVR4) && !defined(__svr4__)
#include <strings.h>
#else
#include <sys/byteorder.h>
#endif
-#include <sys/types.h>
#include <sys/param.h>
#include <sys/time.h>
#include <stdlib.h>
@@ -24,31 +24,33 @@
#include <netinet/in.h>
#include <arpa/inet.h>
#include <netinet/in_systm.h>
+#ifndef linux
#include <netinet/ip_var.h>
+#endif
#include <netinet/ip.h>
#include <netinet/udp.h>
#include <netinet/tcp.h>
#include <netinet/ip_icmp.h>
-#include <netinet/tcpip.h>
#include <net/if.h>
#include <netdb.h>
#include <arpa/nameser.h>
#include <resolv.h>
#include "ip_compat.h"
+#include <netinet/tcpip.h>
#include "ip_fil.h"
#include "ipf.h"
#include "ipt.h"
-#if !defined(lint) && defined(LIBC_SCCS)
-static char sccsid[] = "@(#)misc.c 1.3 2/4/96 (C) 1995 Darren Reed";
-static char rcsid[] = "$Id: misc.c,v 2.0.2.6 1997/04/30 13:54:24 darrenr Exp $";
+#if !defined(lint)
+static const char sccsid[] = "@(#)misc.c 1.3 2/4/96 (C) 1995 Darren Reed";
+static const char rcsid[] = "@(#)$Id: misc.c,v 2.0.2.8.2.1 1997/11/12 10:58:26 darrenr Exp $";
#endif
extern int opts;
void printpacket(ip)
-struct ip *ip;
+ip_t *ip;
{
struct tcphdr *tcp;
diff --git a/contrib/ipfilter/mkfilters b/contrib/ipfilter/mkfilters
index 4cd705961bc8..53c9a7fef7e9 100644
--- a/contrib/ipfilter/mkfilters
+++ b/contrib/ipfilter/mkfilters
@@ -46,19 +46,27 @@ print "#\n";
print "block in log quick from any to any with ipopts\n";
print "block in log quick proto tcp from any to any with short\n";
+$grpi = 0;
+
foreach $i (keys %ifaces) {
if (!defined($inet{$i})) {
next;
}
+
+ $grpi += 100;
+ $grpo = $grpi + 50;
+
if ($i !~ /lo/) {
- print "block in on $i from 127.0.0.0/8 to any\n";
- print "block out on $i from 127.0.0.0/8 to any\n";
- print "block out on $i from any to 127.0.0.0/8\n";
- print "block in on $i from $inet{$i}/32 to any\n";
- print "block out on $i from any to $inet{$i}/32\n";
+ print "pass out on $i all head $grpo\n";
+ print "block out from 127.0.0.0/8 to any group $grpo\n";
+ print "block out from any to 127.0.0.0/8 group $grpo\n";
+ print "block out from any to $inet{$i}/32 group $grpo\n";
+ print "pass in on $i all head $grpi\n";
+ print "block in from 127.0.0.0/8 to any group $grpi\n";
+ print "block in from $inet{$i}/32 to any group $grpi\n";
foreach $j (keys %ifaces) {
if ($i ne $j && $j !~ /^lo/ && defined($net{$j})) {
- print "block in on $i from $net{$j} to any\n";
+ print "block in from $net{$j} to any group $grpi\n";
}
}
}
diff --git a/contrib/ipfilter/ml_ipl.c b/contrib/ipfilter/ml_ipl.c
index 9c3ec3ec5a6c..430cb9ec1b0f 100644
--- a/contrib/ipfilter/ml_ipl.c
+++ b/contrib/ipfilter/ml_ipl.c
@@ -1,5 +1,5 @@
/*
- * (C)opyright 1993,1994,1995 by Darren Reed.
+ * Copyright (C) 1993-1997 by Darren Reed.
*
* Redistribution and use in source and binary forms are permitted
* provided that this notice is preserved and due credit is given
diff --git a/contrib/ipfilter/mlf_ipl.c b/contrib/ipfilter/mlf_ipl.c
new file mode 100644
index 000000000000..3a8ee905620b
--- /dev/null
+++ b/contrib/ipfilter/mlf_ipl.c
@@ -0,0 +1,367 @@
+/*
+ * Copyright (C) 1993-1997 by Darren Reed.
+ *
+ * Redistribution and use in source and binary forms are permitted
+ * provided that this notice is preserved and due credit is given
+ * to the original author and the contributors.
+ */
+/*
+ * 29/12/94 Added code from Marc Huber <huber@fzi.de> to allow it to allocate
+ * its own major char number! Way cool patch!
+ */
+
+
+#include <sys/param.h>
+
+#if defined(__FreeBSD__) && (__FreeBSD__ > 1)
+# ifdef IPFILTER_LKM
+# include <osreldate.h>
+# define ACTUALLY_LKM_NOT_KERNEL
+# else
+# include <sys/osreldate.h>
+# endif
+#endif
+#include <sys/systm.h>
+#if defined(__FreeBSD_version) && (__FreeBSD_version >= 220000)
+# include <sys/conf.h>
+# include <sys/kernel.h>
+# ifdef DEVFS
+# include <sys/devfsext.h>
+# endif /*DEVFS*/
+#endif
+#include <sys/conf.h>
+#include <sys/file.h>
+#include <sys/stat.h>
+#include <sys/proc.h>
+#include <sys/uio.h>
+#include <sys/kernel.h>
+#include <sys/vnode.h>
+#include <sys/namei.h>
+#include <sys/malloc.h>
+#include <sys/mount.h>
+#include <sys/exec.h>
+#include <sys/mbuf.h>
+#if BSD >= 199506
+# include <sys/sysctl.h>
+#endif
+#if (__FreeBSD_version >= 199511)
+#include <net/if.h>
+#include <netinet/in_systm.h>
+#include <netinet/in.h>
+#include <netinet/ip.h>
+#include <net/route.h>
+#include <netinet/ip_var.h>
+#include <netinet/tcp.h>
+#include <netinet/tcpip.h>
+#endif
+#if (__FreeBSD__ > 1)
+# include <sys/sysent.h>
+#endif
+#include <sys/lkm.h>
+#include "netinet/ipl.h"
+#include "netinet/ip_compat.h"
+#include "netinet/ip_fil.h"
+#include "netinet/ip_state.h"
+#include "netinet/ip_nat.h"
+#include "netinet/ip_auth.h"
+#include "netinet/ip_frag.h"
+
+
+#if !defined(VOP_LEASE) && defined(LEASE_CHECK)
+#define VOP_LEASE LEASE_CHECK
+#endif
+
+#ifndef MIN
+#define MIN(a,b) (((a)<(b))?(a):(b))
+#endif
+
+extern int lkmenodev __P((void));
+
+static char *ipf_devfiles[] = { IPL_NAME, IPL_NAT, IPL_STATE, IPL_AUTH,
+ NULL };
+static int if_ipl_unload __P((struct lkm_table *, int));
+static int if_ipl_load __P((struct lkm_table *, int));
+static int if_ipl_remove __P((void));
+int xxxinit __P((struct lkm_table *, int, int));
+
+
+struct cdevsw ipldevsw =
+{
+ iplopen, /* open */
+ iplclose, /* close */
+ iplread, /* read */
+ (void *)nullop, /* write */
+ iplioctl, /* ioctl */
+ (void *)nullop, /* stop */
+ (void *)nullop, /* reset */
+ (void *)NULL, /* tty */
+ (void *)nullop, /* select */
+ (void *)nullop, /* mmap */
+ NULL /* strategy */
+};
+
+#ifdef SYSCTL_INT
+SYSCTL_NODE(_net_inet, OID_AUTO, ipf, CTLFLAG_RW, 0, "IPF");
+SYSCTL_INT(_net_inet_ipf, OID_AUTO, fr_flags, CTLFLAG_RW, &fr_flags, 0, "");
+SYSCTL_INT(_net_inet_ipf, OID_AUTO, fr_pass, CTLFLAG_RW, &fr_pass, 0, "");
+SYSCTL_INT(_net_inet_ipf, OID_AUTO, fr_active, CTLFLAG_RD, &fr_active, 0, "");
+SYSCTL_INT(_net_inet_ipf, OID_AUTO, fr_tcpidletimeout, CTLFLAG_RW,
+ &fr_tcpidletimeout, 0, "");
+SYSCTL_INT(_net_inet_ipf, OID_AUTO, fr_tcpclosewait, CTLFLAG_RW,
+ &fr_tcpclosewait, 0, "");
+SYSCTL_INT(_net_inet_ipf, OID_AUTO, fr_tcplastack, CTLFLAG_RW,
+ &fr_tcplastack, 0, "");
+SYSCTL_INT(_net_inet_ipf, OID_AUTO, fr_tcptimeout, CTLFLAG_RW,
+ &fr_tcptimeout, 0, "");
+SYSCTL_INT(_net_inet_ipf, OID_AUTO, fr_tcpclosed, CTLFLAG_RW,
+ &fr_tcpclosed, 0, "");
+SYSCTL_INT(_net_inet_ipf, OID_AUTO, fr_udptimeout, CTLFLAG_RW,
+ &fr_udptimeout, 0, "");
+SYSCTL_INT(_net_inet_ipf, OID_AUTO, fr_icmptimeout, CTLFLAG_RW,
+ &fr_icmptimeout, 0, "");
+SYSCTL_INT(_net_inet_ipf, OID_AUTO, fr_defnatage, CTLFLAG_RW,
+ &fr_defnatage, 0, "");
+SYSCTL_INT(_net_inet_ipf, OID_AUTO, fr_ipfrttl, CTLFLAG_RW,
+ &fr_ipfrttl, 0, "");
+SYSCTL_INT(_net_inet_ipf, OID_AUTO, ipl_unreach, CTLFLAG_RW,
+ &ipl_unreach, 0, "");
+SYSCTL_INT(_net_inet_ipf, OID_AUTO, ipl_inited, CTLFLAG_RD,
+ &ipl_inited, 0, "");
+SYSCTL_INT(_net_inet_ipf, OID_AUTO, fr_authsize, CTLFLAG_RD,
+ &fr_authsize, 0, "");
+SYSCTL_INT(_net_inet_ipf, OID_AUTO, fr_authused, CTLFLAG_RD,
+ &fr_authused, 0, "");
+SYSCTL_INT(_net_inet_ipf, OID_AUTO, fr_defaultauthage, CTLFLAG_RW,
+ &fr_defaultauthage, 0, "");
+#endif
+
+#if !defined(__FreeBSD_version) || (__FreeBSD_version < 220000)
+int ipl_major = 0;
+
+MOD_DEV(IPL_VERSION, LM_DT_CHAR, -1, &ipldevsw);
+
+extern struct cdevsw cdevsw[];
+extern int vd_unuseddev __P((void));
+extern int nchrdev;
+#else
+int ipl_major = CDEV_MAJOR;
+
+static struct cdevsw ipl_cdevsw = {
+ iplopen, iplclose, iplread, nowrite, /* 79 */
+ iplioctl, nostop, noreset, nodevtotty,
+ noselect, nommap, nostrategy, "ipl",
+ NULL, -1
+};
+#endif
+
+
+static int iplaction __P((struct lkm_table *, int));
+
+
+static int iplaction(lkmtp, cmd)
+struct lkm_table *lkmtp;
+int cmd;
+{
+#if !defined(__FreeBSD_version) || (__FreeBSD_version < 220000)
+ int i = ipl_major;
+ struct lkm_dev *args = lkmtp->private.lkm_dev;
+#endif
+ int err = 0;
+
+ switch (cmd)
+ {
+ case LKM_E_LOAD :
+ if (lkmexists(lkmtp))
+ return EEXIST;
+
+#if !defined(__FreeBSD_version) || (__FreeBSD_version < 220000)
+ for (i = 0; i < nchrdev; i++)
+ if (cdevsw[i].d_open == lkmenodev ||
+ cdevsw[i].d_open == iplopen)
+ break;
+ if (i == nchrdev) {
+ printf("IP Filter: No free cdevsw slots\n");
+ return ENODEV;
+ }
+
+ ipl_major = i;
+ args->lkm_offset = i; /* slot in cdevsw[] */
+#endif
+ printf("IP Filter: loaded into slot %d\n", ipl_major);
+ return if_ipl_load(lkmtp, cmd);
+ break;
+ case LKM_E_UNLOAD :
+ err = if_ipl_unload(lkmtp, cmd);
+ if (!err)
+ printf("IP Filter: unloaded from slot %d\n",
+ ipl_major);
+ return err;
+ case LKM_E_STAT :
+ break;
+ default:
+ err = EIO;
+ break;
+ }
+ return 0;
+}
+
+
+static int if_ipl_remove __P((void))
+{
+ char *name;
+ struct nameidata nd;
+ int error, i;
+
+ for (i = 0; (name = ipf_devfiles[i]); i++) {
+ NDINIT(&nd, DELETE, LOCKPARENT, UIO_SYSSPACE, name, curproc);
+ if ((error = namei(&nd)))
+ return (error);
+ VOP_LEASE(nd.ni_vp, curproc, curproc->p_ucred, LEASE_WRITE);
+ VOP_LOCK(nd.ni_vp);
+ VOP_LEASE(nd.ni_dvp, curproc, curproc->p_ucred, LEASE_WRITE);
+ (void) VOP_REMOVE(nd.ni_dvp, nd.ni_vp, &nd.ni_cnd);
+ }
+
+ return 0;
+}
+
+
+static int if_ipl_unload(lkmtp, cmd)
+struct lkm_table *lkmtp;
+int cmd;
+{
+ int error = 0;
+
+ error = ipldetach();
+ if (!error)
+ error = if_ipl_remove();
+ return error;
+}
+
+
+static int if_ipl_load(lkmtp, cmd)
+struct lkm_table *lkmtp;
+int cmd;
+{
+ struct nameidata nd;
+ struct vattr vattr;
+ int error = 0, fmode = S_IFCHR|0600, i;
+ char *name;
+
+ error = iplattach();
+ if (error)
+ return error;
+ (void) if_ipl_remove();
+
+ for (i = 0; (name = ipf_devfiles[i]); i++) {
+ NDINIT(&nd, CREATE, LOCKPARENT, UIO_SYSSPACE, name, curproc);
+ if ((error = namei(&nd)))
+ return error;
+ if (nd.ni_vp != NULL) {
+ VOP_ABORTOP(nd.ni_dvp, &nd.ni_cnd);
+ if (nd.ni_dvp == nd.ni_vp)
+ vrele(nd.ni_dvp);
+ else
+ vput(nd.ni_dvp);
+ vrele(nd.ni_vp);
+ return (EEXIST);
+ }
+ VATTR_NULL(&vattr);
+ vattr.va_type = VCHR;
+ vattr.va_mode = (fmode & 07777);
+ vattr.va_rdev = (ipl_major << 8) | i;
+ VOP_LEASE(nd.ni_dvp, curproc, curproc->p_ucred, LEASE_WRITE);
+ error = VOP_MKNOD(nd.ni_dvp, &nd.ni_vp, &nd.ni_cnd, &vattr);
+ if (error)
+ return error;
+ }
+ return 0;
+}
+
+
+#if defined(__FreeBSD_version) && (__FreeBSD_version < 220000)
+/*
+ * strlen isn't present in 2.1.* kernels.
+ */
+size_t strlen(string)
+char *string;
+{
+ register char *s;
+
+ for (s = string; *s; s++)
+ ;
+ return (size_t)(s - string);
+}
+
+
+int xxxinit(lkmtp, cmd, ver)
+struct lkm_table *lkmtp;
+int cmd, ver;
+{
+ DISPATCH(lkmtp, cmd, ver, iplaction, iplaction, iplaction);
+}
+#else
+# ifdef IPFILTER_LKM
+# include <sys/exec.h>
+
+MOD_DECL(if_ipl);
+
+
+static struct lkm_dev _module = {
+ LM_DEV,
+ LKM_VERSION,
+ IPL_VERSION,
+ CDEV_MAJOR,
+ LM_DT_CHAR,
+ { (void *)&ipl_cdevsw }
+};
+
+
+int if_ipl __P((struct lkm_table *, int, int));
+
+
+int if_ipl(lkmtp, cmd, ver)
+struct lkm_table *lkmtp;
+int cmd, ver;
+{
+ DISPATCH(lkmtp, cmd, ver, iplaction, iplaction, iplaction);
+}
+# else
+
+#ifdef DEVFS
+static void *ipf_devfs_token[IPL_LOGMAX + 1];
+#endif
+static ipl_devsw_installed = 0;
+
+static void ipl_drvinit __P((void *unused))
+{
+ dev_t dev;
+#ifdef DEVFS
+ void **tp = ipf_devfs_token;
+#endif
+
+ if (!ipl_devsw_installed ) {
+ dev = makedev(CDEV_MAJOR, 0);
+ cdevsw_add(&dev, &ipl_cdevsw, NULL);
+ ipl_devsw_installed = 1;
+
+#ifdef DEVFS
+ tp[IPL_LOGIPF] = devfs_add_devswf(&ipl_cdevsw, IPL_LOGIPF,
+ DV_CHR, 0, 0, 0600,
+ "ipf", IPL_LOGIPF);
+ tp[IPL_LOGNAT] = devfs_add_devswf(&ipl_cdevsw, IPL_LOGNAT,
+ DV_CHR, 0, 0, 0600,
+ "ipnat", IPL_LOGNAT);
+ tp[IPL_LOGSTATE] = devfs_add_devswf(&ipl_cdevsw, IPL_LOGSTATE,
+ DV_CHR, 0, 0, 0600,
+ "ipstate", IPL_LOGSTATE);
+ tp[IPL_LOGAUTH] = devfs_add_devswf(&ipl_cdevsw, IPL_LOGAUTH,
+ DV_CHR, 0, 0, 0600,
+ "ipstate", IPL_LOGAUTH);
+#endif
+ }
+}
+
+SYSINIT(ipldev,SI_SUB_DRIVERS,SI_ORDER_MIDDLE+CDEV_MAJOR,ipl_drvinit,NULL)
+# endif /* IPFILTER_LKM */
+#endif /* _FreeBSD_version */
diff --git a/contrib/ipfilter/mli_ipl.c b/contrib/ipfilter/mli_ipl.c
new file mode 100644
index 000000000000..e4490c38bf7f
--- /dev/null
+++ b/contrib/ipfilter/mli_ipl.c
@@ -0,0 +1,580 @@
+/*
+ * Copyright (C) 1993-1997 by Darren Reed.
+ * (C)opyright 1997 by Marc Boucher.
+ *
+ * Redistribution and use in source and binary forms are permitted
+ * provided that this notice is preserved and due credit is given
+ * to the original authors and the contributors.
+ */
+
+/* TODO: (MARCXXX)
+ - ipl_init failure -> open ENODEV or whatever
+ - prevent multiple LKM loads
+ - surround access to ifnet structures by IFNET_LOCK()/IFNET_UNLOCK() ?
+ - m != m1 problem
+*/
+
+#include <sys/types.h>
+#include <sys/conf.h>
+#ifdef IPFILTER_LKM
+#include <sys/mload.h>
+#endif
+#include <sys/systm.h>
+#include <sys/errno.h>
+#include <net/if.h>
+#include <net/route.h>
+#include <netinet/in.h>
+#ifdef IFF_DRVRLOCK /* IRIX6 */
+#include <sys/hashing.h>
+#include <netinet/in_var.h>
+#endif
+#include <sys/mbuf.h>
+#include <netinet/in_systm.h>
+#include <netinet/ip.h>
+#include <netinet/ip_var.h>
+#include <netinet/tcp.h>
+#include <netinet/udp.h>
+#include <netinet/tcpip.h>
+#include <netinet/ip_icmp.h>
+#include <netinet/ipfilter.h>
+#include "ipl.h"
+#include "ip_compat.h"
+#include "ip_fil.h"
+#include "ip_nat.h"
+
+/*#define IPFDEBUG 1*/
+
+unsigned IPL_EXTERN(devflag) = D_MP;
+#ifdef IPFILTER_LKM
+char *IPL_EXTERN(mversion) = M_VERSION;
+#endif
+
+kmutex_t ipl_mutex, ipf_mutex, ipfs_mutex;
+kmutex_t ipf_frag, ipf_state, ipf_nat, ipf_natfrag, ipf_auth;
+
+int (*fr_checkp) __P((struct ip *, int, void *, int, mb_t **));
+
+#ifdef IPFILTER_LKM
+static int *ipff_addr = 0;
+static int ipff_value;
+static __psunsigned_t *ipfk_addr = 0;
+static __psunsigned_t ipfk_code[4];
+#endif
+
+typedef struct nif {
+ struct nif *nf_next;
+ struct ifnet *nf_ifp;
+ int (*nf_output)(struct ifnet *, struct mbuf *, struct sockaddr *);
+ char nf_name[IFNAMSIZ];
+ int nf_unit;
+} nif_t;
+
+static nif_t *nif_head = 0;
+static int nif_interfaces = 0;
+extern int in_interfaces;
+
+extern ipnat_t *nat_list;
+
+static int
+ipl_if_output(struct ifnet *ifp, struct mbuf *m, struct sockaddr *dst)
+{
+ nif_t *nif;
+
+ MUTEX_ENTER(&ipfs_mutex); /* sets interrupt priority level to splhi */
+ for (nif = nif_head; nif; nif = nif->nf_next)
+ if (nif->nf_ifp == ifp)
+ break;
+
+ MUTEX_EXIT(&ipfs_mutex);
+ if (!nif) {
+ printf("IP Filter: ipl_if_output intf %x NOT FOUND\n", ifp);
+ return ENETDOWN;
+ }
+
+#if IPFDEBUG >= 4
+ static unsigned int cnt = 0;
+ if ((++cnt % 200) == 0)
+ printf("IP Filter: ipl_if_output(ifp=0x%lx, m=0x%lx, dst=0x%lx), m_type=%d m_flags=0x%lx m_off=0x%lx\n", ifp, m, dst, m->m_type, (unsigned long)(m->m_flags), m->m_off);
+#endif
+ if (fr_checkp) {
+ struct mbuf *m1 = m;
+ struct ip *ip;
+ int hlen;
+
+ switch(m->m_type) {
+ case MT_DATA:
+ if (m->m_flags & M_BCAST) {
+#if IPFDEBUG >= 2
+ printf("IP Filter: ipl_if_output: passing M_BCAST\n");
+#endif
+ break;
+ }
+ /* FALLTHROUGH */
+ case MT_HEADER:
+#if IPFDEBUG >= 4
+ if (!MBUF_IS_CLUSTER(m) && ((m->m_off < MMINOFF) || (m->m_off > MMAXOFF))) {
+ printf("IP Filter: ipl_if_output: bad m_off m_type=%d m_flags=0x%lx m_off=0x%lx\n", m->m_type, (unsigned long)(m->m_flags), m->m_off);
+ return (*nif->nf_output)(ifp, m, dst);
+ }
+#endif
+ if (m->m_len < sizeof(char)) {
+ printf("IP Filter: ipl_if_output: mbuf block too small (m_len=%d) for IP vers+hlen, m_type=%d m_flags=0x%lx\n", m->m_len, m->m_type, (unsigned long)(m->m_flags));
+ return (*nif->nf_output)(ifp, m, dst);
+ }
+ ip = mtod(m, struct ip *);
+ if (ip->ip_v != IPVERSION) {
+#if IPFDEBUG >= 4
+ printf("IP Filter: ipl_if_output: bad ip_v m_type=%d m_flags=0x%lx m_off=0x%lx\n", m->m_type, (unsigned long)(m->m_flags), m->m_off);
+#endif
+ return (*nif->nf_output)(ifp, m, dst);
+ }
+
+ hlen = ip->ip_hl << 2;
+ if ((*fr_checkp)(ip, hlen, ifp, 1, &m1))
+ return EHOSTUNREACH;
+
+ if (!m1)
+ return 0;
+
+ m = m1;
+ break;
+
+ default:
+ printf("IP Filter: ipl_if_output: bad m_type=%d m_flags=0x%lxm_off=0x%lx\n", m->m_type, (unsigned long)(m->m_flags), m->m_off);
+ break;
+ }
+ }
+ return (*nif->nf_output)(ifp, m, dst);
+}
+
+int
+IPL_EXTERN(_kernel)(struct ifnet *rcvif, struct mbuf *m)
+{
+#if IPFDEBUG >= 4
+ static unsigned int cnt = 0;
+ if ((++cnt % 200) == 0)
+ printf("IP Filter: ipl_ipfilter_kernel(rcvif=0x%lx, m=0x%lx\n", rcvif, m);
+#endif
+
+ /*
+ * Check if we want to allow this packet to be processed.
+ * Consider it to be bad if not.
+ */
+ if (fr_checkp) {
+ struct mbuf *m1 = m;
+ struct ip *ip;
+ int hlen;
+
+ if ((m->m_type != MT_DATA) && (m->m_type != MT_HEADER)) {
+ printf("IP Filter: ipl_ipfilter_kernel: bad m_type=%d m_flags=0x%lx m_off=0x%lx\n", m->m_type, (unsigned long)(m->m_flags), m->m_off);
+ return IPF_ACCEPTIT;
+ }
+
+#if IPFDEBUG >= 4
+ if (!MBUF_IS_CLUSTER(m) && ((m->m_off < MMINOFF) || (m->m_off > MMAXOFF))) {
+ printf("IP Filter: ipl_ipfilter_kernel: bad m_off m_type=%d m_flags=0x%lx m_off=0x%lx\n", m->m_type, (unsigned long)(m->m_flags), m->m_off);
+ return IPF_ACCEPTIT;
+ }
+#endif
+ if (m->m_len < sizeof(char)) {
+ printf("IP Filter: ipl_ipfilter_kernel: mbuf block too small (m_len=%d) for IP vers+hlen, m_type=%d m_flags=0x%lx\n", m->m_len, m->m_type, (unsigned long)(m->m_flags));
+ return IPF_ACCEPTIT;
+ }
+ ip = mtod(m, struct ip *);
+ if (ip->ip_v != IPVERSION) {
+ printf("IP Filter: ipl_ipfilter_kernel: bad ip_v\n");
+ m_freem(m);
+ return IPF_DROPIT;
+ }
+
+ hlen = ip->ip_hl << 2;
+ if ((*fr_checkp)(ip, hlen, rcvif, 0, &m1) || !m1)
+ return IPF_DROPIT;
+ if (m != m1)
+ printf("IP Filter: ipl_ipfilter_kernel: m != m1\n");
+ }
+
+ return IPF_ACCEPTIT;
+}
+
+static int
+ipfilterattach(void)
+{
+#ifdef IPFILTER_LKM
+ __psunsigned_t *addr_ff, *addr_fk;
+
+ st_findaddr("ipfilterflag", &addr_ff);
+#if IPFDEBUG >= 4
+ printf("IP Filter: st_findaddr ipfilterflag=0x%lx\n", addr_ff);
+#endif
+ if (!addr_ff)
+ return ESRCH;
+
+ st_findaddr("ipfilter_kernel", &addr_fk);
+#if IPFDEBUG >= 4
+ printf("IP Filter: st_findaddr ipfilter_kernel=0x%lx\n", addr_fk);
+#endif
+ if (!addr_fk)
+ return ESRCH;
+
+ MUTEX_ENTER(&ipfs_mutex); /* sets interrupt priority level to splhi */
+
+ ipff_addr = (int *)addr_ff;
+
+ ipff_value = *ipff_addr;
+ *ipff_addr = 0;
+
+
+ ipfk_addr = addr_fk;
+
+ bcopy(ipfk_addr, ipfk_code,
+ sizeof(ipfk_code));
+
+ /* write a "li t4, ipl_ipfilter_kernel" instruction */
+ ipfk_addr[0] = 0x3c0c0000 |
+ (((__psunsigned_t)IPL_EXTERN(_kernel) >> 16) & 0xffff);
+ ipfk_addr[1] = 0x358c0000 |
+ ((__psunsigned_t)IPL_EXTERN(_kernel) & 0xffff);
+ /* write a "jr t4" instruction" */
+ ipfk_addr[2] = 0x01800008;
+
+ /* write a "nop" instruction */
+ ipfk_addr[3] = 0;
+
+ icache_inval(ipfk_addr, sizeof(ipfk_code));
+
+ *ipff_addr = 1; /* enable ipfilter_kernel */
+
+ MUTEX_EXIT(&ipfs_mutex);
+#else
+ extern int ipfilterflag;
+
+ ipfilterflag = 1;
+#endif
+
+ return 0;
+}
+
+/*
+ * attach the packet filter to each non-loopback interface that is running
+ */
+static void
+nifattach()
+{
+ nif_t *nif, *qf2;
+ struct ifnet *ifp;
+ struct frentry *f;
+ ipnat_t *np;
+
+ MUTEX_ENTER(&ipfs_mutex); /* sets interrupt priority level to splhi */
+
+ for (ifp = ifnet; ifp; ifp = ifp->if_next) {
+ if ((!(ifp->if_flags & IFF_RUNNING)) ||
+ (ifp->if_flags & IFF_LOOPBACK))
+ continue;
+
+ /*
+ * Look for entry already setup for this device
+ */
+ for (nif = nif_head; nif; nif = nif->nf_next)
+ if (nif->nf_ifp == ifp)
+ break;
+ if (nif)
+ continue;
+
+ if (ifp->if_output == ipl_if_output) {
+ printf("IP Filter: ERROR INTF 0x%lx STILL ATTACHED\n",
+ ifp);
+ continue;
+ }
+#if IPFDEBUG >= 4
+ printf("IP Filter: nifattach nif %x opt %x\n",
+ ifp, ifp->if_output);
+#endif
+ KMALLOC(nif, nif_t *, sizeof(*nif));
+ if (!nif) {
+ printf("IP Filter: malloc(%d) for nif_t failed\n",
+ sizeof(nif_t));
+ continue;
+ }
+
+ nif->nf_ifp = ifp;
+ strncpy(nif->nf_name, ifp->if_name, sizeof(nif->nf_name));
+ nif->nf_name[sizeof(nif->nf_name) - 1] = '\0';
+ nif->nf_unit = ifp->if_unit;
+
+ nif->nf_next = nif_head;
+ nif_head = nif;
+
+ /*
+ * Activate any rules directly associated with this interface
+ */
+ MUTEX_ENTER(&ipf_mutex);
+ for (f = ipfilter[0][0]; f; f = f->fr_next) {
+ if ((f->fr_ifa == (struct ifnet *)-1)) {
+ if (f->fr_ifname[0] &&
+ (GETUNIT(f->fr_ifname) == ifp))
+ f->fr_ifa = ifp;
+ }
+ }
+ for (f = ipfilter[1][0]; f; f = f->fr_next) {
+ if ((f->fr_ifa == (struct ifnet *)-1)) {
+ if (f->fr_ifname[0] &&
+ (GETUNIT(f->fr_ifname) == ifp))
+ f->fr_ifa = ifp;
+ }
+ }
+ MUTEX_EXIT(&ipf_mutex);
+ MUTEX_ENTER(&ipf_nat);
+ for (np = nat_list; np; np = np->in_next) {
+ if ((np->in_ifp == (void *)-1)) {
+ if (np->in_ifname[0] &&
+ (GETUNIT(np->in_ifname) == ifp))
+ np->in_ifp = (void *)ifp;
+ }
+ }
+ MUTEX_EXIT(&ipf_nat);
+
+ nif->nf_output = ifp->if_output;
+ ifp->if_output = ipl_if_output;
+
+#if IPFDEBUG >= 4
+ printf("IP Filter: nifattach: ifp(%lx)->if_output FROM %lx TO %lx\n",
+ ifp, nif->nf_output, ifp->if_output);
+#endif
+
+ printf("IP Filter: attach to [%s,%d]\n",
+ nif->nf_name, ifp->if_unit);
+ }
+ if (!nif_head)
+ printf("IP Filter: not attached to any interfaces\n");
+
+ nif_interfaces = in_interfaces;
+
+ MUTEX_EXIT(&ipfs_mutex);
+
+ return;
+}
+
+/*
+ * look for bad consistancies between the list of interfaces the filter knows
+ * about and those which are currently configured.
+ */
+int
+ipfsync(void)
+{
+ register struct frentry *f;
+ register ipnat_t *np;
+ register nif_t *nif, **qp;
+ register struct ifnet *ifp;
+
+ MUTEX_ENTER(&ipfs_mutex); /* sets interrupt priority level to splhi */
+ for (qp = &nif_head; (nif = *qp); ) {
+ for (ifp = ifnet; ifp; ifp = ifp->if_next)
+ if ((nif->nf_ifp == ifp) &&
+ (nif->nf_unit == ifp->if_unit) &&
+ !strcmp(nif->nf_name, ifp->if_name)) {
+ break;
+ }
+ if (ifp) {
+ qp = &nif->nf_next;
+ continue;
+ }
+ printf("IP Filter: detaching [%s]\n", nif->nf_name);
+ *qp = nif->nf_next;
+
+ /*
+ * Disable any rules directly associated with this interface
+ */
+ MUTEX_ENTER(&ipf_mutex);
+ for (f = ipfilter[0][0]; f; f = f->fr_next)
+ if (f->fr_ifa == (void *)nif->nf_ifp)
+ f->fr_ifa = (struct ifnet *)-1;
+ for (f = ipfilter[1][0]; f; f = f->fr_next)
+ if (f->fr_ifa == (void *)nif->nf_ifp)
+ f->fr_ifa = (struct ifnet *)-1;
+ MUTEX_EXIT(&ipf_mutex);
+ MUTEX_ENTER(&ipf_nat);
+ for (np = nat_list; np; np = np->in_next)
+ if (np->in_ifp == (void *)nif->nf_ifp)
+ np->in_ifp =(struct ifnet *)-1;
+ MUTEX_EXIT(&ipf_nat);
+
+ KFREE(nif);
+ nif = *qp;
+ }
+ MUTEX_EXIT(&ipfs_mutex);
+
+ nifattach();
+
+ return 0;
+}
+
+
+/*
+ * unhook the IP filter from all defined interfaces with IP addresses
+ */
+static void
+nifdetach()
+{
+ nif_t *nif, *qf2, **qp;
+ struct ifnet *ifp;
+
+ MUTEX_ENTER(&ipfs_mutex); /* sets interrupt priority level to splhi */
+ /*
+ * Make two passes, first get rid of all the unknown devices, next
+ * unlink known devices.
+ */
+ for (qp = &nif_head; (nif = *qp); ) {
+ for (ifp = ifnet; ifp; ifp = ifp->if_next)
+ if (nif->nf_ifp == ifp)
+ break;
+ if (ifp) {
+ qp = &nif->nf_next;
+ continue;
+ }
+ printf("IP Filter: removing [%s]\n", nif->nf_name);
+ *qp = nif->nf_next;
+ KFREE(nif);
+ }
+
+ while ((nif = nif_head)) {
+ nif_head = nif->nf_next;
+ for (ifp = ifnet; ifp; ifp = ifp->if_next)
+ if (nif->nf_ifp == ifp)
+ break;
+ if (ifp) {
+ printf("IP Filter: detaching [%s,%d]\n",
+ nif->nf_name, ifp->if_unit);
+
+#if IPFDEBUG >= 4
+ printf("IP Filter: nifdetach: ifp(%lx)->if_output FROM %lx TO %lx\n",
+ ifp, ifp->if_output, nif->nf_output);
+#endif
+ ifp->if_output = nif->nf_output;
+ }
+ KFREE(nif);
+ }
+ MUTEX_EXIT(&ipfs_mutex);
+
+ return;
+}
+
+
+static void
+ipfilterdetach(void)
+{
+#ifdef IPFILTER_LKM
+ MUTEX_ENTER(&ipfs_mutex); /* sets interrupt priority level to splhi */
+
+ if (ipff_addr) {
+ *ipff_addr = 0;
+
+ if (ipfk_addr)
+ bcopy(ipfk_code, ipfk_addr, sizeof(ipfk_code));
+
+ *ipff_addr = ipff_value;
+ }
+
+ MUTEX_EXIT(&ipfs_mutex);
+#else
+ extern int ipfilterflag;
+
+ ipfilterflag = 0;
+#endif
+}
+
+/* called by ipldetach() */
+void
+ipfilter_sgi_detach(void)
+{
+ nifdetach();
+
+ ipfilterdetach();
+}
+
+/* called by iplattach() */
+int
+ipfilter_sgi_attach(void)
+{
+ int error;
+
+ nif_interfaces = 0;
+
+ error = ipfilterattach();
+
+ if (!error)
+ nifattach();
+
+ return error;
+}
+
+/* this function is called from ipfr_slowtimer at 500ms intervals to
+ keep our interface list in sync */
+void
+ipfilter_sgi_intfsync(void)
+{
+ MUTEX_ENTER(&ipfs_mutex);
+ if (nif_interfaces != in_interfaces) {
+ /* if the number of interfaces has changed, resync */
+ MUTEX_EXIT(&ipfs_mutex);
+ ipfsync();
+ } else
+ MUTEX_EXIT(&ipfs_mutex);
+}
+
+#ifdef IPFILTER_LKM
+/* this routine should be treated as an interrupt routine and should
+ not call any routines that would cause it to sleep, such as: biowait(),
+ sleep(), psema() or delay().
+*/
+int
+IPL_EXTERN(unload)(void)
+{
+ int error = 0;
+
+ error = ipldetach();
+
+ LOCK_DEALLOC(ipl_mutex.l);
+ LOCK_DEALLOC(ipf_auth.l);
+ LOCK_DEALLOC(ipf_natfrag.l);
+ LOCK_DEALLOC(ipf_nat.l);
+ LOCK_DEALLOC(ipf_state.l);
+ LOCK_DEALLOC(ipf_frag.l);
+ LOCK_DEALLOC(ipf_mutex.l);
+ LOCK_DEALLOC(ipfs_mutex.l);
+
+ return error;
+}
+#endif
+
+void
+IPL_EXTERN(init)(void)
+{
+#ifdef IPFILTER_LKM
+ int error;
+#endif
+
+ ipfs_mutex.l = LOCK_ALLOC((uchar_t)-1, IPF_LOCK_PL, (lkinfo_t *)-1, KM_NOSLEEP);
+ ipf_mutex.l = LOCK_ALLOC((uchar_t)-1, IPF_LOCK_PL, (lkinfo_t *)-1, KM_NOSLEEP);
+ ipf_frag.l = LOCK_ALLOC((uchar_t)-1, IPF_LOCK_PL, (lkinfo_t *)-1, KM_NOSLEEP);
+ ipf_state.l = LOCK_ALLOC((uchar_t)-1, IPF_LOCK_PL, (lkinfo_t *)-1, KM_NOSLEEP);
+ ipf_nat.l = LOCK_ALLOC((uchar_t)-1, IPF_LOCK_PL, (lkinfo_t *)-1, KM_NOSLEEP);
+ ipf_natfrag.l = LOCK_ALLOC((uchar_t)-1, IPF_LOCK_PL, (lkinfo_t *)-1, KM_NOSLEEP);
+ ipf_auth.l = LOCK_ALLOC((uchar_t)-1, IPF_LOCK_PL, (lkinfo_t *)-1, KM_NOSLEEP);
+ ipl_mutex.l = LOCK_ALLOC((uchar_t)-1, IPF_LOCK_PL, (lkinfo_t *)-1, KM_NOSLEEP);
+
+ if (!ipfs_mutex.l || !ipf_mutex.l || !ipf_frag.l || !ipf_state.l ||
+ !ipf_nat.l || !ipf_natfrag.l || !ipf_auth.l || !ipl_mutex.l)
+ panic("IP Filter: LOCK_ALLOC failed");
+
+#ifdef IPFILTER_LKM
+ error = iplattach();
+ if (error) {
+ IPL_EXTERN(unload)();
+ }
+#endif
+
+ return;
+}
+
diff --git a/contrib/ipfilter/mln_ipl.c b/contrib/ipfilter/mln_ipl.c
index fe035da0cbb7..3d70831ff9b4 100644
--- a/contrib/ipfilter/mln_ipl.c
+++ b/contrib/ipfilter/mln_ipl.c
@@ -1,5 +1,5 @@
/*
- * (C)opyright 1993,1994,1995 by Darren Reed.
+ * Copyright (C) 1993-1997 by Darren Reed.
*
* Redistribution and use in source and binary forms are permitted
* provided that this notice is preserved and due credit is given
@@ -13,22 +13,16 @@
#include <sys/param.h>
-#if defined(__FreeBSD__) && (__FreeBSD__ > 1)
-# ifdef IPFILTER_LKM
-# include <osreldate.h>
-# define ACTUALLY_LKM_NOT_KERNEL
-# else
-# include <sys/osreldate.h>
-# endif
+/*
+ * Post NetBSD 1.2 has the PFIL interface for packet filters. This turns
+ * on those hooks. We don't need any special mods with this!
+ */
+#if (defined(NetBSD) && (NetBSD > 199609) && (NetBSD <= 1991011)) || \
+ (defined(NetBSD1_2) && NetBSD1_2 > 1)
+# define NETBSD_PF
#endif
+
#include <sys/systm.h>
-#if defined(__FreeBSD_version) && (__FreeBSD_version >= 220000)
-# include <sys/conf.h>
-# include <sys/kernel.h>
-# ifdef DEVFS
-# include <sys/devfsext.h>
-# endif /*DEVFS*/
-#endif
#include <sys/conf.h>
#include <sys/file.h>
#include <sys/stat.h>
@@ -41,10 +35,6 @@
#include <sys/mount.h>
#include <sys/exec.h>
#include <sys/mbuf.h>
-#if BSD >= 199506
-# include <sys/sysctl.h>
-#endif
-#if (__FreeBSD_version >= 199511)
#include <net/if.h>
#include <netinet/in_systm.h>
#include <netinet/in.h>
@@ -53,20 +43,11 @@
#include <netinet/ip_var.h>
#include <netinet/tcp.h>
#include <netinet/tcpip.h>
-#endif
-#if (__FreeBSD__ > 1)
-# include <sys/sysent.h>
-#endif
#include <sys/lkm.h>
-#include "netinet/ipl.h"
-#include "netinet/ip_compat.h"
-#include "netinet/ip_fil.h"
+#include "ipl.h"
+#include "ip_compat.h"
+#include "ip_fil.h"
-#ifndef IPL_NAME
-#define IPL_NAME "/dev/ipl"
-#endif
-#define IPL_NAT "/dev/ipnat"
-#define IPL_STATE "/dev/ipstate"
#if !defined(VOP_LEASE) && defined(LEASE_CHECK)
#define VOP_LEASE LEASE_CHECK
@@ -76,15 +57,38 @@
#define MIN(a,b) (((a)<(b))?(a):(b))
#endif
-extern int lkmenodev __P((void));
+extern int lkmenodev __P((void));
+#if NetBSD >= 199706
+int if_ipl_lkmentry __P((struct lkm_table *, int, int));
+#else
+int xxxinit __P((struct lkm_table *, int, int));
+#endif
static int ipl_unload __P((void));
static int ipl_load __P((void));
static int ipl_remove __P((void));
-int xxxinit __P((struct lkm_table *, int, int));
+static int iplaction __P((struct lkm_table *, int));
+static char *ipf_devfiles[] = { IPL_NAME, IPL_NAT, IPL_STATE, IPL_AUTH,
+ NULL };
+#if (defined(NetBSD1_0) && (NetBSD1_0 > 1)) || \
+ (defined(NetBSD) && (NetBSD <= 1991011) && (NetBSD >= 199511))
+struct cdevsw ipldevsw =
+{
+ iplopen, /* open */
+ iplclose, /* close */
+ iplread, /* read */
+ 0, /* write */
+ iplioctl, /* ioctl */
+ 0, /* stop */
+ 0, /* tty */
+ 0, /* select */
+ 0, /* mmap */
+ NULL /* strategy */
+};
+#else
struct cdevsw ipldevsw =
{
iplopen, /* open */
@@ -99,46 +103,33 @@ struct cdevsw ipldevsw =
(void *)nullop, /* mmap */
NULL /* strategy */
};
-
-#ifdef SYSCTL_INT
-SYSCTL_NODE(_net_inet, OID_AUTO, ipf, CTLFLAG_RW, 0, "IPF");
-SYSCTL_INT(_net_inet_ipf, OID_AUTO, fr_flags, CTLFLAG_RW, &fr_flags, 0, "");
-SYSCTL_INT(_net_inet_ipf, OID_AUTO, fr_pass, CTLFLAG_RW, &fr_pass, 0, "");
-SYSCTL_INT(_net_inet_ipf, OID_AUTO, fr_active, CTLFLAG_RD, &fr_active, 0, "");
-SYSCTL_INT(_net_inet_ipf, OID_AUTO, ipl_unreach, CTLFLAG_RW,
- &ipl_unreach, 0, "");
-SYSCTL_INT(_net_inet_ipf, OID_AUTO, ipl_inited, CTLFLAG_RD,
- &ipl_inited, 0, "");
#endif
-
-#if !defined(__FreeBSD_version) || (__FreeBSD_version < 220000)
int ipl_major = 0;
MOD_DEV(IPL_VERSION, LM_DT_CHAR, -1, &ipldevsw);
-extern struct cdevsw cdevsw[];
extern int vd_unuseddev __P((void));
+extern struct cdevsw cdevsw[];
extern int nchrdev;
-#else
-int ipl_major = CDEV_MAJOR;
-
-static struct cdevsw ipl_cdevsw = {
- iplopen, iplclose, iplread, nowrite, /* 79 */
- iplioctl, nostop, noreset, nodevtotty,
- noselect, nommap, nostrategy, "ipl",
- NULL, -1
-};
-#endif
-static int iplaction __P((struct lkm_table *, int));
+#if NetBSD >= 199706
+int if_ipl_lkmentry(lkmtp, cmd, ver)
+#else
+int xxxinit(lkmtp, cmd, ver)
+#endif
+struct lkm_table *lkmtp;
+int cmd, ver;
+{
+ DISPATCH(lkmtp, cmd, ver, iplaction, iplaction, iplaction);
+}
static int iplaction(lkmtp, cmd)
struct lkm_table *lkmtp;
int cmd;
{
- int i = ipl_major;
+ int i;
struct lkm_dev *args = lkmtp->private.lkm_dev;
int err = 0;
@@ -148,9 +139,8 @@ int cmd;
if (lkmexists(lkmtp))
return EEXIST;
-#if !defined(__FreeBSD_version) || (__FreeBSD_version < 220000)
for (i = 0; i < nchrdev; i++)
- if (cdevsw[i].d_open == lkmenodev ||
+ if (cdevsw[i].d_open == (dev_type_open((*)))lkmenodev ||
cdevsw[i].d_open == iplopen)
break;
if (i == nchrdev) {
@@ -160,51 +150,39 @@ int cmd;
ipl_major = i;
args->lkm_offset = i; /* slot in cdevsw[] */
-#endif
printf("IP Filter: loaded into slot %d\n", ipl_major);
return ipl_load();
- break;
case LKM_E_UNLOAD :
- printf("IP Filter: unloaded from slot %d\n", ipl_major);
- return ipl_unload();
+ err = ipl_unload();
+ if (!err)
+ printf("IP Filter: unloaded from slot %d\n",
+ ipl_major);
+ break;
case LKM_E_STAT :
break;
default:
err = EIO;
break;
}
- return 0;
+ return err;
}
-static int ipl_remove __P((void))
+static int ipl_remove()
{
+ char *name;
struct nameidata nd;
- int error;
-
- NDINIT(&nd, DELETE, LOCKPARENT, UIO_SYSSPACE, IPL_NAME, curproc);
- if ((error = namei(&nd)))
- return (error);
- VOP_LEASE(nd.ni_vp, curproc, curproc->p_ucred, LEASE_WRITE);
- VOP_LOCK(nd.ni_vp);
- VOP_LEASE(nd.ni_dvp, curproc, curproc->p_ucred, LEASE_WRITE);
- (void) VOP_REMOVE(nd.ni_dvp, nd.ni_vp, &nd.ni_cnd);
-
- NDINIT(&nd, DELETE, LOCKPARENT, UIO_SYSSPACE, IPL_NAT, curproc);
- if ((error = namei(&nd)))
- return (error);
- VOP_LEASE(nd.ni_vp, curproc, curproc->p_ucred, LEASE_WRITE);
- VOP_LOCK(nd.ni_vp);
- VOP_LEASE(nd.ni_dvp, curproc, curproc->p_ucred, LEASE_WRITE);
- (void) VOP_REMOVE(nd.ni_dvp, nd.ni_vp, &nd.ni_cnd);
-
- NDINIT(&nd, DELETE, LOCKPARENT, UIO_SYSSPACE, IPL_STATE, curproc);
- if ((error = namei(&nd)))
- return (error);
- VOP_LEASE(nd.ni_vp, curproc, curproc->p_ucred, LEASE_WRITE);
- VOP_LOCK(nd.ni_vp);
- VOP_LEASE(nd.ni_dvp, curproc, curproc->p_ucred, LEASE_WRITE);
- (void) VOP_REMOVE(nd.ni_dvp, nd.ni_vp, &nd.ni_cnd);
+ int error, i;
+
+ for (i = 0; (name = ipf_devfiles[i]); i++) {
+ NDINIT(&nd, DELETE, LOCKPARENT, UIO_SYSSPACE, name, curproc);
+ if ((error = namei(&nd)))
+ return (error);
+ VOP_LEASE(nd.ni_vp, curproc, curproc->p_ucred, LEASE_WRITE);
+ VOP_LOCK(nd.ni_vp);
+ VOP_LEASE(nd.ni_dvp, curproc, curproc->p_ucred, LEASE_WRITE);
+ (void) VOP_REMOVE(nd.ni_dvp, nd.ni_vp, &nd.ni_cnd);
+ }
return 0;
}
@@ -213,7 +191,12 @@ static int ipl_unload()
{
int error = 0;
+ /*
+ * Unloading - remove the filter rule check from the IP
+ * input/output stream.
+ */
error =