Program to add/delete a rule from pf

Rajkumar S rajkumars at gmail.com
Tue Jul 18 17:30:59 UTC 2006


Hi,

I am trying to do a pf module for snortsam, that requires a function
to add and delete
rules, much like iptables -A and -D As pfctl does not support deletion
of rules, and as
reloading all rules every time a new rule has to be added or deleted
is a pita, I am
trying to write a program to do it, which will be used to write snortsam plugin.

After going through sources of pfctl and some other programs, I wrote
a skeltel program
to add a rule via ioctl, but that is not working.

My feeling is  that I need to do some more init of pfioc_rule and
pf_rule structures to
get it working, but the code of pfctl is bit dense to get a clear
understanding. It will
be great if some one here can lend a helping hand!

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


More information about the freebsd-pf mailing list