文本格式报文转换为pcap文件的方法

偶然的一个需求,需要用文本文件中的码流生成pcap,然后用wireshark查看,网上都是讲如何解码pcap,于是按照别人写的,反向写了一个函数,来完成这个功能呢;

文本文件里村了时间戳和码流,但是都是文本格式,程序的主要功能是从文本中找到时间戳和码流,并转换为十六进制,写入pcap文件。

1、由于文件中有IP码流,所以只需要构造pcap文件头,数据包头和以太网帧头:

//pacp文件头结构体


struct pcap_file_header
{
    bpf_u_int32 magic;       /* 0xa1b2c3d4 */
u_short version_major;   /* magjor Version 2 */
u_short version_minor;   /* magjor Version 4 */
bpf_int32 thiszone;      /* gmt to local correction */
bpf_u_int32 sigfigs;     /* accuracy of timestamps */
bpf_u_int32 snaplen;     /* max length saved portion of each pkt */
bpf_u_int32 linktype;    /* data link type (LINKTYPE_*) */
};

//时间戳
struct time_val
{
long tv_sec;         /* seconds 含义同 time_t 对象的值 */
long tv_usec;        /* and microseconds */
};


//pcap数据包头结构体
struct pcap_pkthdr
{
struct time_val ts;  /* time stamp */
bpf_u_int32 caplen; /* length of portion present */
bpf_u_int32 len;    /* length this packet (off wire) */
};


//数据帧头
typedef struct FramHeader_t
{ //Pcap捕获的数据帧头
u_int8 DstMAC[6]; //目的MAC地址
u_int8 SrcMAC[6]; //源MAC地址
u_short FrameType;    //帧类型
} FramHeader_t;

2、pcap文件的pcap文件头都长一个样,照着格式填就行了,数据包头需要填对时间戳和包长

//使用time.h计算时间戳很靠谱,夏时令为0,月份要减1,年要减1900,wday和yday
可以不填
DWORD calcTimeNew(BYTE *ptTime)
{
//time_t time;
tm tm;
t m.tm_year= (ptTime[0]*1000)+(ptTime[1]*100)+(ptTime[2]*10)+ptTime[3]-1900;
tm.tm_mon= ptTime[4]*10+ptTime[5]-1;
tm.tm_mday= (ptTime[6]*10+ptTime[7]);
tm.tm_hour= (ptTime[8]*10+ptTime[9]);
tm.tm_min= (ptTime[10]*10+ptTime[11]);
tm.tm_sec= (ptTime[12]*10+ptTime[13]);
tm.tm_isdst= 0;
//time= mktime(&tm);
//cout<<ctime(&time)<<endl;
return (DWORD)(mktime(&tm));
}

//把数组格式转成BCD格式

void convertByte(BYTE* pb,int m,BYTE *abtemp)
{
for(int i =0,j=0;i<m;i+=2,j++)
abtemp[j] = (((pb[i]<<4)&0xF0)|(pb[i+1]&0x0F));
}

//包长用这个数一下

while(!file.eof())
{
getline(file,str);
if (str.size()<3) //避免读空行 
{
continue;  
}  
if(pcstreamB=findsubstr4RawStream(str.c_str(),acstream))//找到“09 00 34 00 35”的报文首地址位置,对应  水平定位符号和45(IP头)
{
int n=0,m=0,p=0;
//找到本行末尾
while((*(pcstreamB+n)-'\r')&&(*(pcstreamB+n)-'\n'))//算出报文首地址到本行结尾的字节数
{
n++;
}
}
}

//由于文件中每行的末尾是换行回车,所以不能用\0作为结束符,需要用\r \n作为结束符
char *findsubstr4RawStream(const char *str1, const char *str2)
{
char *cp = (char*)str1;
char *s1, *s2;
while ((*cp-'\r')&&(*cp-'\n'))
{
s1 = cp;
s2 = (char *)str2;
while ((*s1-'\r')&&(*s1-'\n') && (*s2-']') && !(*s1 - *s2))
s1++, s2++;
if (!(*s2-']'))
return(cp);
cp++;
}
return(NULL);
}

//由于采用fwrite或fprintf或fputs向文件写入CHAR或BYTE时,\r会被替换成\r\n,即0x0A会被替换为0x0A 0x0D,所以需要用file.open带wb参数
void WriteByte2File(FILE *pf,BYTE *pbArray,int iWriteNum)
{
for(;iloop<iWriteNum;iloop++)
{
fwrite(&pbArray[iloop],sizeof(BYTE),1,pf);

}
}

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值