我们还提供了一个钩子函数的示例,展示了阻止数据包。以下示例阻止了目的 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 仅表示数据包被当前钩子函数接受,它仍可能被其他钩子函数阻止)。
最后修改: 2025年05月9日 星期五 23:04