pcap文件解析(二)--初识IP包
来源:互联网 发布:卡巴斯基mac版激活码 编辑:程序博客网 时间:2024/05/16 16:14
转载自:http://blog.csdn.net/yhangleo/article/details/8486927
在上一篇我们简单认识pcap文件,现在我们来看看IP包的大致结构。
IP包
在开始之前给大家推荐一个非常好用的工具RFCView,通过这个工具我们只需要输入RFC(Request For Comments,基本的因特网通讯协定都有在RFC文件内详细说明)号码就能查看各种RFC文档了。
在RFC791中详细定义了IP包的数据结构,这里做大致介绍:
0 1 2 3
0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|Version| IHL |Type of Service| Total Length |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
| Identification |Flags| Fragment Offset |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
| Time to Live | Protocol | Header Checksum |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
| Source Address |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
| Destination Address |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
| Options | Padding |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|Version| IHL |Type of Service| Total Length |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
| Identification |Flags| Fragment Offset |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
| Time to Live | Protocol | Header Checksum |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
| Source Address |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
| Destination Address |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
| Options | Padding |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
Version:版本号 4位
IHL:包头长度,IHL并不直接表示包头所占用的长度,而是表示包头占用了多少个32位 4位
Type of Service: 服务类型,为在数据传输中选择具体网络类型的摘要描述。 8位
Total Length: 总长度 16位
Identification: 用于组装数据包的标识符 16位
Flags:控制表示 3位
Bit 0: reserved, must be zero
Bit 1: (DF) 0 = May Fragment, 1 = Don't Fragment.
Bit 2: (MF) 0 = Last Fragment, 1 = More Fragments.
Bit 1: (DF) 0 = May Fragment, 1 = Don't Fragment.
Bit 2: (MF) 0 = Last Fragment, 1 = More Fragments.
Fragment Offset:数据偏移 13位
Time to Live:生命周期 8位
Protocol:协议类型,具体定义见:RFC790文档 8位
Header Checksum:头校验码 16位
Source Address:源地址 32位
Destination Address:目的地址 32位
IP数据在PCAP文件中的位置
pcap头数据包头目的MAC、源MAC、TYPE(14字节)IP数据……数据包头目的MAC、源MAC、TYPE(14字节)IP数据……
根据上表……在每个IP数据包中,IP数据的起始位置=数据包起始位置+包头长度+14。
根据上表……在每个IP数据包中,IP数据的起始位置=数据包起始位置+包头长度+14。
解析IP数据
下面是一个重pacp文件中导出SCTP协议数据的程序。
pcap_header.h
- #pragma pack( push, 1)
- // 为了保证在windows和linux下都能正常编译,放弃使用INT64或者_int_64
- typedef unsigned short _Int16;
- typedef unsigned long _Int32;
- typedef unsigned char Byte;
- typedef int bool;
- #define false 1
- #define true 0
- // Pcap文件头
- struct __file_header
- {
- _Int32 iMagic;
- _Int16 iMaVersion;
- _Int16 iMiVersion;
- _Int32 iTimezone;
- _Int32 iSigFlags;
- _Int32 iSnapLen;
- _Int32 iLinkType;
- };
- typedef struct __file_header __pcap_header;
- // 数据包头
- struct __pkthdr
- {
- _Int32 iTimeSecond;
- _Int32 iTimeSS;
- _Int32 iPLength;
- _Int32 iLength;
- };
- typedef struct __pkthdr __pk_header;
- struct __iphdr
- {
- Byte byteVersions:4;
- Byte byteHdLength:4;
- Byte byteSerType;
- _Int16 iTotalLength;
- _Int16 iIdentification;
- union
- {
- _Int16 iFlags;
- _Int16 iFragmentOffset;
- };
- Byte byteTimeToLive;
- Byte byteProtocol;
- _Int16 iHeaderChecksum;
- _Int32 iSourceAddress;
- _Int32 iDestinationAddress;
- };
- // Flags
- #define IP_DF 0x4000
- #define IP_MF 0x2000
- // FragmentOffset mask
- #define IP_OFFMASK 0x1fff
- typedef struct __iphdr __ip_header;
- #pragma pack( pop)
pcap_adapter.h
- #include <stdio.h>
- #include "pcap_header.h"
- // 打开Pcap文件
- bool OpenPcapFile( char* strPath);
- // 获得Pcap文件头
- void GetPcapHeader( __pcap_header* pHeader);
- // 获得当前包内容 返回值为buffer长度,buffer不含头信息, 获得信息后会自动跳转到下个包头
- int GetPacketAndMoveNext( __pk_header* pPacket, Byte** pBuffer);
- // 移动到第一个包的位置 读取包数据前需要优先调用这个函数
- bool MoveFirst();
- // 是否已经到达文件尾
- bool IeEof();
- // 获取ip信息
- void GetIpData( /*out*/ __ip_header* pIpData , /*IN*/ Byte* pDataBuffer);
- #include "pcap_adapter.h"
- #include "value_checker.h"
- #define NULL 0
- #define CHECKFILE if( m_gpPcapFile == NULL) \
- { \
- printf( "未打开文件"); \
- return ; \
- }
- #define CHECKFILEEX(x) if( m_gpPcapFile == NULL) \
- { \
- printf( "未打开文件"); \
- return x; \
- }
- #define NTETOHOST_SHORT(x) x = t_ntohs(x)
- #define NTETOHOST_LONG(x) x = t_ntohl(x)
- FILE* m_gpPcapFile = NULL;
- int m_giFileLength = 0;
- bool OpenPcapFile( char* strPath)
- {
- m_gpPcapFile = fopen( strPath, "rb");
- CHECKFILEEX(false);
- fseek( m_gpPcapFile, 0, SEEK_END);
- m_giFileLength = ftell( m_gpPcapFile);
- fseek( m_gpPcapFile, 0, SEEK_SET);
- return true;
- }
- void GetPcapHeader( __pcap_header* pHeader)
- {
- CHECKFILE;
- // 保存当前游标位置
- int iNowPos = ftell( m_gpPcapFile);
- fseek( m_gpPcapFile, 0, SEEK_SET);
- fread( (void*)pHeader, sizeof( __pcap_header), 1,m_gpPcapFile);
- fseek( m_gpPcapFile, iNowPos, SEEK_SET);
- }
- bool MoveFirst()
- {
- CHECKFILEEX(false);
- return fseek( m_gpPcapFile, sizeof( __pcap_header), SEEK_SET) == 0;
- }
- int GetPacketAndMoveNext( __pk_header* pPacket, Byte** pBuffer)
- {
- CHECKFILEEX(0);
- fread( (void*)pPacket, sizeof( __pk_header), 1,m_gpPcapFile);
- *pBuffer = (Byte*)malloc( pPacket->iLength);
- fread( (void*)*pBuffer, pPacket->iLength, 1,m_gpPcapFile);
- return pPacket->iLength;
- }
- bool IeEof()
- {
- CHECKFILEEX(false);
- int iNowPos = ftell( m_gpPcapFile);
- return iNowPos >= m_giFileLength;
- }
- void GetIpData( /*out*/ __ip_header* pIpData , /*IN*/ Byte* pDataBuffer)
- {
- memcpy( (void*)pIpData, pDataBuffer + 14, sizeof( __ip_header));
- NTETOHOST_SHORT(pIpData->iTotalLength);
- NTETOHOST_SHORT( pIpData->iIdentification);
- NTETOHOST_SHORT( pIpData->iFragmentOffset);
- NTETOHOST_SHORT( pIpData->iHeaderChecksum);
- NTETOHOST_LONG( pIpData->iSourceAddress);
- NTETOHOST_LONG( pIpData->iDestinationAddress);
- }
main.c
- #include"pcap_adapter.h"
- int main()
- {
- if( OpenPcapFile( "ZSRNC3_IUPS_inerface3.pcap"))
- {
- printf( "打开pcap文件失败");
- return 0;
- }
- __pcap_header header;
- GetPcapHeader( &header);
- int iNo = 1;
- MoveFirst();
- FILE* pwFile = fopen( "export-file.pcap", "wb");
- fwrite((void*)&header, sizeof( __pcap_header), 1, pwFile);
- while( !IeEof())
- {
- __pk_header data;
- __ip_header ipData;
- Byte* pBuffer;
- GetPacketAndMoveNext( &data, &pBuffer);
- GetIpData( &ipData, pBuffer);
- // SCTP == 132
- if( ipData.byteProtocol == 132)
- {
- fwrite( (void*)(&data), sizeof(struct __pkthdr), 1, pwFile);
- fwrite( (void*)pBuffer, data.iLength, 1, pwFile);
- }
- free( pBuffer);
- }
- fclose( pwFile);
- printf( "Export over");
- return 1;
- }
0 0
- pcap文件解析(二)--初识IP包
- pcap文件解析(二)--初识IP包
- pcap文件解析(二)--初识IP包
- pcap文件解析(二)--初识IP包(初级)
- 解析PCAP包理解TCP/IP
- pcap文件解析--pcap文件头与包文件头(一)
- pcap文件解析--pcap文件头与包文件头(一)
- pcap文件解析--pcap文件头与包文件头(一)(初级)
- pcap文件解析--pcap文件头与包文件头(一)
- pcap文件解析(三)--拆分SCTP包
- pcap文件解析(三)--拆分SCTP包
- python 抓包保存为pcap文件并解析
- pcap文件解析
- pcap文件解析
- Java之Pcap文件解析(二:建立数据结构)
- 借助WireShark解析PCAP包
- PCAP 文件内容解析命令
- pcap文件格式及文件解析
- 冒泡排序原理详解
- xp系统启动时0x0000007B(0XF799A524,0XC0000034,0X00000000,0X00000000)错误
- 树dp (至少砍掉几个树枝,能得到有m个结点的子树)
- 在Visual Studio 2010[VC++]中使用ffmpeg类库
- 串口通信程序中十六进制格式发送和接收实现
- pcap文件解析(二)--初识IP包
- 2013级C++第11周(春)项目——通过继承拥有基类的资源 【项目1 - 存储班长信息的学生类】
- Android 常见错误总结
- easyui 下拉框类控件使用注意
- JQuery一些常见用法与技巧
- C++出错提示英汉对照表
- 基于ASP.NET WPF技术及MVP模式实战太平人寿客户管理项目开发(Repository模式)
- linux查看某端口是否被占用
- CListCtrl 部分用法