AF_PACKET套接字解密 --- 02
2013-03-13 18:23
253 查看
AF_PACKET套接字解密 --- 02 2012-05-23
22:36:57
分类: LINUX
当AF_PACKET套接字注册了prot_hook后,怎样进行监听呢,先来看发送:
当协议栈准备将数据交给net_device发送时,它将调用dev_queue_xmit():
点击(此处)折叠或打开
int dev_queue_xmit(struct sk_buff *skb)
{
struct net_device *dev = skb->dev;
......
rc = dev_hard_start_xmit(skb, dev, txq);
......
}
点击(此处)折叠或打开
int dev_hard_start_xmit(struct
sk_buff *skb, struct net_device *dev,
struct netdev_queue *txq)
{
......
if (!list_empty(&ptype_all))
dev_queue_xmit_nit(skb, dev);
......
}
由于AF_PACKET套接字注册了prot_hook,将导致dev_queue_xmit_nit()被调用:
点击(此处)折叠或打开
static void dev_queue_xmit_nit(struct sk_buff *skb, struct
net_device *dev)
{
struct packet_type *ptype;
struct sk_buff *skb2 = NULL;
struct packet_type *pt_prev = NULL;
rcu_read_lock();
list_for_each_entry_rcu(ptype, &ptype_all, list) {
/* Never send packets back to the socket
* they originated from - MvS (miquels@drinkel.ow.org)
*/
if ((ptype->dev == dev || !ptype->dev) &&
(ptype->af_packet_priv == NULL ||
(struct sock *)ptype->af_packet_priv != skb->sk)) {
if (pt_prev) {
deliver_skb(skb2, pt_prev, skb->dev);
pt_prev = ptype;
continue;
}
skb2 = skb_clone(skb, GFP_ATOMIC);
if (!skb2)
break;
......
}
}
if (pt_prev)
pt_prev->func(skb2, skb->dev, pt_prev, skb->dev);
rcu_read_unlock();
}
在遍历ptype_all链表时,这里有几点需要着重说明:
1:对于发送的包过滤条件有:
1). net_device是否是prot_hook指定的dev(NULL代表全部匹配)。
2). ptype->af_packet_priv在packet_creat()中被设定为自己,故自己发送的包不会被监听。
2:遍历ptype_all时,第一次会复制skb;只有ptype_all中不止1个entry时,将调用deliver_skb()。
3:当退出遍历时,将调用prot_hook的func成员,即packet_rcv()。
4: deliver_skb()仅仅是在调用prot_hook的func成员前增加skb的引用计算数。
点击(此处)折叠或打开
static int packet_rcv(struct sk_buff *skb, struct
net_device *dev,
struct packet_type *pt, struct net_device *orig_dev)
{
......
__skb_queue_tail(&sk->sk_receive_queue, skb);
......
}
经过packet_rcv(),发送的数据包被加入到了AF_PACKET套接字的接收队列,等待我们的读取。。。一切就是这么简单!
22:36:57
分类: LINUX
当AF_PACKET套接字注册了prot_hook后,怎样进行监听呢,先来看发送:
当协议栈准备将数据交给net_device发送时,它将调用dev_queue_xmit():
点击(此处)折叠或打开
int dev_queue_xmit(struct sk_buff *skb)
{
struct net_device *dev = skb->dev;
......
rc = dev_hard_start_xmit(skb, dev, txq);
......
}
点击(此处)折叠或打开
int dev_hard_start_xmit(struct
sk_buff *skb, struct net_device *dev,
struct netdev_queue *txq)
{
......
if (!list_empty(&ptype_all))
dev_queue_xmit_nit(skb, dev);
......
}
由于AF_PACKET套接字注册了prot_hook,将导致dev_queue_xmit_nit()被调用:
点击(此处)折叠或打开
static void dev_queue_xmit_nit(struct sk_buff *skb, struct
net_device *dev)
{
struct packet_type *ptype;
struct sk_buff *skb2 = NULL;
struct packet_type *pt_prev = NULL;
rcu_read_lock();
list_for_each_entry_rcu(ptype, &ptype_all, list) {
/* Never send packets back to the socket
* they originated from - MvS (miquels@drinkel.ow.org)
*/
if ((ptype->dev == dev || !ptype->dev) &&
(ptype->af_packet_priv == NULL ||
(struct sock *)ptype->af_packet_priv != skb->sk)) {
if (pt_prev) {
deliver_skb(skb2, pt_prev, skb->dev);
pt_prev = ptype;
continue;
}
skb2 = skb_clone(skb, GFP_ATOMIC);
if (!skb2)
break;
......
}
}
if (pt_prev)
pt_prev->func(skb2, skb->dev, pt_prev, skb->dev);
rcu_read_unlock();
}
在遍历ptype_all链表时,这里有几点需要着重说明:
1:对于发送的包过滤条件有:
1). net_device是否是prot_hook指定的dev(NULL代表全部匹配)。
2). ptype->af_packet_priv在packet_creat()中被设定为自己,故自己发送的包不会被监听。
2:遍历ptype_all时,第一次会复制skb;只有ptype_all中不止1个entry时,将调用deliver_skb()。
3:当退出遍历时,将调用prot_hook的func成员,即packet_rcv()。
4: deliver_skb()仅仅是在调用prot_hook的func成员前增加skb的引用计算数。
点击(此处)折叠或打开
static int packet_rcv(struct sk_buff *skb, struct
net_device *dev,
struct packet_type *pt, struct net_device *orig_dev)
{
......
__skb_queue_tail(&sk->sk_receive_queue, skb);
......
}
经过packet_rcv(),发送的数据包被加入到了AF_PACKET套接字的接收队列,等待我们的读取。。。一切就是这么简单!
相关文章推荐
- AF_PACKET套接字解密
- AF_PACKET套接字解密 一
- AF_PACKET套接字解密 二
- AF_PACKET套接字解密 http://write.blog.csdn.net/postedit
- AF_PACKET套接字解密 --- 01
- OD使用教程2 - 调试篇02|解密系列
- 链路层套接字PF_PACKET简介
- AF_INET与套接字
- 02-4. BCD解密(10)
- Linux Socket学习 -- 无名套接字 AF_UNIX
- 02-4. BCD解密(10)
- java加密解密--密钥格式,证书格式-02
- 【Linux4.1.12源码分析】AF_PACKET raw socket实现原理分析
- 最新整理手机解密大全02
- 使用AF_PACKET抓无线数据包
- 链路层套接字PF_PACKET简介(转)
- 02-4. BCD解密(10)
- PE格式详细讲解2 - 系统篇02|解密系列
- PE格式详细讲解2 - 系统篇02|解密系列