小工具,从wireshark中导出原始16进制数据,进而导出RTPPayload数据

wireshark抓到的包可以导出:file->export->file

在packet format下可以选择导出的格式,但如果需要的数据是多个包的组合那就麻烦了,因为导出的数据无论如何都会加上链路层、IP层和传输层的头信息,手动删除基本可能。

比如,我捕获了很多RTP包,但我只想取出RTP的payload来分析数据是否正确,我可以这样做:


首先导出packet byte格式的数据,我把该数据保存在RAW.dat中,数据的格式是这样的(一个wireshark中的包):



然后把其中的16进制数据提取出来,上代码:

#include "stdlib.h"
#include "stdio.h"


typedef enum state //状态机实现
{
	IGNORE,
	WAITCR,
	WAITLF,
	READY,
	READ_L,
	READ_H
}STATE;

int AToI(unsigned char *pData)
{
	unsigned char tmp[2];
	int ret;
	tmp[0] = *pData;
	tmp[1] = *(pData+1);
	for (int i=0; i<2; i++)
	{
		if (tmp[i] <= 0x39 && tmp[i] >= 0x30)
		{
			tmp[i] &= 0x0f;
		}
		else if(tmp[i] <= 0x66 && tmp[i] >= 0x61)
		{
			tmp[i] = 9 + tmp[i]&0x0f;
		}
		else
		{
			printf("Err\n");
			return -1;
		}
	}

	ret = tmp[0]*16 + tmp[1];
	return ret;
}

int main()
{
	FILE *FI, *FO;
	
	FI = fopen("RAW.dat", "rb");
	FO = fopen("RTP.dat", "wb");
	
	STATE stat=IGNORE;
	unsigned char tmp;
	int hex;
	unsigned char ch[2] = {0};
	int count = 0, line = 0;
	int blankCount = 0;
	bool bFalse = false;
	unsigned long PacketCount = 0;

	while(!feof(FI) && !bFalse)
	{
		tmp = fgetc(FI);

		switch(stat)
		{
		case IGNORE:
			if (tmp == 0x20)
			{
				stat = READY;
			}
			break;
		case WAITCR:
			if (tmp == 0x0d)
			{
				stat = WAITLF;
			}
			break;
		case WAITLF:
			if (tmp == 0x0a)
			{
				stat = IGNORE;
			}
			break;
		case READY:
			if(tmp != 0x20)
			{
				ch[0] = tmp;
				stat = READ_L;
				blankCount = 0;
			}
			else
			{
				if (++blankCount >= 2)
				{
					PacketCount++;
					blankCount = 0;
					count = 0;
					stat = WAITCR;
				}
			}
			break;
		case READ_L:
			ch[1] = tmp;
			stat = READ_H;
			break;
		case READ_H:
			hex = AToI(ch);
			if (hex < 0)
			{
				bFalse = true;
				break;
			}
			fputc(hex, FO);
			if (++count == 16)
			{
				count = 0;
				line++;
				stat = WAITCR;
			}
			else
			{
				stat = READY;
			}
			break;
		}
	}

	fclose(FI);
	fclose(FO);

	return 0;
}


因为我抓取的是RTP数据,因此我又写了个小工具,从上面提取的裸数据中在一起提取出RTP数据:

#include "stdlib.h"
#include "stdio.h"

#include <assert.h>

int main()
{
	FILE *FI, *FO;

	FI = fopen("raw.dat", "rb");
	FO = fopen("rtp.dat", "wb");
	if (!FI || !FO)
	{
		return -1;
	}

	int ret=0;
	unsigned long ToTalLen=0, PacketLen = 0;
	unsigned long count = 0;
	unsigned char *pBuf = new unsigned char[10 * 1024 *1024];
	unsigned char *pPos = pBuf;
	int paddingLen = 0;
	bool bHasPadding = false;

	do
	{
		ret = fread(pPos, 1, 1024*1024, FI);
		ToTalLen += ret;
		pPos += ret;
	}while(ret > 0);
	pPos = pBuf;

	do 
	{	
		while(ToTalLen > 0)
		{
			if(*pPos != 0x50 || *(pPos+1)!= 0xe5)
			{
				printf("Has decode %d\n", count);
				break;
			}
			PacketLen = (*(pPos+38)<<8) + *(pPos+39);
			PacketLen -= (8 + 12);
			if (PacketLen > 1460)
			{
				break;
			}

			pPos += (14 + 20 + 8 + 12);

			if (PacketLen != fwrite(pPos, 1, PacketLen, FO))
			{
				break;
			}
			count++;
			pPos += PacketLen;
			//如果RTP的payload是4, 那么以太网的包长度肯定为4 + 12 + 8 + 20 + 14 == 58 小于 60
			//因此会有2个字节是需要丢弃的
			if (PacketLen == 4)
			{
				pPos += 2;
			}
		}
	} while(0);
	
	delete []pBuf;
	fclose(FI);
	fclose(FO);
	return 0;
}

其他的传输层数据可以类似地提取,不用去掉RTP头长度(12)。


  • 1
    点赞
  • 8
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值