iptc example

转自: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);}


  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值