Add match by interface from which packet arrived (via)
Handle right fragmented packets. Remove checking option from kernel..
This commit is contained in:
parent
fab9e6db0e
commit
10a642bb05
@ -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 @@ struct ip_fw *chain;
|
||||
* 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 @@ struct ip_fw *chain;
|
||||
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 @@ struct ip_fw *chain;
|
||||
|
||||
|
||||
#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 @@ int nh_conv;
|
||||
* 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
|
||||
|
@ -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)
|
||||
|
@ -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 @@ ipintr()
|
||||
|
||||
#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 @@ ipintr()
|
||||
* 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++;
|
||||
|
@ -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 @@ ip_output(m0, opt, ro, flags, imo)
|
||||
* 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:
|
||||
|
@ -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:
|
||||
|
Loading…
Reference in New Issue
Block a user