1145516Sdarrenr/* $FreeBSD$ */ 2145516Sdarrenr 3145516Sdarrenr/* 4145516Sdarrenr* Copyright (C) 1993-2000 by Darren Reed. 5145516Sdarrenr* 6145516Sdarrenr* Redistribution and use in source and binary forms are permitted 7145516Sdarrenr* provided that this notice is preserved and due credit is given 8145516Sdarrenr* to the original author and the contributors. 9145516Sdarrenr*/ 10145516Sdarrenr 11145516Sdarrenr#include <sys/types.h> 12145516Sdarrenr#include <sys/time.h> 13145516Sdarrenr#include <sys/socket.h> 14145516Sdarrenr#if !defined(__FreeBSD__) && !defined(__OpenBSD__) && !defined(__sgi) 15145516Sdarrenr# include <sys/systm.h> 16145516Sdarrenr#endif 17145516Sdarrenr#include <sys/errno.h> 18145516Sdarrenr#include <sys/param.h> 19145516Sdarrenr#if !defined(__SVR4) && !defined(__svr4__) && !defined(__hpux) 20145516Sdarrenr# include <sys/mbuf.h> 21145516Sdarrenr#endif 22145516Sdarrenr#if defined(__FreeBSD__) && (__FreeBSD_version > 220000) 23145516Sdarrenr# include <sys/sockio.h> 24145516Sdarrenr#else 25145516Sdarrenr# include <sys/ioctl.h> 26145516Sdarrenr#endif /* FreeBSD */ 27145516Sdarrenr#include <net/if.h> 28145516Sdarrenr#include <netinet/in.h> 29145516Sdarrenr#include <netinet/in_systm.h> 30145516Sdarrenr#include <netinet/ip.h> 31145516Sdarrenr#include <netinet/tcp.h> 32145516Sdarrenr#include "netinet/ip_compat.h" 33145516Sdarrenr#include "netinet/ip_fil.h" 34145516Sdarrenr 35145516Sdarrenr#include "netinet/ip_rules.h" 36145516Sdarrenr 37145516Sdarrenr#ifndef _KERNEL 38145516Sdarrenr# include <string.h> 39145516Sdarrenr#endif /* _KERNEL */ 40145516Sdarrenr 41145516Sdarrenr#ifdef IPFILTER_COMPILED 42145516Sdarrenr 43145516Sdarrenrstatic u_long in_rule__0[] = { 44145516Sdarrenr0, 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 45145516Sdarrenr}; 46145516Sdarrenr 47145516Sdarrenrstatic u_long out_rule__0[] = { 48145516Sdarrenr0, 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 49145516Sdarrenr}; 50145516Sdarrenr 51145516Sdarrenrfrentry_t *ipf_rules_in_[1] = { 52145516Sdarrenr (frentry_t *)&in_rule__0 53145516Sdarrenr}; 54145516Sdarrenr 55145516Sdarrenrfrentry_t *ipfrule_match_in_(fin, passp) 56145516Sdarrenrfr_info_t *fin; 57145516Sdarrenru_32_t *passp; 58145516Sdarrenr{ 59145516Sdarrenr frentry_t *fr = NULL; 60145516Sdarrenr 61145516Sdarrenr fr = (frentry_t *)&in_rule__0; 62145516Sdarrenr return fr; 63145516Sdarrenr} 64145516Sdarrenr 65145516Sdarrenrfrentry_t *ipf_rules_out_[1] = { 66145516Sdarrenr (frentry_t *)&out_rule__0 67145516Sdarrenr}; 68145516Sdarrenr 69145516Sdarrenrfrentry_t *ipfrule_match_out_(fin, passp) 70145516Sdarrenrfr_info_t *fin; 71145516Sdarrenru_32_t *passp; 72145516Sdarrenr{ 73145516Sdarrenr frentry_t *fr = NULL; 74145516Sdarrenr 75145516Sdarrenr fr = (frentry_t *)&out_rule__0; 76145516Sdarrenr return fr; 77145516Sdarrenr} 78145516Sdarrenrstatic frentry_t ipfrule_out_; 79145516Sdarrenr 80145516Sdarrenrint ipfrule_add_out_() 81145516Sdarrenr{ 82145516Sdarrenr int i, j, err = 0, max; 83145516Sdarrenr frentry_t *fp; 84145516Sdarrenr 85145516Sdarrenr max = sizeof(ipf_rules_out_)/sizeof(frentry_t *); 86145516Sdarrenr for (i = 0; i < max; i++) { 87145516Sdarrenr fp = ipf_rules_out_[i]; 88145516Sdarrenr fp->fr_next = NULL; 89145516Sdarrenr for (j = i + 1; j < max; j++) 90145516Sdarrenr if (strncmp(fp->fr_group, 91145516Sdarrenr ipf_rules_out_[j]->fr_group, 92145516Sdarrenr FR_GROUPLEN) == 0) { 93145516Sdarrenr fp->fr_next = ipf_rules_out_[j]; 94145516Sdarrenr break; 95145516Sdarrenr } 96145516Sdarrenr } 97145516Sdarrenr 98145516Sdarrenr fp = &ipfrule_out_; 99145516Sdarrenr bzero((char *)fp, sizeof(*fp)); 100145516Sdarrenr fp->fr_type = FR_T_CALLFUNC|FR_T_BUILTIN; 101145516Sdarrenr fp->fr_flags = FR_OUTQUE|FR_NOMATCH; 102145516Sdarrenr fp->fr_data = (void *)ipf_rules_out_[0]; 103145516Sdarrenr fp->fr_dsize = sizeof(ipf_rules_out_[0]); 104145516Sdarrenr fp->fr_v = 4; 105145516Sdarrenr fp->fr_func = (ipfunc_t)ipfrule_match_out_; 106145516Sdarrenr err = frrequest(IPL_LOGIPF, SIOCADDFR, (caddr_t)fp, fr_active, 0); 107145516Sdarrenr return err; 108145516Sdarrenr} 109145516Sdarrenr 110145516Sdarrenr 111145516Sdarrenrint ipfrule_remove_out_() 112145516Sdarrenr{ 113145516Sdarrenr int err = 0, i; 114145516Sdarrenr frentry_t *fp; 115145516Sdarrenr 116145516Sdarrenr /* 117145516Sdarrenr * Try to remove the outbound rule. 118145516Sdarrenr */ 119145516Sdarrenr if (ipfrule_out_.fr_ref > 0) { 120145516Sdarrenr err = EBUSY; 121145516Sdarrenr } else { 122145516Sdarrenr i = sizeof(ipf_rules_out_)/sizeof(frentry_t *) - 1; 123145516Sdarrenr for (; i >= 0; i--) { 124145516Sdarrenr fp = ipf_rules_out_[i]; 125145516Sdarrenr if (fp->fr_ref > 1) { 126145516Sdarrenr err = EBUSY; 127145516Sdarrenr break; 128145516Sdarrenr } 129145516Sdarrenr } 130145516Sdarrenr } 131145516Sdarrenr if (err == 0) 132145516Sdarrenr err = frrequest(IPL_LOGIPF, SIOCDELFR, 133145516Sdarrenr (caddr_t)&ipfrule_out_, fr_active, 0); 134145516Sdarrenr if (err) 135145516Sdarrenr return err; 136145516Sdarrenr 137145516Sdarrenr 138145516Sdarrenr return err; 139145516Sdarrenr} 140145516Sdarrenrstatic frentry_t ipfrule_in_; 141145516Sdarrenr 142145516Sdarrenrint ipfrule_add_in_() 143145516Sdarrenr{ 144145516Sdarrenr int i, j, err = 0, max; 145145516Sdarrenr frentry_t *fp; 146145516Sdarrenr 147145516Sdarrenr max = sizeof(ipf_rules_in_)/sizeof(frentry_t *); 148145516Sdarrenr for (i = 0; i < max; i++) { 149145516Sdarrenr fp = ipf_rules_in_[i]; 150145516Sdarrenr fp->fr_next = NULL; 151145516Sdarrenr for (j = i + 1; j < max; j++) 152145516Sdarrenr if (strncmp(fp->fr_group, 153145516Sdarrenr ipf_rules_in_[j]->fr_group, 154145516Sdarrenr FR_GROUPLEN) == 0) { 155145516Sdarrenr fp->fr_next = ipf_rules_in_[j]; 156145516Sdarrenr break; 157145516Sdarrenr } 158145516Sdarrenr } 159145516Sdarrenr 160145516Sdarrenr fp = &ipfrule_in_; 161145516Sdarrenr bzero((char *)fp, sizeof(*fp)); 162145516Sdarrenr fp->fr_type = FR_T_CALLFUNC|FR_T_BUILTIN; 163145516Sdarrenr fp->fr_flags = FR_INQUE|FR_NOMATCH; 164145516Sdarrenr fp->fr_data = (void *)ipf_rules_in_[0]; 165145516Sdarrenr fp->fr_dsize = sizeof(ipf_rules_in_[0]); 166145516Sdarrenr fp->fr_v = 4; 167145516Sdarrenr fp->fr_func = (ipfunc_t)ipfrule_match_in_; 168145516Sdarrenr err = frrequest(IPL_LOGIPF, SIOCADDFR, (caddr_t)fp, fr_active, 0); 169145516Sdarrenr return err; 170145516Sdarrenr} 171145516Sdarrenr 172145516Sdarrenr 173145516Sdarrenrint ipfrule_remove_in_() 174145516Sdarrenr{ 175145516Sdarrenr int err = 0, i; 176145516Sdarrenr frentry_t *fp; 177145516Sdarrenr 178145516Sdarrenr /* 179145516Sdarrenr * Try to remove the inbound rule. 180145516Sdarrenr */ 181145516Sdarrenr if (ipfrule_in_.fr_ref > 0) { 182145516Sdarrenr err = EBUSY; 183145516Sdarrenr } else { 184145516Sdarrenr i = sizeof(ipf_rules_in_)/sizeof(frentry_t *) - 1; 185145516Sdarrenr for (; i >= 0; i--) { 186145516Sdarrenr fp = ipf_rules_in_[i]; 187145516Sdarrenr if (fp->fr_ref > 1) { 188145516Sdarrenr err = EBUSY; 189145516Sdarrenr break; 190145516Sdarrenr } 191145516Sdarrenr } 192145516Sdarrenr } 193145516Sdarrenr if (err == 0) 194145516Sdarrenr err = frrequest(IPL_LOGIPF, SIOCDELFR, 195145516Sdarrenr (caddr_t)&ipfrule_in_, fr_active, 0); 196145516Sdarrenr if (err) 197145516Sdarrenr return err; 198145516Sdarrenr 199145516Sdarrenr 200145516Sdarrenr return err; 201145516Sdarrenr} 202145516Sdarrenr 203145516Sdarrenrint ipfrule_add() 204145516Sdarrenr{ 205145516Sdarrenr int err; 206145516Sdarrenr 207145516Sdarrenr err = ipfrule_add_out_(); 208145516Sdarrenr if (err != 0) 209145516Sdarrenr return err; 210145516Sdarrenr err = ipfrule_add_in_(); 211145516Sdarrenr if (err != 0) 212145516Sdarrenr return err; 213145516Sdarrenr return 0; 214145516Sdarrenr} 215145516Sdarrenr 216145516Sdarrenr 217145516Sdarrenrint ipfrule_remove() 218145516Sdarrenr{ 219145516Sdarrenr int err; 220145516Sdarrenr 221145516Sdarrenr err = ipfrule_remove_out_(); 222145516Sdarrenr if (err != 0) 223145516Sdarrenr return err; 224145516Sdarrenr err = ipfrule_remove_in_(); 225145516Sdarrenr if (err != 0) 226145516Sdarrenr return err; 227145516Sdarrenr return 0; 228145516Sdarrenr} 229145516Sdarrenr#endif /* IPFILTER_COMPILED */ 230