防火墙实验:实现一个简单防火墙
Completion requirements
我们还提供了一个钩子函数的示例,展示了阻止数据包。以下示例阻止了目的 IP 为 8.8.8.8 且目的端口为 53 的UDP数据包,这意味着阻止了对域名服务器 8.8.8.8 的 DNS 查询。
// 代码示例:阻止UDP
unsigned int blockUDP(void *priv, struct sk_buff *skb, const struct nf_hook_state *state)
{
struct iphdr *iph;
struct udphdr *udph;
u32 ip_addr;
char ip[16] = "8.8.8.8";
// 将 IPv4 地址从点分十进制格式(即,字符串,如 1.2.3.4)转换为一个 32 位二进制数
in4_pton(ip, -1, (u8 *)&ip_addr, '\0', NULL); 🄰
iph = ip_hdr(skb);
if (iph->protocol == IPPROTO_UDP) {
udph = udp_hdr(skb);
if (iph->daddr == ip_addr && ntohs(udph->dest) == 53){ 🄱
printk(KERN_DEBUG "****Dropping %pI4 (UDP), port %d\n",
&(iph->daddr), port);
return NF_DROP; 🄲
}
}
return NF_ACCEPT; 🄳
}
在上面的代码中,第 🄰 行展示了在内核中如何将点分十进制格式的IP地址(即一个字符串,如 1.2.3.4)转换为32位的二进制(0x01020304),以便与存储在数据包中的二进制数进行比较。第 🄱 行将目标IP地址和端口号与我们指定规则中的值进行比较。如果匹配,NF_DROP 将返回给 Netfilter,从而丢弃数据包。否则,NF_ACCEPT 将被返回,Netfilter 将允许数据包继续传输(NF_ACCEPT 仅表示数据包被当前钩子函数接受,它仍可能被其他钩子函数阻止)。
Last modified: Friday, 9 May 2025, 11:04 PM