The new firewall functionality:

Filter on the direction (in/out).
	Filter on fragment/not fragment.
This commit is contained in:
Poul-Henning Kamp 1996-02-24 00:17:35 +00:00
parent 7ee32b9fba
commit b83e431483
Notes: svn2git 2020-12-20 02:59:44 +00:00
svn path=/head/; revision=14230
4 changed files with 70 additions and 57 deletions

View File

@ -11,7 +11,7 @@
*
* This software is provided ``AS IS'' without any warranties of any kind.
*
* $Id: ip_fw.c,v 1.14.4.5 1996/02/23 20:10:52 phk Exp $
* $Id: ip_fw.c,v 1.30 1996/02/23 20:11:37 phk Exp $
*/
/*
@ -69,7 +69,7 @@ static int ipopts_match __P((struct ip *ip, struct ip_fw *f));
static int port_match __P((u_short *portptr, int nports, u_short port,
int range_flag));
static int tcpflg_match __P((struct tcphdr *tcp, struct ip_fw *f));
static void ipfw_report __P((char *txt, struct ip *ip));
static void ipfw_report __P((char *txt, int rule, struct ip *ip));
/*
* Returns 1 if the port is matched by the vector, 0 otherwise
@ -183,14 +183,14 @@ bad:
}
static void
ipfw_report(char *txt, struct ip *ip)
ipfw_report(char *txt, int rule, struct ip *ip)
{
struct tcphdr *tcp = (struct tcphdr *) ((u_long *) ip + ip->ip_hl);
struct udphdr *udp = (struct udphdr *) ((u_long *) ip + ip->ip_hl);
struct icmp *icmp = (struct icmp *) ((u_long *) ip + ip->ip_hl);
if (!fw_verbose)
return;
printf("ipfw: %s ",txt);
printf("ipfw: %d %s ",rule, txt);
switch (ip->ip_p) {
case IPPROTO_TCP:
printf("TCP ");
@ -245,21 +245,14 @@ ip_fw_chk(m, ip, rif, dir)
u_short src_port = 0, dst_port = 0;
u_short f_prt = 0, prt, len = 0;
/*
* Handle fragmented packets, if the Fragment Offset is big enough
* to not harm essential stuff in the UDP/TCP header, even in the
* precense of IP options, we assume that it's OK.
*/
if ((ip->ip_off & IP_OFFMASK) > 1)
return 1;
/*
* ... else if non-zero, highly unusual and interesting, but
* we're not going to pass it...
*/
if ((ip->ip_off & IP_OFFMASK)) {
ipfw_report("Refuse", ip);
goto bad_packet;
if ((ip->ip_off & IP_OFFMASK) == 1) {
ipfw_report("Refuse", -1, ip);
m_freem(m);
return 0;
}
src = ip->ip_src;
@ -297,15 +290,7 @@ ip_fw_chk(m, ip, rif, dir)
break;
}
#if 0
/*
* If the fields are not valid, don't validate them
*/
if (len < ip->ip_len) {
ipfw_report("Too Short", ip);
/* goto bad_packet; */
}
#endif
/* XXX Check that we have sufficient header for TCP analysis */
/*
* Go down the chain, looking for enlightment
@ -313,6 +298,18 @@ ip_fw_chk(m, ip, rif, dir)
for (chain=ip_fw_chain.lh_first; chain; chain = chain->chain.le_next) {
f = chain->rule;
/* Check direction inbound */
if (!dir && !(f->fw_flg & IP_FW_F_IN))
continue;
/* Check direction outbound */
if (dir && !(f->fw_flg & IP_FW_F_OUT))
continue;
/* Fragments */
if ((f->fw_flg & IP_FW_F_FRAG) && !(ip->ip_off & IP_OFFMASK))
continue;
/* If src-addr doesn't match, not this rule. */
if ((src.s_addr & f->fw_smsk.s_addr) != f->fw_src.s_addr)
continue;
@ -382,6 +379,10 @@ ip_fw_chk(m, ip, rif, dir)
if (prt == IP_FW_F_ICMP)
goto got_match;
/* Fragments can't match past this point */
if (ip->ip_off & IP_OFFMASK)
continue;
/* TCP, a little more checking */
if (prt == IP_FW_F_TCP &&
(f->fw_tcpf != f->fw_tcpnf) &&
@ -396,26 +397,25 @@ ip_fw_chk(m, ip, rif, dir)
dst_port, f->fw_flg & IP_FW_F_DRNG))
continue;
goto got_match;
}
/* Just in case ... */
goto bad_packet;
got_match:
f->fw_pcnt++;
f->fw_bcnt+=ip->ip_len;
if (f->fw_flg & IP_FW_F_PRN) {
f->fw_pcnt++;
f->fw_bcnt+=ip->ip_len;
if (f->fw_flg & IP_FW_F_PRN) {
if (f->fw_flg & IP_FW_F_ACCEPT)
ipfw_report("Accept", f->fw_number, ip);
else if (f->fw_flg & IP_FW_F_COUNT)
ipfw_report("Count", f->fw_number, ip);
else
ipfw_report("Deny", f->fw_number, ip);
}
if (f->fw_flg & IP_FW_F_ACCEPT)
ipfw_report("Accept", ip);
else
ipfw_report("Deny", ip);
return 1;
if (f->fw_flg & IP_FW_F_COUNT)
continue;
break;
}
if (f->fw_flg & IP_FW_F_ACCEPT)
return 1;
bad_packet:
/*
* Don't icmp outgoing packets at all
*/
@ -474,10 +474,9 @@ add_entry(chainptr, frwl)
} else {
nbr=0;
for (fcp = chainptr->lh_first; fcp; fcp = fcp->chain.le_next)
if (ftmp->fw_number > fcp->rule->fw_number) {
LIST_INSERT_AFTER(fcp, fwc, chain);
break;
} else if (fcp->rule->fw_number == (u_short)-1) {
if (fcp->rule->fw_number == (u_short)-1 ||
( ftmp->fw_number &&
fcp->rule->fw_number > ftmp->fw_number)) {
if (!ftmp->fw_number)
ftmp->fw_number = nbr + 100;
if (fcpl) {
@ -516,7 +515,7 @@ del_entry(chainptr, frwl)
splx(s);
free(fcp->rule, M_IPFW);
free(fcp, M_IPFW);
return 1;
return 0;
}
}
splx(s);
@ -541,6 +540,11 @@ check_ipfw_struct(m)
frwl->fw_flg));
return (NULL);
}
/* If neither In nor Out, then both */
if (!(frwl->fw_flg & (IP_FW_F_IN | IP_FW_F_OUT)))
frwl->fw_flg |= IP_FW_F_IN | IP_FW_F_OUT;
if ((frwl->fw_flg & IP_FW_F_SRNG) && frwl->fw_nsp < 2) {
dprintf(("ip_fw_ctl: src range set but n_src_p=%d\n",
frwl->fw_nsp));

View File

@ -11,7 +11,7 @@
*
* This software is provided ``AS IS'' without any warranties of any kind.
*
* $Id: ip_fw.h,v 1.11.4.2 1996/02/23 15:26:05 phk Exp $
* $Id: ip_fw.h,v 1.15 1996/02/23 15:47:52 phk Exp $
*/
/*
@ -66,21 +66,27 @@ struct ip_fw_chain {
#define IP_FW_F_ICMP 0x003 /* This is a ICMP packet rule */
#define IP_FW_F_KIND 0x003 /* Mask to isolate rule kind */
#define IP_FW_F_ACCEPT 0x004 /* This is an accept rule */
#define IP_FW_F_PRN 0x008 /* Print if this rule matches */
#define IP_FW_F_ICMPRPL 0x010 /* Send back icmp unreachable packet */
#define IP_FW_F_IN 0x004 /* Inbound */
#define IP_FW_F_OUT 0x008 /* Outboun */
#define IP_FW_F_ACCEPT 0x010 /* This is an accept rule */
#define IP_FW_F_COUNT 0x020 /* This is an accept rule */
#define IP_FW_F_PRN 0x040 /* Print if this rule matches */
#define IP_FW_F_ICMPRPL 0x080 /* Send back icmp unreachable packet */
#define IP_FW_F_SRNG 0x020 /* The first two src ports are a min *
#define IP_FW_F_SRNG 0x100 /* The first two src ports are a min *
* and max range (stored in host byte *
* order). */
#define IP_FW_F_DRNG 0x040 /* The first two dst ports are a min *
#define IP_FW_F_DRNG 0x200 /* The first two dst ports are a min *
* and max range (stored in host byte *
* order). */
#define IP_FW_F_IFNAME 0x080 /* Use interface name/unit (not IP) */
#define IP_FW_F_IFNAME 0x400 /* Use interface name/unit (not IP) */
#define IP_FW_F_MASK 0x0FF /* All possible flag bits mask */
#define IP_FW_F_FRAG 0x800 /* Fragment */
#define IP_FW_F_MASK 0xFFF /* All possible flag bits mask */
/*
* Definitions for IP option names.
@ -96,7 +102,7 @@ struct ip_fw_chain {
#define IP_FW_TCPF_FIN TH_FIN
#define IP_FW_TCPF_SYN TH_SYN
#define IP_FW_TCPF_RST TH_RST
#define IP_FW_TCPF_PUSH TH_PUSH
#define IP_FW_TCPF_PSH TH_PUSH
#define IP_FW_TCPF_ACK TH_ACK
#define IP_FW_TCPF_URG TH_URG

View File

@ -31,7 +31,7 @@
* SUCH DAMAGE.
*
* @(#)ip_input.c 8.2 (Berkeley) 1/4/94
* $Id: ip_input.c,v 1.35 1996/02/05 20:36:02 wollman Exp $
* $Id: ip_input.c,v 1.36 1996/02/23 15:47:53 phk Exp $
*/
#include <sys/param.h>
@ -172,6 +172,9 @@ ip_init()
ipq.next = ipq.prev = &ipq;
ip_id = time.tv_sec & 0xffff;
ipintrq.ifq_maxlen = ipqmaxlen;
#ifdef IPFIREWALL
ip_fw_init();
#endif
}
static struct sockaddr_in ipaddr = { sizeof(ipaddr), AF_INET };

View File

@ -31,7 +31,7 @@
* SUCH DAMAGE.
*
* @(#)ip_output.c 8.3 (Berkeley) 1/21/94
* $Id: ip_output.c,v 1.28 1996/02/22 21:32:23 peter Exp $
* $Id: ip_output.c,v 1.29 1996/02/23 15:47:55 phk Exp $
*/
#include <sys/param.h>
@ -340,7 +340,7 @@ sendit:
* Check with the firewall...
*/
if (!(*ip_fw_chk_ptr)(m,ip,ifp,1)) {
error = 0;
error = EACCES;
goto done;
}