diff options
Diffstat (limited to 'netinet/ip_rules.c')
-rw-r--r-- | netinet/ip_rules.c | 229 |
1 files changed, 229 insertions, 0 deletions
diff --git a/netinet/ip_rules.c b/netinet/ip_rules.c new file mode 100644 index 0000000..f080ec5b --- /dev/null +++ b/netinet/ip_rules.c @@ -0,0 +1,229 @@ +/* $FreeBSD$ */ + +/* +* Copyright (C) 1993-2000 by Darren Reed. +* +* Redistribution and use in source and binary forms are permitted +* provided that this notice is preserved and due credit is given +* to the original author and the contributors. +*/ + +#include <sys/types.h> +#include <sys/time.h> +#include <sys/socket.h> +#if !defined(__FreeBSD__) && !defined(__OpenBSD__) && !defined(__sgi) +# include <sys/systm.h> +#endif +#include <sys/errno.h> +#include <sys/param.h> +#if !defined(__SVR4) && !defined(__svr4__) && !defined(__hpux) +# include <sys/mbuf.h> +#endif +#if defined(__FreeBSD__) && (__FreeBSD_version > 220000) +# include <sys/sockio.h> +#else +# include <sys/ioctl.h> +#endif /* FreeBSD */ +#include <net/if.h> +#include <netinet/in.h> +#include <netinet/in_systm.h> +#include <netinet/ip.h> +#include <netinet/tcp.h> +#include "netinet/ip_compat.h" +#include "netinet/ip_fil.h" + +#include "netinet/ip_rules.h" + +#ifndef _KERNEL +# include <string.h> +#endif /* _KERNEL */ + +#ifdef IPFILTER_COMPILED + +static u_long in_rule__0[] = { +0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0xffffffff, 0, 0, 0, 0, 0, 0, 0x1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0x80000000, 0x8002, 0, 0, 0, 0xffff, 0, 0, 0x4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 +}; + +static u_long out_rule__0[] = { +0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0xffffffff, 0, 0, 0, 0, 0, 0, 0x1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0x80000000, 0x4002, 0, 0, 0, 0xffff, 0, 0, 0x4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 +}; + +frentry_t *ipf_rules_in_[1] = { + (frentry_t *)&in_rule__0 +}; + +frentry_t *ipfrule_match_in_(fin, passp) +fr_info_t *fin; +u_32_t *passp; +{ + frentry_t *fr = NULL; + + fr = (frentry_t *)&in_rule__0; + return fr; +} + +frentry_t *ipf_rules_out_[1] = { + (frentry_t *)&out_rule__0 +}; + +frentry_t *ipfrule_match_out_(fin, passp) +fr_info_t *fin; +u_32_t *passp; +{ + frentry_t *fr = NULL; + + fr = (frentry_t *)&out_rule__0; + return fr; +} +static frentry_t ipfrule_out_; + +int ipfrule_add_out_() +{ + int i, j, err = 0, max; + frentry_t *fp; + + max = sizeof(ipf_rules_out_)/sizeof(frentry_t *); + for (i = 0; i < max; i++) { + fp = ipf_rules_out_[i]; + fp->fr_next = NULL; + for (j = i + 1; j < max; j++) + if (strncmp(fp->fr_group, + ipf_rules_out_[j]->fr_group, + FR_GROUPLEN) == 0) { + fp->fr_next = ipf_rules_out_[j]; + break; + } + } + + fp = &ipfrule_out_; + bzero((char *)fp, sizeof(*fp)); + fp->fr_type = FR_T_CALLFUNC|FR_T_BUILTIN; + fp->fr_flags = FR_OUTQUE|FR_NOMATCH; + fp->fr_data = (void *)ipf_rules_out_[0]; + fp->fr_dsize = sizeof(ipf_rules_out_[0]); + fp->fr_v = 4; + fp->fr_func = (ipfunc_t)ipfrule_match_out_; + err = frrequest(IPL_LOGIPF, SIOCADDFR, (caddr_t)fp, fr_active, 0); + return err; +} + + +int ipfrule_remove_out_() +{ + int err = 0, i; + frentry_t *fp; + + /* + * Try to remove the outbound rule. + */ + if (ipfrule_out_.fr_ref > 0) { + err = EBUSY; + } else { + i = sizeof(ipf_rules_out_)/sizeof(frentry_t *) - 1; + for (; i >= 0; i--) { + fp = ipf_rules_out_[i]; + if (fp->fr_ref > 1) { + err = EBUSY; + break; + } + } + } + if (err == 0) + err = frrequest(IPL_LOGIPF, SIOCDELFR, + (caddr_t)&ipfrule_out_, fr_active, 0); + if (err) + return err; + + + return err; +} +static frentry_t ipfrule_in_; + +int ipfrule_add_in_() +{ + int i, j, err = 0, max; + frentry_t *fp; + + max = sizeof(ipf_rules_in_)/sizeof(frentry_t *); + for (i = 0; i < max; i++) { + fp = ipf_rules_in_[i]; + fp->fr_next = NULL; + for (j = i + 1; j < max; j++) + if (strncmp(fp->fr_group, + ipf_rules_in_[j]->fr_group, + FR_GROUPLEN) == 0) { + fp->fr_next = ipf_rules_in_[j]; + break; + } + } + + fp = &ipfrule_in_; + bzero((char *)fp, sizeof(*fp)); + fp->fr_type = FR_T_CALLFUNC|FR_T_BUILTIN; + fp->fr_flags = FR_INQUE|FR_NOMATCH; + fp->fr_data = (void *)ipf_rules_in_[0]; + fp->fr_dsize = sizeof(ipf_rules_in_[0]); + fp->fr_v = 4; + fp->fr_func = (ipfunc_t)ipfrule_match_in_; + err = frrequest(IPL_LOGIPF, SIOCADDFR, (caddr_t)fp, fr_active, 0); + return err; +} + + +int ipfrule_remove_in_() +{ + int err = 0, i; + frentry_t *fp; + + /* + * Try to remove the inbound rule. + */ + if (ipfrule_in_.fr_ref > 0) { + err = EBUSY; + } else { + i = sizeof(ipf_rules_in_)/sizeof(frentry_t *) - 1; + for (; i >= 0; i--) { + fp = ipf_rules_in_[i]; + if (fp->fr_ref > 1) { + err = EBUSY; + break; + } + } + } + if (err == 0) + err = frrequest(IPL_LOGIPF, SIOCDELFR, + (caddr_t)&ipfrule_in_, fr_active, 0); + if (err) + return err; + + + return err; +} + +int ipfrule_add() +{ + int err; + + err = ipfrule_add_out_(); + if (err != 0) + return err; + err = ipfrule_add_in_(); + if (err != 0) + return err; + return 0; +} + + +int ipfrule_remove() +{ + int err; + + err = ipfrule_remove_out_(); + if (err != 0) + return err; + err = ipfrule_remove_in_(); + if (err != 0) + return err; + return 0; +} +#endif /* IPFILTER_COMPILED */ |