summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--sys/netinet/ip_fw.c678
-rw-r--r--sys/netinet/ip_fw.h45
-rw-r--r--sys/netinet/ip_input.c21
-rw-r--r--sys/netinet/ip_output.c18
-rw-r--r--sys/netinet/raw_ip.c19
5 files changed, 518 insertions, 263 deletions
diff --git a/sys/netinet/ip_fw.c b/sys/netinet/ip_fw.c
index 3b2f938..293f469 100644
--- a/sys/netinet/ip_fw.c
+++ b/sys/netinet/ip_fw.c
@@ -24,25 +24,30 @@
#include <sys/protosw.h>
#include <sys/socket.h>
#include <sys/errno.h>
-#include <sys/time.h>
+#include <sys/time.h>
#include <sys/kernel.h>
#include <net/if.h>
#include <net/route.h>
+
#include <netinet/in.h>
#include <netinet/in_systm.h>
#include <netinet/ip.h>
-#include <netinet/in_pcb.h>
-#include <netinet/in_var.h>
-#include <netinet/ip_var.h>
#include <netinet/ip_icmp.h>
+#include <arpa/inet.h>
+
#include <netinet/ip_fw.h>
+#ifdef IPFIREWALL
struct ip_fw *ip_fw_fwd_chain;
struct ip_fw *ip_fw_blk_chain;
int ip_fw_policy=1;
+#endif
+#ifdef IPACCT
+struct ip_fw *ip_acct_chain;
+#endif
inline
@@ -61,7 +66,6 @@ struct in_addr xaddr;
/*
* Returns 1 if the port is matched by the vector, 0 otherwise
*/
-
inline
int port_match(portptr,nports,port,range_flag)
u_short *portptr;
@@ -69,6 +73,8 @@ int nports;
u_short port;
int range_flag;
{
+ if (!nports)
+ return 1;
if ( range_flag ) {
if ( portptr[0] <= port && port <= portptr[1] ) {
return( 1 );
@@ -89,22 +95,20 @@ int range_flag;
* Returns 0 if packet should be dropped, 1 or more if it should be accepted
*/
-
+#ifdef IPFIREWALL
int ip_fw_chk(ip,chain)
struct ip *ip;
struct ip_fw *chain;
{
struct in_addr src, dst;
- char got_proto = 0;
- int frwl_proto, proto = 0;
- register struct ip_fw *fptr;
- u_short src_port = 0, dst_port = 0;
-#ifdef IPFIREWALL_VERBOSE
- u_short *portptr = (u_short *)&(((u_int *)ip)[ip->ip_hl]);
-#endif
-
- if ( chain == NULL ) { /* Is there a frwl chain? */
- return(1);
+ char got_proto=0;
+ int frwl_proto, proto=0;
+ register struct ip_fw *f;
+ u_short src_port=0, dst_port=0;
+ u_short *portptr=(u_short *)&(((u_int *)ip)[ip->ip_hl]);
+
+ if (!chain) {
+ return(1); /* If no chain , always say Ok to packet */
}
src = ip->ip_src;
@@ -112,142 +116,149 @@ struct ip_fw *chain;
#ifdef DEBUG_IPFIREWALL
{
- u_short *portptr = (u_short *)&(((u_int *)ip)[ip->ip_hl]);
printf("packet ");
switch(ip->ip_p) {
- case IPPROTO_TCP: printf("TCP "); break;
- case IPPROTO_UDP: printf("UDP "); break;
- case IPPROTO_ICMP: printf("ICMP:%d ",((char *)portptr)[0]&0xff); break;
- default: printf("p=%d ",ip->ip_p); break;
+ case IPPROTO_TCP:
+ printf("TCP ");
+ break;
+ case IPPROTO_UDP:
+ printf("UDP ");
+ break;
+ case IPPROTO_ICMP:
+ printf("ICMP:%d ",((char *)portptr)[0]&0xff);
+ break;
+ default:
+ printf("p=%d ",ip->ip_p);
+ break;
}
print_ip(ip->ip_src);
- if ( ip->ip_p == IPPROTO_TCP || ip->ip_p == IPPROTO_UDP ) {
+ if (ip->ip_p==IPPROTO_TCP || ip->ip_p==IPPROTO_UDP) {
printf(":%d ",ntohs(portptr[0]));
}
print_ip(ip->ip_dst);
- if ( ip->ip_p == IPPROTO_TCP || ip->ip_p == IPPROTO_UDP ) {
+ if ( ip->ip_p==IPPROTO_TCP || ip->ip_p==IPPROTO_UDP) {
printf(":%d ",ntohs(portptr[1]));
}
printf("\n");
}
#endif
- for ( fptr = chain; fptr != NULL; fptr = fptr->next ) {
-
- if ( (src.s_addr & fptr->src_mask.s_addr) == fptr->src.s_addr
- && (dst.s_addr & fptr->dst_mask.s_addr) == fptr->dst.s_addr ) {
-
- if ( (frwl_proto = fptr->flags & IP_FW_F_KIND)
- == IP_FW_F_ALL ) {
-
- /* Universal frwl - we've got a match! */
+ 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) {
+ /* Universal frwl - we've got a match! */
#ifdef DEBUG_IPFIREWALL
printf("universal frwl match\n");
#endif
#ifdef IPFIREWALL_VERBOSE
- /*
- * VERY ugly piece of code which actually
- * makes kernel printf for denyed packets...
- * This thingy will be added in more places...
- */
- if ( !(fptr->flags & IP_FW_F_ACCEPT) &&
- (fptr->flags & IP_FW_F_PRN)) {
- printf("ip_fw_chk says no to ");
- switch(ip->ip_p) {
- case IPPROTO_TCP: printf("TCP "); break;
- case IPPROTO_UDP: printf("UDP "); break;
- case IPPROTO_ICMP: printf("ICMP:%d ",((char *)portptr)[0]&0xff); break;
- default: printf("p=%d ",ip->ip_p); break;
- }
- print_ip(ip->ip_src);
- if ( ip->ip_p == IPPROTO_TCP || ip->ip_p == IPPROTO_UDP ) {
- printf(":%d ",ntohs(portptr[0]));
- } else {
- printf("\n");
- }
- print_ip(ip->ip_dst);
- if ( ip->ip_p == IPPROTO_TCP || ip->ip_p == IPPROTO_UDP ) {
- printf(":%d ",ntohs(portptr[1]));
- }
- printf("\n");
- return(0);
- }
+ if (!(f->flags & IP_FW_F_ACCEPT))
+ goto bad_packet;
+ return 1;
+#else
+ return( f->flags & IP_FW_F_ACCEPT );
#endif
- return( fptr->flags & IP_FW_F_ACCEPT );
} else {
-
- /* Specific frwl - packet's protocol must match frwl's */
-
- if ( !got_proto ) {
- u_short *portptr = (u_short *)&(((u_int *)ip)[ip->ip_hl]);
- switch( ip->ip_p ) {
- case IPPROTO_TCP:
- proto = IP_FW_F_TCP;
- src_port = ntohs(portptr[0]); /* first two shorts in TCP */
- dst_port = ntohs(portptr[1]); /* are src and dst ports */
- break;
- case IPPROTO_UDP:
- proto = IP_FW_F_UDP;
- src_port = ntohs(portptr[0]); /* first two shorts in UDP */
- dst_port = ntohs(portptr[1]); /* are src and dst ports */
- break;
+ /*
+ * Specific firewall - packet's
+ * protocol must match firewall's
+ */
+ if (!got_proto) {
+ /*
+ * We still had not determined the protocol
+ * of this packet,now the time to do so.
+ */
+ switch(ip->ip_p) {
+ case IPPROTO_TCP:
+ /*
+ * First two shorts in TCP are src/dst ports
+ */
+ proto=IP_FW_F_TCP;
+ src_port=ntohs(portptr[0]);
+ dst_port=ntohs(portptr[1]);
+ break;
+ case IPPROTO_UDP:
+ /*
+ * First two shorts in UDP are src/dst ports
+ */
+ proto = IP_FW_F_UDP;
+ src_port = ntohs(portptr[0]);
+ dst_port = ntohs(portptr[1]);
+ break;
case IPPROTO_ICMP:
- proto = IP_FW_F_ICMP;
- break;
- default: proto = IP_FW_F_ALL;
+ proto=IP_FW_F_ICMP;
+ break;
+ default:
+ proto=IP_FW_F_ALL;
#ifdef DEBUG_IPFIREWALL
- printf("non TCP/UDP packet\n");
+ printf("non TCP/UDP packet\n");
#endif
- }
- got_proto = 1;
- }
+ }
+ got_proto=1;
+ }
+ /*
+ * At this moment we surely know the protocol of this
+ * packet and we'll check if it matches,then proceed futher..
+ */
+ if (proto==frwl_proto) {
+
+ if (proto==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,
+ f->flags&IP_FW_F_DRNG))) {
+#ifdef IPFIREWALL_VERBOSE
+ if (!(f->flags & IP_FW_F_ACCEPT))
+ goto bad_packet;
+ return 1;
+#else
+ return( f->flags & IP_FW_F_ACCEPT);
+#endif
+ } /* Ports match */
+ } /* Proto matches */
+ } /* ALL/Specific */
+} /* IP addr/mask matches */
- if ( proto == frwl_proto ) {
-
- if (
- proto == IP_FW_F_ICMP
- ||
- (
- (
- fptr->n_src_p == 0
- ||
- port_match( &fptr->ports[0],
- fptr->n_src_p,
- src_port,
- fptr->flags & IP_FW_F_SRNG
- )
- )
- &&
- (
- fptr->n_dst_p == 0
- ||
- port_match( &fptr->ports[fptr->n_src_p],
- fptr->n_dst_p,
- dst_port,
- fptr->flags & IP_FW_F_DRNG
- )
- )
- )
- ) {
+ /*
+ * If we get here then none of the firewalls matched.
+ * So now we relay on policy defined by user-unmatched packet can
+ * be ever accepted or rejected...
+ */
+
+#ifdef IPFIREWALL_VERBOSE
+ if (!(ip_fw_policy))
+ goto bad_packet;
+ return 1;
+#else
+ return(ip_fw_policy);
+#endif
#ifdef IPFIREWALL_VERBOSE
+bad_packet:
/*
* VERY ugly piece of code which actually
- * makes kernel printf for denyed packets...
- * This thingy will be added in more places...
+ * makes kernel printf for denied packets...
*/
- if ( !(fptr->flags & IP_FW_F_ACCEPT) &&
- (fptr->flags & IP_FW_F_PRN)) {
+ if (f->flags&IP_FW_F_PRN) {
printf("ip_fw_chk says no to ");
switch(ip->ip_p) {
- case IPPROTO_TCP: printf("TCP "); break;
- case IPPROTO_UDP: printf("UDP "); break;
- case IPPROTO_ICMP: printf("ICMP:%d ",((char *)portptr)[0]&0xff); break;
- default: printf("p=%d ",ip->ip_p); break;
+ case IPPROTO_TCP:
+ printf("TCP ");
+ break;
+ case IPPROTO_UDP:
+ printf("UDP ");
+ break;
+ case IPPROTO_ICMP:
+ printf("ICMP:%d ",((char *)portptr)[0]&0xff);
+ break;
+ default:
+ printf("p=%d ",ip->ip_p);
+ break;
}
print_ip(ip->ip_src);
- if ( ip->ip_p == IPPROTO_TCP || ip->ip_p == IPPROTO_UDP ) {
+ if (ip->ip_p==IPPROTO_TCP || ip->ip_p==IPPROTO_UDP) {
printf(":%d ",ntohs(portptr[0]));
} else {
printf("\n");
@@ -257,60 +268,147 @@ struct ip_fw *chain;
printf(":%d ",ntohs(portptr[1]));
}
printf("\n");
- return(0);
}
+ return(0);
#endif
- return( fptr->flags & IP_FW_F_ACCEPT);
- }
+}
+#endif /* IPFIREWALL */
- }
- }
- }
- }
+#ifdef IPACCT
+void ip_acct_cnt(ip,chain,nh_conv)
+struct ip *ip;
+struct ip_fw *chain;
+int nh_conv;
+{
+ struct in_addr src, dst;
+ char got_proto=0,rev=0;
+ int frwl_proto, proto=0;
+ register struct ip_fw *f;
+ u_short src_port=0, dst_port=0;
+ u_short *portptr=(u_short *)&(((u_int *)ip)[ip->ip_hl]);
- /*
- * If we get here then none of the frwls matched.
- * So now we relay on policy defined by user-unmatched packet can
- * be ever accepted or rejected...
- */
+ if (!chain)
+ return;
-#ifdef IPFIREWALL_VERBOSE
+ src = ip->ip_src;
+ dst = ip->ip_dst;
+
+ 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) {
+ rev=0;
+ goto addr_match;
+ }
+ if ((f->flags&IP_FW_F_BIDIR) &&
+ ((src.s_addr&f->src_mask.s_addr)==f->dst.s_addr
+ && (dst.s_addr&f->dst_mask.s_addr)==f->src.s_addr)) {
+ rev=1;
+ goto addr_match;
+ }
+ continue;
+addr_match:
+ frwl_proto=f->flags&IP_FW_F_KIND;
+ if (frwl_proto==IP_FW_F_ALL) {
+ /* Universal frwl - we've got a match! */
+
+ f->p_cnt++; /* Rise packet count */
+
+ /*
+ * Rise byte count,
+ * if need to convert from
+ * host to network byte
+ * order,do it.
+ */
+ if (nh_conv)
+ f->b_cnt+=ntohs(ip->ip_len);
+ else
+ f->b_cnt+=ip->ip_len;
+ } else {
+ /*
+ * Specific firewall - packet's
+ * protocol must match firewall's
+ */
+ if (!got_proto) {
/*
- * VERY ugly piece of code which actually
- * makes kernel printf for denyed packets...
- * This thingy will be added in more places...
+ * We still had not determined the protocol
+ * of this packet,now the time to do so.
*/
- if ( !(ip_fw_policy) &&
- (fptr->flags & IP_FW_F_PRN)) {
- printf("ip_fw_chk says no to ");
- switch(ip->ip_p) {
- case IPPROTO_TCP: printf("TCP "); break;
- case IPPROTO_UDP: printf("UDP "); break;
- case IPPROTO_ICMP: printf("ICMP:%d ",((char *)portptr)[0]&0xff); break;
- default: printf("p=%d ",ip->ip_p); break;
- }
- print_ip(ip->ip_src);
- if ( ip->ip_p == IPPROTO_TCP || ip->ip_p == IPPROTO_UDP ) {
- printf(":%d ",ntohs(portptr[0]));
- } else {
- printf("\n");
- }
- print_ip(ip->ip_dst);
- if ( ip->ip_p == IPPROTO_TCP || ip->ip_p == IPPROTO_UDP ) {
- printf(":%d ",ntohs(portptr[1]));
- }
- printf("\n");
- return(0);
- }
-#endif
- return(ip_fw_policy);
+ switch(ip->ip_p) {
+ case IPPROTO_TCP:
+ /*
+ * First two shorts in TCP are src/dst ports
+ */
+ proto=IP_FW_F_TCP;
+ src_port=ntohs(portptr[0]);
+ dst_port=ntohs(portptr[1]);
+ break;
+ case IPPROTO_UDP:
+ /*
+ * First two shorts in UDP are src/dst ports
+ */
+ proto = IP_FW_F_UDP;
+ src_port = ntohs(portptr[0]);
+ dst_port = ntohs(portptr[1]);
+ break;
+ case IPPROTO_ICMP:
+ proto=IP_FW_F_ICMP;
+ break;
+ default:
+ proto=IP_FW_F_ALL;
+ }
+ got_proto=1;
+ }
+ /*
+ * At this moment we surely know the protocol of this
+ * packet and we'll check if it matches,then proceed futher..
+ */
+ if (proto==frwl_proto) {
+
+ if ((proto==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,
+ f->flags&IP_FW_F_DRNG)))
+ || ((rev)
+ && (port_match(&f->ports[0],f->n_src_p,dst_port,
+ f->flags&IP_FW_F_SRNG)
+ && port_match(&f->ports[f->n_src_p],f->n_dst_p,src_port,
+ f->flags&IP_FW_F_DRNG))))
+ {
+ f->p_cnt++; /* Rise packet count */
+ /*
+ * Rise byte count,
+ * if need to convert from
+ * host to network byte
+ * order,do it.
+ */
+ if (nh_conv)
+ f->b_cnt+=ntohs(ip->ip_len);
+ else
+ f->b_cnt+=ip->ip_len;
+ } /* Ports match */
+ } /* Proto matches */
+ } /* ALL/Specific */
+} /* IP addr/mask matches */
+} /* End of whole function */
+#endif /* IPACCT */
+static
+void
+zero_fw_chain(chainptr)
+struct ip_fw *chainptr;
+{
+struct ip_fw *ctmp=chainptr;
+ while(ctmp) {
+ ctmp->p_cnt=0l;
+ ctmp->b_cnt=0l;
+ ctmp=ctmp->next;
+ }
}
-
static
void
free_fw_chain(chainptr)
@@ -353,6 +451,9 @@ struct ip_fw *frwl;
}
bcopy( frwl, ftmp, sizeof( struct ip_fw ) );
+ ftmp->p_cnt=0L;
+ ftmp->b_cnt=0L;
+
ftmp->next = NULL;
if (*chainptr==NULL)
@@ -371,8 +472,10 @@ struct ip_fw *frwl;
if (newkind!=IP_FW_F_ALL
&& oldkind!=IP_FW_F_ALL
- && oldkind!=newkind)
- continue;
+ && oldkind!=newkind) {
+ chtmp_prev=chtmp;
+ continue;
+ }
/*
* Very very *UGLY* code...
* Sorry,but i had to do this....
@@ -459,7 +562,7 @@ struct ip_fw *frwl;
ftmp->n_dst_p : USHRT_MAX;
if (chtmp->flags & IP_FW_F_DRNG)
- o_dr=chtmp->ports[n_o+1]-chtmp->ports[n_o];
+ o_dr=chtmp->ports[n_o+1]-chtmp->ports[n_o];
else
o_dr=(chtmp->n_dst_p)?
chtmp->n_dst_p : USHRT_MAX;
@@ -571,12 +674,121 @@ struct ip_fw *frwl;
else return(EINVAL);
}
+struct ip_fw *
+check_ipfw_struct(m)
+struct mbuf *m;
+{
+struct ip_fw *frwl;
+
+ if ( m->m_len != sizeof(struct ip_fw) ) {
+#ifdef DEBUG_IPFIREWALL
+ printf("ip_fw_ctl: len=%d, want %d\n",m->m_len,
+ sizeof(struct ip_fw));
+#endif
+ return(NULL);
+ }
+
+ frwl = mtod(m,struct ip_fw*);
+
+ if ( (frwl->flags & ~IP_FW_F_MASK) != 0 ) {
+#ifdef DEBUG_IPFIREWALL
+ printf("ip_fw_ctl: undefined flag bits set (flags=%x)\n",
+ frwl->flags);
+#endif
+ return(NULL);
+ }
+
+ if ( (frwl->flags & IP_FW_F_SRNG) && frwl->n_src_p < 2 ) {
+#ifdef DEBUG_IPFIREWALL
+ printf("ip_fw_ctl: src range set but n_src_p=%d\n",
+ frwl->n_src_p);
+#endif
+ return(NULL);
+ }
+
+ if ( (frwl->flags & IP_FW_F_DRNG) && frwl->n_dst_p < 2 ) {
+#ifdef DEBUG_IPFIREWALL
+ printf("ip_fw_ctl: dst range set but n_dst_p=%d\n",
+ frwl->n_dst_p);
+#endif
+ return(NULL);
+ }
+
+ if ( frwl->n_src_p + frwl->n_dst_p > IP_FW_MAX_PORTS ) {
+#ifdef DEBUG_IPFIREWALL
+ printf("ip_fw_ctl: too many ports (%d+%d)\n",
+ frwl->n_src_p,frwl->n_dst_p);
+#endif
+ return(NULL);
+ }
+
+#if 0
+ if ( (frwl->flags & IP_FW_F_KIND) == IP_FW_F_ICMP ) {
+#ifdef DEBUG_IPFIREWALL
+ printf("ip_fw_ctl: request for unsupported ICMP frwling\n");
+#endif
+ return(NULL);
+ }
+#endif
+return frwl;
+}
+
+
+
+
+#ifdef IPACCT
+int
+ip_acct_ctl(stage,m)
+int stage;
+struct mbuf *m;
+{
+if ( stage == IP_ACCT_FLUSH )
+ {
+ free_fw_chain(&ip_acct_chain);
+ return(0);
+ }
+if ( stage == IP_ACCT_ZERO )
+ {
+ zero_fw_chain(ip_acct_chain);
+ return(0);
+ }
+if ( stage == IP_ACCT_ADD
+ || stage == IP_ACCT_DEL
+ ) {
+
+ struct ip_fw *frwl;
+
+ if (!(frwl=check_ipfw_struct(m)))
+ return (EINVAL);
+
+ switch (stage) {
+ case IP_ACCT_ADD:
+ return( add_to_chain(&ip_acct_chain,frwl));
+ case IP_ACCT_DEL:
+ return( del_from_chain(&ip_acct_chain,frwl));
+ default:
+ /*
+ * Should be panic but...
+ */
+#ifdef DEBUG_IPFIREWALL
+ printf("ip_acct_ctl: unknown request %d\n",stage);
+#endif
+ return(EINVAL);
+ }
+ }
+#ifdef DEBUG_IPFIREWALL
+ printf("ip_acct_ctl: unknown request %d\n",stage);
+#endif
+ return(EINVAL);
+}
+#endif
+
+#ifdef IPFIREWALL
int
ip_fw_ctl(stage,m)
int stage;
struct mbuf *m;
{
-int *tmp_policy_ptr;
if ( stage == IP_FW_FLUSH )
{
free_fw_chain(&ip_fw_blk_chain);
@@ -584,120 +796,98 @@ if ( stage == IP_FW_FLUSH )
return(0);
}
- if ( m == 0 )
- {
- printf("ip_fw_ctl: NULL mbuf ptr\n");
- return( EINVAL );
- }
+if ( m == 0 )
+ {
+ printf("ip_fw_ctl: NULL mbuf ptr\n");
+ return(EINVAL);
+ }
if ( stage == IP_FW_POLICY )
{
+ int *tmp_policy_ptr;
tmp_policy_ptr=mtod(m,int *);
if ((*tmp_policy_ptr)!=1 && (*tmp_policy_ptr)!=0)
- return ( EINVAL );
+ return (EINVAL);
ip_fw_policy=*tmp_policy_ptr;
return 0;
}
- if ( stage == IP_FW_CHK_BLK || stage == IP_FW_CHK_FWD ) {
+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) ) {
#ifdef DEBUG_IPFIREWALL
- printf("ip_fw_ctl: mbuf len=%d, want at least %d\n",m->m_len,sizeof(struct ip) + 2 * sizeof(u_short));
+ printf("ip_fw_ctl: mbuf len=%d, want at least %d\n",
+ m->m_len,sizeof(struct ip) + 2 * sizeof(u_short));
#endif
return( EINVAL );
- }
+ }
+
ip = mtod(m,struct ip *);
+
if ( ip->ip_hl != sizeof(struct ip) / sizeof(int) ) {
#ifdef DEBUG_IPFIREWALL
- printf("ip_fw_ctl: ip->ip_hl=%d, want %d\n",ip->ip_hl,sizeof(struct ip)/sizeof(int));
+ printf("ip_fw_ctl: ip->ip_hl=%d, want %d\n",ip->ip_hl,
+ sizeof(struct ip)/sizeof(int));
#endif
- return( EINVAL );
- }
+ 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);
- }
-
- } else if ( stage == IP_FW_ADD_BLK
- || stage == IP_FW_ADD_FWD
- || stage == IP_FW_DEL_BLK
- || stage == IP_FW_DEL_FWD
- ) {
-
- struct ip_fw *frwl;
-
- if ( m->m_len != sizeof(struct ip_fw) ) {
-#ifdef DEBUG_IPFIREWALL
- printf("ip_fw_ctl: len=%d, want %d\n",m->m_len,sizeof(struct ip_fw));
-#endif
- return( EINVAL );
- }
-
- frwl = mtod(m,struct ip_fw*);
- if ( (frwl->flags & ~IP_FW_F_MASK) != 0 ) {
-#ifdef DEBUG_IPFIREWALL
- printf("ip_fw_ctl: undefined flag bits set (flags=%x)\n",frwl->flags);
-#endif
- return( EINVAL );
- }
+ return(0);
+ else
+ return(EACCES);
+ }
- if ( (frwl->flags & IP_FW_F_SRNG) && frwl->n_src_p < 2 ) {
-#ifdef DEBUG_IPFIREWALL
- printf("ip_fw_ctl: src range set but n_src_p=%d\n",frwl->n_src_p);
-#endif
- return( EINVAL );
- }
+/*
+ * Here we really working hard-adding new elements
+ * to blocking/forwarding chains or deleting'em
+ */
- if ( (frwl->flags & IP_FW_F_DRNG) && frwl->n_dst_p < 2 ) {
-#ifdef DEBUG_IPFIREWALL
- printf("ip_fw_ctl: dst range set but n_dst_p=%d\n",frwl->n_dst_p);
-#endif
- return( EINVAL );
- }
+if ( stage == IP_FW_ADD_BLK
+ || stage == IP_FW_ADD_FWD
+ || stage == IP_FW_DEL_BLK
+ || stage == IP_FW_DEL_FWD
+ ) {
- if ( frwl->n_src_p + frwl->n_dst_p > IP_FW_MAX_PORTS ) {
-#ifdef DEBUG_IPFIREWALL
- printf("ip_fw_ctl: too many ports (%d+%d)\n",frwl->n_src_p,frwl->n_dst_p);
+ struct ip_fw *frwl;
+
+ frwl=check_ipfw_struct(m);
+ if (frwl==NULL)
+ return (EINVAL);
+#ifdef nenado
+ if (!(frwl=check_ipfw_struct(m)))
+ return (EINVAL);
#endif
- return( EINVAL );
- }
-#if 0
- if ( (frwl->flags & IP_FW_F_KIND) == IP_FW_F_ICMP ) {
+ switch (stage) {
+ case IP_FW_ADD_BLK:
+ return(add_to_chain(&ip_fw_blk_chain,frwl));
+ case IP_FW_ADD_FWD:
+ return(add_to_chain(&ip_fw_fwd_chain,frwl));
+ case IP_FW_DEL_BLK:
+ return(del_from_chain(&ip_fw_blk_chain,frwl));
+ case IP_FW_DEL_FWD:
+ return(del_from_chain(&ip_fw_fwd_chain,frwl));
+ default:
+ /*
+ * Should be panic but...
+ */
#ifdef DEBUG_IPFIREWALL
- printf("ip_fw_ctl: request for unsupported ICMP frwling\n");
+ printf("ip_fw_ctl: unknown request %d\n",stage);
#endif
- return( EINVAL );
+ return(EINVAL);
}
-
-#endif
- if ( stage == IP_FW_ADD_BLK )
- {
- return( add_to_chain(&ip_fw_blk_chain,frwl));
- }
- if ( stage == IP_FW_ADD_FWD )
- {
- return( add_to_chain(&ip_fw_fwd_chain,frwl));
- }
- if ( stage == IP_FW_DEL_BLK )
- {
- return( del_from_chain(&ip_fw_blk_chain,frwl));
- }
- if ( stage == IP_FW_DEL_FWD )
- {
- return( del_from_chain(&ip_fw_fwd_chain,frwl));
- }
- }
+}
#ifdef DEBUG_IPFIREWALL
printf("ip_fw_ctl: unknown request %d\n",stage);
#endif
return(EINVAL);
-
}
+#endif /* IPFIREWALL */
diff --git a/sys/netinet/ip_fw.h b/sys/netinet/ip_fw.h
index ca999bc..f9979b6 100644
--- a/sys/netinet/ip_fw.h
+++ b/sys/netinet/ip_fw.h
@@ -26,39 +26,40 @@ 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 */
- u_short flags;
-
- u_short n_src_p, n_dst_p; /* # of src ports and # of dst ports */
+ 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 */
/* src ports; max of 10 ports in all; */
/* count of 0 means match all ports) */
-#define IP_FW_MAX_PORTS 10 /* A reasonable maximum */
- u_short ports[IP_FW_MAX_PORTS]; /* Array of port numbers to match */
+#define IP_FW_MAX_PORTS 10 /* A reasonable maximum */
+ u_short ports[IP_FW_MAX_PORTS]; /* Array of port numbers to match */
+ u_long p_cnt,b_cnt; /* Packet and byte counters */
};
/*
* Values for "flags" field .
*/
-#define IP_FW_F_ALL 0 /* This is a universal packet firewall*/
-#define IP_FW_F_TCP 1 /* This is a TCP packet firewall */
-#define IP_FW_F_UDP 2 /* This is a UDP packet firewall */
-#define IP_FW_F_ICMP 3 /* This is a ICMP packet firewall */
-#define IP_FW_F_KIND 3 /* Mask to isolate firewall kind */
-#define IP_FW_F_ACCEPT 4 /* This is an accept firewall (as *
+#define IP_FW_F_ALL 0x00 /* This is a universal packet firewall*/
+#define IP_FW_F_TCP 0x01 /* This is a TCP packet firewall */
+#define IP_FW_F_UDP 0x02 /* This is a UDP packet firewall */
+#define IP_FW_F_ICMP 0x03 /* This is a ICMP packet firewall */
+#define IP_FW_F_KIND 0x03 /* Mask to isolate firewall kind */
+#define IP_FW_F_ACCEPT 0x04 /* This is an accept firewall (as *
* opposed to a deny firewall)*
* */
-#define IP_FW_F_SRNG 8 /* The first two src ports are a min *
+#define IP_FW_F_SRNG 0x08 /* The first two src ports are a min *
* and max range (stored in host byte *
* order). *
* */
-#define IP_FW_F_DRNG 16 /* The first two dst ports are a min *
+#define IP_FW_F_DRNG 0x10 /* The first two dst ports are a min *
* and max range (stored in host byte *
* order). *
* (ports[0] <= port <= ports[1]) *
* */
-#define IP_FW_F_PRN 32 /* In verbose mode print this firewall*/
-#define IP_FW_F_MASK 0x3F /* All possible flag bits mask */
+#define IP_FW_F_PRN 0x20 /* In verbose mode print this firewall*/
+#define IP_FW_F_BIDIR 0x40 /* For accounting-count two way */
+#define IP_FW_F_MASK 0x7F /* All possible flag bits mask */
/*
* New IP firewall options for [gs]etsockopt at the RAW IP level.
@@ -74,12 +75,24 @@ struct ip_fw {
#define IP_FW_FLUSH (IP_FW_BASE_CTL+6)
#define IP_FW_POLICY (IP_FW_BASE_CTL+7)
+#define IP_ACCT_ADD (IP_FW_BASE_CTL+10)
+#define IP_ACCT_DEL (IP_FW_BASE_CTL+11)
+#define IP_ACCT_FLUSH (IP_FW_BASE_CTL+12)
+#define IP_ACCT_ZERO (IP_FW_BASE_CTL+13)
+
/*
* Main firewall chains definitions and global var's definitions.
*/
+#ifdef KERNEL
+#ifdef IPFIREWALL
extern struct ip_fw *ip_fw_blk_chain;
extern struct ip_fw *ip_fw_fwd_chain;
extern int ip_fw_policy;
-
#endif
+#ifdef IPACCT
+extern struct ip_fw *ip_acct_chain;
+#endif
+#endif /* KERNEL */
+
+#endif /* _IP_FW_H */
diff --git a/sys/netinet/ip_input.c b/sys/netinet/ip_input.c
index fd7eab6..085d0ff 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.9 1994/10/28 15:09:48 jkh Exp $
+ * $Id: ip_input.c,v 1.10 1994/11/08 12:47:29 jkh Exp $
*/
#include <sys/param.h>
@@ -59,6 +59,9 @@
#ifdef IPFIREWALL
#include <netinet/ip_fw.h>
#endif
+#ifdef IPACCT
+#include <netinet/ip_fw.h>
+#endif
#include <sys/socketvar.h>
struct socket *ip_rsvpd;
@@ -353,6 +356,17 @@ next:
ours:
+#ifdef IPACCT
+ /*
+ * If packet came to us we count it...
+ * This way we count all incoming packets which has
+ * not been forwarded...
+ * 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);
+#endif
+
/*
* If offset or IP_MF are set, must reassemble.
* Otherwise, nothing need be done.
@@ -1125,6 +1139,11 @@ 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 358b42f..a734c42 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.7 1994/09/09 22:05:02 wollman Exp $
+ * $Id: ip_output.c,v 1.8 1994/09/14 03:10:13 wollman Exp $
*/
#include <sys/param.h>
@@ -53,6 +53,13 @@
#include <netinet/in_var.h>
#include <netinet/ip_var.h>
+#ifdef IPFIREWALL
+#include <netinet/ip_fw.h>
+#endif
+#ifdef IPACCT
+#include <netinet/ip_fw.h>
+#endif
+
#ifdef vax
#include <machine/mtpr.h>
#endif
@@ -401,6 +408,15 @@ sendorfree:
done:
if (ro == &iproute && (flags & IP_ROUTETOIF) == 0 && ro->ro_rt)
RTFREE(ro->ro_rt);
+#ifdef IPACCT
+ /*
+ * Count outgoing packet,here we count both our packets and
+ * those we forward.
+ * Here we want to convert ip_len to host byte order when counting
+ * so we set 3rd arg to 1.
+ */
+ ip_acct_cnt(ip,ip_acct_chain,1);
+#endif
return (error);
bad:
m_freem(m0);
diff --git a/sys/netinet/raw_ip.c b/sys/netinet/raw_ip.c
index 949e427..4b33614 100644
--- a/sys/netinet/raw_ip.c
+++ b/sys/netinet/raw_ip.c
@@ -56,6 +56,9 @@
#ifdef IPFIREWALL
#include <netinet/ip_fw.h>
#endif
+#ifdef IPACCT
+#include <netinet/ip_fw.h>
+#endif
struct inpcb rawinpcb;
@@ -227,7 +230,21 @@ rip_ctloutput(op, so, level, optname, m)
error=EINVAL;
return(error);
#endif
-
+#ifdef IPACCT
+ case IP_ACCT_DEL:
+ case IP_ACCT_ADD:
+ case IP_ACCT_FLUSH:
+ case IP_ACCT_ZERO:
+
+ if (op = PRCO_SETOPT) {
+ error=ip_acct_ctl(optname, *m);
+ if (*m)
+ (void)m_free(*m);
+ }
+ else
+ error=EINVAL;
+ return(error);
+#endif
case IP_RSVP_ON:
error = ip_rsvp_init(so);
OpenPOWER on IntegriCloud