`

分片重组与原始套接字

 
阅读更多

winpcap是对链路层的封装,而链路层是不对IP分片进行排序。

TCP传播方式应该是,应用层将数据从应用进程的缓冲区写入套接字发送缓冲区(可用SO_SENBUF设置),TCP分片时从套接字发送缓冲区取得MSS-TCP头数量 [ MSS <=MTU-IP头数量,一般由对方通告,(对方通告可以得到路径MTU,以免在通过路由等网络设备或到达对方主机时再分片)如果对方没有通告则设置为536 ] 大小的数据加上TCP头,传给IP层,IP层加上IP头,再将数据(IP头+TCP头+用户数据)分为小与MTU的包发给链路层的输出队列。因为TCP层转数据到IP层时,只传等于MSS大小的TCP分节,再加上IP头也不会超过MTU,所以就不存在IP层的分片。IP层的分片主要用于UDP数据及ICMP包,而不是用于TCP的。

注意
无连接的数据报传输过程中,作为服务器的一方必须先启动
通信的一方可以不用bind()绑定地址和端口,由系统分配
不绑定IP地址和端口号的一方必须首先向绑定地址的一方发送数据
无连接客户端一般不调用connect(),在数据发送前客户与服务器各自通过socket()和bind()建立了半相关,发送数据时除指定本地套接口的地址外,还需要指定接收方套接口地址,从而在数据收发过程中动态建立全连接


RAW Socket原始套接字编程可以接收到本机网卡上的数据帧或者数据包,对与监听网络的流量和分析是很有作用的.一共可以有3种方式创建这种socket
1.socket(AF_INET, SOCK_RAW, IPPROTO_TCP|IPPROTO_UDP|IPPROTO_ICMP)发送接收ip数据包
2.socket(PF_PACKET, SOCK_RAW, htons(ETH_P_IP|ETH_P_ARP|ETH_P_ALL))发送接收以太网数据帧
3.socket(AF_INET, SOCK_PACKET, htons(ETH_P_IP|ETH_P_ARP|ETH_P_ALL))过时了,不要用。
理解一下SOCK_RAW的原理, 比如网卡收到了一个 14+20+8+100+4 的udp的以太网数据帧.
首先,网卡对该数据帧进行硬过滤(根据网卡的模式不同会有不同的动作,如果设置了promisc混杂模式的话,则不做任何过滤直接交给下一层输入例程,否则非本机mac或者广播mac会被直接丢弃).按照上面的例子,如果成功的话,会进入ip输入例程.但是在进入ip输入例程之前,系统会检查系统中是否有通过socket(AF_PACKET, SOCK_RAW, ..)创建的套接字.如果有的话并且协议相符,在这个例子中就是需要ETH_P_IP或者ETH_P_ALL类型.系统就给每个这样的socket接收缓冲区发送一个数据帧拷贝.然后进入下一步.
其次,进入了ip输入例程(ip层会对该数据包进行软过滤,就是检查校验或者丢弃非本机ip或者广播ip的数据包等,具体要参考源代码),例子中就是如果成功的话会进入udp输入例程.但是在交给udp输入例程之前,系统会检查系统中是否有通过socket(AF_INET, SOCK_RAW, ..)创建的套接字.如果有的话并且协议相符,在这个例子中就是需要IPPROTO_UDP类型.系统就给每个这样的socket接收缓冲区发送一个数据帧拷贝.然后进入下一步.
最后,进入udp输入例程 ...
ps:如果校验和出错的话,内核会直接丢弃该数据包的.而不会拷贝给sock_raw的套接字,因为校验和都出错了,数据肯定有问题的包括所有信息都没有意义了.

进一步分析他们的能力.
1. socket(AF_INET, SOCK_RAW, IPPROTO_UDP);
能:该套接字可以接收协议类型为(tcp udp icmp等)发往本机的ip数据包,从上面看的就是20+8+100.
不能:不能收到非发往本地ip的数据包(ip软过滤会丢弃这些不是发往本机ip的数据包).
不能:不能收到从本机发送出去的数据包.
发送的话需要自己组织tcp udp icmp等头部.可以setsockopt来自己包装ip头部
这种套接字用来写个ping程序比较适合
2. socket(PF_PACKET, SOCK_RAW, htons(x)); 
这个套接字比较强大,创建这种套接字可以监听网卡上的所有数据帧.从上面看就是20+20+8+100.最后一个以太网crc从来都不算进来的,因为内核已经判断过了,对程序来说没有任何意义了.
能: 接收发往本地mac的数据帧
能: 接收从本机发送出去的数据帧(第3个参数需要设置为ETH_P_ALL)
能: 接收非发往本地mac的数据帧(网卡需要设置为promisc混杂模式)
协议类型一共有四个
ETH_P_IP 0x800 只接收发往本机mac的ip类型的数据帧
ETH_P_ARP 0x806 只接受发往本机mac的arp类型的数据帧
ETH_P_ARP 0x8035 只接受发往本机mac的rarp类型的数据帧
ETH_P_ALL 0x3 接收发往本机mac的所有类型ip arp rarp的数据帧, 接收从本机发出的所有类型的数据帧.(混杂模式打开的情况下,会接收到非发往本地mac的数据帧)

发送的时候需要自己组织整个以太网数据帧.所有相关的地址使用struct sockaddr_ll 而不是struct sockaddr_in(因为协议簇是PF_PACKET不是AF_INET了),比如发送给某个机器,对方的地址需要使用struct sockaddr_ll.

分享到:
评论

相关推荐

    原始套接字编程,综合ping

    网络编程,原始套接字编程实验实验。具体功能如下: IP首部的构造;基于原始套接字的分片ICMP ECHO请求发送功能;基于原始套接字的ICMP ECHO响应接收功能;重叠分片的发送功能; 可以用来测试windows系统和Linux系统...

    unix网络编程源代码:卷1:套接字联网API;unpv13e

    首先,本书介绍了套接字的基本概念,包括套接字类型(如流式套接字、数据报套接字和原始套接字)、地址族(如IPv4的AF_INET和IPv6的AF_INET6)以及套接字的创建、绑定、监听和连接过程。创建套接字时,我们需要指定...

    C语言 tcp数据包重组

    2. **绑定(Binding)**:使用`bind()`函数将套接字与本地IP地址和端口号关联,以便接收数据。 3. **监听(Listening)**:通过调用`listen()`函数设置服务器为监听状态,等待客户端的连接请求。 4. **接受连接...

    linux网络编程(入门篇)

    - **原始套接字**:直接处理IP层数据包,可用于实现特定的协议或进行底层网络编程。 **1.2 套接字地址结构** - 在Linux中,不同的套接字类型使用不同的地址结构,例如AF_INET类型使用`sockaddr_in`结构体来存储...

    计算机网络课程设计报告-解析IP数据包.doc

    创建原始套接字使用`WSASocket()`函数,指定`SOCK_RAW`类型和`IPPROTO_IP`协议。通过`setsockopt()`函数设置`IP_HDRINCL`选项,表明程序会处理IP头部信息。 程序运行流程如下: 1. 初始化环境,创建输出日志文件。...

    计算机网络 监控ip包流量

    在本课程设计中,学生被要求通过编写程序来实现这一功能,从而深入理解IP数据包的结构、IP协议的工作原理,以及如何利用原始套接字(Raw Socket)进行编程。 IP数据包是Internet Protocol(因特网协议)的基础,每...

    LINUX网络详解.ppt

    套接字的类型包括流式套接字(TCP)、数据报套接字(UDP)和原始套接字,每种都有其特定的应用场景。套接字的基本结构包括套接字描述符、地址族、类型和协议。初始化套接字时,通常需要调用socket()函数来创建,然后...

    (源码)基于C语言的网络协议栈实现.zip

    通过原始套接字(raw socket),项目展示了如何从应用层到数据链路层的完整通信过程,包括帧的封装、IP分片与重组、UDP校验和计算等功能。 ## 项目的主要特性和功能 1. 数据链路层(Ethernet Frame) 使用自定义...

    linux网络编程(网页形式)

    8. **原始套接字**:原始套接字允许开发者访问底层网络协议,例如发送自定义的IP包或捕获网络流量。这部分可能涵盖IP选项、RAW套接字和网络嗅探。 9. **后记**:通常会总结整个Linux网络编程的学习要点,给出进一步...

    基于C++的TCP UDP 使用实例.zip

    3. **bind()**:将套接字与本地IP地址和端口号绑定,使服务器端能监听特定端口上的连接请求。 4. **listen()**:仅对TCP套接字有效,表示服务器开始监听连接请求。 5. **accept()**:接收客户端的连接请求,返回一...

    使用C/C++使用TCP实现简单的文件传输下载

    2. **绑定IP和端口**:使用`bind()`函数将套接字与特定IP地址和端口号关联起来。服务端通常使用`INADDR_ANY`表示任何可用的IP地址。 3. **监听连接**:使用`listen()`函数使套接字进入监听状态,等待客户端的连接...

    网路编程基础知识与TCP Socket的封装

    封装数据时,程序员需要考虑多个层面,包括数据格式的转换、数据包的分片和重组以及错误检测和纠正等。数据的正确封装和传输是网络编程的核心,而实现这一点通常需要程序员对各种网络协议有深入的理解。 最后,要...

    Linux系统下接收jpeg视频流及H264视频流

    2. **绑定IP和端口**:使用`bind()`函数将套接字与本地IP和特定端口绑定,以便接收数据。 3. **接收数据**:使用`recvfrom()`函数从套接字接收数据包,此函数可以获取发送者的信息。 4. **处理JPEG数据**:接收到的...

    精选_Socket通信之TCP通信小程序_源码打包

    8. **数据分片与重组**:由于网络传输中可能需要经过多个路由器,TCP可能会将大块数据分割成多个较小的数据段进行传输,并在接收端重组这些数据段以还原原始数据。 9. **异常处理**:在实际编程中,需要考虑各种...

    解析IP数据包(网路协议分析课程设计)

    这些字段提供了诸如数据包路由、分片重组和错误检测等功能。数据部分则携带了上层协议(如TCP、UDP或ICMP)的数据。 解析IP数据包通常涉及到以下几个步骤: 1. **数据捕获**:要获取IP数据包,可以使用底层网络...

    TCP协议图片上传

    TCP(Transmission Control Protocol)协议是...总的来说,TCP协议图片上传涉及网络连接的建立、数据的分片与重组、以及输入输出流的使用。理解并熟练掌握这些知识点,能帮助开发者构建稳定、高效的文件传输系统。

    IP数据包捕获程序

    6. **片偏移**:当数据包需要分片时,这个字段用于指示当前数据包相对于原始未分片IP数据包的位置。 7. **协议**:“协议”字段指示了IP数据包载荷中所使用的上层协议,如TCP、UDP或ICMP,这些协议决定了数据包如何...

    发送和接收TCP数据包的客户端和服务器

    - TCP数据包是分片传输的,因此在接收端可能需要重组数据包以恢复原始消息。 - 数据通常会被封装在结构体或类中,以便于管理和处理。 9. **错误处理**: - 网络编程中,错误处理非常重要,因为网络状况不可预测...

    C#网络编程.pdf

    网络层还负责数据包的分片和重组,以及定义了数据包的寻址和路由机制。 传输层负责在源和目的地之间提供可靠的数据传输服务。它通过协议如TCP(传输控制协议)和UDP(用户数据报协议)来实现这一层的服务。TCP提供...

Global site tag (gtag.js) - Google Analytics