2 11th-hour fixes from Ugen (not Uben, sorry!) J.S.Antsilevich.

I think it's time for Ugen to get a freefall account, just so I can
direct mail at him directly and let him drop off patches for us here.  Ugen?
Done!
Submitted by:	ugen
This commit is contained in:
jkh 1994-11-07 10:01:32 +00:00
parent db6ac921c8
commit 319fc7e1e0
2 changed files with 104 additions and 58 deletions

View File

@ -340,36 +340,44 @@ void
free_firewall_chain(chainptr)
struct ip_firewall **chainptr;
{
int s=splnet();
while ( *chainptr != NULL ) {
struct ip_firewall *ftmp;
ftmp = *chainptr;
*chainptr = ftmp->next;
free(ftmp,M_SOOPTS);
}
splx(s);
}
static
int
add_to_chain(chainptr,firewall)
struct ip_firewall **chainptr;
struct ip_firewall *firewall;
add_to_chain(chainptr,frwl)
struct ip_fw **chainptr;
struct ip_fw *frwl;
{
struct ip_firewall *ftmp;
struct ip_firewall *chaintmp=NULL;
struct ip_firewall *chaintmp_prev=NULL;
struct ip_fw *ftmp;
struct ip_fw *chtmp=NULL;
struct ip_fw *chtmp_prev=NULL;
int s=splnet();
u_long m_src_mask,m_dst_mask;
u_long n_sa,n_da,o_sa,o_da,o_sm,o_dm,n_sm,n_dm;
u_short n_sr,n_dr,o_sr,o_dr;
u_short oldkind,newkind;
int addb4=0;
int n_o,n_n;
ftmp = malloc( sizeof(struct ip_firewall), M_SOOPTS, M_DONTWAIT );
ftmp = malloc( sizeof(struct ip_fw), M_SOOPTS, M_DONTWAIT );
if ( ftmp == NULL ) {
printf("ip_firewall_ctl: malloc said no\n");
#ifdef DEBUG_IPFIREWALL
printf("ip_fw_ctl: malloc said no\n");
#endif
splx(s);
return( ENOSPC );
}
bcopy( firewall, ftmp, sizeof( struct ip_firewall ) );
bcopy( frwl, ftmp, sizeof( struct ip_fw ) );
ftmp->next = NULL;
if (*chainptr==NULL)
@ -378,16 +386,16 @@ struct ip_firewall *firewall;
}
else
{
chaintmp_prev=NULL;
for (chaintmp=*chainptr;chaintmp!=NULL;chaintmp=chaintmp->next) {
chtmp_prev=NULL;
for (chtmp=*chainptr;chtmp!=NULL;chtmp=chtmp->next) {
addb4=0;
newkind=ftmp->flags & IP_FIREWALL_KIND;
oldkind=chaintmp->flags & IP_FIREWALL_KIND;
newkind=ftmp->flags & IP_FW_F_KIND;
oldkind=chtmp->flags & IP_FW_F_KIND;
if (newkind!=IP_FIREWALL_UNIVERSAL
&& oldkind!=IP_FIREWALL_UNIVERSAL
if (newkind!=IP_FW_F_ALL
&& oldkind!=IP_FW_F_ALL
&& oldkind!=newkind)
continue;
/*
@ -399,10 +407,10 @@ struct ip_firewall *firewall;
n_sm=ntohl(ftmp->src_mask.s_addr);
n_dm=ntohl(ftmp->dst_mask.s_addr);
o_sa=ntohl(chaintmp->src.s_addr);
o_da=ntohl(chaintmp->dst.s_addr);
o_sm=ntohl(chaintmp->src_mask.s_addr);
o_dm=ntohl(chaintmp->dst_mask.s_addr);
o_sa=ntohl(chtmp->src.s_addr);
o_da=ntohl(chtmp->dst.s_addr);
o_sm=ntohl(chtmp->src_mask.s_addr);
o_dm=ntohl(chtmp->dst_mask.s_addr);
m_src_mask = o_sm & n_sm;
m_dst_mask = o_dm & n_dm;
@ -424,54 +432,85 @@ struct ip_firewall *firewall;
if (((o_da & o_dm) == (n_da & n_dm))
&&((o_sa & o_sm) == (n_sa & n_sm)))
{
if (newkind!=IP_FIREWALL_UNIVERSAL &&
oldkind==IP_FIREWALL_UNIVERSAL)
if (newkind!=IP_FW_F_ALL &&
oldkind==IP_FW_F_ALL)
addb4++;
if (newkind==oldkind && (oldkind==IP_FIREWALL_TCP
|| oldkind==IP_FIREWALL_UDP)) {
if ( (!(ftmp->flags & IP_FIREWALL_SRC_RANGE)
&& ftmp->num_src_ports>0)
|| (!(ftmp->flags & IP_FIREWALL_DST_RANGE)
&& ftmp->num_dst_ports>0))
if (newkind==oldkind && (oldkind==IP_FW_F_TCP
|| oldkind==IP_FW_F_UDP)) {
/*
* Here the main ide is to check the size
* of port range which the frwl covers
* We actually don't check their values but
* just the wideness of range they have
* so that less wide ranges or single ports
* go first and wide ranges go later. No ports
* at all treated as a range of maximum number
* of ports.
*/
if (ftmp->flags & IP_FW_F_SRNG)
n_sr=ftmp->ports[1]-ftmp->ports[0];
else
n_sr=(ftmp->n_src_p)?
ftmp->n_src_p : USHRT_MAX;
if (chtmp->flags & IP_FW_F_SRNG)
o_sr=chtmp->ports[1]-chtmp->ports[0];
else
o_sr=(chtmp->n_src_p)?
chtmp->n_src_p : USHRT_MAX;
if (n_sr<o_sr)
addb4++;
if ((ftmp->flags & IP_FIREWALL_SRC_RANGE) &&
(chaintmp->flags & IP_FIREWALL_SRC_RANGE))
if ((ftmp->ports[1]-ftmp->ports[0])<
(chaintmp->ports[1]-chaintmp->ports[0]))
addb4++;
n_n=ftmp->num_src_ports;
n_o=chaintmp->num_src_ports;
if ((n_n>(IP_FIREWALL_MAX_PORTS-2)) ||
(n_o>(IP_FIREWALL_MAX_PORTS-2)))
goto skip_1_check;
if (n_sr>o_sr)
addb4--;
n_n=ftmp->n_src_p;
n_o=chtmp->n_src_p;
/*
* Actually this cannot happen as the firewall control
* Actually this cannot happen as the frwl control
* procedure checks for number of ports in source and
* destination range but we will try to be more safe.
*/
if ((ftmp->flags & IP_FIREWALL_DST_RANGE) &&
(chaintmp->flags & IP_FIREWALL_DST_RANGE))
if ((ftmp->ports[n_n+1]-ftmp->ports[n_n])<
(chaintmp->ports[n_o+1]-chaintmp->ports[n_o]))
addb4++;
skip_1_check:
if ((n_n>(IP_FW_MAX_PORTS-2)) ||
(n_o>(IP_FW_MAX_PORTS-2)))
goto skip_check;
if (ftmp->flags & IP_FW_F_DRNG)
n_dr=ftmp->ports[n_n+1]-ftmp->ports[n_n];
else
n_dr=(ftmp->n_dst_p)?
ftmp->n_dst_p : USHRT_MAX;
if (chtmp->flags & IP_FW_F_DRNG)
o_dr=chtmp->ports[n_o+1]-chtmp->ports[n_o];
else
o_dr=(chtmp->n_dst_p)?
chtmp->n_dst_p : USHRT_MAX;
if (n_dr<o_dr)
addb4++;
if (n_dr>o_dr)
addb4--;
skip_check:
}
}
if (addb4>0) {
if (chaintmp_prev) {
chaintmp_prev->next=ftmp;
ftmp->next=chaintmp;
if (chtmp_prev) {
chtmp_prev->next=ftmp;
ftmp->next=chtmp;
} else {
*chainptr=ftmp;
ftmp->next=chaintmp;
ftmp->next=chtmp;
}
splx(s);
return 0;
}
chaintmp_prev=chaintmp;
chtmp_prev=chtmp;
}
if (chaintmp_prev)
chaintmp_prev->next=ftmp;
if (chtmp_prev)
chtmp_prev->next=ftmp;
else
#define wrong
#ifdef wrong
@ -481,9 +520,12 @@ struct ip_firewall *firewall;
#endif
#undef wrong
}
splx(s);
return(0);
}
static
int
del_from_chain(chainptr,firewall)
@ -493,13 +535,15 @@ struct ip_firewall *firewall;
struct ip_firewall *ftmp,*ltmp;
u_short tport1,tport2,tmpnum;
char matches,was_found;
int s=splnet();
ftmp=*chainptr;
if ( ftmp == NULL ) {
printf("ip_firewall_ctl: chain is empty\n");
splx(s);
return( EINVAL );
}
}
ltmp=NULL;
was_found=0;
@ -532,14 +576,12 @@ struct ip_firewall *firewall;
ltmp->next=ftmp->next;
free(ftmp,M_SOOPTS);
ftmp=ltmp->next;
/* return 0; */
}
else
{
*chainptr=ftmp->next;
free(ftmp,M_SOOPTS);
ftmp=*chainptr;
/* return 0; */
}
}
@ -549,6 +591,7 @@ struct ip_firewall *firewall;
ftmp = ftmp->next;
}
}
splx(s);
if (was_found) return 0;
else return(EINVAL);
}

View File

@ -31,7 +31,7 @@
* SUCH DAMAGE.
*
* @(#)raw_ip.c 8.2 (Berkeley) 1/4/94
* $Id: raw_ip.c,v 1.5 1994/10/02 17:48:42 phk Exp $
* $Id: raw_ip.c,v 1.6 1994/10/28 15:09:49 jkh Exp $
*/
#include <sys/param.h>
@ -218,8 +218,11 @@ rip_ctloutput(op, so, level, optname, m)
case IP_FW_FLUSH:
case IP_FW_POLICY:
if (op == PRCO_SETOPT)
error=ip_firewall_ctl(optname, *m);
if (op == PRCO_SETOPT) {
error=ip_fw_ctl(optname, *m);
if (*m)
(void)m_free(*m);
}
else
error=EINVAL;
return(error);