Chinaunix首页 | 论坛 | 博客
  • 博客访问: 410832
  • 博文数量: 82
  • 博客积分: 2600
  • 博客等级: 少校
  • 技术积分: 961
  • 用 户 组: 普通用户
  • 注册时间: 2010-03-08 21:44
文章分类
文章存档

2013年(2)

2012年(56)

2010年(24)

我的朋友

分类: LINUX

2012-06-12 22:06:01

PF_PACKET在内核的流程
 
套接字创建
packet_create() --> 赋值packet_ops
 
接收流程
packet_recvmsg()
skb_recv_datagram()
__skb_recv_datagram() --> 检测sk->sk_receive_queue
 
自下而上
 
netif_receive_skb()
__netif_receive_skb()
list_for_each_entry_rcu(ptype, &ptype_all, list) --> packet_create()时dev_add_pack()添加
deliver_skb()
pt_prev->func()
packet_rcv()
__skb_queue_tail()

发送流程
packet_sendmsg()
packet_snd()
dev_queue_xmit()
....

附注:
PF_PACKET接口可以操作链路层的数据。
isock = socket(PF_PACKET, SOCK_DGRAM, 0); //为0,之后会用setsockopt之类的设置
第二个参数,在使用SOCK_RAW, SOCK_DGRAM和SOCK_PACKET的区别:
(1)使用SOCK_RAW发送的数据必须包含链路层的协议头,接受得到的数据包,包含链路层协议头。而使用SOCK_DGRAM则都不含链路层的协议头。
(2)SOCK_PACKET也是可以使用的,但是已经废弃,以后不保证还能支持,不推荐使用。
(3)在使用SOCK_RAW或SOCK_DGRAM和SOCK_PACKET时,在sendto和recvfrom中使用的地址类型不同,前两者使用sockaddr_ll类型的地址,
而后者使用sockaddr类型的地址。
(4)如socket的第一个参数使用PF_INET,第二个参数使用SOCK_RAW,则可以得到原始的IP包。
阅读(3196) | 评论(0) | 转发(2) |
给主人留下些什么吧!~~