Chinaunix首页 | 论坛 | 博客
  • 博客访问: 26917
  • 博文数量: 6
  • 博客积分: 240
  • 博客等级: 二等列兵
  • 技术积分: 80
  • 用 户 组: 普通用户
  • 注册时间: 2008-12-09 22:54
文章分类
文章存档

2011年(1)

2010年(2)

2009年(3)

我的朋友

分类: LINUX

2010-08-04 11:03:22

 
原来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) |
给主人留下些什么吧!~~