IP Firewall code from Daniel Boulet and J.S.Antsilevich

Submitted by:	danny ugen
This commit is contained in:
Jordan K. Hubbard 1994-10-28 15:09:49 +00:00
parent b877c0f37e
commit 100ba1a617
10 changed files with 761 additions and 8 deletions

View File

@ -4,7 +4,7 @@
#
# This kernel is NOT MEANT to be runnable!
#
# $Id: LINT,v 1.100 1994/10/26 19:20:27 jkh Exp $
# $Id: LINT,v 1.101 1994/10/26 21:10:13 wollman Exp $
#
#
@ -41,6 +41,12 @@ options MATH_EMULATE #Support for x87 emulation
#options GPL_MATH_EMULATE #Support for x87 emualtion via
#new math emulator
# Enable the following (IPFIREWALL_VERBOSE optional) to enable the IP firewall
# code. This is used in conjunction with the ipfw(1) command. See the
# man page for more details.
options IPFIREWALL #firewall test
options IPFIREWALL_VERBOSE #print information about dropped packets
#
# This directive defines a number of things:
# - The compiled kernel is to be called `kernel'

View File

@ -1,7 +1,7 @@
# This file tells config what files go into building a kernel,
# files marked standard are always included.
#
# $Id: files.i386,v 1.55 1994/10/26 19:19:12 jkh Exp $
# $Id: files.i386,v 1.56 1994/10/27 20:44:27 jkh Exp $
#
i386/apm/apm.c optional apm device-driver
i386/apm/apm_setup.s optional apm
@ -158,3 +158,4 @@ gnu/i386/fpemul/reg_u_mul.s optional gpl_math_emulate
gnu/i386/fpemul/reg_u_sub.s optional gpl_math_emulate
gnu/i386/fpemul/wm_shrx.s optional gpl_math_emulate
gnu/i386/fpemul/wm_sqrt.s optional gpl_math_emulate
netinet/ip_fw.c optional ipfirewall

100
sys/i386/conf/IPFIREWALL Normal file
View File

@ -0,0 +1,100 @@
#
# IPFIREWALL -- Sample Generic kernel suitable for building an IP firewall.
#
# $Id$
#
machine "i386"
cpu "I386_CPU"
cpu "I486_CPU"
cpu "I586_CPU"
ident GENERIC
maxusers 10
options INET #InterNETworking
options FFS #Berkeley Fast File System
options NFS #Network File system
options PROCFS #Process filesystem
options "COMPAT_43" #Compatible with BSD 4.3
options UCONSOLE #X Console support
options "FAT_CURSOR" #block cursor in syscons or pccons
options "SCSI_DELAY=15" #Be pessimistic about Joe SCSI device
options "NCONS=4" #4 virtual consoles
options BOUNCE_BUFFERS #include support for DMA bounce buffers
options USERCONFIG #Allow user configuration with -c
options GATEWAY #Pass packets
options IPFIREWALL #firewall code
options IPFIREWALL_VERBOSE #print information about dropped packets
options IPBROADCASTECHO=1 #send reply to broadcast pings
options IPMASKAGENT=1 #send reply to icmp mask requests
config kernel root on wd0 swap on wd0 and wd1 and sd0 and sd1 dumps on wd0
controller isa0
controller pci0
controller fdc0 at isa? port "IO_FD1" bio irq 6 drq 2 vector fdintr
disk fd0 at fdc0 drive 0
disk fd1 at fdc0 drive 1
#tape ft0 at fdc0 drive 2
controller wdc0 at isa? port "IO_WD1" bio irq 14 vector wdintr
disk wd0 at wdc0 drive 0
disk wd1 at wdc0 drive 1
controller wdc1 at isa? port "IO_WD2" bio irq 15 vector wdintr
disk wd2 at wdc1 drive 0
disk wd3 at wdc1 drive 1
controller ncr0
controller bt0 at isa? port "IO_BT0" bio irq ? vector btintr
controller ahb0 at isa? bio irq ? vector ahbintr
controller aha0 at isa? port "IO_AHA0" bio irq ? drq 5 vector ahaintr
controller uha0 at isa? port "IO_UHA0" bio irq ? drq 5 vector uhaintr
controller aic0 at isa? port 0x340 bio irq 11 vector aicintr
controller pas0 at isa? port 0x1f88 bio
controller sea0 at isa? bio irq 5 iomem 0xc8000 iosiz 0x2000 vector seaintr
controller scbus0
device sd0
device sd1
device sd2
device sd3
device st0
device st1
device cd0 #Only need one of these, the code dynamically grows
device wt0 at isa? port 0x300 bio irq 5 drq 1 vector wtintr
device mcd0 at isa? port 0x300 bio irq 10 vector mcdintr
device mcd1 at isa? port 0x340 bio irq 11 vector mcdintr
device sc0 at isa? port "IO_KBD" tty irq 1 vector scintr
device npx0 at isa? port "IO_NPX" irq 13 vector npxintr
device sio0 at isa? port "IO_COM1" tty irq 4 vector siointr
device sio1 at isa? port "IO_COM2" tty irq 3 vector siointr
device sio2 at isa? port "IO_COM3" tty irq 5 vector siointr
device sio3 at isa? port "IO_COM4" tty irq 9 vector siointr
device lpt0 at isa? port? tty irq 7 vector lptintr
device lpt1 at isa? port? tty
device lpt2 at isa? port? tty
device ed0 at isa? port 0x280 net irq 5 iomem 0xd8000 vector edintr
device ed1 at isa? port 0x300 net irq 5 iomem 0xd8000 vector edintr
device ed2 at isa? port 0x300 net irq 10 iomem 0xcc000 vector edintr
device ie0 at isa? port 0x360 net irq 7 iomem 0xd0000 vector ieintr
device is0 at isa? port 0x280 net irq 10 drq 7 vector isintr
pseudo-device loop
pseudo-device ether
pseudo-device log
pseudo-device ppp 2
pseudo-device sl 2
pseudo-device pty 16
pseudo-device speaker
pseudo-device gzip # Exec gzipped a.out's
pseudo-device bpfilter 1

View File

@ -4,7 +4,7 @@
#
# This kernel is NOT MEANT to be runnable!
#
# $Id: LINT,v 1.100 1994/10/26 19:20:27 jkh Exp $
# $Id: LINT,v 1.101 1994/10/26 21:10:13 wollman Exp $
#
#
@ -41,6 +41,12 @@ options MATH_EMULATE #Support for x87 emulation
#options GPL_MATH_EMULATE #Support for x87 emualtion via
#new math emulator
# Enable the following (IPFIREWALL_VERBOSE optional) to enable the IP firewall
# code. This is used in conjunction with the ipfw(1) command. See the
# man page for more details.
options IPFIREWALL #firewall test
options IPFIREWALL_VERBOSE #print information about dropped packets
#
# This directive defines a number of things:
# - The compiled kernel is to be called `kernel'

View File

@ -4,7 +4,7 @@
#
# This kernel is NOT MEANT to be runnable!
#
# $Id: LINT,v 1.100 1994/10/26 19:20:27 jkh Exp $
# $Id: LINT,v 1.101 1994/10/26 21:10:13 wollman Exp $
#
#
@ -41,6 +41,12 @@ options MATH_EMULATE #Support for x87 emulation
#options GPL_MATH_EMULATE #Support for x87 emualtion via
#new math emulator
# Enable the following (IPFIREWALL_VERBOSE optional) to enable the IP firewall
# code. This is used in conjunction with the ipfw(1) command. See the
# man page for more details.
options IPFIREWALL #firewall test
options IPFIREWALL_VERBOSE #print information about dropped packets
#
# This directive defines a number of things:
# - The compiled kernel is to be called `kernel'

View File

@ -1,7 +1,7 @@
# This file tells config what files go into building a kernel,
# files marked standard are always included.
#
# $Id: files.i386,v 1.55 1994/10/26 19:19:12 jkh Exp $
# $Id: files.i386,v 1.56 1994/10/27 20:44:27 jkh Exp $
#
i386/apm/apm.c optional apm device-driver
i386/apm/apm_setup.s optional apm
@ -158,3 +158,4 @@ gnu/i386/fpemul/reg_u_mul.s optional gpl_math_emulate
gnu/i386/fpemul/reg_u_sub.s optional gpl_math_emulate
gnu/i386/fpemul/wm_shrx.s optional gpl_math_emulate
gnu/i386/fpemul/wm_sqrt.s optional gpl_math_emulate
netinet/ip_fw.c optional ipfirewall

512
sys/netinet/ip_fw.c Normal file
View File

@ -0,0 +1,512 @@
/*
* Copyright (c) 1993 Daniel Boulet
* Copyright (c) 1994 Ugen J.S.Antsilevich
*
* Redistribution and use in source forms, with and without modification,
* are permitted provided that this entire comment appears intact.
*
* Redistribution in binary form may occur without any restrictions.
* Obviously, it would be nice if you gave credit where credit is due
* but requiring it would be too onerous.
*
* This software is provided ``AS IS'' without any warranties of any kind.
*/
/*
* Implement IP packet firewall
*/
#include <sys/param.h>
#include <sys/systm.h>
#include <sys/malloc.h>
#include <sys/mbuf.h>
#include <sys/domain.h>
#include <sys/protosw.h>
#include <sys/socket.h>
#include <sys/errno.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 <netinet/ip_fw.h>
struct ip_firewall *ip_fw_fwd_chain;
struct ip_firewall *ip_fw_blk_chain;
int ip_fw_policy=1;
inline
void
print_ip(xaddr)
struct in_addr xaddr;
{
u_long addr = ntohl(xaddr.s_addr);
printf("%d.%d.%d.%d",(addr>>24) & 0xff,
(addr>>16)&0xff,
(addr>>8)&0xff,
addr&0xFF);
}
/*
* Returns 1 if the port is matched by the vector, 0 otherwise
*/
inline
int port_match(portptr,nports,port,range_flag)
u_short *portptr;
int nports;
u_short port;
int range_flag;
{
if ( range_flag ) {
if ( portptr[0] <= port && port <= portptr[1] ) {
return( 1 );
}
nports -= 2;
portptr += 2;
}
while ( nports-- > 0 ) {
if ( *portptr++ == port ) {
return( 1 );
}
}
return(0);
}
/*
* Returns 0 if packet should be dropped, 1 if it should be accepted
*/
int ip_firewall_check_print(ip,chain)
struct ip *ip;
struct ip_firewall *chain;
{
if ( !ip_firewall_check_noprint(ip,chain) ) {
u_short *portptr = (u_short *)&(((u_int *)ip)[ip->ip_hl]);
printf("ip_firewall_check 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);
}
return(1);
}
int ip_firewall_check_noprint(ip,chain)
struct ip *ip;
struct ip_firewall *chain;
{
struct in_addr src, dst;
char got_proto = 0;
int firewall_proto, proto = 0;
register struct ip_firewall *fptr;
u_short src_port = 0, dst_port = 0;
if ( chain == NULL ) { /* Is there a firewall chain? */
return(1);
}
src = ip->ip_src;
dst = ip->ip_dst;
#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;
}
print_ip(ip->ip_src);
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 ) {
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 ( (firewall_proto = fptr->flags & IP_FIREWALL_KIND) == IP_FIREWALL_UNIVERSAL ) {
/* Universal firewall - we've got a match! */
#ifdef DEBUG_IPFIREWALL
printf("universal firewall match\n");
#endif
#ifdef olf
return( (fptr->flags & IP_FIREWALL_ACCEPT) == IP_FIREWALL_ACCEPT );
#else
return( fptr->flags & IP_FIREWALL_ACCEPT );
#endif
} else {
/* Specific firewall - packet's protocol must match firewall's */
if ( !got_proto ) {
u_short *portptr = (u_short *)&(((u_int *)ip)[ip->ip_hl]);
switch( ip->ip_p ) {
case IPPROTO_TCP:
proto = IP_FIREWALL_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_FIREWALL_UDP;
src_port = ntohs(portptr[0]); /* first two shorts in UDP */
dst_port = ntohs(portptr[1]); /* are src and dst ports */
break;
case IPPROTO_ICMP:
proto = IP_FIREWALL_ICMP;
break;
default: proto = IP_FIREWALL_UNIVERSAL;
#ifdef DEBUG_IPFIREWALL
printf("non TCP/UDP packet\n");
#endif
}
got_proto = 1;
}
if ( proto == firewall_proto ) {
if (
proto == IP_FIREWALL_ICMP
||
(
(
fptr->num_src_ports == 0
||
port_match( &fptr->ports[0],
fptr->num_src_ports,
src_port,
fptr->flags & IP_FIREWALL_SRC_RANGE
)
)
&&
(
fptr->num_dst_ports == 0
||
port_match( &fptr->ports[fptr->num_src_ports],
fptr->num_dst_ports,
dst_port,
fptr->flags & IP_FIREWALL_DST_RANGE
)
)
)
) {
#ifdef old
return( (fptr->flags & IP_FIREWALL_ACCEPT) == IP_FIREWALL_ACCEPT );
#else
return( fptr->flags & IP_FIREWALL_ACCEPT);
#endif
}
}
}
}
}
/*
* If we get here then none of the firewalls matched.
* If the first firewall was an accept firewall then reject the packet.
* If the first firewall was a deny firewall then accept the packet.
*
* The basic idea is that there is a virtual final firewall which is
* the exact complement of the first firewall (this idea is a slight
* variant of the way that the Telebit's Netblazer IP filtering scheme
* handles this case).
*/
#ifdef old
return( ((chain->flags) & IP_FIREWALL_ACCEPT) != IP_FIREWALL_ACCEPT );
#else
return(ip_fw_policy);
#endif
}
static
void
free_firewall_chain(chainptr)
struct ip_firewall **chainptr;
{
while ( *chainptr != NULL ) {
struct ip_firewall *ftmp;
ftmp = *chainptr;
*chainptr = ftmp->next;
free(ftmp,M_SOOPTS);
}
}
static
int
add_to_chain(chainptr,firewall)
struct ip_firewall **chainptr;
struct ip_firewall *firewall;
{
struct ip_firewall *ftmp;
struct ip_firewall *chaintmp=NULL;
ftmp = malloc( sizeof(struct ip_firewall), M_SOOPTS, M_DONTWAIT );
if ( ftmp == NULL ) {
printf("ip_firewall_ctl: malloc said no\n");
return( ENOSPC );
}
bcopy( firewall, ftmp, sizeof( struct ip_firewall ) );
ftmp->next = NULL;
if (*chainptr==NULL)
{
*chainptr=ftmp;
}
else
{
/*
* This made so to get firewall behavior more *human* oriented-
* as to speed up the packet check the first firewall matching
* the packet used to determine ALLOW/DENY condition,and one
* tends to set up more specific firewall later then more general
* this change allows adding firewalls to the head of chain so
* that the first matching is last added in line of matching
* firewalls.This change is not real turn in behavior but helps
* to use firewall efficiently.
*/
#ifdef old
chaintmp=*chainptr;
while(chaintmp->next!=NULL)
chaintmp=chaintmp->next;
chaintmp->next=ftmp;
#else
chaintmp=*chainptr;
*chainptr=ftmp;
ftmp->next=chaintmp;
#endif
}
return(0);
}
static
int
del_from_chain(chainptr,firewall)
struct ip_firewall **chainptr;
struct ip_firewall *firewall;
{
struct ip_firewall *ftmp,*ltmp;
u_short tport1,tport2,tmpnum;
char matches,was_found;
ftmp=*chainptr;
if ( ftmp == NULL ) {
printf("ip_firewall_ctl: chain is empty\n");
return( EINVAL );
}
ltmp=NULL;
was_found=0;
while( ftmp != NULL )
{
matches=1;
if ((bcmp(&ftmp->src,&firewall->src,sizeof(struct in_addr)))
|| (bcmp(&ftmp->src_mask,&firewall->src_mask,sizeof(struct in_addr)))
|| (bcmp(&ftmp->dst,&firewall->dst,sizeof(struct in_addr)))
|| (bcmp(&ftmp->dst_mask,&firewall->dst_mask,sizeof(struct in_addr)))
|| (ftmp->flags!=firewall->flags))
matches=0;
tport1=ftmp->num_src_ports+ftmp->num_dst_ports;
tport2=firewall->num_src_ports+firewall->num_dst_ports;
if (tport1!=tport2)
matches=0;
else
if (tport1!=0)
{
for (tmpnum=0;tmpnum < tport1 && tmpnum < IP_FIREWALL_MAX_PORTS;tmpnum++)
if (ftmp->ports[tmpnum]!=firewall->ports[tmpnum])
matches=0;
}
if(matches)
{
was_found=1;
if (ltmp)
{
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; */
}
}
else
{
ltmp = ftmp;
ftmp = ftmp->next;
}
}
if (was_found) return 0;
else return(EINVAL);
}
int
ip_firewall_ctl(stage,m)
int stage;
struct mbuf *m;
{
int *tmp_policy_ptr;
if ( stage == IP_FW_FLUSH )
{
free_firewall_chain(&ip_fw_blk_chain);
free_firewall_chain(&ip_fw_fwd_chain);
return(0);
}
if ( m == 0 )
{
printf("ip_firewall_ctl: NULL mbuf ptr\n");
return( EINVAL );
}
if ( stage == IP_FW_POLICY )
{
tmp_policy_ptr=mtod(m,int *);
ip_fw_policy=*tmp_policy_ptr;
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) ) {
printf("ip_firewall_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) ) {
printf("ip_firewall_ctl: ip->ip_hl=%d, want %d\n",ip->ip_hl,sizeof(struct ip)/sizeof(int));
return( EINVAL );
}
if ( ip_firewall_check(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_firewall *firewall;
if ( m->m_len != sizeof(struct ip_firewall) ) {
printf("ip_firewall_ctl: len=%d, want %d\n",m->m_len,sizeof(struct ip_firewall));
return( EINVAL );
}
firewall = mtod(m,struct ip_firewall*);
if ( (firewall->flags & ~IP_FIREWALL_FLAG_BITS) != 0 ) {
printf("ip_firewall_ctl: undefined flag bits set (flags=%x)\n",firewall->flags);
return( EINVAL );
}
if ( (firewall->flags & IP_FIREWALL_SRC_RANGE) && firewall->num_src_ports < 2 ) {
printf("ip_firewall_ctl: SRC_RANGE set but num_src_ports=%d\n",firewall->num_src_ports);
return( EINVAL );
}
if ( (firewall->flags & IP_FIREWALL_DST_RANGE) && firewall->num_dst_ports < 2 ) {
printf("ip_firewall_ctl: DST_RANGE set but num_dst_ports=%d\n",firewall->num_dst_ports);
return( EINVAL );
}
if ( firewall->num_src_ports + firewall->num_dst_ports > IP_FIREWALL_MAX_PORTS ) {
printf("ip_firewall_ctl: too many ports (%d+%d)\n",firewall->num_src_ports,firewall->num_dst_ports);
return( EINVAL );
}
#if 0
if ( (firewall->flags & IP_FIREWALL_KIND) == IP_FIREWALL_ICMP ) {
printf("ip_firewall_ctl: request for unsupported ICMP firewalling\n");
return( EINVAL );
}
#endif
if ( stage == IP_FW_ADD_BLK )
{
return( add_to_chain(&ip_fw_blk_chain,firewall));
}
if ( stage == IP_FW_ADD_FWD )
{
return( add_to_chain(&ip_fw_fwd_chain,firewall));
}
if ( stage == IP_FW_DEL_BLK )
{
return( del_from_chain(&ip_fw_blk_chain,firewall));
}
if ( stage == IP_FW_DEL_FWD )
{
return( del_from_chain(&ip_fw_fwd_chain,firewall));
}
}
printf("ip_firewall_ctl: unknown request %d\n",stage);
return(EINVAL);
}

77
sys/netinet/ip_fw.h Normal file
View File

@ -0,0 +1,77 @@
/*
* Copyright (c) 1993 Daniel Boulet
* Copyright (c) 1994 Ugen J.S.Antsilevich
*
* Redistribution and use in source forms, with and without modification,
* are permitted provided that this entire comment appears intact.
*
* Redistribution in binary form may occur without any restrictions.
* Obviously, it would be nice if you gave credit where credit is due
* but requiring it would be too onerous.
*
* This software is provided ``AS IS'' without any warranties of any kind.
*/
/*
* Format of an IP firewall descriptor
*
* src, dst, src_mask, dst_mask are always stored in network byte order.
* flags and num_*_ports are stored in host byte order (of course).
* Port numbers are stored in HOST byte order.
*/
struct ip_firewall {
struct ip_firewall *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;
#define IP_FIREWALL_UNIVERSAL 0 /* This is a universal packet firewall*/
#define IP_FIREWALL_TCP 1 /* This is a TCP packet firewall */
#define IP_FIREWALL_UDP 2 /* This is a UDP packet firewall */
#define IP_FIREWALL_ICMP 3 /* This is a ICMP packet firewall */
#define IP_FIREWALL_KIND 3 /* Mask to isolate firewall kind */
#define IP_FIREWALL_ACCEPT 4 /* This is an accept firewall (as */
/* opposed to a deny firewall) */
#define IP_FIREWALL_SRC_RANGE 8 /* The first two src ports are a min
* and max range (stored in host byte
* order).
*/
#define IP_FIREWALL_DST_RANGE 16 /* The first two dst ports are a min
* and max range (stored in host byte
* order).
* (ports[0] <= port <= ports[1])
*/
#define IP_FIREWALL_FLAG_BITS 0x1f /* All possible flag bits */
u_short num_src_ports, num_dst_ports;/* # 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_FIREWALL_MAX_PORTS 10 /* A reasonable maximum */
u_short ports[IP_FIREWALL_MAX_PORTS]; /* Array of port numbers to match */
};
/*
* New IP firewall options for [gs]etsockopt at the RAW IP level.
*/
#define IP_FW_BASE_CTL 53
#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)
#define IP_FW_POLICY (IP_FW_BASE_CTL+7)
extern struct ip_firewall *ip_fw_blk_chain;
extern struct ip_firewall *ip_fw_fwd_chain;
extern int ip_fw_policy;
#ifdef IPFIREWALL_VERBOSE
#define ip_firewall_check ip_firewall_check_print
#else
#define ip_firewall_check ip_firewall_check_noprint
#endif

View File

@ -31,7 +31,7 @@
* SUCH DAMAGE.
*
* @(#)ip_input.c 8.2 (Berkeley) 1/4/94
* $Id: ip_input.c,v 1.7 1994/10/02 17:48:39 phk Exp $
* $Id: ip_input.c,v 1.8 1994/10/10 07:56:07 phk Exp $
*/
#include <sys/param.h>
@ -56,6 +56,10 @@
#include <netinet/ip_var.h>
#include <netinet/ip_icmp.h>
#ifdef IPFIREWALL
#include <netinet/ip_fw.h>
#endif
#include <sys/socketvar.h>
struct socket *ip_rsvpd;
@ -231,6 +235,13 @@ ipintr()
m_adj(m, ip->ip_len - m->m_pkthdr.len);
}
#ifdef IPFIREWALL
if ( ((char *)&(ip->ip_dst.s_addr))[0] != 127
&& !ip_firewall_check(ip,ip_fw_blk_chain) ) {
goto bad;
}
#endif
/*
* Process options and, if not destined for us,
* ship it on. ip_dooptions returns 1 when an
@ -341,6 +352,7 @@ ipintr()
goto next;
ours:
/*
* If offset or IP_MF are set, must reassemble.
* Otherwise, nothing need be done.
@ -1019,9 +1031,19 @@ ip_forward(m, srcrt)
dest = 0;
#ifdef DIAGNOSTIC
if (ipprintfs)
printf("forward: src %lx dst %lx ttl %x\n",
printf("forward: src %lx dst %lx ttl %x\n",
ip->ip_src.s_addr, ip->ip_dst.s_addr, ip->ip_ttl);
#endif
#ifdef IPFIREWALL
if ( ((char *)&(ip->ip_dst.s_addr))[0] != 127
&& !ip_firewall_check(ip,ip_fw_fwd_chain) ) {
ipstat.ips_cantforward++;
m_freem(m);
return;
}
#endif
if (m->m_flags & M_BCAST || in_canforward(ip->ip_dst) == 0) {
ipstat.ips_cantforward++;
m_freem(m);

View File

@ -31,7 +31,7 @@
* SUCH DAMAGE.
*
* @(#)raw_ip.c 8.2 (Berkeley) 1/4/94
* $Id: raw_ip.c,v 1.4 1994/09/14 03:10:15 wollman Exp $
* $Id: raw_ip.c,v 1.5 1994/10/02 17:48:42 phk Exp $
*/
#include <sys/param.h>
@ -53,6 +53,10 @@
#include <netinet/ip_mroute.h>
#include <netinet/in_pcb.h>
#ifdef IPFIREWALL
#include <netinet/ip_fw.h>
#endif
struct inpcb rawinpcb;
/*
@ -204,6 +208,24 @@ rip_ctloutput(op, so, level, optname, m)
}
break;
#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:
case IP_FW_POLICY:
if (op == PRCO_SETOPT)
error=ip_firewall_ctl(optname, *m);
else
error=EINVAL;
return(error);
#endif
case IP_RSVP_ON:
error = ip_rsvp_init(so);
break;