设置过滤环境
加载过滤需要的内核模块
– # modprobe iptable_filter
– # modprobe ip_queue
设置过滤规则
– iptables -A OUTPUT -p icmp -j QUEUE
编写应用程序:
程序框架
ipq_create_handle()
->ipq_set_mode()
->包过滤处理循环while(1){
->ipq_read()
->分析包ipq_message_type() ipq_get_packet()
->包处理ipq_set_verdict()
}
->ipq_destroy()
实验代码如下:
//test.c
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <arpa/inet.h>
#include <linux/netfilter.h>
#include <libipq/libipq.h>
#include <libnet.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;
char *ip_dst_s="192.168.48.1";
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);
struct libnet_ipv4_hdr* iph;
iph=(struct libnet_ipv4_hdr*)m->payload;
if(m->data_len<20){
fprintf(stderr, "ip header is too short\n");
die(h);
}
char *dst = libnet_addr2name4(iph->ip_dst.s_addr, LIBNET_DONT_RESOLVE);
if(!strcmp(dst, ip_dst_s)){
status = ipq_set_verdict(h, m->packet_id, NF_ACCEPT, 0, NULL);
printf("dst ip:%s state: accept\n", dst);
}
else{
status = ipq_set_verdict(h, m->packet_id, NF_DROP, 0, NULL);
printf("dst ip:%s state: drop\n", dst);
}
if (status < 0)
die(h);
break;
}
default:
fprintf(stderr, "Unknown message type!\n");
break;
}
} while (1);
ipq_destroy_handle(h);
return 0;
}
至于实验结果就不帖了,读者想知道就自己编译一下测试测试
编译方法是:
gcc test.c -lipq -lnet
实验体会:
很多软件都定义了一些相同的数据结构,但是名字不同,感觉这是一大缺陷,比如ip header,实验手册中给的是linux/ip.h 中的struct iphdr,libnet中libnet-headers.h有struct libnet_ipv4_hdr和struct libnet_ipv6_hdr,分析snort源码时,snort也定义了一个自己的typedef struct _IPHdr{…} IPHdr;,对同一数据结构进行了多次的不同的定义,明显感觉有的复用性没有达到,我选择了libnet_ipv4_hdr,因为手头有libnet的手册,查询比较方便。就应该开发一套通用的放到c语言规范里,这样可以避免大量的重复劳动,而且程序员也不需要有太大的负担