summaryrefslogtreecommitdiffstats
path: root/sbin/ipfw
diff options
context:
space:
mode:
authorphk <phk@FreeBSD.org>1996-02-24 13:39:46 +0000
committerphk <phk@FreeBSD.org>1996-02-24 13:39:46 +0000
commitbd3794521a93fc0c1e53c786e393c55fdf0f4868 (patch)
tree9c6edb8b7b4a56a9212cfc1bdb730581fbc2a30d /sbin/ipfw
parent45a7f29691072258573e111c1034432e37e944f2 (diff)
downloadFreeBSD-src-bd3794521a93fc0c1e53c786e393c55fdf0f4868.zip
FreeBSD-src-bd3794521a93fc0c1e53c786e393c55fdf0f4868.tar.gz
Update to match kernel code.
Diffstat (limited to 'sbin/ipfw')
-rw-r--r--sbin/ipfw/Makefile11
-rw-r--r--sbin/ipfw/ipfw.8223
-rw-r--r--sbin/ipfw/ipfw.c118
3 files changed, 252 insertions, 100 deletions
diff --git a/sbin/ipfw/Makefile b/sbin/ipfw/Makefile
index fd1f05b..3effc23 100644
--- a/sbin/ipfw/Makefile
+++ b/sbin/ipfw/Makefile
@@ -1,16 +1,5 @@
PROG= ipfw
-DPADD= ${LIBKVM}
-LDADD= -lkvm
MAN8= ipfw.8
-test: ipfw
- ./ipfw add reject tcp from any to any
- ./ipfw add 11 reject tcp from 1.2.3.4 to 5.6.7.8 established
- ./ipfw add 11 reject tcp from 1.2.3.4 to 5.6.7.8/24 in
- ./ipfw add 11 reject tcp from 1.2.3.4 to 5.6.7.8 in out
- ./ipfw add 11 reject tcp from 1.2.3.4 to 5.6.7.8 frag out
- ./ipfw add 11 reject tcp from 1.2.3.4 to 5.6.7.8 tcpf p,f,!a ipopt !ts
- ./ipfw add 12 count log udp from 1.2.3.4 to 5.6.7.8 123-125,234,245
-
.include <bsd.prog.mk>
diff --git a/sbin/ipfw/ipfw.8 b/sbin/ipfw/ipfw.8
index 3dc78ec..bbf0e4e 100644
--- a/sbin/ipfw/ipfw.8
+++ b/sbin/ipfw/ipfw.8
@@ -1,25 +1,206 @@
-.Dd November 16, 1994
+.Dd February 24, 1996
.Dt IPFW 8 SMM
.Os FreeBSD
.Sh NAME
.Nm ipfw
-.Nd controlling utility for IP firewall / IP accounting facilities.
+.Nd controlling utility for IP firewall
.Sh SYNOPSIS
-.Nm
+.Nm ipfw
+.Ar file
+.Nm ipfw
+flush
+.Nm ipfw
+zero
+.Nm ipfw
+delete
+.Ar number
+.Nm ipfw
.Oo
-.Fl n
+.Fl aN
.Oc
-.Ar entry_action chain_entry_pattern
+list
.Nm ipfw
+add
.Oo
-.Fl ans
+.Ar number
+.Oc
+.Ar action
+.Oo
+log
+.Oc
+.Ar proto
+from
+.Ar src
+to
+.Ar dst
+.Oo
+via
+.Ar name|ipno
+.Oc
+.Oo
+.Ar options
.Oc
-.Ar chain_action chain[s]_type
-.\" ipfw [-n] <entry-action> <chain entry pattern>
-.\" ipfw [-ans] <chain-action> <chain[s] type>
-.Sh WARNING
-This manual page is out of date!
.Sh DESCRIPTION
+If used as shown in the first synopsis line, the
+.Ar file
+will be read line by line and applied as arguments to the
+.Nm ipfw
+command.
+.Pp
+The ipfw code works by going through the rule-list for each packet,
+until a match is found.
+All rules have two counters associated with them, a packet count and
+a byte count.
+These counters are updated when a packet matches the rule.
+.Pp
+The rules are ordered by a ``line-number'' that is used to order and
+delete rules.
+If a rule is added without a number, it is put at the end, just before
+the terminal ``policy-rule'', and numbered 100 higher than the previous
+rule.
+.Pp
+One rule is always present:
+.Bd -literal -offset center
+65535 deny all from any to any
+.Ed
+
+this is rule is the default policy, ie. don't allow anything at all.
+Your job in setting up rules is to modify this policy to match your
+needs.
+.Pp
+The following options are available:
+.Bl -tag -width flag
+.It Fl a
+While listing, show counter values. This option is the only way to see
+accounting records.
+.It Fl N
+Try to resolve addresses.
+.El
+.Pp
+.Ar action :
+.Bl -hang -offset flag -width 1234567890123456
+.It Nm accept
+Accept packets that match rule.
+The search terminates.
+.It Nm pass
+same as accept.
+.It Nm count
+update counters for all packets that match rule.
+The search continues with next rule.
+.It Nm deny
+Discard packets that match this rule.
+The search terminates.
+.It Nm reject
+Discard packets that match this rule, try to send ICMP notice.
+The search terminates.
+.El
+.Pp
+When a packet matches a rule with the
+.Nm log
+keyword, a message will be printed on the console.
+.Pp
+.Ar proto :
+.Bl -hang -offset flag -width 1234567890123456
+.It Nm ip
+All packets match.
+.It Nm all
+All packets match.
+.It Nm tcp
+Only TCP packets match.
+.It Nm udp
+Only UDP packets match.
+.It Nm icmp
+Only ICMP packets match.
+.El
+.Pp
+.Ar src
+and
+.Ar dst :
+.Bl -hang -offset flag -width 1234567890123456
+.It Ar ipno
+An ipnumber of the form 1.2.3.4.
+Only this exact ip number match the rule.
+.It Ar ipno/bits
+An ipnumber with a mask width of the form 1.2.3.4/24.
+In this case all ip numbers from 1.2.3.0 to 1.2.3.255 will match.
+.It Ar ipno:mask
+An ipnumber with a mask width of the form 1.2.3.4:255.255.240.0
+In this case all ip numbers from 1.2.0.0 to 1.2.15.255 will match.
+.El
+.Pp
+If ``via''
+.Ar name
+is specified, only packets received via or on their way out of an interface
+matching
+.Ar name
+will match this rule.
+.Pp
+If ``via''
+.Ar ipno
+is specified, only packets received via or on their way out of an interface
+having the address
+.Ar ipno
+will match this rule.
+.Pp
+.Ar options :
+.Bl -hang -offset flag -width 1234567890123456
+.It frag
+Matches is the packet is a fragment and this is not the first fragment
+of the datagram.
+.It in
+Matches if this packet was on the way in.
+.It out
+Matches if this packet was on the way out.
+.It ipoptions Ar spec
+Not yet documented. Look in the source: src/sys/netnet/ipfw.c.
+.It established
+Matches packets that do not have the SYN bit set.
+TCP packets only.
+.It setup
+Matches packets that have the SYN bit set but no ACK bit.
+TCP packets only.
+.It tcpflags Ar spec
+Not yet documented. Look in the source: src/sys/netnet/ipfw.c.
+TCP packets only.
+.El
+.Sh CHECKLIST
+Here are some important points to consider when designing your
+rules:
+.Bl -bullet -hang -offset flag -width 1234567890123456
+.It
+Remember that you filter both packets going in and out.
+Most connections needs packets going in both directions.
+.It
+Remember to test very carefully.
+It is a good idea to be near the console when doint this.
+.It
+Don't forget the loopback interface.
+.El
+.Sh FINE POINTS
+There is one kind of packet that the firewall will always discard,
+that is an IP fragment with a fragment offset of one.
+This is a valid packet, but it only has one use, to try to circumvent
+firewalls.
+.Pp
+If you are logged in over a network, loading the LKM version of
+.Nm
+is probably not as straightforward as you would think.
+I recommend this command line:
+.Bd -literal -offset center
+modload /lkm/ipfw_mod.o && \e
+ipfw add 32000 allow all from any to any
+.Ed
+
+Along the same lines, doing a
+.Bd -literal -offset center
+ipfw flush
+.Ed
+
+in similar surroundings is also a bad idea.
+.Sh WARNING
+This manual page is out of date beyond this point!
+It is left here until some new text can be written.
+.Sh OLD
In the first synopsis form,
.Nm
controls the firewall and accounting chains. In the second
@@ -28,24 +209,6 @@ synopsis form,
sets the global firewall / accounting properties and
show the chain list's contents.
.Pp
-The following options are available:
-.Bl -tag -width flag
-.It Fl a
-While listing, show counter values. This option is the only way to see
-accounting records. Works only with
-.Fl s
-.It Fl n
-Do not resolve anything. When setting entries, do not try to resolve a
-given address. When listing, display addresses in numeric form.
-.It Fl s
-Short listing form. By default, the listing format is compatible with
-.Nm
-input string format, so you can save listings to file and then reuse
-them. With this option list format is much more short but incompatible
-with the
-.Nm
-syntax.
-.El
.Pp
These are the valid
.Ar entry_actions :
@@ -323,3 +486,5 @@ The FreeBSD version is written completely by:
.Dl Ugen J.S.Antsilevich <ugen@FreeBSD.ORG>
.Pp
while the synopsis is partially compatible with the old one.
+.Pp
+This has all been extensively rearranged by Poul-Henning Kamp.
diff --git a/sbin/ipfw/ipfw.c b/sbin/ipfw/ipfw.c
index 010ff18..77c3765 100644
--- a/sbin/ipfw/ipfw.c
+++ b/sbin/ipfw/ipfw.c
@@ -15,36 +15,27 @@
*
* NEW command line interface for IP firewall facility
*
- * $Id: ipfw.c,v 1.19 1996/02/23 15:52:28 phk Exp $
+ * $Id: ipfw.c,v 1.20 1996/02/24 00:20:56 phk Exp $
*
*/
#include <stdio.h>
#include <ctype.h>
#include <err.h>
-#include <stdlib.h>
-#include <string.h>
#include <unistd.h>
-#include <paths.h>
-#include <fcntl.h>
-#include <limits.h>
+#include <string.h>
+#include <stdlib.h>
#include <netdb.h>
-#include <kvm.h>
-#include <sys/socket.h>
+#include <limits.h>
#include <sys/queue.h>
-#include <net/if.h>
+#include <sys/socket.h>
#include <netinet/in.h>
-#include <netinet/in_systm.h>
-#include <netinet/ip.h>
+#include <netinet/ip_fw.h>
#include <netinet/tcp.h>
#include <arpa/inet.h>
-#define IPFIREWALL
-#include <netinet/ip_fw.h>
-
-#define MAXSTR 256
int lineno = -1;
-char progname[MAXSTR]; /* Program name for errors */
+char progname[BUFSIZ]; /* Program name for errors */
int s; /* main RAW socket */
int do_resolv=0; /* Would try to resolv all */
@@ -229,6 +220,8 @@ show_ipfw(chain)
if (chain->fw_tcpf == IP_FW_TCPF_SYN &&
chain->fw_tcpnf == IP_FW_TCPF_ACK)
+ printf(" setup");
+ else if (chain->fw_tcpnf == IP_FW_TCPF_SYN && !chain->fw_tcpf)
printf(" established");
else if (chain->fw_tcpf || chain->fw_tcpnf) {
int _flg_printed = 0;
@@ -252,38 +245,23 @@ show_ipfw(chain)
printf("\n");
}
-struct nlist nlf[]={ { "_ip_fw_chain" } };
-
void
list(ac, av)
int ac;
char **av;
{
- kvm_t *kd;
- static char errb[_POSIX2_LINE_MAX];
- struct ip_fw b;
- struct ip_fw_chain *fcp,fc;
-
- if (!(kd=kvm_openfiles(NULL,NULL,NULL,O_RDONLY,errb))) {
- fprintf(stderr,"%s: kvm_openfiles: %s\n",
- progname,kvm_geterr(kd));
- exit(1);
- }
-
- if (kvm_nlist(kd,nlf)<0 || nlf[0].n_type==0) {
- fprintf(stderr,"%s: kvm_nlist: no namelist in %s\n",
- progname,getbootfile());
- exit(1);
- }
-
- kvm_read(kd,(u_long)nlf[0].n_value,&fcp,sizeof fcp);
- printf("FireWall chain entries:\n");
- while(fcp!=NULL) {
- kvm_read(kd,(u_long)fcp,&fc,sizeof fc);
- kvm_read(kd,(u_long)fc.rule,&b,sizeof b);
- show_ipfw(&b);
- fcp = fc.chain.le_next;
- }
+ struct ip_fw *r;
+ struct ip_fw rules[1024];
+ int l,i;
+
+ memset(rules,0,sizeof rules);
+ l = sizeof rules;
+ i = getsockopt(s, IPPROTO_IP, IP_FW_GET, rules, &l);
+ if (i < 0)
+ err(2,"getsockopt(IP_FW_GET)");
+ printf("FireWall chain entries: %d %d\n",l,i);
+ for (r=rules; l >= sizeof rules[0]; r++, l-=sizeof rules[0])
+ show_ipfw(r);
}
void
@@ -513,9 +491,6 @@ add(ac,av)
rule.fw_flg |= IP_FW_F_PRN; av++; ac--;
}
- /* [protocol] */
- if (ac && !strncmp(*av,"protocol",strlen(*av))) { av++; ac--; }
-
/* protocol */
if (ac && !strncmp(*av,"ip",strlen(*av))) {
rule.fw_flg |= IP_FW_F_ALL; av++; ac--;
@@ -557,6 +532,23 @@ add(ac,av)
av++; ac--;
}
+ if (ac && !strncmp(*av,"via",strlen(*av))) {
+ av++; ac--;
+ if (!isdigit(**av)) {
+ char *q;
+
+ strcpy(rule.fw_via_name, *av);
+ for (q = rule.fw_via_name; *q && !isdigit(*q); q++)
+ continue;
+ rule.fw_via_unit = atoi(q);
+ *q = '\0';
+ rule.fw_flg |= IP_FW_F_IFNAME;
+ } else if (inet_aton(*av,&rule.fw_via_ip) == INADDR_NONE) {
+ show_usage("bad IP# after via\n");
+ }
+ av++; ac--;
+ }
+
while (ac) {
if (!strncmp(*av,"frag",strlen(*av))) {
rule.fw_flg |= IP_FW_F_FRAG; av++; ac--; continue;
@@ -567,21 +559,27 @@ add(ac,av)
if (!strncmp(*av,"out",strlen(*av))) {
rule.fw_flg |= IP_FW_F_OUT; av++; ac--; continue;
}
- if (!strncmp(*av,"established",strlen(*av))) {
- rule.fw_tcpf |= IP_FW_TCPF_SYN;
- rule.fw_tcpnf |= IP_FW_TCPF_ACK;
- av++; ac--; continue;
- }
- if (ac > 1 && !strncmp(*av,"tcpflags",strlen(*av))) {
- av++; ac--;
- fill_tcpflag(&rule.fw_tcpf, &rule.fw_tcpnf, av);
- av++; ac--; continue;
- }
if (ac > 1 && !strncmp(*av,"ipoptions",strlen(*av))) {
av++; ac--;
fill_ipopt(&rule.fw_ipopt, &rule.fw_ipnopt, av);
av++; ac--; continue;
}
+ if ((rule.fw_flg & IP_FW_F_KIND) == IP_FW_F_TCP) {
+ if (!strncmp(*av,"established",strlen(*av))) {
+ rule.fw_tcpnf |= IP_FW_TCPF_SYN;
+ av++; ac--; continue;
+ }
+ if (!strncmp(*av,"setup",strlen(*av))) {
+ rule.fw_tcpf |= IP_FW_TCPF_SYN;
+ rule.fw_tcpnf |= IP_FW_TCPF_ACK;
+ av++; ac--; continue;
+ }
+ if (ac > 1 && !strncmp(*av,"tcpflags",strlen(*av))) {
+ av++; ac--;
+ fill_tcpflag(&rule.fw_tcpf, &rule.fw_tcpnf, av);
+ av++; ac--; continue;
+ }
+ }
printf("%d %s\n",ac,*av);
show_usage("Unknown argument\n");
}
@@ -606,12 +604,12 @@ ipfw_main(ac,av)
show_usage(NULL);
}
- while ((ch = getopt(ac, av ,"an")) != EOF)
+ while ((ch = getopt(ac, av ,"aN")) != EOF)
switch(ch) {
case 'a':
do_acct=1;
break;
- case 'n':
+ case 'N':
do_resolv=1;
break;
case '?':
@@ -656,7 +654,7 @@ main(ac, av)
char **av;
{
#define MAX_ARGS 32
- char buf[_POSIX_ARG_MAX];
+ char buf[BUFSIZ];
char *args[MAX_ARGS];
char linename[10];
int i;
@@ -676,7 +674,7 @@ main(ac, av)
if (av[1] && !access(av[1], R_OK)) {
lineno = 0;
f = fopen(av[1], "r");
- while (fgets(buf, _POSIX_ARG_MAX, f)) {
+ while (fgets(buf, BUFSIZ, f)) {
if (buf[strlen(buf)-1]=='\n')
buf[strlen(buf)-1] = 0;
OpenPOWER on IntegriCloud