环境:
1. Linux Client, 我做测试用的系统为:Ubuntu, 内核版本为2.6.38
2. apache, 版本任意,作为HTTP请求的服务端
3. libnfnetlink/libnetfilter_queue, 安装请参考:http://blog.csdn.net/tqtuuuu/article/details/6790433
4. iptables, 系统自带
5. 等等其他项,如libipq等,由于我是首先倒腾netfilter->然后libipq->然后才是netfilter_queue,过程中倒腾了一些软件包,不清楚netfilter_queue是否依赖这些软件包,如果需要,可查阅相关libipq相关配置部署资料。
目的:
通过简单的实例打印所指定的packet header 信息,方便后续操作,如根据特定信息的包做什么坏事等...
开始,
我一直以为我是一个实干家,没想到废话了这么多才到开始,实在是对不住大家~
使用Makefile文件并不是必须的,只是我shell比较烂,并且觉得Makefile对于这个功能的使用也很方便,就是为iptables设定某些规则或者清除某些规则。
Makefile文件内容,使用make install和make clean添加和取消iptables规则。
install:
iptables -A INPUT -p tcp --dport 80 -j NFQUEUE
iptables -A OUTPUT -p tcp --sport 80 -j NFQUEUE
clean:
iptables -D INPUT -p tcp --dport 80 -j NFQUEUE
iptables -D OUTPUT -p tcp --sport 80 -j NFQUEUE
上面的规则设置将input的tcp协议的且目的端口为80的packet加入NFQUEUE队列,将output的tcp协议的且源端口为80的packet加入NFQUEUE队列。好乱啊,其实代码比文字更好懂...
为了方便,再库目录下自带的测试文件基础上进行修改,测试文件在libnetfilter_queue-1.0.0/utils/nfqnl_test.c, 添加如下代码.
ret = nfq_get_payload(tb, &data);
if (ret >= 0)
printf("payload_len=%d ", ret);
struct iphdr *iphdrp = (struct iphdr*)data;
struct tcphdr *tcphdrp = (struct tcphdr*)((u_int8_t*)iphdrp + (iphdrp->ihl<<2));
if (iphdrp == NULL)
{
printf("iphdrp == NULL");
exit(1);
}
if (iphdrp->protocol == IPPROTO_TCP) {
printf("tcp...");
printf("\nsrc-ip:%u.%u.%u.%u, dest-ip:%u.%u.%u.%u", IPQUAD(iphdrp->saddr), IPQUAD(iphdrp->daddr));
printf("\nsrc-port:%d, dest-port:%d", tcphdrp->source, tcphdrp->dest);
printf("\nseq%d, ack_seq:%d", tcphdrp->seq, tcphdrp->ack_seq);
printf("\nwindow:%d", tcphdrp->window);
printf("\ndata-offset:%d", tcphdrp->doff);
}
那么iphdr和tcphdr结构体到底定义了啥东西呢?去头文件<linux/ip.h>和<linux/tcp.h>下查看,如下:
struct iphdr {
#if defined(__LITTLE_ENDIAN_BITFIELD)
__u8 ihl:4,
version:4;
#elif defined (__BIG_ENDIAN_BITFIELD)
__u8 version:4,
ihl:4;
#else
#error "Please fix <asm/byteorder.h>"
#endif
__u8 tos;
__be16 tot_len;
__be16 id;
__be16 frag_off;
__u8 ttl;
__u8 protocol;
__sum16 check;
__be32 saddr;
__be32 daddr;
/*The options start here. */
};
struct tcphdr {
__be16 source;
__be16 dest;
__be32 seq;
__be32 ack_seq;
#if defined(__LITTLE_ENDIAN_BITFIELD)
__u16 res1:4,
doff:4,
fin:1,
syn:1,
rst:1,
psh:1,
ack:1,
urg:1,
ece:1,
cwr:1;
#elif defined(__BIG_ENDIAN_BITFIELD)
__u16 doff:4,
res1:4,
cwr:1,
ece:1,
urg:1,
ack:1,
psh:1,
rst:1,
syn:1,
fin:1;
#else
#error "Adjust your <asm/byteorder.h> defines"
#endif
__be16 window;
__sum16 check;
__be16 urg_ptr;
};
iphdr和tcphdr分别定义了packet header各有什么,找找看有没有你需要的字段。比较一下个字段与struct中各属性的名字,你懂的。