AF_INET和AF_PACKET区别

本文详细阐述了原始套接字的工作原理、特点及使用注意事项,包括如何通过原始套接字直接访问链路层数据,以及在不同场景下的应用实例。重点介绍了原始套接字与标准套接字的区别,以及在实际开发中如何有效利用原始套接字功能。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

http://blog.youkuaiyun.com/kzm2008/article/details/5372834



man 7 ip

man 7 packet
  

Packet  sockets  are used to receive or send raw packets at the device driver (OSI Layer 2) level.  They allow the user to implement protocol modules in user space on top of the physical layer. 用AF_INET,上层代码无法获取以太头部信息。


1.原始套接字(raw socket)

  1.1 原始套接字工作原理与规则
         原始套接字是一个特殊的套接字类型,它的创建方式跟TCP/UDP创建方法几乎是
一摸一样,例如,通过

       int sockfd;
       sockfd = socktet(AF_INET, SOCK_RAW, IPPROTO_ICMP);

这两句程序你就可以创建一个原始套接字.然而这种类型套接字的功能却与TCP或者UDP类型套接字的功能有很大的不同:TCP/UDP类型的套接字只能够访问传输层以及传输层以上的数据,因为当IP层把数据传递给传输层时,下层的数据包头已经被丢掉了.而原始套接字却可以访问传输层以下的数据,,所以使用 raw套接字你可以实现上至应用层的数据操作,也可以实现下至链路层的数据操作.
         比如:通过

sock = socket(PF_PACKET, SOCK_RAW, htons(ETH_P_IP))

方式创建的raw socket就能直接读取链路层的数据.

1)使用原始套接字时应该注意的问题(参考<<unix网络编程>>以及网上的优秀文档)

(1):对于UDP/TCP产生的IP数据包,内核不将它传递给任何原始套接字,而只是将这些数据交给对应的UDP/TCP数据处理句柄(所以,如果你想要通过原始套接字来访问TCP/UDP或者其它类型的数据,调用socket函数创建原始套接字第三个参数应该指定为htons(ETH_P_IP),也就是通过直接访问数据链路层来实现.(我们后面的密码窃取器就是基于这种类型的).

(2):对于ICMP和EGP等使用IP数据包承载数据但又在传输层之下的协议类型的IP数据包,内核不管是否已经有注册了的句柄来处理这些数据,都会将这些IP数据包复制一份传递给协议类型匹配的原始套接字.

(3):对于不能识别协议类型的数据包,内核进行必要的校验,然后会查看是否有类型匹配的原始套接字负责处理这些数据,如果有的话,就会将这些IP数据包复制一份传递给匹配的原始套接字,否则,内核将会丢弃这个IP数据包,并返回一个ICMP主机不可达的消息给源主机.

(4): 如果原始套接字bind绑定了一个地址,核心只将目的地址为本机IP地址的数包传递给原始套接字,如果某个原始套接字没有bind地址,核心就会把收到的所有IP数据包发给这个原始套接字.

(5): 如果原始套接字调用了connect函数,则核心只将源地址为connect连接的IP地址的IP数据包传递给这个原始套接字.

(6):如果原始套接字没有调用bind和connect函数,则核心会将所有协议匹配的IP数据包传递给这个原始套接字.


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值