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



Reply via email to