AF_INET和AF_PACKET区别

来源:互联网 发布:fpga软件下载 编辑:程序博客网 时间:2024/05/09 05:26

http://blog.csdn.net/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创建方法几乎是
一摸一样,例如,通过

CODE:
[Copy to clipboard]
       int sockfd;
       sockfd = socktet(AF_INET, SOCK_RAW, IPPROTO_ICMP);

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

CODE:
[Copy to clipboard]
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数据包传递给这个原始套接字.


原创粉丝点击