原来iptables本来就是不能过滤dhcp包的。原因有两个:
(1)iptables 之所以不能拦截 DHCPREQUREST 的主要原因,就是因为 iptables 不支持 raw socket 造成的,dhcp 协议属于 raw socket
(2)还和iptables的实现有关。只要保证在数据报走到iptables的hook之前被clone一份交给其他协议处理,那么iptables将无法将缓冲区的这个包Drop掉。
正好手边有一个dhcp的代码, 研究了一下。
dhcp client的socket是这样创建的:
socket(PF_PACKET, SOCK_DGRAM, htons(ETH_P_IP))
加上iptables的规则确实不能过滤dhcp client发出的包。
在内核中,对于PF_PACKET类型的socket的创建,会调用packet_create().
\net\packet\af_packet.c中找到此函数。
static int packet_create(struct socket *sock, int protocol) { ...... sock->ops = &packet_ops; #ifdef CONFIG_SOCK_PACKET if (sock->type == SOCK_PACKET) sock->ops = &packet_ops_spkt; #endif ...... po->prot_hook.func = packet_rcv; #ifdef CONFIG_SOCK_PACKET if (sock->type == SOCK_PACKET) po->prot_hook.func = packet_rcv_spkt; #endif
...... if (protocol) {
...... dev_add_pack(&po->prot_hook);
...... }
......
}
|
调用了函数dev_add_pack将此socket加入ptype_base中。
当收到server回的offer包时,内核运行到netif_receive_skb()中再调用packet_rcv(). packet_rcv() 函数将直接调用 skb_queue_tail() 将数据报文存放在代表相应网络连接控制结构(struct sock)的接收队列 receive_queue 中。这样数据报文在接收过程中就绕过了 TCP 层和 IP 层的协议处理过程, 不会被hook.
阅读(2616) | 评论(0) | 转发(0) |