打开APP
userphoto
未登录

开通VIP,畅享免费电子书等14项超值服

开通VIP
pcap文件解析(三)
这一章,我们将了解SCTP数据包结构,并简要介绍SCTP协议,最后将带有多个chunk的SCTP包拆分问单个SCTP数据包。
SCTP数据包
数据包头
Eth信息
IP头
SCTP头
SCTP Chunk 1
……
SCTP Chunk n
其中数据包头和IP头已经在前面做过介绍了,这里先简单介绍一下Eth信息。
[cpp]view plaincopy
// Ethernet 信息
typedef struct__Ethernet_Info
{
Byte    DestMac[6];
Byte    SrcMac[6];
_Int16  iType;
} __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 plaincopy
// SCTP头
typedef struct __Sctp_header
{
_Int16 SrcPort;
_Int16 DstPort;
_Int32 iVerTag;
_Int32 iChecksum;
} __SctpHeader;
// chunk头
typedef struct __Sctp_chunk_header
{
Byte Type;
Byte Flag;
_Int16  iLength;
} __SctpChunkHeader;
// 单个SCTP Chunk
typedef struct __Sctp_chunk
{
__SctpChunkHeader header;
Byte* pData;
} __SctpChunk;
拆分SCTP数据块
下面的代码将逐个解析数据包,当数据包位SCTP包时,对DATA chunk进行拆分。
[cpp]view plaincopy
bool main()
{
__pcap_header header;
int iNo = 1;
// 打开源文件和输出文件
if( !OpenPcapFile( "sctp.pcap")|| !OpenOutFile( "export.pcap"))
{
return false;
}
// 获得文件头
GetPcapHeader( &header);
//写入文件头
WriteFileHeader( &header);
MoveFirst();
while( !IeEof())
{
__pk_header data;
__ip_header ipData;
__EthernetInfo ethInfo;
Byte* pBuffer;
// 获取下一个数据包
GetPacketAndMoveNext( &data,&pBuffer);
// 获得ETH信息
GetEthernetInfo( eInfo, pBuffer,0);
// 获得IP信息
GetIpData( &ipData, pBuffer,sizeof(__EthernetInfo));
// SCTP == 132
if( ipData.byteProtocol == 132)
{
// 获取SCTP头
int iOffset = sizeof(__EthernetInfo) + ipData.byteHdLength * 4;
int iChunkOffset =iOffset + sizeof( __SctpHeader);
__SctpHeader sctpHeader;
__SctpChunksctpChunkArr[MAX_CHUNK_NUM];
// 当前已保存的chunk数量
int iChunkNum = 0;
// 当前已保存的chunk长度
int iLenght = 0;
// 获得SCTP头
GetSctpHeader(&sctpHeader, pBuffer, iOffset);
while( true)
{
// 当前读取的chunk
__SctpChunksctpChunk;
// for 循环标志
int i = 0;
GetSctpChunk(&sctpChunk, pBuffer, iChunkOffset);
if(sctpChunk.header.Type == 0) // DATA块  建立新数据包并写入chunk信息
{
WritePkHeader(&data, iLenght + sctpChunk.header.iLength + LENGTH_SCTPALLHEADER(ipData));
WriteEthInfo(eInfo);
WriteIpHeader(&ipData, iLenght + sctpChunk.header.iLength + LENGTH_SCTPIPHEADER(ipData));
WriteSctpHeader(&sctpHeader);
for( i =0; i < iChunkNum; i++)
{
WriteSctpChunk(sctpChunkArr + i);
}
WriteSctpChunk(&sctpChunk);
iChunkNum = iLenght = 0;
}
else
{
// 当前块位非DATA块
sctpChunkArr[iChunkNum++] = sctpChunk;
iLenght +=sctpChunk.header.iLength;
}
iChunkOffset +=sctpChunk.header.iLength;
if( iChunkOffset>=
ipData.iTotalLength- ((ipData.byteHdLength & 0x0f) * 4))
{
if(iChunkNum > 0)
{
//存在未写入的chunk数据,全部新建数据包写入
if(sctpChunk.header.Type != 0)
iLenght-= sctpChunk.header.iLength;
WritePkHeader(&data, iLenght + sctpChunk.header.iLength + LENGTH_SCTPALLHEADER(ipData));
WriteEthInfo(eInfo);
WriteIpHeader(&ipData, iLenght + sctpChunk.header.iLength + LENGTH_SCTPIPHEADER(ipData));
WriteSctpHeader(&sctpHeader);
for(i = 0; i < iChunkNum; i++)
{
WriteSctpChunk(sctpChunkArr + i);
}
}
break;
}
}
}
free( pBuffer);
}
CloseOutFile();
ClosePcapFile();
printf( "Export over");
return true;
}
源码下载:http://download.csdn.net/detail/yhangleo/4998322
IP checksum 计算 :http://blog.csdn.net/yhangleo/article/details/8508003
本站仅提供存储服务,所有内容均由用户发布,如发现有害或侵权内容,请点击举报
打开APP,阅读全文并永久保存 查看更多类似文章
猜你喜欢
类似文章
【热】打开小程序,算一算2024你的财运
4G和5G网络中的SCTP
SCTP协议详解
MP4文件格式详解
MP4文件格式(转)
AVI RIFF 文件参考手册
视频文件头解析--MP4-层结构解析
更多类似文章 >>
生活服务
热点新闻
分享 收藏 导长图 关注 下载文章
绑定账号成功
后续可登录账号畅享VIP特权!
如果VIP功能使用有故障,
可点击这里联系客服!

联系客服