[iptables] 使用libiptc下发iptables规则

1、库libiptc

什么是libiptc

libiptc是用于与netfilter通信的库,netfilter是负责防火墙和数据包过滤的内部内核代码。这段代码和iptables由Paul “Rusty”Russell 编写 。iptables是使用libiptc调用开发的,以完成工作。

 

如何获取这些知识

文档参考地址:

http://tldp.org/HOWTO/Querying-libiptc-HOWTO/index.html

 

iptables源代码:

       在程序iptables-save.c中,使用libiptc从防火墙内核代码转储信息

安装iptables + libiptc

要安装libiptc,请按照下列步骤操作:

  1. 从 http://netfilter.samba.org/ 下载iptables-1.2.6.tar.bz2。
  2. sudo apt-get install iptables-dev和iptables
  3. 在iptables源码中的libiptc目录中make,获取库文件.lib
  4. 将./.lib  拷贝到/usr/lib即可

编译时链接该库即可

gcc test.c -l ip4tc

注意:libiptc库需要root权限,才能使用

问题:

       编译后的程序,使用root权限执行:

报错iptc_init函数问题:iptables who? (do you need to insmod?)

       但是代码没有进行修改,在终端下发一条iptables规则

sudo iptables -D INPUT -p tcp --dport 80 -j REJECT

       重新执行,程序正常。

问题原因未找到,怀疑是由于底层iptables模块未启动。导致执行失败。

 

如何创建程序

编写程序,可以使用以下的库,避免出现找不到函数的情况:

        / *我的节目* /

 

#include <getopt.h>

#include <sys / errno.h>

#include <stdio.h>

#include <fcntl.h>

#include <stdlib.h>

#include <string.h>

#include <dlfcn.h>

#include <time.h>

#include“libiptc / libiptc.h”

#include“iptables.h”

 

int main(void)

{

  / *总是将此部分用于您的程序....从这里...... **** * /

  iptc_handle_t h;

  const char * chain = NULL;

  const char * tablename = NULL;

 

  program_name =“my_program”;

  program_version = NETFILTER_VERSION;

  /* .... 到这里 .... ************************************** ****** * /

 

  / *从这里你编写自己的代码* /

  ....你的代码......

  ....

  ....

}

libiptc的函数介绍

iptc和ip6tc的函数,均由宏定义替代函数名进行的声明。

例如iptc_init

libiptc/libip4tc.c:87:#define TC_INIT                  iptc_init

然后iptc_init的具体实现为

libiptc/libiptc.c:1302:TC_INIT(const char *tablename)

查询类函数

iptc_init和iptc_free

函数原型:

struct xtc_handle *iptc_init(const char *tablename);

void iptc_free(struct xtc_handle *h);

              其中:#define iptc_handle xtc_handle

 

函数功能:

       iptc_init函数获取rules的快照。如果出现错误,return NULL。该函数必须在调用任何其他函数之前调用

参数:

       tablename是我们需要查询或修改的表的名称; 这可能是filter, mangle,nat以及raw。

返回值:

       指向iptc_handle_t类型结构的指针,该结构必须用作我们将从libiptc调用的其余函数的主要参数。iptc_init返回指向结构的指针,如果失败则返回NULL。如果发生这种情况,您可以调用 iptc_strerror来获取有关错误的信息。

例如:

iptc_free:

       iptc_init()函数的清除函数,与iptc_free()对应使用

iptc_strerror

函数原型:

       const char *iptc_strerror(int err);

函数功能:

       将错误码转化为易读形式

描述:

该函数返回iptc库中失败代码的更有意义的解释。如果函数失败,它将始终设置 errno。可以将此值传递给 iptc_strerror()以生成错误消息。

参数:

err是一个表示错误号的整数。

返回:

包含错误描述的Char指针。

iptc_first_chain

函数原型:

const char *iptc_first_chain(struct xtc_handle *handle);

函数功能:

       函数返回表中的第一个链名称。

参数:

指向iptc_handle_t类型结构的指针,该结构是通过先前调用iptc_init获得的。

返回:

指向链名称的Char指针。

iptc_next_chain

函数原型:

const char *iptc_next_chain(struct xtc_handle *handle);

函数功能:

       获取下一个链

参数:

指向iptc_handle_t类型结构的指针,该结构是通过先前调用iptc_init获得的。

返回:

指向链名称的Char指针。

iptc_is_chain

函数原型:

int iptc_is_chain(const char *chain, struct xtc_handle *const handle);

函数功能:

       检查chain是否存在

参数:

       chain:需要检查的是否存在的链

       handle:iptc_init函数提供的指向表的指针

返回值:

       存在 return 1;不存在 return 0

iptc_builtin

函数原型:

int iptc_builtin(const char *chain, struct xtc_handle *const handle);

函数功能:

       检测chain是否为内置链。

参数:

       chain:链

       handle:iptc_init函数提供的指向表的指针

返回值:

       如果给定的链名是内置链,则返回整数值1(true); 不是, 返回整数值0(false)

 

 

iptc_first_rule

函数原型:

const struct ipt_entry *iptc_first_rule(const char *chain,

                                   struct xtc_handle *handle);

函数功能:

       获取指定链中的第一条规则。如果是空链,则返回NULL

iptc_next_rule

函数原型:

const struct ipt_entry *iptc_next_rule(const struct ipt_entry *prev,

                                   struct xtc_handle *handle);

函数功能:

       获取指定链的下一条规则。

返回值:

       返回指定链中的下一条规则的指针;返回NULL表示链的末尾

iptc_get_target

函数原型:

const char *iptc_get_target(const struct ipt_entry *e,

                         struct xtc_handle *handle);

函数功能:

由于内置链的存在,我们不知道是返回一个动作还是一个内置链

该函数获取给定规则的目标。如果它是扩展目标,则返回该目标的名称。如果是跳转到另一个链,则返回该链的名称。如果是判决(例如DROP),则返回该名称。如果它没有目标(会计样式规则),则返回空字符串。请注意,应该使用此函数而不是直接使用ipt_entry结构的verdict字段 的值,因为它提供了对标准判定的上述进一步解释。

参数:

e是指向ipt_entry类型结构的指针,该结构 必须首先通过先前调用函数iptc_first_rule或函数 iptc_next_rule获得。

handle是指向iptc_handle_t类型结构的指针,该结构是通过先前调用iptc_init获得的。

返回:

返回指向目标名称的char指针。

iptc_get_policy

函数原型:
const char *iptc_get_policy(const char *chain,

                         struct xt_counters *counter,

                         struct xtc_handle *handle);

函数功能:

       此函数获取内置链的策略,并使用该策略的命中统计信息填充 counters参数。

参数:

您必须将要获取策略的内置链的名称作为参数传递,指向要 由函数填充的ipt_counters结构的指针以及标识我们正在处理的表的 iptc_handle_t结构。

该ipt_counters结构在前面的部分进行了说明; 不要忘记iptc_handle_t 必须通过先前调用函数iptc_init获得。

返回:

返回指向策略名称的char指针。

iptc_read_counter

函数原型:

struct xt_counters *iptc_read_counter(const xt_chainlabel chain,

                                   unsigned int rulenum,

                                   struct xtc_handle *handle);

函数功能:

       此函数读取并返回位于 rulenum的链链中的条目规则的数据包和字节计数器。计数器返回指向类型结构ipt_counters的指针。第一条规则的规则编号从1开始。

参数:

chain是一个指向要被加入的链名称的char指针; 

rulenum是一个整数值,定义了规则链中的位置,该计数器将被读取。

handle是指向iptc_handle_t类型结构的指针,该结构 是通过先前调用 iptc_init获得的。

返回:返回指向ipt_counters结构的指针,该结构包含已加入的字节和数据包计数器。

修改防火墙规则和统计信息的函数

iptc_commit

函数原型:

int iptc_commit(struct xtc_handle *handle);

函数功能:

       提交修改。在调用iptc_commit()函数之前,不会写回您更改的表 。这意味着在同一链上运行的两个库用户可以相互竞争; 需要锁定以防止这种情况,目前尚未完成。然而,没有与柜台比赛; 计数器以这样的方式重新添加到内核中,即表的读取和写入之间的计数器增量仍然显示在新表中。要保护系统状态,您必须提交更改。(功能类似git commit)

参数:

handle是指向iptc_handle_t类型结构的指针,该结构 是通过先前调用iptc_init获得的。

返回:

如果成功则返回整数值1(true); 如果失败,则返回整数值0(false)。在这种情况下,errno设置为生成的错误号。使用iptc_strerror获取有关该问题的有用信息。如果errno == 0,则表示存在版本错误(即升级libiptc)。

iptc_insert_entry

函数原型:

int iptc_insert_entry(const xt_chainlabel chain,

                    const struct ipt_entry *e,

                    unsigned int rulenum,

                    struct xtc_handle *handle);

函数功能:

       在链中插入新规则。插入ipt_entry到序号为rulenum的位置

参数:

chain是一个指向要修改的链名称的char指针; 

e是指向ipt_entry类型结构的指针,该结构 包含有关要插入的规则的信息。程序员必须在将指针作为参数传递给函数之前,使用定义其规则所需的值填充此结构的字段。

rulenum是一个整数值,定义了将插入新规则的规则链中的位置。第一条规则的规则编号从1开始。 

handle是指向iptc_handle_t类型结构的指针,该结构 是通过先前调用iptc_init获得的。

返回:

如果成功则返回整数值1(true); 如果失败,则返回整数值0(false)。在这种情况下,errno设置为生成的错误号。使用iptc_strerror获取有关该问题的有用信息。如果errno == 0,则表示存在版本错误(即升级libiptc)。

iptc_check_entry

/* Check whether a mathching rule exists */

函数原型

int iptc_check_entry(const xt_chainlabel chain,

                    const struct ipt_entry *origfw,

                    unsigned char *matchmask,

                    struct xtc_handle *handle);

函数功能:
       检查规则是否已经存在

 

iptc_replace_entry

函数原型:

int iptc_replace_entry(const xt_chainlabel chain,

                     const struct ipt_entry *e,

                     unsigned int rulenum,

                     struct xtc_handle *handle);

函数功能:

       使用新规则替换序号为rulenum旧规则。第一条规则序号为1

参数:

chain是一个指向要修改的链名称的char指针; 

e是指向ipt_entry类型结构的指针,该结构 包含有关要插入的规则的信息。程序员必须在将指针作为参数传递给函数之前,使用定义其规则所需的值填充此结构的字段。

rulenum是一个整数值,定义了规则链中的位置,旧规则将被新规则替换。第一条规则的规则编号从1开始。 

handle是指向iptc_handle_t类型结构的指针,该结构 是通过先前调用 iptc_init获得的。

返回:

如果成功则返回整数值1(true); 如果失败,则返回整数值0(false)。在这种情况下,errno设置为生成的错误号。使用iptc_strerror获取有关该问题的有用信息。如果errno == 0,则表示存在版本错误(即升级libiptc)。

iptc_append_entry

函数原型:

int iptc_append_entry(const xt_chainlabel chain,

                    const struct ipt_entry *e,

                    struct xtc_handle *handle);

函数功能:

此函数在链链中附加在结构类型ipt_entry中定义的规则 (相当于使用rulenum = chain of length的insert)。

参数:

chain是一个指向要修改的链名称的char指针; 

e是指向ipt_entry类型结构的指针,该结构 包含有关要追加的规则的信息。程序员必须在将指针作为参数传递给函数之前,使用定义其规则所需的值填充此结构的字段。

handle是指向iptc_handle_t类型结构的指针,该结构是通过先前调用iptc_init获得的。

返回:

如果成功则返回整数值1(true); 如果失败,则返回整数值0(false)。在这种情况下,errno设置为生成的错误号。使用iptc_strerror获取有关该问题的有用信息。如果errno == 0,则表示存在版本错误(即升级libiptc)

iptc_delete_entry

/* Delete the first rule in `chain' which matches `e', subject to

   matchmask (array of length == origfw) */

函数原型

int iptc_delete_entry(const xt_chainlabel chain,

                    const struct ipt_entry *origfw,

                    unsigned char *matchmask,

                    struct xtc_handle *handle);

函数功能:

       删除与指定ipt_entry的匹配掩码(matchmask)部分相同的rules

iptc_delete_num_entry

函数原型:

int iptc_delete_num_entry(const xt_chainlabel chain,

                       unsigned int rulenum,

                       struct xtc_handle *handle);

函数功能:

此函数删除位于rulenum的链链中的输入规则。第一条规则的规则编号从1开始。

参数:

.      chain是一个指向要修改的链名称的char指针; 

rulenum是一个整数值,用于定义规则链中将删除规则的位置。 

handle是指向iptc_handle_t类型结构的指针,该结构 是通过先前调用 iptc_init获得的。

返回:

如果成功则返回整数值1(true); 如果失败,则返回整数值0(false)。在这种情况下,errno设置为生成的错误号。使用iptc_strerror获取有关该问题的有用信息。如果errno == 0,则表示存在版本错误(即升级libiptc)。

iptc_flush_entries

函数原型:

int iptc_flush_entries(const xt_chainlabel chain,

                     struct xtc_handle *handle);

函数功能:

       清空指定链

参数:

chain是指向要刷新的链的名称的char指针; 

handle是指向iptc_handle_t类型结构的指针,该结构 是通过先前调用 iptc_init获得的。

返回:

如果成功则返回整数值1(true); 如果失败,则返回整数值0(false)。在这种情况下,errno设置为生成的错误号。使用iptc_strerror获取有关该问题的有用信息。如果errno == 0,则表示存在版本错误(即升级libiptc)。

iptc_zero_entries

函数原型:

int iptc_zero_entries(const xt_chainlabel chain,

                    struct xtc_handle *handle);

函数功能:

       将给定链的计数器归零

参数:

chain是指向链名称的char指针,计数器将为零; 

handle是指向iptc_handle_t类型结构的指针,该结构是通过先前调用iptc_init获得的。

返回:

如果成功则返回整数值1(true); 如果失败,则返回整数值0(false)。在这种情况下,errno设置为生成的错误号。使用iptc_strerror获取有关该问题的有用信息。如果errno == 0,则表示存在版本错误(即升级libiptc)。

iptc_create_chain

函数原型:

int iptc_create_chain(const xt_chainlabel chain,

                    struct xtc_handle *handle);

函数功能:

       在给定的表中创建一条新链

参数:

chain是一个指向要创建的链名称的char指针; 

handle是指向iptc_handle_t类型结构的指针,该结构是通过先前调用iptc_init获得的。

返回:

如果成功则返回整数值1(true); 如果失败,则返回整数值0(false)。在这种情况下,errno设置为生成的错误号。使用iptc_strerror获取有关该问题的有用信息。如果errno == 0,则表示存在版本错误(即升级libiptc)。

iptc_delete_chain

函数原型:

int iptc_delete_chain(const xt_chainlabel chain,

                    struct xtc_handle *handle);

函数功能:

       删除指定表中的指定链

参数:

chain是指向要删除的链名称的char指针; 

handle是指向iptc_handle_t类型结构的指针,该结构是通过先前调用iptc_init获得的。

返回:

如果成功则返回整数值1(true); 如果失败,则返回整数值0(false)。在这种情况下,errno设置为生成的错误号。使用iptc_strerror获取有关该问题的有用信息。如果errno == 0,则表示存在版本错误(即升级libiptc)。

iptc_rename_chain

函数原型:

int iptc_rename_chain(const xt_chainlabel oldname,

                    const xt_chainlabel newname,

                    struct xtc_handle *handle);

函数功能:

       将指定的表中的指定链重新命名为newname

参数:

oldname是一个char指针,指向要重命名的链的名称,

newname是新名称; 

handle是指向iptc_handle_t类型结构的指针,该结构 是通过先前调用iptc_init获得的。

返回:

如果成功则返回整数值1(true); 如果失败,则返回整数值0(false)。在这种情况下,errno设置为生成的错误号。使用iptc_strerror获取有关该问题的有用信息。如果errno == 0,则表示存在版本错误(即升级libiptc)。

iptc_set_policy

函数原型:

int iptc_set_policy(const xt_chainlabel chain,

                  const xt_chainlabel policy,

                  struct xt_counters *counters,

                  struct xtc_handle *handle);

函数功能:

       在内置链中设置策略。这个函数在链中的策略由字符指针所代表的policy。如果要同时设置链的计数器,请在ipt_counters类型的结构中填充这些值,并将指针作为参数计数器传递给它。注意:链条 必须是内置链条。

参数:

chain是一个指向要修改的链名称的char指针; 

policy是指向要设置的策略名称的char指针。

计数器是一个指向 ipt_counters结构要被用于设置链的计数器。

handle是指向iptc_handle_t类型结构的指针,该结构 是通过先前调用 iptc_init获得的。

返回:

如果成功则返回整数值1(true); 如果失败,则返回整数值0(false)。在这种情况下,errno设置为生成的错误号。使用iptc_strerror获取有关该问题的有用信息。如果errno == 0,则表示存在版本错误(即升级libiptc)。

iptc_zero_counter

函数原型:

int iptc_zero_counter(const xt_chainlabel chain,

                    unsigned int rulenum,

                    struct xtc_handle *handle);

函数功能:

       将指定表中的指定链的指定规则的计数器清零

参数:

chain是一个指向要修改的链名称的char指针; 

rulenum是一个整数值,定义了规则链中的位置,计数器将为零。 

handle是指向iptc_handle_t类型结构的指针,该结构 是通过先前调用 iptc_init获得的。

返回:

如果成功则返回整数值1(true); 如果失败,则返回整数值0(false)。在这种情况下,errno设置为生成的错误号。使用iptc_strerror获取有关该问题的有用信息。如果errno == 0,则表示存在版本错误(即升级libiptc)。

iptc_set_counter

函数原型:

int iptc_set_counter(const xt_chainlabel chain,

                   unsigned int rulenum,

                   struct xt_counters *counters,

                   struct xtc_handle *handle);

函数功能:

       设置指定的表中的指定链的指定规则的包和字节的计数器

参数:

chain是一个指向要修改的链名称的char指针; 

rulenum是一个整数值,定义了规则链中的位置,计数器将被设置。 

计数器是一个指向一个 ipt_counters要使用结构来设置规则中的计数器; 程序员必须用要设置的值填充此结构的字段。

handle是指向iptc_handle_t类型结构的指针,该结构是通过先前调用iptc_init获得的。

返回:

如果成功则返回整数值1(true); 如果失败,则返回整数值0(false)。在这种情况下,errno设置为生成的错误号。使用iptc_strerror获取有关该问题的有用信息。如果errno == 0,则表示存在版本错误(即升级libiptc)。

 

iptc_get_references

/* Get the number of references to this chain */

函数原型:

int iptc_get_references(unsigned int *ref,

                     const xt_chainlabel chain,

                     struct xtc_handle *handle);

函数功能:

       获取对应链的引用次数

iptc_get_raw_socket

/* Get raw socket. */

函数原型

int iptc_get_raw_socket(void);

函数功能:

       获取原始套接字

libiptc的重要结构体

几个重要的结构体的定义在iptables/libiptc/libiptc.c和libiptc.h文件中。

struct xtc_handle

#define iptc_handle xtc_handle

struct xtc_handle {

 

        int sockfd;

        int changed;                     /* Have changes been made? */

 

        struct list_head chains;

 

        struct chain_head *chain_iterator_cur;

        struct rule_head *rule_iterator_cur;

 

        unsigned int num_chains;         /* number of user defined chains */

 

        struct chain_head **chain_index;   /* array for fast chain list access*/

        unsigned int        chain_index_sz;/* size of chain index array */

 

        int sorted_offsets; /* if chains are received sorted from kernel,

                             * then the offsets are also sorted. Says if its

                             * possible to bsearch offsets using chain_index.

                             */

        STRUCT_GETINFO info;

        STRUCT_GET_ENTRIES *entries;

};

struct ipt_entry

struct ipt_entry {

        struct ipt_ip ip;

 

        /* Mark with fields that we care about. */

        unsigned int nfcache;

 

        /* Size of ipt_entry + matches */

        __u16 target_offset;

        /* Size of ipt_entry + matches + target */

        __u16 next_offset;

 

        /* Back pointer */

        unsigned int comefrom;

 

        /* Packet and byte counters. */

        struct xt_counters counters;

 

        /* The matches (if any), then the target. */

        unsigned char elems[0];

};

struct ipt_ip

struct ipt_ip {

        /* Source and destination IP addr */

        struct in_addr src, dst;

        /* Mask for src and dest IP addr */

        struct in_addr smsk, dmsk;

        char iniface[IFNAMSIZ], outiface[IFNAMSIZ];

        unsigned char iniface_mask[IFNAMSIZ], outiface_mask[IFNAMSIZ];

 

        /* Protocol, 0 = ANY */

        __u16 proto;

 

        /* Flags word */

        __u8 flags;

        /* Inverse flags */

        __u8 invflags;

};

struct xt_counters

struct xt_counters {

        __u64 pcnt, bcnt;                       /* Packet and byte counters */

};

 

rule下发

规则下发可以参考:http://lib.csdn.net/article/linux/56211

 

Linux c/c++编程使用 libiptc库下发规则可以代替system调用 iptables 命令方法,可以满足程序中批量地创建连接所需的批量增加、删除iptables规则;

但是使用步骤确实比较繁琐,得注意iptables版本的问题,编译相关库需要“-lip4tc” “-lxtables”,头文件需要“libiptc/libiptc.h” “net/netfilter/nf_nat.h” “iptables.h”;需要填写多个结构体,操作复杂。

而且实验结果表明,当多进程高频率得操作iptables时,system 和 libiptc 均会出现 “Resource temporarily unavailable” 错误,建议进行返回值判定和多进程的加锁保护;

操作较少时,建议采用popen或者system进行操作。

system和popen的不同:

system和popen都是执行了类似的运行流程,大致是fork->execl->return。

system在执行期间调用进程会一直等待shell命令执行完成(waitpid等待子进程结束)才返回。

popen无须等待shell命令执行完成就返回了。

我们可以理解system为串行执行,在执行期间调用进程放弃了”控制权”,popen为并行执行。 

popen中的子进程没人给它”收尸”了啊?是的,如果你没有在调用popen后调用pclose那么这个子进程就可能变成”僵尸”

3、下发entry(IPv4)

entry主要的难点在于ipt_entry的封装。

match可以是多个

封装结构如图所示。对于自定义的结构体,应该使用iptables/include/linux/netfilter下的文件定义的结构体。

例如,

使用mac匹配规则:xt_mac.h

使用udp或者tcp匹配:xt_tcpudp.h

使用物理接口匹配:xt_physdev.h

 

首先匹配的应该是ipt_entry中的ipt_ip字段。如果ipt_ip中的protocol字段为0,表示任何协议都可以通过,(协议定义在linux的in.h文件中);进一步与自定义的match进行匹配,例如mac匹配。

struct ipt_entry

struct ipt_entry {

       struct ipt_ip ip;

       unsigned int nfcache;

       __u16 target_offset;     /* Size of ipt_entry + matches */

       __u16 next_offset;        /* Size of ipt_entry + matches + target */

       unsigned int comefrom;/* 后退指针 */

       struct xt_counters counters;/* 报文和字节计数 */

       unsigned char elems[0];/* match和target ,可以是多个match */

};

该结构体用于每个防火墙规则的定义。包含三部分

  1. 通用的ip头
  2. match,匹配
  3. target,处理

 

其中的ipt_ip结构体如下:

struct ipt_ip {

       /* Source and destination IP addr */

       struct in_addr src, dst;

       /* Mask for src and dest IP addr */

       struct in_addr smsk, dmsk;

       char iniface[IFNAMSIZ], outiface[IFNAMSIZ];

       unsigned char iniface_mask[IFNAMSIZ], outiface_mask[IFNAMSIZ];

 

       /* Protocol, 0 = ANY */

       __u16 proto;

 

       /* Flags word */

       __u8 flags;

       /* Inverse flags */

       __u8 invflags;

};

其中的protocol字段的所有定义在in.h中有定义。

/* Standard well-defined IP protocols.  */

enum {

  IPPROTO_IP = 0,              /* Dummy protocol for TCP        */

#define IPPROTO_IP           IPPROTO_IP

  IPPROTO_ICMP = 1,         /* Internet Control Message Protocol */

#define IPPROTO_ICMP             IPPROTO_ICMP

  IPPROTO_IGMP = 2,        /* Internet Group Management Protocol   */

#define IPPROTO_IGMP             IPPROTO_IGMP

  IPPROTO_IPIP = 4,           /* IPIP tunnels (older KA9Q tunnels use 94) */

#define IPPROTO_IPIP         IPPROTO_IPIP

  IPPROTO_TCP = 6,           /* Transmission Control Protocol */

#define IPPROTO_TCP        IPPROTO_TCP

  IPPROTO_EGP = 8,          /* Exterior Gateway Protocol              */

#define IPPROTO_EGP        IPPROTO_EGP

  IPPROTO_PUP = 12,         /* PUP protocol                          */

#define IPPROTO_PUP        IPPROTO_PUP

  IPPROTO_UDP = 17,        /* User Datagram Protocol         */

#define IPPROTO_UDP       IPPROTO_UDP

  IPPROTO_IDP = 22,          /* XNS IDP protocol                   */

#define IPPROTO_IDP         IPPROTO_IDP

  IPPROTO_TP = 29,           /* SO Transport Protocol Class 4 */

#define IPPROTO_TP          IPPROTO_TP

  IPPROTO_DCCP = 33,             /* Datagram Congestion Control Protocol */

#define IPPROTO_DCCP            IPPROTO_DCCP

  IPPROTO_IPV6 = 41,        /* IPv6-in-IPv4 tunnelling           */

#define IPPROTO_IPV6       IPPROTO_IPV6

  IPPROTO_RSVP = 46,              /* RSVP Protocol                 */

#define IPPROTO_RSVP             IPPROTO_RSVP

  IPPROTO_GRE = 47,         /* Cisco GRE tunnels (rfc 1701,1702)   */

#define IPPROTO_GRE        IPPROTO_GRE

  IPPROTO_ESP = 50,         /* Encapsulation Security Payload protocol */

#define IPPROTO_ESP         IPPROTO_ESP

  IPPROTO_AH = 51,          /* Authentication Header protocol     */

#define IPPROTO_AH         IPPROTO_AH

  IPPROTO_MTP = 92,        /* Multicast Transport Protocol          */

#define IPPROTO_MTP       IPPROTO_MTP

  IPPROTO_BEETPH = 94,          /* IP option pseudo header for BEET  */

#define IPPROTO_BEETPH         IPPROTO_BEETPH

  IPPROTO_ENCAP = 98,           /* Encapsulation Header                    */

#define IPPROTO_ENCAP          IPPROTO_ENCAP

  IPPROTO_PIM = 103,              /* Protocol Independent Multicast     */

#define IPPROTO_PIM        IPPROTO_PIM

  IPPROTO_COMP = 108,          /* Compression Header Protocol       */

#define IPPROTO_COMP           IPPROTO_COMP

  IPPROTO_SCTP = 132,            /* Stream Control Transport Protocol */

#define IPPROTO_SCTP             IPPROTO_SCTP

  IPPROTO_UDPLITE = 136,       /* UDP-Lite (RFC 3828)               */

#define IPPROTO_UDPLITE        IPPROTO_UDPLITE

  IPPROTO_RAW = 255,             /* Raw IP packets                */

#define IPPROTO_RAW              IPPROTO_RAW

  IPPROTO_MAX

};

struct ipt_entry_target

#define ipt_entry_target xt_entry_target

struct xt_entry_target {

       union {

              struct {

                     __u16 target_size;/* target的长度 */

                     char name[XT_EXTENSION_MAXNAMELEN];/* chainname */

                     __u8 revision;

              } user;

              struct {

                     __u16 target_size; /* target的长度 */

                     struct xt_target *target;

              } kernel;

              __u16 target_size;

       } u;

       unsigned char data[0];/* 指向自定义的target */

};

struct ipt_entry_match

#define ipt_entry_match xt_entry_match

struct xt_entry_match {

       union {

              struct {

                     __u16 match_size;

                     char name[XT_EXTENSION_MAXNAMELEN];

                     __u8 revision;

              } user;

              struct {

                     __u16 match_size;

                     struct xt_match *match;

              } kernel;

              __u16 match_size;

       } u;

       unsigned char data[0];/* 指向自定义的match */

};

 

初学libiptc

如果不清楚如何使用libiptc下发想要的规则。可以在iptables中的generate_entry函数中加入log。打印entry信息。

然后使用iptables下发想要的规则。获取entry信息。

然后根据entry信息,自定义封装规则。

代码例程

http://github.com/hanfs390/iptables_hfs

 

  • 3
    点赞
  • 9
    收藏
    觉得还不错? 一键收藏
  • 3
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值