Chinaunix首页 | 论坛 | 博客
  • 博客访问: 104042
  • 博文数量: 30
  • 博客积分: 0
  • 博客等级: 民兵
  • 技术积分: 402
  • 用 户 组: 普通用户
  • 注册时间: 2014-07-22 11:09
个人简介

摸着石头过河

文章分类

全部博文(30)

文章存档

2015年(2)

2014年(28)

我的朋友

分类: LINUX

2014-10-24 17:21:52

       常用的tcp和udp编程只能读写tcp和udp的数据,而原始套接字则具有下述三种能力:
      1、可以读写ICMPV4、IGMPV4和IGMPV6的数据。
           这样的话就不用自己组包了,就像tcp一样填充一些套接字就可以了,比较简便。
      2、可以处理内核不认识的ip数据报,大部分的内核只处理ip协议字段值为1(icmp)、2(igmp)、6(tcp)和17(udp)的分组。像OSPF路由协议直接使用ip协议,将ip协议字段值填充为89,这样内核就不认识了,只能采用原始套接字来处理。
      3、可以自行构造ipv4首部。
           后面会举例说明
      一、创建原始套接字
         socket函数原型:
         int socket(int domain, int type, int protocol);
         原始套接字的编程主要是t注意ype和protocol的赋值,type取值为SOCK_RAW,而protocol得取值一般为IPPROTO_XXX, 
          如IPPROTO_IGMP。

         int fd;
         fd=socket(AF_INET,SOCK_RAW,IPPROTO_IGMP);
      二、原始套接字的输入
            就是内核把ip数据报输入给原始套接字。在这之前先讨论下内核会把什么样子的ip数据报交给套接字。
           (1)若接收到的ip分组协议字段说明其数据部分是tcp或udp分组则不会将该ip分组交给套接字。
           (2)对于ICMP分组,大多数内核在处理完ICMP分组中的消息后传递到原始套接字(这个不太理解,内核既然处理完为何还要交给原始套接字呢?),而Berkeley 则是内核处理ICMp回射请求、时间戳请求和地址掩码请求,剩下的icmp消息传递给原始套接字。
          (3)所有的IGMP分组在内核处理完其中的IGMP消息后交给原始套接字。
          (4)内核将所有协议字段不认识的ip报文交给原始套接字处理,内核只对这些ip报文做最基本的处理:目的ip检测、首部监测等。
         (5)如果ip报文有分片,在所有的分片没有全部到来重组成完整的ip报文之前,内核不会把单个ip分片交给原始套接字。
          接下来说内核会把收到的ip报文交给哪个原始套接字呢?
          内核会对所有进程的所有原始套接字做检查,只有以下三个测试均为真内核才会把ip报文交给这个原始套接字。
         (1)创建原始套接字时第三个参数protocol非0时,收到的ip分组的协议字段值必须与该protocol相同。
         (2)如果该原始套接字已经被bind绑定到某个ip,则收到的ip分组的目的地址必须与该ip相同。
         (3)
如果该原始套接字已经被connect调用指定了对端ip,则收到的ip分组的源地址与该ip相同
          在ipv4中传递给原始套接字所在进程的都是完整的ip报文,而在ipv6中传递的是净菏。


          
            
阅读(713) | 评论(0) | 转发(0) |
给主人留下些什么吧!~~