- 论坛徽章:
- 0
|
回复 #8 qtdszws 的帖子
要么改变fprog中的指令值(具体原理现在明白了)为
{ 0x28, 0, 0, 0xfffff000 },
{ 0x15, 0, 3, 0x00000800 },
{ 0x20, 0, 0, 0x00000010 },
{ 0x15, 0, 1, 0xc0a801d6 },
{ 0x6, 0, 0, 0x00000060 },
{ 0x6, 0, 0, 0x00000000 }
其中的原理查看内核代码就可以明白,简单指出
v2.4.0
在调用packet_rcv之前,skb->data指向网络层
static int packet_rcv(struct sk_buff *skb, struct net_device *dev, struct packet_type *pt)
{
..
//tcpdump -i any -nnn ip,使用SOCK_DGRAM
//tcpdump -i eth0 -nnn ip,使用SOCK_RAW
if (dev->hard_header) {//<<<
/* The device has an explicit notion of ll header,
exported to higher levels.
Otherwise, the device hides datails of it frame
隐藏帧结构
structure, so that corresponding packet head
相应的包头不发送给用户
never delivered to user.
SOCK_DGRAM,也不发送
*/
//本skb是clone过的,所以不需要恢复下面的操作
if (sk->type != SOCK_DGRAM)
skb_push(skb, skb->data - skb->mac.raw);//SOCK_RAW,data从网络层拉回链路层
else if (skb->pkt_type == PACKET_OUTGOING) {//捕获的外出包
/* Special case: outgoing packets have ll header at head */
skb_pull(skb, skb->nh.raw - skb->data);//略过链路层
}
}
...
}
也即SOCK_RAW,相对于链路头偏移寻址
SOCK_DGRAM,相对于网络头偏移寻址
因此SOCK_DGRAM下,
{ 0x28, 0, 0, 0x0000000c },//c为协议域相对于链路头偏移
需要改成
{ 0x28, 0, 0, 0xfffff000 },//0xfffff000指示从skb->protocol中取协议值
{ 0x20, 0, 0, 0x0000001e },//1e为目的ip地址相对于链路头偏移
需改成
{ 0x20, 0, 0, 0x00000010 },//10为目的ip地址相对于网络头偏移 |
|