Chinaunix首页 | 论坛 | 博客
  • 博客访问: 379016
  • 博文数量: 73
  • 博客积分: 3574
  • 博客等级: 中校
  • 技术积分: 1503
  • 用 户 组: 普通用户
  • 注册时间: 2010-03-26 11:17
文章分类

全部博文(73)

文章存档

2012年(14)

2011年(15)

2010年(44)

分类: LINUX

2011-12-02 18:31:44

   在看网络编程书的时候却发现这样一条讲解:
 
   接收到的UDP分组和TCP分组绝不传递到任何原始套接口。如果一个进程想要读取含有UDP分组或TCP分组的IP数据报,它就必须在数据链路层读取这些分组。
 
   这句讲解让人很疑惑,按理说是能够通过raw socket接口编写tcp syn数据包进行syn探测的,如果不能接收tcp分组就不能对回应的数据包进行判断。因此,写了几个小程序进行了一下测试。
 
   测试结果如下:
   对于通过socket(PF_INET,SOCK_RAW,IPPROTO_XX)创建的raw 套接字能够接收所有L4层协议类型为指定IPPROTO_XX的数据包,而不会区分所接收数据包的五元组(源地址、目的地址、源端口、目的端口),所有指定协议的数据报文都能被接收,所以,如何区分是需要应用层去做的,比如对于icmp报文可以通过id、seq进行判断,对于tcp、udp则可以通过源地址及端口进行判断。
   正是因为如此,raw socket经常用于icmp这类便于区分的类型,而tcp、udp则可能被对端发来数据包所欺骗。
   其中,IPPROTO_XX的范围从0到255,其中协议号为0,即IPPROTO_IP,不能创建套接字;而协议号255,即IPPROTO_RAW,为默认开启IP_HDRINCL套接口选项,此时能够构造全部L4,L3报文部分完成发送,但通过此套接字不能够接收到IP报文。即对此套接字进行recvfrom不能获取到数据。
   若想接收IP报文,则必须通过创建另一种套接字socket(PF_PACKET,SOCK_RAW,htons(ETH_P_IP)),此时才能够从链路层直接获取整个IP数据报文。  
   在通过raw socket进行编程时,创建出的套接字选项与sockaddr并不关联,也就是说在完成数据发送后,可以通过创建同种类型的另一套接字进行接收,只要协议类型符合即可。
 
   这样看来,跟书上那句话应该是相冲突的,也许是linux内核实现不同,也许还没理解这句话的真正含义。。。
 
 
   
阅读(1954) | 评论(0) | 转发(0) |
给主人留下些什么吧!~~