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);
}