要求
- 设置iptables过滤规则为:所有从本机发出的icmp包全部到自己编写的应用程序
- 编写应用程序,功能如下:
·2.1 允许从本机出发,目的地址为win ip的icmp包;
·2.2 丢弃其他任何icmp包;
·2.3 当出现错误时,做错误处理,能够清理占用资源,退出程序。
实验环境
red hat 9.0
步骤
- 下载iptables-1.2.7a.tar.bz2.rar到red hat 9.0
- tar xjvf iptables-1.2.7a.tar.bz2.rar
- cd iptables-1.2.7a
- make
- make install-devel
- 加载过滤需要的内核模块
modprobe iptable_filter
modprobe ip_queue - 设置过滤规则
iptables -A OUTPUT -p icmp -j QUEUE
代码如下
#include <linux/netfilter.h>
#include <libipq.h>
#include <stdio.h>
#include <netinet/in.h>
#include <stdlib.h>
#include <netinet/ip.h>
#define BUFSIZE 2048
static void die(struct ipq_handle *h)
{
ipq_perror("passer");
ipq_destroy_handle(h);
exit(1);
}
int main(int argc, char **argv)
{
int status;
unsigned char buf[BUFSIZE];
struct ipq_handle *h;
struct iphdr *iphead;
h = ipq_create_handle(0, PF_INET);
if (!h)
{
die(h);
}
status = ipq_set_mode(h, IPQ_COPY_PACKET, BUFSIZE);
if (status < 0)
{
die(h);
}
do{
status = ipq_read(h, buf, BUFSIZE, 0);
if (status < 0)
{
die(h);
}
switch (ipq_message_type(buf)) {
case NLMSG_ERROR:
fprintf(stderr, "Received error message %d\\n",
ipq_get_msgerr(buf));
break;
case IPQM_PACKET: {
ipq_packet_msg_t *m = ipq_get_packet(buf);
iphead = (struct iphdr *)m->payload;
if(iphead->daddr == inet_addr(argv[1]))
{
status = ipq_set_verdict(h,m->packet_id,
NF_ACCEPT,0,NULL);
if(status < 0)
{
die(h);
}
}
else
{
status = ipq_set_verdict(h,m->packet_id,
NF_DROP,0,NULL);
if(status < 0)
{
die(h);
}
}
break;
}
default:
fprintf(stderr, "Unknown message type!\\n");
break;
}
} while (1);
ipq_destroy_handle(h);
return 0;
}