ip_tables.h:217: error:invalid conversion from 'void*' to 'xt_entry_target*'

来源:互联网 发布:厦大经济学院八高 知乎 编辑:程序博客网 时间:2024/06/06 07:00

最近项目有个功能,需要读取linux服务器上iptables rule的信息。

一开始我是用popen 去调用命令“iptables -L -nv”,然后用fgets去获取命令返回结果。

但是这种方法CPU耗时非常打,特别是调用popen和fgets的开销大。

所以需要换一种方法,用libiptc的接口来实现。

但是在编译的时候,因为我是用的C++编译,但是失败了,

ip_tables.h:217: error:invalid conversion from 'void*' to 'xt_entry_target*'

这是因为我在#include “libiptc/libiptc.h”后,libiptc.h里面会再#include <linux/netfilter_ipv4/ip_tables.h>

而#include <linux/netfilter_ipv4/ip_tables.h>是C语言的头文件,它允许将 'void*' 强制类型转换成 'xt_entry_target*',

但在C++编译器里面不允许这种类型转换。


我一开始去修改这个头文件,编译通过了。

static __inline__ struct xt_entry_target *

 ipt_get_target(struct ipt_entry *e)

 {

-        return (void *)e +e->target_offset;

+       return (struct xt_entry_target*)((__u8 *)e + e->target_offset);

 }

但是同事建议不要去修改系统带头文件,这样可能会造成其他代码出问题。


所以我只好另想一个workround的方法,写一个C代码去包含这个#include “libiptc/libiptc.h”(这个要放在.c文件里面) ,并在代码里面写一个函数将取到的iptables rule的结果存放到结构体数组里面,这样就可以用C编译器去编译这段代码。

然后再写一个和C代码对应的C头文件,在C++代码中用extern “C” {#include xxxxxx.h}去包含这个头文件,并调用C里面的函数来获取结果。

iptc.c

#include "libiptc/libiptc.h"#include "string.h"#include "WalIptc.h"int GetRuleMatch(RuleMatch *rule_match){    const char *tablename = "filter";    const char *chain = "VLAN_CNT";    struct iptc_handle *h;    h = iptc_init(tablename);    if (!h){        return -1;    }    int match_num = 0;    const struct ipt_entry *e;    e = iptc_first_rule(chain, h);    while(e) {        strncpy((rule_match+match_num)->iniface, e->ip.iniface, INIFACE_LEN);        (rule_match+match_num)->pcnt = e->counters.pcnt;        ++match_num;        e = iptc_next_rule(e, h);    }    iptc_free(h)    return match_num;}






iptc.h

#ifndef _IPTC_YES#define _IPTC_YES#include <stdint.h>#define INIFACE_LEN 15#define RULEMATCH_LEN 10typedef struct RuleMatchInfo{    char iniface[INIFACE_LEN];    uint64_t pcnt;}RuleMatch;int GetRuleMatch(RuleMatch *rule_match);#endif //_IPTC_YES





原创粉丝点击