• 首页>
  • GRE考试>
  • Linux的网络协议栈-TCP/IP协议的消息格式分析(包括代码演示)

Linux的网络协议栈-TCP/IP协议的消息格式分析(包括代码演示)

2023-02-12 15:59:58来源:留学时间作者:凉牧 阅读量:17429

前言:在编程的时候调用网络侧的API,有过不知道具体原理的烦恼吗; 使用基本的ifconfig等命令,但不太了解其输出; 对于长的MAC地址、IP地址、子网掩码,不知道分配机制; 看了网上路由器、交换机、TCP、UDP、DHCP、DNS等知识点的介绍,依然感到迷茫。

请不要担心。 你会逐步掌握好网络知识。

互联网围绕TCP/IP协议的知识非常重要,我们今天用电脑手机聊天、玩游戏、购物、追剧等,其实是无意中在使用TCP/IP协议。

要成为编程专家,不仅需要数据结构、算法、设计模式等知识,还需要网络知识。

一、传输层消息1、TCP分组的报头

typedef struct _ TCP _ header { ushortnsourport; //源端口号16bitUSHORT nDestPort; //目标端口号16bitUINT nSequNum; //序列号32位uint nacknowledgenum; //确认号32bitUSHORT nHLenAndFlag; //前4位: TCP头长度; 中六)保留; 低位6比特:标志位16bitUSHORT nWindowSize; //窗口大小16bitUSHORT nCheckSum; //检查和16bitUSHORT nrgentPointer; //紧急数据偏移16比特*PTCP_HEADER,*PTCP_HEADER; 2、UDP数据包报头

typedef struct _ UDP _ header { ushortnsourport; //源端口号16bitUSHORT nDestPort; //目标端口号16bitUSHORT nLength; //数据包长度16bitUSHORT nCheckSum; //校验和16位*PUDP_HEADER,*PUDP_HEADER; 进入协议栈的过程:(与从协议栈出来的正好相反) )。

二、网络层消息1、IP报头IP分组,也称为IP分组,被传输到ISO网络的7层结构的网络层。 它由IP报头和IP消息用户数据组成,IP报头的长度通常在20到60字节之间,但一个IP数据包的最大长度不能超过655到35字节。

下图是IP数据包的标题格式,标题的前20个字节是固定的,之后的可变版本号:用于识别IP版本号的4个bit。

此4位字段的值设置为二进制的0100表示IPv4,设置为0110表示IPv6。

当前使用的IP协议的版本号是4。

头部长度: 4位。

标识包含选项的IP标头字段的长度。

服务类型: 8位。

服务类型字段分为两个子字段: 3位优先级字段和4位tos字段,最后位置为0。

4位TOS分别表示最小延迟、最大吞吐量、最高可靠性和最低成本。

将4bit中的1个bit位置设为1个。

如果四个位都为0,则表示一般服务。

目前,大多数TCP/IP实现不支持TOS特性,但已在4.3BSD Reno或更高版本的系统上设置。

OSPF和IS-IS还可以根据这些字段中的值设置路由策略。

而像SLIP这样的协议提供了基于服务类型的排队方法,可以优先处理交互数据,但其排队机制由SLIP自己判断和处理。

驱动程序首先检查协议字段以确定它是否是TCP段。 然后检查TCP源和宿的端口号以确定它是否是交互式服务。

最近,TOS字段被重新定义为区分服务( Diffserv )体系结构的一部分。

Diffserv比TOS定义允许的处理更灵活。

使用Diffserv,可以在一台路由器上定义服务分类( COS ),并将包分类为这些分类。

路由器可以根据分类使用不同的优先级转发包。

各排序和转发处理称为PHB。

该体系结构也称为COS。

您可以使用前6位组成DSCP位,使用任何数字,也可以根据分区服务体系结构中预定义的服务类型,定义最多64个不同的服务类型并将其组合为PHB。

ECN是显式拥塞通知比特。

如果路由器支持此特性,则这些位可用于拥塞信号( ECN=11 )。

总长度字段: 16位。

接收方可以通过从IP数据报的全长中减去IP报头的长度来确定分组数据有效载荷的大小。

IP数据报的最大大小为65535字节。

id字段: 16位。

唯一标识主机发送的所有数据报。

接收端根据分片中的标识字段是否相同,判断这些分片是否为同一数据报的分片,并进行分片重组。

通常,每次发送消息时,值都会加1。

标志字段: 3位。

标识数据报是否已分片。

第一名没有使用。 第2位是不分段( DF )位。

如果DF位设置为1,则表示路由器无法对包进行分段。

如果由于无法拆分而无法转发数据包,路由器将丢弃该数据包,并向源发送ICMP不可用的消息。

第三位是分段( MF )位。

路由器对包进行分段时,除了最后一个段的MF位设置为0外,其他段的MF位都将设置为1。 这样,接收者就会等待,直到接收到MF位为0的片。

位偏移: 13位。

在接收方重组数据报时用于标识分片的顺序。

指示段起点相对于标头起点的偏移。

位偏移字段允许收件人以正确的顺序重组包,因为段到达时可能会出现顺序偏差。

如果分组的长度超过它想要去的数据链路的MTU,则路由器必须将其片段。

数据包中的数据被分成小片,每个小片封装在独立的数据包中。

在接收方,使用识别符、段偏移、标签域的MF比特进行再构成。

生存时间: 8位。

TTL域防止丢失的包的无中断传播。

此域包含由生成包的主机设置的8位整数。

TTL值设置包可以通过的路由器的数量。

TTL的初始值由源主机设置,通常为32或64。 每经由处理它的路由器,TTL的值减少1。

当路由器将TTL减少到0时,数据包将被丢弃,并向数据包的源地址发送ICMP超时消息。

注意: TTL值在通过PIX时不减1。

协议字段: 8位。

用于识别哪个协议向IP传输数据。

ICMP为1,IGMP为2,TCP为6,UDP为17,GRE为47,ESP为50。

标头校验和:根据IP标头计算的校验和代码。

源IP地址: 32位、4字节、每个字节为0到255之间的整数,以及日常可见的IP地址格式。

目标IP地址: 32位、4字节、各字节为0~255的整数,以及日常可见的IP地址格式。

选项:数据报可变长度的可选信息。

选项字段以32bit为边界,如果不足,插入值用0填充字节。

IP报头保证始终是32bit的整数倍。

因为Delphi没有域这一概念,所以在定义结构时只能使用全字节。 我想念C和Erlang。 域已定义,使用起来很方便。

//IP数据包tip header=packedrecordiph _ verlen:byte; //版本和长度iph_tos: byte; //服务类型iph_length: word; //全长,无符号字节2个,所以65535 iph_id: word; iph_offset: word; //徽标和切片偏移量iph_ttl: byte; //生存时间iph_protocol: byte; //协议iph_xsum: word; //头校验和iph_src: longword; //源地址iph_dest: longword; //目标地址end; 这个结构体有什么用呢? 其实在嗅探的时候很有用。

2、ICMP报头和消息校验和计算

ICMP标头typedef struct _ icmp _ header { byte btype; //类型8bitBYTE bCode; //代码8bitUSHORT nCheckSum; //校验和16位短整型; //标记,本进程ID16bitUSHORT nSequence; //序列号16位uint n timestamp; //选项,在此为时间,时间32bit} ICMP_HEADER,*PICMP_HEADER; 当发送ICMP消息时,程序必须自己计算校验和并将其嵌入到ICMP报头中的相应域中。

校验和的计算方法是以字( 16比特)为单位将数据累计为双字)的强变换双字型),在数据长度为奇数)奇数字节的情况下,最后的字节扩展为字,累计的结果成为双字,最后是该双字

//计算ICMP数据包检查值//参数1:ICMP数据包缓冲区//参数2:ICMP数据包长度ushortgetchecksum(LPbytelpbuf,DWORD dwSize ) { dword dw chw ushort*LPword=(ushort* ) lpBuf; //累计while(Dwsize1) {dwCheckSum =*lpWord; dwSize -=2; //长度为奇数if(Dwsize==1) dwchecksum=* ) ) LPbyte ) lpWord ); //高位16位和低位16位相加后的dwchecksum=(dwchecksum16 ) ( dwCheckSum0xFFFF ); //反return(ushort ) (~dwCheckSum ); }

相关文章

热门文章