我正在编写一个netfilter模块,根据目标IP检查丢弃数据包。
我注册了一个nf钩子
nfho_out.hook = hook_func_out;
nfho_out.hooknum = NF_INET_LOCAL_OUT;
nfho_out.pf = PF_INET;
nfho_out.priority = NF_IP_PRI_FIRST;
nf_register_hook(&nfho_out);
这是我的nf钩子函数
unsigned int hook_func_out(unsigned int hooknum, struct sk_buff *skb, const struct net_device *in, const struct net_device *out, int (*okfn)(struct sk_buff *)) {
struct iphdr *ip_header = (struct iphdr *)skb_network_header(skb);
struct udphdr *udp_header;
struct tcphdr *tcp_header;
struct list_head *p;
unsigned int src_ip = (unsigned int)ip_header->saddr;
unsigned int dest_ip = (unsigned int)ip_header->daddr;
unsigned int src_port = 0;
unsigned int dest_port = 0;
if (ip_header->protocol==17) {
udp_header = (struct udphdr *)skb_transport_header(skb);
src_port = (unsigned int)ntohs(udp_header->source);
} else if (ip_header->protocol == 6) {
tcp_header = (struct tcphdr *)skb_transport_header(skb);
src_port = (unsigned int)ntohs(tcp_header->source);
dest_port = (unsigned int)ntohs(tcp_header->dest);
}
printk(KERN_INFO "OUT packet info: src ip: %u, src port: %u; dest ip: %u, dest port: %u; proto: %u\n", src_ip, src_port, dest_ip, dest_port, ip_header->protocol);
printk(KERN_DEBUG "IP addres = %pI4 DEST = %pI4\n", &src_ip, &dest_ip);
....
....
}
我在网络浏览器中打开了google.com,但我无法获得google.com解析的实际目标IP地址。问题是我总是得到一些奇怪的IP地址(因为我怀疑代理服务器或DNS服务器)而不是实际的IP地址。
如何在nf钩子函数中获取实际的目标地址?
答案 0 :(得分:3)
我发现您发布的代码段没有任何问题。
当您在网络浏览器中打开www.google.com时,首先会重新启动DNS并更新以后的HTTP消息。因此,您会看到在DNS解析期间,dest_ip
是 GATEWAY / DNS SERVER ip。解析完DNS后,dest_ip
始终是已解析的www.google.com IP。
首先通过在终端上发出以下命令来检查www.google.com解决的问题:
[s.roy@roy ~]$ nslookup www.google.com
Server: 192.168.1.1
Address: 192.168.1.1#53
Non-authoritative answer:
Name: www.google.com
Address: 216.58.220.36
正如您所看到的,www.google.com已被DNS服务器 192.168.1.1 解析为 216.58.220.36 ,这也是我案例中的默认网关。请注意,在 nslookup 期间,我的dest_ip
为192.168.1.1。
DNS解析后,我的系统会发送dest_ip
为 216.58.220.36 的TCP和HTTP消息。
<强> test.c的强>
static struct nf_hook_ops nfho_out;
static unsigned int hook_func_out(unsigned int hooknum,
struct sk_buff *skb,
const struct net_device *in,
const struct net_device *out,
int (*okfn)(struct sk_buff *))
{
struct iphdr *ip_header = (struct iphdr *)skb_network_header(skb);
struct udphdr *udp_header;
struct tcphdr *tcp_header;
struct list_head *p;
unsigned int src_ip = (unsigned int)ip_header->saddr;
unsigned int dest_ip = (unsigned int)ip_header->daddr;
unsigned int src_port = 0;
unsigned int dest_port = 0;
if (ip_header->protocol==17) {
udp_header = (struct udphdr *)skb_transport_header(skb);
src_port = (unsigned int)ntohs(udp_header->source);
} else if (ip_header->protocol == 6) {
tcp_header = (struct tcphdr *)skb_transport_header(skb);
src_port = (unsigned int)ntohs(tcp_header->source);
dest_port = (unsigned int)ntohs(tcp_header->dest);
}
printk(KERN_DEBUG "IP addres = %pI4 DEST = %pI4\n", &src_ip, &dest_ip);
return NF_ACCEPT;
}
static int __init test_init(void)
{
printk(KERN_INFO "Loading \n");
nfho_out.hook = hook_func_out;
nfho_out.hooknum = NF_INET_LOCAL_OUT;
nfho_out.pf = PF_INET;
nfho_out.priority = NF_IP_PRI_FIRST;
nf_register_hook(&nfho_out);
return 0;
}
static void __exit test_exit(void)
{
printk(KERN_INFO "Unloading \n");
nf_unregister_hook(&nfho_out);
}
module_init(test_init);
module_exit(test_exit);
罗伊
答案 1 :(得分:1)
你的代码似乎没有逻辑错误。您的问题根植于网络结构(如下所述)或Web服务器计算机。现在服务器可以检测查询是来自Web浏览器还是其他一些软件 你不能在最终用户的互联网电脑上做这种过滤。问题是从你的电脑到谷歌服务器有一些障碍,如代理,路由器的设置,防火墙/网关交叉。您的电脑似乎只获得自己的本地网络网关/代理地址 一些建议来解决这个问题
从不同的网络测试您的应用,以确认您自己的防火墙/代理不是问题的原因 如果您有一些资源,使用路由器和交换机进行简单的互联网,并尝试访问托管在您自己的互联网上的网站。如果你没有硬件,那么尝试一些网络仿真器/模拟器来测试你的代码。 NS2 / NS3和OMNET免费提供很多教程。
问题的根源在于您在某种程度上受到防火墙的保护。您的10.169.95.255
是本地IP,这意味着您无法跨越自己的网络。