deleting a rule

2006-07-19 Thread Rajkumar S.

Hi,

I am trying to do a pf plugin for snortsam, that requires a function  
to add and delete rules, much like iptables -A and -D. I am using  
freebsd 6.1


There is already a pf plugin in snortsam which defines an anchor and  
put the following rules inside it.


table blockin persist
table blockout persist
block in log quick from blockin to any
block out log quick from any to blockout

The problem with this approach is that I can only block whole ip,  
while I want to block only connections. The rules that I want inside  
the anchor is some thing like


block in quick on fxp0 proto tcp from 192.168.3.3 port 1025 to  
64.233.167.99 port 80
block in quick on fxp0 proto tcp from 192.168.3.23 port 1054 to  
72.14.207.99 port 8080


And these rules are dynamic ie, the rule one might be for 10 minutes  
and after which it needs to be deleted.


The current way is to flush the anchor and then load the anchor with  
all the rules except the one deleted. It is a pita if I want to do  
this with out touching the disk, that too from a snortsam pluin.


So I am trying to write a simple program that can add a rule using  
ioctl, deleting is next. I am trying to learn from pfctl and other  
sources, but I am getting stuck at DIOCADDRULE which needs a couple of  
data structures to be initialised. It seems I have correctly called  
DIOCXBEGIN and DIOCGETADDRS to get both ticket and pool ticket. But  
DIOCADDRULE does not execute successfully. I am attaching the code I  
have, if some one can lend a helping hand it would be great!


Again, I am going through all these only to get the iptables -D and -A  
functionality (ie add and delete a rule with out touching file system)  
If there is a solution for it, that's the one I want.


with warm regards,

raj

--
#include sys/ioctl.h
#include sys/socket.h
#include net/if.h
#include netinet/in.h
#include net/pfvar.h
#include arpa/inet.h
#include fcntl.h

#define IP_PROTO_TCP 6

int main (){
struct pfioc_trans trans;
struct pfioc_trans_e   trans_e;
struct pf_rule pr;
struct pfioc_rule  pr_ioctl;
struct pfioc_pooladdr  pp;

struct hostent *h;

char*pf_device = /dev/pf;
char anchor[100];
int  dev;
int  mode  = O_RDWR;

dev = open(pf_device, mode);

bzero(trans, sizeof(trans));
bzero(trans_e, sizeof(trans_e));
bzero(pr, sizeof(pr));
bzero(pp, sizeof(pp));
bzero(h, sizeof(h));

strlcpy(trans_e.anchor, snortsam, sizeof(trans_e.anchor));
trans_e.rs_num = PF_RULESET_FILTER;

trans.size = 1;
trans.esize = sizeof(struct pfioc_trans_e);
trans.array = trans_e;
if (ioctl(dev, DIOCXBEGIN, trans)) printf (Error\n);

memcpy(pp.anchor, anchor, sizeof(pp.anchor));
pp.r_action = PF_DROP;
pp.r_num = 0;
if (ioctl(dev, DIOCGETADDRS, pp)) printf (DIOCGETADDRS\n);

pr.action = PF_DROP;
pr.direction = PF_IN;
pr.af = AF_INET;
pr.proto = IP_PROTO_TCP;
pr_ioctl.ticket =  trans_e.ticket;
pr_ioctl.pool_ticket = pp.ticket;
memcpy(pr_ioctl.rule, pr, sizeof(pr_ioctl.rule));
strlcpy(pr_ioctl.anchor_call, anchor, sizeof(pr_ioctl.anchor_call));

if (ioctl(dev, DIOCADDRULE, pr_ioctl))  printf (DIOCADDRULE\n);
close (dev);
}





Re: deleting a rule

2006-07-19 Thread Daniel Hartmeier
On Wed, Jul 19, 2006 at 01:35:51PM +0530, Rajkumar S. wrote:

 And these rules are dynamic ie, the rule one might be for 10 minutes  
 and after which it needs to be deleted.
 
 The current way is to flush the anchor and then load the anchor with  
 all the rules except the one deleted. It is a pita if I want to do  
 this with out touching the disk, that too from a snortsam pluin.

Why don't you create sub-anchors, one for each single rule? Then
removing one rule (and the sub-anchor that contains it) can be done by
simply flushing the sub-anchor.

You need one call in the main ruleset or the existing anchor, using the
wildcard '*', that call evaluates all sub-anchors, and the call doesn't
need to be updated when you insert/remove sub-anchors.

You could even use the sub-anchor names in some clever way, like put the
rule's expiration time (unix epoch) in that string, so to purge expired
rules, you can traverse the list of sub-anchors alphabetically and stop
when a name is larger than time(NULL).

Or store some ID in the name (which your plugin associates with the
entry), which helps you purge the sub-anchor without traversing them all
searching for some rule.

Unless you expect to have several thousand rules like this concurrently,
the overhead of the sub-anchor evaluation isn't that terrible.

IIRC, the ioctl API once contained a call to insert/remove one
particular rule in a certain place of the ruleset, but it was
cumbersome, and the entire (sub-)anchor concept makes it superfluous in
most cases.

Daniel


Re: deleting a rule

2006-07-19 Thread Rajkumar S.

Quoting Daniel Hartmeier [EMAIL PROTECTED]:


Why don't you create sub-anchors, one for each single rule?


Brilliant!! Thanks a lot! This is what I want!

raj

PS: I still would love to see an example program to use pf ioctl, or  
some documentation, now just for academic purpose. pfctl is bit  
complex, especially when it gets to the parse.y and because it uses  
pfctl structure for most of the data.





Re: deleting a rule

2006-07-19 Thread Camiel Dobbelaar


On Wed, 19 Jul 2006, Rajkumar S. wrote:
 PS: I still would love to see an example program to use pf ioctl, or some
 documentation, now just for academic purpose. pfctl is bit complex, especially
 when it gets to the parse.y and because it uses pfctl structure for most of
 the data.

/usr/src/usr.sbin/ftp-proxy/filter.c  is pretty bare bones.


--
Cam