pcap文件解析(三)--拆分SCTP包

这一章,我们将了解SCTP数据包结构,并简要介绍SCTP协议,最后将带有多个chunk的SCTP包拆分问单个SCTP数据包。

SCTP数据包

数据包头

Eth信息

IP头

SCTP头

SCTP Chunk 1

……

SCTP Chunk n

其中数据包头和IP头已经在前面做过介绍了,这里先简单介绍一下Eth信息。

[cpp]  view plain copy
  1. // Ethernet 信息  
  2. typedef struct__Ethernet_Info  
  3. {  
  4.         Byte    DestMac[6];  
  5.         Byte    SrcMac[6];  
  6.         _Int16  iType;  
  7.    
  8. } __EthernetInfo;  



DsetMac 目的主机mac地址

SrcMac   源主机MAC地址

Type 协议类型,IP为0x0800

 

SCTP简介


一个 SCTP 分组含了一个公共的分组头(Common Header)和若干数据块(Chunk),每个数据块中既可以包含控制信息,也可以包含用户数据。除了INIT、INIT ACK和SHUTDOWN COMPLETE 数据块外,其他类型的多个数据块可以捆绑在一个SCTP 分组中,以满足对 MTU 大小的要求。当然,这些数据块也可以不与其他数据块捆绑在一个分组中。如果一个用户消息不能放在一个SCTP 分组中,这个消息可以被分成若干个数据块。

SCTP头

         SCTP 公共分组头中包括了源端口号(Source Port Number)、目的端口号(Destination PortNumber)、验证标签(Verification Tag)和校验码(Checksum)

 1.源端口号(16 bits)

                   源端口号识别 SCTP 发送端点的SCTP 端口号。接收方可以使用源端口号、源IP 地址、目的端口号和目的IP 地址标识该SCTP 分组所属的偶联。

         2.目的端口号(16 bits)

                   目的端口号为目的端点的 SCTP 端口号。接收主机可以使用目的端口号将SCTP 分组解复用到正确的端点或应用中。

         3.验证标签(32 bits)

                   验证标签是偶联建立时,本端端点为这个偶联生成一个随机标识。偶联建立过程中,双方会交换这个TAG,到了数据传递时,发送端必须在公共分组头中带上对端的这个TAG,以备校验。

          4.校验码(32 bits)

                   SCTP 通过对用户数据使用ADLER-32 算法,计算出一个32 位的校验码,带在数据报中,在接收端进行同样的运算,通过检查校验码是否相等来验证用户数据是否遭到破坏。

数据块

         数据块包括了块类型(Chunk Type)、块标志位(Chunk Flags)、块长度(Chunk Length)和块值(Chunk Value )。

          1.块类型(8 bits)

                   块类型定义在块值(Chunk Value)中消息所属的类型。

                  

0DATA(净数据) 传输的用户数据块。
1INIT 用于发起两个端点之间的SCTP 偶联。
2INIT ACK 用来确认SCTP 偶联的发起消息(INIT)。
3SACK 该数据块送至对端,以确认收到DATA 块,并且通知对端DATA 的接收顺序间隙。
4HEARTBEAT 端点发送该数据块至对端,以检测当前偶联中定义的某一目的地址的可达性。
5HEARTBEAT ACK 响应HEARTBEAT 消息。
6ABORT 关闭偶联。
7SHUTDOWN 偶联中的一个端点对其偶联发起一个GRACEFUL关闭。
8SHUTDOWN ACK 响应SHUTDOWN 消息,关闭程序完成时发出。
9ERROR 通知对端,SCTP 偶联发生某种错误。
10COOKIE ECHO 仅用于偶联发起过程,它由偶联的发起者发送至对端以完成发起程序。
11COOKIE ACK COOKIE 证实,相对于COOKIE ECHO
12ECNE 保留,应用于外部环境拥塞发布回声
13CWR 保留,应用于降低拥塞窗口
14SHUTDOWN COMPLETE用于关闭程序完成时对SHUTDOWN ACK 消息进行确认
15-62IETF 保留
63IETF 定义块扩展使用
64-126IETF 保留
127定义块扩展使用
128-190IETF 保留
191定义块扩展使用
192-254IETF 保留
255IETF 定义块扩展使用如果接收端点不能识别块类型时,块类型最高位2bit 用于标识需要进行的各种操作。

                            Bits(最高两位) 含义

                           

00停止处理并丢弃此SCTP 分组,不再处理该SCTP 分组中的其他消息块。
01停止处理并丢弃此SCTP 分组,不再处理该SCTP 分组中的其他消息块,并且在“ERROR”或“INIT ACK”中向发起端点返回不能识别的参数。
10 跳过此数据块并继续执行。
11跳过此数据块并继续执行,并且在“ERROR”或“INIT ACK”中向发起端点返回不能识别的参数。

          2.数据块标志位(8bit)

                   块标志位用法由块类型决定。除非被置为其他值,块标记在传送过程中会被置0 而且接收端点会忽视块标记。

                   定义见:HTTP:\\

          3.块长度(16bit)

                   块长度包括块类型(Chunk Type)、块标记(Chunk Flags)、块长度(Chunk Length)和块值(Chunk Value),长度使用二进制表示。

          4.块值(可变长度)

                   块值的内容在块中传送实际的信息,内容由消息块类型决定。块值的长度为不定长。

SCTP结构体定义

[cpp]  view plain copy
  1. // SCTP头  
  2. typedef struct __Sctp_header  
  3. {  
  4.     _Int16 SrcPort;  
  5.     _Int16 DstPort;  
  6.   
  7.     _Int32 iVerTag;  
  8.     _Int32 iChecksum;  
  9. } __SctpHeader;  
  10.   
  11. // chunk头  
  12. typedef struct __Sctp_chunk_header  
  13. {  
  14.     Byte Type;  
  15.     Byte Flag;  
  16.     _Int16  iLength;  
  17. } __SctpChunkHeader;  
  18.   
  19. // 单个SCTP Chunk  
  20. typedef struct __Sctp_chunk  
  21. {  
  22.     __SctpChunkHeader header;  
  23.     Byte* pData;  
  24. } __SctpChunk;  


拆分SCTP数据块

         下面的代码将逐个解析数据包,当数据包位SCTP包时,对DATA chunk进行拆分。

[cpp]  view plain copy
  1. bool main()  
  2. {  
  3.         __pcap_header header;  
  4.         int iNo = 1;  
  5.          
  6.         // 打开源文件和输出文件  
  7.     if( !OpenPcapFile( "sctp.pcap")|| !OpenOutFile( "export.pcap"))  
  8.     {  
  9.         return false;  
  10.     }  
  11.    
  12.     // 获得文件头  
  13.     GetPcapHeader( &header);  
  14.         //写入文件头  
  15.         WriteFileHeader( &header);  
  16.    
  17.         MoveFirst();  
  18.         while( !IeEof())  
  19.         {  
  20.                __pk_header data;  
  21.                __ip_header ipData;  
  22.                __EthernetInfo ethInfo;  
  23.                Byte* pBuffer;  
  24.                // 获取下一个数据包  
  25.         GetPacketAndMoveNext( &data,&pBuffer);  
  26.                // 获得ETH信息  
  27.                GetEthernetInfo( ðInfo, pBuffer,0);  
  28.                // 获得IP信息  
  29.         GetIpData( &ipData, pBuffer,sizeof(__EthernetInfo));  
  30.    
  31.         // SCTP == 132  
  32.         if( ipData.byteProtocol == 132)  
  33.         {  
  34.                        // 获取SCTP头  
  35.                        int iOffset = sizeof(__EthernetInfo) + ipData.byteHdLength * 4;  
  36.                        int iChunkOffset =iOffset + sizeof( __SctpHeader);  
  37.                        __SctpHeader sctpHeader;  
  38.                        __SctpChunksctpChunkArr[MAX_CHUNK_NUM];  
  39.                        // 当前已保存的chunk数量  
  40.                        int iChunkNum = 0;  
  41.                        // 当前已保存的chunk长度  
  42.                        int iLenght = 0;  
  43.                        // 获得SCTP头  
  44.                        GetSctpHeader(&sctpHeader, pBuffer, iOffset);  
  45.    
  46.                        whiletrue)  
  47.                        {  
  48.                                // 当前读取的chunk  
  49.                                __SctpChunksctpChunk;  
  50.                                // for 循环标志  
  51.                                int i = 0;  
  52.                                GetSctpChunk(&sctpChunk, pBuffer, iChunkOffset);  
  53.                                 
  54.                                if(sctpChunk.header.Type == 0) // DATA块  建立新数据包并写入chunk信息  
  55.                                {  
  56.                                       WritePkHeader(&data, iLenght + sctpChunk.header.iLength + LENGTH_SCTPALLHEADER(ipData));  
  57.                                       WriteEthInfo(ðInfo);  
  58.                                       WriteIpHeader(&ipData, iLenght + sctpChunk.header.iLength + LENGTH_SCTPIPHEADER(ipData));  
  59.                                       WriteSctpHeader(&sctpHeader);  
  60.                                       for( i =0; i < iChunkNum; i++)  
  61.                                       {  
  62.                                               WriteSctpChunk(sctpChunkArr + i);  
  63.                                       }  
  64.                                       WriteSctpChunk(&sctpChunk);  
  65.                                       iChunkNum = iLenght = 0;  
  66.                                }  
  67.                                else  
  68.                                {  
  69.                                       // 当前块位非DATA块  
  70.                                       sctpChunkArr[iChunkNum++] = sctpChunk;  
  71.                                       iLenght +=sctpChunk.header.iLength;  
  72.                                }  
  73.    
  74.                                iChunkOffset +=sctpChunk.header.iLength;  
  75.    
  76.                                if( iChunkOffset>=  
  77.                                       ipData.iTotalLength- ((ipData.byteHdLength & 0x0f) * 4))  
  78.                                {  
  79.                                       if(iChunkNum > 0)  
  80.                                       {  
  81.                                               //存在未写入的chunk数据,全部新建数据包写入  
  82.                                               if(sctpChunk.header.Type != 0)  
  83.                                                      iLenght-= sctpChunk.header.iLength;  
  84.    
  85.                                               WritePkHeader(&data, iLenght + sctpChunk.header.iLength + LENGTH_SCTPALLHEADER(ipData));  
  86.                                               WriteEthInfo(ðInfo);  
  87.                                               WriteIpHeader(&ipData, iLenght + sctpChunk.header.iLength + LENGTH_SCTPIPHEADER(ipData));  
  88.                                               WriteSctpHeader(&sctpHeader);  
  89.                                               for(i = 0; i < iChunkNum; i++)  
  90.                                               {  
  91.                                                      WriteSctpChunk(sctpChunkArr + i);  
  92.                                               }  
  93.                                       }  
  94.                                       break;  
  95.                                }  
  96.    
  97.                        }  
  98.         }  
  99.    
  100.         free( pBuffer);  
  101.         }  
  102.    
  103.      
  104.         CloseOutFile();  
  105.         ClosePcapFile();  
  106.         printf( "Export over");  
  107.         return true;  
  108. }  
  • 2
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
### 回答1: 《pcap04-eva-kit-manual.pdf》是一份关于pcap04-eva套件的使用手册。该手册详细介绍了如何正确使用pcap04-eva套件以及相关工具和软件。 首先,手册提供了该套件的概述,括其基本组成部分和主要功能。它还介绍了与套件一起提供的所有配件和连接器,以便用户能够了解套件的整体结构。 其次,手册提供了关于套件的安装和设置的详细步骤。它括如何正确连接电缆和插头以及如何将套件与计算机或其他设备连接起来。手册指导用户如何安装套件的驱动程序和软件,以确保套件可以正常工作。 此外,手册提供了使用套件进行数据采集和分析的详细说明。它介绍了如何配置套件以捕获网络数据,并提供了一些常见问题的解决方案和调试技巧。手册还简要介绍了套件支持的其他功能,例如网络分析和性能监测等。 最后,手册提供了一些使用套件时的最佳实践和建议。它括了一些实用的技巧和注意事项,以确保用户可以充分利用套件的功能和性能。 总之,《pcap04-eva-kit-manual.pdf》是一份详尽的使用手册,旨在帮助用户正确使用pcap04-eva套件。它提供了从安装到数据采集和分析的全面指导,使用户能够快速上手并充分发挥套件的潜力。 ### 回答2: "pcap04-eva-kit-manual.pdf" 是一份关于PCAP04评测套件的使用手册。PCAP04评测套件是一种用于评估触摸屏性能的工具。这份手册提供了使用指南,以帮助用户了解如何设置和操作PCAP04评测套件。 手册中首先介绍了PCAP04评测套件的概述,括套件内的部件和其主要功能。接着详细说明了安装和配置套件的步骤,括所需的软件和硬件设备。用户可以按照手册中的说明,逐步进行安装和设置。 手册还介绍了使用套件进行触摸屏评估的方法。它详细解释了评估过程中所需的各种设置选项和参数,以及如何根据评估的目的和需求进行选择。此外,手册还提供了一些相关的背景知识和理论,以帮助用户更好地理解评估结果。 最后,手册还含了一些故障排除指南和常见问题解答,以帮助用户在遇到问题时进行解决。 通过阅读并遵循这份手册,用户可以更好地理解和使用PCAP04评估套件,从而评估和改进触摸屏的性能。手册提供了详细的说明和指导,以帮助用户更好地使用这一评估工具,提升产品的质量和用户体验。 ### 回答3: 《pcap04-eva-kit-manual.pdf》是一本关于PCAP04评估套件的操作手册。PCAP04评估套件是一种用于评估和测试PCAP04传感器模块性能的工具。手册提供了详细的使用说明和操作步骤,以帮助用户正确安装、配置和操作评估套件。 手册的内容括评估套件的硬件和软件设置、连接说明、电源和接地要求等。它还介绍了如何使用套件进行各种测试,例如读取传感器数据、调整采样率和灵敏度、校准传感器等。手册还提供了解决常见问题的方法和故障排除的步骤,以确保用户能够顺利进行评估和测试工作。 《pcap04-eva-kit-manual.pdf》是一份非常有用的文档,可以帮助用户快速了解和使用PCAP04评估套件。无论是新用户还是有经验的用户都可以通过阅读手册掌握评估套件的操作技巧,并准确有效地进行测试和评估工作。通过合理正确地使用评估套件,用户可以充分发挥PCAP04传感器模块的性能,并提供高质量的数据和结果。 总之,该手册是PCAP04评估套件的重要参考资料,对于用户来说具有很高的实用价值。通过仔细阅读并按照手册上的操作步骤进行操作,用户可以顺利地完成评估工作,并获得准确可靠的结果。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值