iptc example

来源:互联网 发布:网络新闻稿 编辑:程序博客网 时间:2024/05/05 08:43

转自:http://wiki.tldp.org/iptc%20library%20HOWTO

 

now let's see the small example (the working one). We'd like to create iptables' equivalent rule:

iptables -A INPUT -s 156.145.1.3 -d 168.220.1.9 -i eth0 -p tcp --sport 0:59136 --dport 0:51201 -m limit -limit 2000/s --limit-burst 10 -m physdev-in eth0 -j ACCEPT

test.c:

 /* * To compile this code, use the following line: * gcc -g -o test test.c -liptc -liptables -ldl */#include <sys/errno.h>#include <stdio.h>#include <stdlib.h>#include <string.h>#include "libiptc/libiptc.h"#include "linux/netfilter/xt_limit.h"#include "linux/netfilter/xt_physdev.h"#include "iptables.h"#include <netinet/in.h>int main(void){        iptc_handle_t h;        const ipt_chainlabel chain = "INPUT";        const char * tablename = "filter";        struct ipt_entry * e;        struct ipt_entry_match * match_proto, * match_limit, * match_physdev;        struct ipt_entry_target * target;        struct ipt_tcp * tcpinfo;        struct xt_rateinfo * rateinfo;        struct xt_physdev_info * physdevinfo;        unsigned int size_ipt_entry, size_ipt_entry_match, size_ipt_entry_target, size_ipt_tcp, size_rateinfo, size_physdevinfo, total_length;        size_ipt_entry = IPT_ALIGN(sizeof(struct ipt_entry));        size_ipt_entry_match = IPT_ALIGN(sizeof(struct ipt_entry_match));        size_ipt_entry_target = 36;//IPT_ALIGN(sizeof(struct ipt_entry_target)); I don't know why the IPT_ALIGN() does not work in this case, may be 36 is 42 in netfilter :)        size_ipt_tcp = IPT_ALIGN(sizeof(struct ipt_tcp));        size_rateinfo = IPT_ALIGN(sizeof(struct xt_rateinfo));        size_physdevinfo = IPT_ALIGN(sizeof(struct xt_physdev_info));        total_length =  size_ipt_entry + size_ipt_entry_match * 3 + size_ipt_entry_target + size_ipt_tcp + size_rateinfo + size_physdevinfo;        //memory allocation for all structs that represent the netfilter rule we want to insert        e = calloc(1, total_length);        if(e == NULL)        {                printf("malloc failure");                exit(1);        }        //offsets to the other bits:        //target struct begining        e->target_offset = size_ipt_entry + size_ipt_entry_match * 3 + size_ipt_tcp + size_rateinfo + size_physdevinfo;        //next "e" struct, end of the current one        e->next_offset = total_length;        //set up packet matching rules: “-s 156.145.1.3 -d 168.220.1.9 -i eth0” part        //of our desirable rule        e->ip.src.s_addr = inet_addr("156.145.1.3");        e->ip.smsk.s_addr= inet_addr("255.255.255.255");        e->ip.dst.s_addr = inet_addr("168.220.1.9");        e->ip.dmsk.s_addr= inet_addr("255.255.255.255");        e->ip.proto = IPPROTO_TCP;        e->nfcache = 0;        strcpy(e->ip.iniface, "eth0");        //match structs setting:        //set match rule for the protocol to use        //”-p tcp” part of our desirable rule        match_proto = (struct ipt_entry_match *) e->elems;        match_proto->u.match_size = size_ipt_entry_match + size_ipt_tcp;        strcpy(match_proto->u.user.name, "tcp");//set name of the module, we will use in this match        //set match rule for the packet number per time limitation - against DoS attacks        //”-m limit” part of our desirable rule        match_limit = (struct ipt_entry_match *) (e->elems + match_proto->u.match_size);        match_limit->u.match_size = size_ipt_entry_match + size_rateinfo;        strcpy(match_limit->u.user.name, "limit");//set name of the module, we will use in this match        //set match rule for specific Ethernet card (interface)        //”-m physdev” part of our desirable rule        match_physdev = (struct ipt_entry_match *) (e->elems + match_proto->u.match_size + match_limit->u.match_size);        match_physdev->u.match_size = size_ipt_entry_match + size_physdevinfo;        strcpy(match_physdev->u.user.name, "physdev");//set name of the module, we will use in this match        //tcp module - match extension        //”--sport 0:59136 --dport 0:51201” part of our desirable rule        tcpinfo = (struct ipt_tcp *)match_proto->data;        tcpinfo->spts[0] = ntohs(0);        tcpinfo->spts[1] = ntohs(0xE7);        tcpinfo->dpts[0] = ntohs(0);        tcpinfo->dpts[1] = ntohs(0x1C8);        //limit module - match extension        //”-limit 2000/s --limit-burst 10” part of our desirable rule        rateinfo = (struct xt_rateinfo *)match_limit->data;        rateinfo->avg = 5;        rateinfo->burst = 10;        //physdev module - match extension        //”-in eth0” part of our desirable rule        physdevinfo = (struct xt_physdev_info *)match_physdev->data;        strcpy(physdevinfo->physindev, "eth0");        memset(physdevinfo->in_mask, 0xFF, IFNAMSIZ);        physdevinfo->bitmask = 1;        //target struct        //”-j ACCEPT” part of our desirable rule        target = (struct ipt_entry_target *)(e->elems + size_ipt_entry_match * 3 + size_ipt_tcp + size_rateinfo + size_physdevinfo);        target->u.target_size = size_ipt_entry_target;        strcpy(target->u.user.name, "ACCEPT");        program_name = "p4";        program_version = "NETFILTER_VERSION";        //All the functions, mentioned below could be found in "Querying libiptc HOWTO" manual        h = iptc_init(tablename);        if ( !h )        {                printf("Error initializing: %s\n", iptc_strerror(errno));                exit(errno);        }        //analogous to “iptables -A INPUT” part of our desirable rule + the rule itself                 //inside of the e struct        int x = iptc_append_entry(chain, e, &h);        if (!x)        {                printf("Error append_entry: %s\n", iptc_strerror(errno));                exit(errno);        }        printf("%s", target->data);        int y = iptc_commit(&h);        if (!y)        {                printf("Error commit: %s\n", iptc_strerror(errno));                exit(errno);        }        exit(0);}

0 0
原创粉丝点击