The new firewall functionality:
Filter on the direction (in/out). Filter on fragment/not fragment.
This commit is contained in:
parent
76dbdac3af
commit
91b3fcc1e2
@ -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 @@ ipopts_match(ip, f)
|
||||
}
|
||||
|
||||
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) {
|
||||
if (f->fw_flg & IP_FW_F_ACCEPT)
|
||||
ipfw_report("Accept", ip);
|
||||
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", ip);
|
||||
ipfw_report("Deny", f->fw_number, ip);
|
||||
}
|
||||
|
||||
if (f->fw_flg & IP_FW_F_ACCEPT)
|
||||
return 1;
|
||||
if (f->fw_flg & IP_FW_F_COUNT)
|
||||
continue;
|
||||
break;
|
||||
|
||||
}
|
||||
|
||||
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));
|
||||
|
@ -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_SRNG 0x020 /* The first two src ports are a min *
|
||||
#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 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
|
||||
|
||||
|
@ -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 };
|
||||
|
@ -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 @@ ip_output(m0, opt, ro, flags, imo)
|
||||
* Check with the firewall...
|
||||
*/
|
||||
if (!(*ip_fw_chk_ptr)(m,ip,ifp,1)) {
|
||||
error = 0;
|
||||
error = EACCES;
|
||||
goto done;
|
||||
}
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user