summaryrefslogtreecommitdiffstats
path: root/sys/netinet
diff options
context:
space:
mode:
authorugen <ugen@FreeBSD.org>1994-12-12 17:20:55 +0000
committerugen <ugen@FreeBSD.org>1994-12-12 17:20:55 +0000
commitdd9e9b49e3773143f680ad0f18ead7b8023682cc (patch)
tree773d863fe59cc745780c988f947286cd83a89acb /sys/netinet
parentd3899ce8a10f936258877e027e9db900c9076e68 (diff)
downloadFreeBSD-src-dd9e9b49e3773143f680ad0f18ead7b8023682cc.zip
FreeBSD-src-dd9e9b49e3773143f680ad0f18ead7b8023682cc.tar.gz
Add match by interface from which packet arrived (via)
Handle right fragmented packets. Remove checking option from kernel..
Diffstat (limited to 'sys/netinet')
-rw-r--r--sys/netinet/ip_fw.c180
-rw-r--r--sys/netinet/ip_fw.h3
-rw-r--r--sys/netinet/ip_input.c13
-rw-r--r--sys/netinet/ip_output.c6
-rw-r--r--sys/netinet/raw_ip.c4
5 files changed, 128 insertions, 78 deletions
diff --git a/sys/netinet/ip_fw.c b/sys/netinet/ip_fw.c
index 155a49e..c93ed56 100644
--- a/sys/netinet/ip_fw.c
+++ b/sys/netinet/ip_fw.c
@@ -124,26 +124,51 @@ int range_flag;
*/
#ifdef IPFIREWALL
-int ip_fw_chk(ip,chain)
-struct ip *ip;
-struct ip_fw *chain;
+int ip_fw_chk(ip,rif,chain)
+struct ip *ip;
+struct ifnet *rif;
+struct ip_fw *chain;
{
- struct in_addr src, dst;
- char notcpsyn=1;
- int frwl_proto=0, proto;
- struct mbuf *m;
register struct ip_fw *f;
- u_short src_port=0, dst_port=0;
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);
+ struct ifaddr *ia=NULL, *ia_p;
+ struct in_addr src, dst, ia_i;
+ struct mbuf *m;
+ u_short src_port=0, dst_port=0;
+ u_short f_prt=0, prt;
+ char notcpsyn=1;
+ /*
+ * If the chain is empty
+ * allow any packet-this is equal
+ * to disabling firewall.
+ */
if (!chain)
- return(1); /* If no chain , always say Ok to packet */
+ return(1);
+
+ /*
+ * This way we handle fragmented packets.
+ * we ignore all fragments but the first one
+ * so the whole packet can't be reassembled.
+ * This way we relay on the full info which
+ * stored only in first packet.
+ */
+ if (ip->ip_off&IP_OFFMASK)
+ return(1);
src = ip->ip_src;
dst = ip->ip_dst;
+ /*
+ * If we got interface from
+ * which packet came-store
+ * pointer to it's first adress
+ */
+ if (rif)
+ ia=rif->if_addrlist;
+
dprintf1("Packet ");
switch(ip->ip_p) {
case IPPROTO_TCP:
@@ -152,21 +177,21 @@ struct ip_fw *chain;
dst_port=ntohs(tcp->th_dport);
if (tcp->th_flags&TH_SYN)
notcpsyn=0; /* We *DO* have SYN ,value FALSE */
- proto=IP_FW_F_TCP;
+ prt=IP_FW_F_TCP;
break;
case IPPROTO_UDP:
dprintf1("UDP ");
src_port=ntohs(udp->uh_sport);
dst_port=ntohs(udp->uh_dport);
- proto=IP_FW_F_UDP;
+ prt=IP_FW_F_UDP;
break;
case IPPROTO_ICMP:
dprintf2("ICMP:%u ",icmp->icmp_type);
- proto=IP_FW_F_ICMP;
+ prt=IP_FW_F_ICMP;
break;
default:
dprintf2("p=%d ",ip->ip_p);
- proto=IP_FW_F_ALL;
+ prt=IP_FW_F_ALL;
break;
}
dprint_ip(ip->ip_src);
@@ -183,8 +208,43 @@ struct ip_fw *chain;
for (f=chain;f;f=f->next)
if ((src.s_addr&f->src_mask.s_addr)==f->src.s_addr
&& (dst.s_addr&f->dst_mask.s_addr)==f->dst.s_addr) {
- frwl_proto=f->flags&IP_FW_F_KIND;
- if (frwl_proto==IP_FW_F_ALL) {
+ if (f->via.s_addr && rif) {
+ for (ia_p=ia;ia_p;ia_p=ia_p->ifa_next) {
+ if (!ia_p->ifa_addr ||
+ ia_p->ifa_addr->sa_family!=AF_INET)
+ /*
+ * Next interface adress.
+ * This is continue for
+ * local "for"
+ */
+ continue;
+ ia_i.s_addr=(((struct sockaddr_in *)\
+ (ia_p->ifa_addr))->sin_addr.s_addr);
+ if (ia_i.s_addr==f->via.s_addr)
+ goto via_match;
+ }
+ /*
+ * Next interface adress.
+ * This is continue for
+ * local "for"
+ */
+ continue;
+ } else {
+ /*
+ * No special "via" adress set
+ * or interface from which packet
+ * came unknown so match anyway
+ */
+ goto via_match;
+ }
+ /*
+ * Skip to next firewall entry - via
+ * address did not matched.
+ */
+ continue;
+via_match:
+ f_prt=f->flags&IP_FW_F_KIND;
+ if (f_prt==IP_FW_F_ALL) {
/* Universal frwl - we've got a match! */
goto got_match;
} else {
@@ -201,9 +261,9 @@ struct ip_fw *chain;
* Specific firewall - packet's
* protocol must match firewall's
*/
- if (proto==frwl_proto) {
+ if (prt==f_prt) {
- if (proto==IP_FW_F_ICMP ||
+ if (prt==IP_FW_F_ICMP ||
(port_match(&f->ports[0],f->n_src_p,src_port,
f->flags&IP_FW_F_SRNG) &&
port_match(&f->ports[f->n_src_p],f->n_dst_p,dst_port,
@@ -273,7 +333,7 @@ bad_packet:
* Do not ICMP reply to icmp
* packets....:)
*/
- if (frwl_proto==IP_FW_F_ICMP)
+ if (f_prt==IP_FW_F_ICMP)
return 0;
/*
* Reply to packets rejected
@@ -292,7 +352,7 @@ bad_packet:
return 0;
m->m_len = sizeof(struct ip)+64;
bcopy((caddr_t)ip,mtod(m, caddr_t),(unsigned)m->m_len);
- if (frwl_proto=IP_FW_F_ALL)
+ if (f_prt==IP_FW_F_ALL)
icmp_error(m, ICMP_UNREACH, ICMP_UNREACH_HOST, 0L, 0);
else
icmp_error(m, ICMP_UNREACH, ICMP_UNREACH_PORT, 0L, 0);
@@ -313,41 +373,49 @@ good_packet:
#ifdef IPACCT
-void ip_acct_cnt(ip,chain,nh_conv)
-struct ip *ip;
-struct ip_fw *chain;
+void ip_acct_cnt(ip,rif,chain,nh_conv)
+struct ip *ip;
+struct ifnet *rif;
+struct ip_fw *chain;
int nh_conv;
{
- struct in_addr src, dst;
- char rev=0;
- int frwl_proto, proto=0;
register struct ip_fw *f;
- u_short src_port=0, dst_port=0;
struct tcphdr *tcp=(struct tcphdr *)((u_long *)ip+ip->ip_hl);
struct udphdr *udp=(struct udphdr *)((u_long *)ip+ip->ip_hl);
+ struct ifaddr *ia=NULL, *ia_p;
+ struct in_addr src, dst, ia_i;
+ u_short src_port=0, dst_port=0;
+ u_short f_prt, prt=0;
+ char rev=0;
if (!chain)
return;
+ if (ip->ip_off&IP_OFFMASK)
+ return;
+
src = ip->ip_src;
dst = ip->ip_dst;
+ if (rif)
+ ia=rif->if_addrlist;
+
switch(ip->ip_p) {
case IPPROTO_TCP:
src_port=ntohs(tcp->th_sport);
dst_port=ntohs(tcp->th_dport);
- proto=IP_FW_F_TCP;
+ prt=IP_FW_F_TCP;
break;
case IPPROTO_UDP:
src_port=ntohs(udp->uh_sport);
dst_port=ntohs(udp->uh_dport);
- proto=IP_FW_F_UDP;
+ prt=IP_FW_F_UDP;
break;
case IPPROTO_ICMP:
- proto=IP_FW_F_ICMP;
+ prt=IP_FW_F_ICMP;
break;
default:
- proto=IP_FW_F_ALL;
+ prt=IP_FW_F_ALL;
break;
}
@@ -365,8 +433,24 @@ int nh_conv;
}
continue;
addr_match:
- frwl_proto=f->flags&IP_FW_F_KIND;
- if (frwl_proto==IP_FW_F_ALL) {
+ if (f->via.s_addr && rif) {
+ for (ia_p=ia;ia_p;ia_p=ia_p->ifa_next) {
+ if (!ia_p->ifa_addr ||
+ ia_p->ifa_addr->sa_family!=AF_INET)
+ continue;
+ ia_i.s_addr=(((struct sockaddr_in *)\
+ (ia_p->ifa_addr))->sin_addr.s_addr);
+ if (ia_i.s_addr==f->via.s_addr)
+ goto via_match;
+ }
+ continue;
+ } else {
+ goto via_match;
+ }
+ continue;
+via_match:
+ f_prt=f->flags&IP_FW_F_KIND;
+ if (f_prt==IP_FW_F_ALL) {
/* Universal frwl - we've got a match! */
f->p_cnt++; /* Rise packet count */
@@ -386,9 +470,9 @@ addr_match:
* Specific firewall - packet's
* protocol must match firewall's
*/
- if (proto==frwl_proto) {
+ if (prt==f_prt) {
- if ((proto==IP_FW_F_ICMP ||
+ if ((prt==IP_FW_F_ICMP ||
(port_match(&f->ports[0],f->n_src_p,src_port,
f->flags&IP_FW_F_SRNG) &&
port_match(&f->ports[f->n_src_p],f->n_dst_p,dst_port,
@@ -813,34 +897,6 @@ if ( stage == IP_FW_POLICY )
return 0;
}
-if ( stage == IP_FW_CHK_BLK
- || stage == IP_FW_CHK_FWD ) {
-
- struct ip *ip;
-
- if ( m->m_len < sizeof(struct ip) + 2 * sizeof(u_short) ) {
- dprintf3("ip_fw_ctl: mbuf len=%d, want at least %d\n",
- m->m_len,sizeof(struct ip) + 2 * sizeof(u_short));
- return( EINVAL );
- }
-
- ip = mtod(m,struct ip *);
-
- if ( ip->ip_hl != sizeof(struct ip) / sizeof(int) ) {
- dprintf3("ip_fw_ctl: ip->ip_hl=%d, want %d\n",ip->ip_hl,
- sizeof(struct ip)/sizeof(int));
- return(EINVAL);
- }
-
- if ( ip_fw_chk(ip,
- stage == IP_FW_CHK_BLK ?
- ip_fw_blk_chain : ip_fw_fwd_chain )
- )
- return(0);
- else
- return(EACCES);
- }
-
/*
* Here we really working hard-adding new elements
* to blocking/forwarding chains or deleting'em
diff --git a/sys/netinet/ip_fw.h b/sys/netinet/ip_fw.h
index 9c30210..ecae108 100644
--- a/sys/netinet/ip_fw.h
+++ b/sys/netinet/ip_fw.h
@@ -26,6 +26,7 @@ struct ip_fw {
struct ip_fw *next; /* Next firewall on chain */
struct in_addr src, dst; /* Source and destination IP addr */
struct in_addr src_mask, dst_mask; /* Mask for src and dest IP addr */
+ struct in_addr via; /* IP addr of interface "via" */
u_short flags; /* Flags word */
u_short n_src_p, n_dst_p; /* # of src ports and # of dst ports */
/* in ports array (dst ports follow */
@@ -70,8 +71,6 @@ struct ip_fw {
#define IP_FW_ADD_BLK (IP_FW_BASE_CTL)
#define IP_FW_ADD_FWD (IP_FW_BASE_CTL+1)
-#define IP_FW_CHK_BLK (IP_FW_BASE_CTL+2)
-#define IP_FW_CHK_FWD (IP_FW_BASE_CTL+3)
#define IP_FW_DEL_BLK (IP_FW_BASE_CTL+4)
#define IP_FW_DEL_FWD (IP_FW_BASE_CTL+5)
#define IP_FW_FLUSH (IP_FW_BASE_CTL+6)
diff --git a/sys/netinet/ip_input.c b/sys/netinet/ip_input.c
index 085d0ff..3b2678c 100644
--- a/sys/netinet/ip_input.c
+++ b/sys/netinet/ip_input.c
@@ -31,7 +31,7 @@
* SUCH DAMAGE.
*
* @(#)ip_input.c 8.2 (Berkeley) 1/4/94
- * $Id: ip_input.c,v 1.10 1994/11/08 12:47:29 jkh Exp $
+ * $Id: ip_input.c,v 1.11 1994/11/16 10:17:08 jkh Exp $
*/
#include <sys/param.h>
@@ -240,7 +240,7 @@ next:
#ifdef IPFIREWALL
if ( ((char *)&(ip->ip_dst.s_addr))[0] != 127
- && !ip_fw_chk(ip,ip_fw_blk_chain) ) {
+ && !ip_fw_chk(ip,m->m_pkthdr.rcvif,ip_fw_blk_chain) ) {
goto bad;
}
#endif
@@ -364,7 +364,7 @@ ours:
* Do not convert ip_len to host byte order when
* counting,ppl already made it for us before..
*/
- ip_acct_cnt(ip,ip_acct_chain,0);
+ ip_acct_cnt(ip,m->m_pkthdr.rcvif,ip_acct_chain,0);
#endif
/*
@@ -1051,7 +1051,7 @@ ip_forward(m, srcrt)
#ifdef IPFIREWALL
if ( ((char *)&(ip->ip_dst.s_addr))[0] != 127
- && !ip_fw_chk(ip,ip_fw_fwd_chain) ) {
+ && !ip_fw_chk(ip,m->m_pkthdr.rcvif,ip_fw_fwd_chain) ) {
ipstat.ips_cantforward++;
m_freem(m);
return;
@@ -1139,11 +1139,6 @@ ip_forward(m, srcrt)
if (error)
ipstat.ips_cantforward++;
else {
-#ifdef wrong
-#ifdef IPACCT
- ip_acct_cnt(ip,ip_acct_chain);
-#endif
-#endif
ipstat.ips_forward++;
if (type)
ipstat.ips_redirectsent++;
diff --git a/sys/netinet/ip_output.c b/sys/netinet/ip_output.c
index a734c42..986f9dd 100644
--- a/sys/netinet/ip_output.c
+++ b/sys/netinet/ip_output.c
@@ -31,7 +31,7 @@
* SUCH DAMAGE.
*
* @(#)ip_output.c 8.3 (Berkeley) 1/21/94
- * $Id: ip_output.c,v 1.8 1994/09/14 03:10:13 wollman Exp $
+ * $Id: ip_output.c,v 1.9 1994/11/16 10:17:10 jkh Exp $
*/
#include <sys/param.h>
@@ -414,8 +414,10 @@ done:
* those we forward.
* Here we want to convert ip_len to host byte order when counting
* so we set 3rd arg to 1.
+ * This is locally generated packet so it has not
+ * incoming interface.
*/
- ip_acct_cnt(ip,ip_acct_chain,1);
+ ip_acct_cnt(ip,NULL,ip_acct_chain,1);
#endif
return (error);
bad:
diff --git a/sys/netinet/raw_ip.c b/sys/netinet/raw_ip.c
index 4b33614..bbba46e 100644
--- a/sys/netinet/raw_ip.c
+++ b/sys/netinet/raw_ip.c
@@ -31,7 +31,7 @@
* SUCH DAMAGE.
*
* @(#)raw_ip.c 8.2 (Berkeley) 1/4/94
- * $Id: raw_ip.c,v 1.6 1994/10/28 15:09:49 jkh Exp $
+ * $Id: raw_ip.c,v 1.8 1994/11/16 10:17:11 jkh Exp $
*/
#include <sys/param.h>
@@ -214,8 +214,6 @@ rip_ctloutput(op, so, level, optname, m)
#ifdef IPFIREWALL
case IP_FW_ADD_BLK:
case IP_FW_ADD_FWD:
- case IP_FW_CHK_BLK:
- case IP_FW_CHK_FWD:
case IP_FW_DEL_BLK:
case IP_FW_DEL_FWD:
case IP_FW_FLUSH:
OpenPOWER on IntegriCloud