使用 libiptc 操作 iptables

这些代码花了我三天才写出来,filter表的操作没问题,nat表操作不太对。在arm平台也有点不对,懒得调试了,分享出来吧。

#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 <netdb.h>

#include <libiptc/libiptc.h>

//#include <ip_tables.h>

#define MIN_PORT 0

#define MAX_PORT 65535

//linux/include/linux/netfilter_ipv4/ip_tables.h

#define IPT_ALIGN(s) (((s) + (__alignof__(struct ipt_entry)-1)) & ~(__alignof__(struct ipt_entry)-1))

struct xtc_handle *t_handle;

void show_all_rule()

{

const char *chain = NULL;

const char * policy = NULL;

struct ipt_counters counter;

for (chain = iptc_first_chain(t_handle); chain; chain = iptc_next_chain(t_handle))

{

printf("\nChain: %s\n", chain);

if (chain!=NULL && t_handle!=NULL)

{

policy = iptc_get_policy(chain,&counter,t_handle);

printf("policy: %s\n",policy);

printf("  packet count: %llu\t",counter.pcnt);

printf("  byte count: %llu\n",counter.bcnt);

}

else

printf("policy error !\n");

x_get_rule(chain,t_handle);

}//for

}

//append rule

int  x_append_rule(char *chain ,struct ipt_entry *e)

{

if (iptc_append_entry(chain,e,t_handle)!=1)

{

printf("Error x_append_rule: %s\n", iptc_strerror(errno));

return 0;

}

iptc_commit(t_handle);

return 1;

}

//insert tule by num

int x_insert_rule(char *chain ,struct ipt_entry *e,int num)

{

if (iptc_insert_entry(chain,e,num,t_handle)!=1)

{

printf("Error x_insert_rule: %s\n", iptc_strerror(errno));

return 0;

}

iptc_commit(t_handle);

return 1;

}

//iptables -I OUTPUT -s 192.168.6.2 -d 192.168.3.4 -p UDP --dport 1933 -j DROP

int demo_insert()

{

struct ipt_entry_target *a_t ;

struct ipt_entry_match  *a_m;

struct ipt_entry  *a_e;

struct ipt_tcp *ptcp;

struct ipt_ip *pip;

size_t target_size,match_size,entry_size;

//init size

match_size = sizeof(struct ipt_entry_match) + sizeof(struct ipt_tcp);

target_size = IPT_ALIGN(sizeof(struct ipt_entry_target)) + IPT_ALIGN(sizeof(int));

entry_size = sizeof(*a_e) + target_size + match_size;

//full struct ipt_entry

a_e = malloc(entry_size);

memset(a_e,0,entry_size);

a_e->ip.src.s_addr = inet_addr("192.168.6.2");

a_e->ip.smsk.s_addr = -1;

//--- for --to--destination

a_e->ip.dst.s_addr = inet_addr("192.168.3.4");

a_e->ip.dmsk.s_addr = -1;

//---

a_e->ip.proto = 17;//udp

a_e->target_offset = sizeof(*a_e) + match_size;

a_e->next_offset = entry_size;

//full struct ip_entry_match

a_m = (struct ipt_entry_match*)a_e->elems;

a_m->u.user.match_size = match_size;

strcpy(a_m->u.user.name,"udp");

//full struct ipt_tcp

ptcp = (struct ipt_tcp*)a_m->data;

ptcp->spts[0] = -1;ptcp->spts[1] = -1;//any sport

ptcp->dpts[0] = 1933;ptcp->dpts[1] = 1933;//one port

//full struct ipt_entry_target

a_t = (struct ipt_entry_target*)(a_e->elems + match_size);

a_t->u.user.target_size = target_size;

strcpy(a_t->u.user.name,"DROP");

//do_command

x_insert_rule("OUTPUT",a_e,0);//num==1 can‘t add ??

return 1;

}

//get chain and policy list

void x_get_rule(const char *chain,struct xtc_handle *handle)

{

const struct ipt_entry* rule;

struct ipt_entry_match* a_m;

struct ipt_tcp* ptcp;

for(rule = iptc_first_rule(chain,handle); rule; rule = iptc_next_rule(rule,handle))

{

const char *target = NULL;

target= iptc_get_target(rule,handle);

//printf("rule name : %s\n",target);

//printf("rule count: %llu\n",rule->counters.pcnt);

//printf("rule strlen:%llu\n",rule->counters.bcnt);

struct protoent *pro = NULL;

pro= getprotobynumber(rule->ip.proto);

if(pro != NULL )

{

printf("  policy_id:%04d    proto_name:%s  \n",pro->p_proto, pro->p_name);

}

printf("  in_iface: ");

if(rule->ip.iniface[0] == ‘\0‘ )// -i param

printf("any\t");

else

printf("%s\t",rule->ip.iniface);

printf("  out_iface: ");

if(rule->ip.outiface[0] == ‘\0‘ )//-o param

printf("any\n");

else

printf("%s\n",rule->ip.outiface);

char addr[32] = {0};

printf("  sip:%s/%s    \t",inet_ntop(AF_INET,&(rule->ip.src),addr,sizeof(addr)),inet_ntop(AF_INET,&(rule->ip.smsk),addr,sizeof(addr)) );

printf("dip:%s/%s\n",inet_ntop(AF_INET,&(rule->ip.dst),addr,sizeof(addr)),inet_ntop(AF_INET,&(rule->ip.dmsk),addr,sizeof(addr)) );

//ip.dmsk.s_addr

//full struct ip_entry_match

a_m = (struct ipt_entry_match*)rule->elems;

//full struct ipt_tcp

ptcp = (struct ipt_tcp*)a_m->data;

if (ptcp->spts[0]<=0 || ptcp->spts[0]==0xffff)

printf("  sport : any \t");

else

printf("  sport range :  %d --- %d \t",ptcp->spts[0],ptcp->spts[1]);

if (ptcp->dpts[0]<=0 || ptcp->dpts[0]==0xffff)

printf("d_port : any \t");

else

printf("d_port range :  %d --- %d \n",ptcp->dpts[0],ptcp->dpts[1]);

}

}

//init libiptc

int  x_init(int type)

{

//if  "-t nat" tablename == "nat" ,it table can use PREROUTING

const char *default_tablename = "filter";

const char *nat_tablename = "nat";

const char *chain = NULL;

if (type==1)

{

t_handle = iptc_init(default_tablename);

printf("***** oepn nat table *****\n");

}

else

{

printf("***** open nat table *****\n");

t_handle = iptc_init(nat_tablename);

}

if ( t_handle == NULL )

{

printf("Error initializing: %s\n", iptc_strerror(errno));

return errno;

}

//del nat table all rule

for (chain = iptc_first_chain(t_handle); chain; chain = iptc_next_chain(t_handle))

{

iptc_flush_entries(chain,t_handle);

printf("Clean %s rule \n",chain);

}//for

return 1;

}

//---------------------------------------------------------------

//iptables -A INPUT -i eth0 -p icmp -j DROP

int demo_append1()

{

//***append route

struct ipt_entry_target *a_t = NULL;

struct ipt_entry  *a_e ;

int i;

size_t  target_size,entry_size;

//init size

target_size = IPT_ALIGN(sizeof(struct ipt_entry_target)) + IPT_ALIGN(sizeof(int));

entry_size = sizeof(*a_e) + target_size;

//full ipt_entry

a_e = malloc(entry_size);

memset(a_e,0,entry_size);

strcpy(a_e->ip.iniface,"eth0");

//a_e->ip.iniface[0] == ‘\0‘

for(i=0;i<(strlen("eth0")+1);i++)

a_e->ip.iniface_mask[i] = 0xffff;

a_e->ip.proto = 1; //icmp

a_e->target_offset = sizeof(*a_e);

a_e->next_offset = entry_size;

//full ipt_entry_target

a_t = (struct ipt_entry_target *)a_e->elems;

a_t->u.user.target_size = target_size;

strcpy(a_t->u.user.name,"DROP");

//do_command

x_append_rule("INPUT",a_e);

return 1;

}

/*

struct xt_tcp

{

__u16 spts[2];                  //Source port range.

__u16 dpts[2];                  //Destination port range.

__u8 option;                   //TCP Option iff non-zero

__u8 flg_mask;                  // TCP flags mask byte

__u8 flg_cmp;                  //TCP flags compare byte

__u8 invflags;                // Inverse flags

};

struct ipt_ip

{

struct in_addr src, dst;

struct in_addr smsk, dmsk;

char iniface[IFNAMSIZ], outiface[IFNAMSIZ];

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

u_int16_t proto;

u_int8_t flags;

u_int8_t invflags;

};

*/

//iptables -A FORWARD -s 192.168.2.2 -d 192.168.3.4 -p tcp --dport 80 -j ACCEPT

int demo_append2()

{

struct ipt_entry_target *a_t ;

struct ipt_entry_match  *a_m;

struct ipt_entry  *a_e;

struct ipt_tcp *ptcp;

struct ipt_ip *pip;

size_t target_size,match_size,entry_size;

//init size

match_size = sizeof(struct ipt_entry_match) + sizeof(struct ipt_tcp);

target_size = IPT_ALIGN(sizeof(struct ipt_entry_target)) + IPT_ALIGN(sizeof(int));

entry_size = sizeof(*a_e) + target_size + match_size;

//full struct ipt_entry

a_e = malloc(entry_size);

memset(a_e,0,entry_size);

a_e->ip.src.s_addr = inet_addr("192.168.2.2");

a_e->ip.smsk.s_addr = -1;

a_e->ip.dst.s_addr = inet_addr("192.168.3.4");

a_e->ip.dmsk.s_addr = -1;

a_e->ip.proto = 6;//tcp

a_e->target_offset = sizeof(*a_e) + match_size;

a_e->next_offset = entry_size;

//full struct ip_entry_match

a_m = (struct ipt_entry_match*)a_e->elems;

a_m->u.user.match_size = match_size;

strcpy(a_m->u.user.name,"tcp");

//full struct ipt_tcp

ptcp = (struct ipt_tcp*)a_m->data;

ptcp->spts[0] = -1;ptcp->spts[1] = -1;//any sport

ptcp->dpts[0] = 80;ptcp->dpts[1] = 80;//one port

//full struct ipt_entry_target

a_t = (struct ipt_entry_target*)(a_e->elems + match_size);

a_t->u.user.target_size = target_size;

strcpy(a_t->u.user.name,"ACCEPT");

//do_command

x_append_rule("FORWARD",a_e);

return 1;

}

//iptables -A PREROUTING -d 0.0.0.0/0 -p tcp --dport 80 -j DNAT --to--destination 172.16.1.1

void demo_do_nat()

{

struct ipt_entry_target *a_t ;

struct ipt_entry_match  *a_m;

struct ipt_entry  *a_e;

struct ipt_tcp *ptcp;

struct ipt_ip *pip;

size_t target_size,match_size,entry_size;

//init size

match_size = sizeof(struct ipt_entry_match) + sizeof(struct ipt_tcp);

target_size = IPT_ALIGN(sizeof(struct ipt_entry_target)) + IPT_ALIGN(sizeof(int));

entry_size = sizeof(*a_e) + target_size + match_size;

//full struct ipt_entry

a_e = malloc(entry_size);

memset(a_e,0,entry_size);

a_e->ip.src.s_addr = 0;

a_e->ip.dmsk.s_addr = -1;

a_e->ip.dst.s_addr = 0;

a_e->ip.dmsk.s_addr = -1;

a_e->ip.proto = 6;//tcp

a_e->target_offset = sizeof(*a_e) + match_size;

a_e->next_offset = entry_size;

//full struct ip_entry_match

a_m = (struct ipt_entry_match*)a_e->elems;

a_m->u.user.match_size = match_size;

strcpy(a_m->u.user.name,"tcp");

//full struct ipt_tcp

ptcp = (struct ipt_tcp*)a_m->data;

ptcp->spts[0] = -1;ptcp->spts[1] = -1;//any sport

ptcp->dpts[0] = 80;ptcp->dpts[1] = 80;//one port

//full struct ipt_entry_target

a_t = (struct ipt_entry_target*)(a_e->elems + match_size);

a_t->u.user.target_size = target_size;

strcpy(a_t->u.user.name,"DNAT");

//do_command

x_append_rule("PREROUTING",a_e);

}

//opt nat table

void do_nat_table()

{

//open nat table

if (x_init(2)!=1)

{

exit(0);

}

//iptables

//iptables -t nat -A PREROUTING -d 0.0.0.0/0 -p tcp --dport 80 -j DNAT --to--destination 172.16.1.1

demo_do_nat();//....

//show all nat table rule

printf("****************************************\n");

printf("SHOW ALL NAT TABLE RULE \n");

printf("****************************************\n");

show_all_rule();

}

//opt to filter table

void do_filter_table()

{

//open filter table

if (x_init(1)!=1)

{

exit(0);

}

//iptables -A INPUT -i eth0 -p icmp -j DROP

demo_append1();

//iptables -A FORWARD -s 192.168.2.2 -d 192.168.3.4 -p tcp --dport 80 -j DROP

demo_append2();

//iptables -I OUTPUT 1 -s 192.168.6.2 -d 192.168.3.4 -p UDP --dport 1933 -j DROP

demo_insert();

//show all filter table rule

printf("****************************************\n");

printf("SHOW ALL FILTER TABLE RULE \n");

printf("****************************************\n");

show_all_rule();

}

int main(void)

{

//use default table filter to  : iptc_append_entry() iptc_insert_entry()

//note filter talbe can use policy is  FORWARD,INPUT ,OUTPUT

do_filter_table();

//user table nat to : iptc_append_entry()

//note -DNAT  only can use in nat talbe,and policy == PREROUTING and OUTPUT

do_nat_table();

exit(0);

} /* main */

运行结果:

***** oepn nat table *****

Clean INPUT rule

Clean FORWARD rule

Clean OUTPUT rule

****************************************

SHOW ALL FILTER TABLE RULE

****************************************

Chain: INPUT

policy: ACCEPT

packet count: 821       byte count: 83028

policy_id:0001    proto_name:icmp

in_iface: eth0          out_iface: any

sip:0.0.0.0/0.0.0.0           dip:0.0.0.0/0.0.0.0

sport : any   d_port range :  17 --- 0

Chain: FORWARD

policy: ACCEPT

packet count: 0         byte count: 0

policy_id:0006    proto_name:tcp

in_iface: any   out_iface: any

sip:192.168.2.2/192.168.2.2           dip:192.168.3.4/192.168.3.4

sport : any   d_port range :  80 --- 80

Chain: OUTPUT

policy: ACCEPT

packet count: 282       byte count: 46662

policy_id:0017    proto_name:udp

in_iface: any   out_iface: any

sip:192.168.6.2/192.168.6.2           dip:192.168.3.4/192.168.3.4

sport : any   d_port range :  1933 --- 1933

***** open nat table *****

Clean PREROUTING rule

Clean INPUT rule

Clean OUTPUT rule

Clean POSTROUTING rule

****************************************

SHOW ALL NAT TABLE RULE

****************************************

Chain: PREROUTING

policy: ACCEPT

packet count: 7334      byte count: 384511

policy_id:0006    proto_name:tcp

in_iface: any   out_iface: any

sip:0.0.0.0/0.0.0.0           dip:0.0.0.0/0.0.0.0

sport : any   d_port range :  80 --- 80

Chain: INPUT

policy: ACCEPT

packet count: 698       byte count: 105695

Chain: OUTPUT

policy: ACCEPT

packet count: 714       byte count: 40988

Chain: POSTROUTING

policy: ACCEPT

packet count: 714       byte count: 40988

时间: 2025-01-05 20:30:59

使用 libiptc 操作 iptables的相关文章

iptables 实际操作 之 规则查询 2

在之前的文章中,我们已经总结过,iptables 为我们预定义了4张表,他们分别是raw 表,mangle表,nat表,filter表,不同的表拥有不同的功能. filter 负责过滤功能,比如允许那些IP 地址访问,拒绝那些IP地址访问,允许访问那些端口,禁止访问那些端口,filter表会根据我们定义的规则进行过滤,filter表应该是我们最常用到的表了,所以此处,我们一filter表为例,开始学习怎样实际操作iptables. 一. 查看filter 表的规则 [[email protect

Kubernetes1.2如何使用iptables

转:http://blog.csdn.net/horsefoot/article/details/51249161 本次分析的kubernetes版本号:v1.2.1-beta.0. Kubernetes中kube-proxy组件负责维护NODE节点上的防火墙规则和路由规则,Kube-proxy有两种实现方式,一种是通过iptables,一种是通过userspace,在1.2中将使用iptables作为首选,可以大幅提升性能,下面看看kube-proxy组件是如何操作iptables的. kub

10.15 iptables filter表案例 10.16/10.17/10.18 iptables nat表应用

10.15 iptables filter表案例 10.16/10.17/10.18 iptables nat表应用 扩展 iptables应用在一个网段 http://www.aminglinux.com/bbs/thread-177-1-1.html sant,dnat,masquerade http://www.aminglinux.com/bbs/thread-7255-1-1.html iptables限制syn速率 http://www.aminglinux.com/bbs/thre

iptables综合实验

实验目的: 使用iptables作为公司内网的网关,使内网用户可以正常访问外网. 内网有一台web服务器需要对外提供 内网有两台服务器部署了samba,ftp和dns服务,给内网用户使用 对192.168.1.10-192.168.1.50的用户限速 GW 192.168.1.200(连接外网)  192.168.2.1(连接内网)   WEB Server 192.168.2.202   Other Servers 192.168.2.101 192.168.2.102 一.配置WEB Ser

Linux之防火墙iptables

防火墙可分为主机防火墙和网络防火墙,主机防火墙主要通过在主机之上安装一些防火墙软件来保护系统的网络安全. iptables:(包过滤器)Packets Filter Firewall; Firewall:隔离工具:工作于主机或网络的边缘,对经由的报文根据预先定义的规则(识别条件)进行检测,对于能够被规则匹配到的报文实行某预定义的处理机制的一套组件: iptables/netfilter:包过滤型防火墙:带状态检测的包过滤型防火墙:连接追踪(connection tracking): 硬件防火墙:

iptables的实战整理

一.iptables使用场景: 内网情况下使用:在大并发的情况下不要开iptables否则影响性能 二.iptables出现下面的问题: 在yewufangwenbijiaoman/var/log/message中出现 ip(nf)_conntrack: table full 使得企业访问较慢的解决方法: vim /etc/sysctl.conf #加大 ip_conntrack_max 值 net.ipv4.ip_conntrack_max =393216 net.ipv4.netfilter

防火墙iptables详解(一)

-- 防火墙 常见的防火墙 :瑞星 江民 诺顿 卡巴斯基 天网...... iptables firewalld http://www.netfilter.org/ netfilter / iptables --iptables 的全名 2.4版本内核后都集成有这个组件 # yum install iptables\* # rpm -qa |grep iptables iptables-services-1.4.21-17.el7.x86_64 iptables-utils-1.4.21-17.

iptables配置conntrack的NOTRACK和TRACK

iptables本身没有TRACK target,以至于你不能指定需要被conntrack模块处理的数据包白名单,比如我想实现:除了来源IP是192.168.10.0/16网段的需要被track之外,其它的都不要track.       当然,你可以通过下面的配置实现我的需求:iptables -t raw -A PREROUTING ! -s 192.168.10.0/16 -j NOTRACK...反向NOTRACK类似,-s换-d如果更复杂一点呢?比如除了来源IP限制之外,还有协议,端口等

iptables之NAT实现

nat的优点:      防护内网中的主机,保护主机的安全      解决c类地址短缺的情况 SNAT和DNAT的区分是根据请求的源地址转换还是目标地址转换而决定的 以下实验中,内网的主机,将网关指向192.168.100.1这个地址 SNAT:源地址转换 拓扑: 过程解析: 报文的源地址为192.168.100.2,目标地址为外面主机地址211.70.160.16 但是到达nat服务器的eth0后,将报文的源地址改变成eth0的地址211.70.160.1 这个地址是一个公网地址 外网的web