我正在编写一个应该将strongSwan日志转换为WireShark数据包的程序。因此,例如,我们在文本文件中有这样的序列。
Feb 14 14:53:22 dubu12 charon: 13[IKE] sending cert request for "C=RU, ST=NW, O=Company, CN=StronSwanSERV"
Feb 14 14:53:22 dubu12 charon: 13[IKE] shared Diffie Hellman secret => 128 bytes @ 0x7f36e8001ed0
Feb 14 14:53:22 dubu12 charon: 13[IKE] 0: 23 D9 25 9F F1 78 9F C4 83 89 2F 06 E3 DB C2 69 #.%..x..../....i
Feb 14 14:53:22 dubu12 charon: 13[IKE] 16: 24 06 49 01 75 2E 6A 4F AF E6 07 9C F9 77 07 A1 $.I.u.jO.....w..
Feb 14 14:53:22 dubu12 charon: 13[IKE] 32: 02 D8 52 0C F0 27 10 14 19 69 B8 B7 CB 0F 41 40 ..R..'...i....A@
Feb 14 14:53:22 dubu12 charon: 13[IKE] 48: 72 AA 50 8C 90 FF 4D C8 66 88 6C F8 44 B3 2E A2 r.P...M.f.l.D...
Feb 14 14:53:22 dubu12 charon: 13[IKE] 64: 62 F4 C8 4B 31 3C A9 DF DE C8 DF 85 6D 3E E7 56 b..K1<......m>.V
Feb 14 14:53:22 dubu12 charon: 13[IKE] 80: 9D 32 6B 29 C9 7E 9F 41 9C C2 EB D8 8D 3F 51 68 .2k).~.A.....?Qh
Feb 14 14:53:22 dubu12 charon: 13[IKE] 96: 75 74 3A 96 D6 09 B6 34 38 D8 28 5E 6F 7D 20 44 ut:....48.(^o} D
Feb 14 14:53:22 dubu12 charon: 13[IKE] 112: E3 3F 72 1E DD A5 73 B0 CC E0 92 8C 7A 54 3B 34 .?r...s.....zT;4
我有自己的类,通过Libpcap执行所有操作。
int TgrReader::dump(std::deque<TgrPacket> deqTgrPacket, char* fileName)
{
pcap_t* pHandle = pcap_open_dead(DLT_RAW, 65535);
pcap_dumper_t* pDumper = pcap_dump_open(pHandle, fileName);
std::deque<TgrPacket>::iterator iter=deqTgrPacket.begin();
while(iter != deqTgrPacket.end())
{
pcap_dump(reinterpret_cast<u_char*>(pDumper), &(iter->header), reinterpret_cast<u_char*>(iter->data.toLocal8Bit().data()));
iter++;
}
pcap_dump_close(pDumper);
pcap_close(pHandle);
return 0;
}
所以,我们有那个包。我们有数据包的标题,数据(字符串从0:到112 :)存储在char *变量中。我试图像这样转储一个包,但它以某种方式弄乱了位置
。 在这样的情况下,我试图以适当的方式倾销,但似乎无法找到解决方案。谁知道我做错了什么?
UPD: 带有数据的双端队列包含以下元素:
struct TgrPacket
{
pcap_pkthdr header;
QString data;
TgrPacket(pcap_pkthdr pHeader, QString pData);
};
因此数据存储在单个QString中。在扫描文本文件时,我正在寻找第一个数据字符串(看起来像&#34; ... 0:23 D9 25 ......&#34;)并从&#34; :&#34;并将其附加到QString数据。然后我从下一个字符串中获取数据,直到我到达该数据包的最后一行,然后我再次开始寻找新数据包。在我完成附加我的QString之后,我得到数据包的时间,将其转换为time_val并创建一个带有time_val字段和带有数据的QString的结构。 如果你想看一下,这个功能是这样的:
std::deque<TgrPacket> TgrReader::readFile(std::deque<TgrPacket>& deqTgrPacket)
{
//1) read to "dataString"
//2) parse it
//3) loop add data from "dataString" to "qDataString" if data was found
//4) eject time from "dataString" and add it to "vTm", which is struct tm type
//5) create packet and add to deque
char* dataString = new char [ 255 ];
char* dataBlock = new char [40];
QString* qTimeString = new QString;
QString* qTempDataString = new QString;
time_t vTime_t = 0;
struct tm* vTm = new tm;
while(!feof(srcFile))
{
fgets(dataString, 65535, srcFile);
switch(parse(dataString, stringState))
{
case BLANK: //skip blank lines
stringState = BLANK;
break;
case LINE: //read data lines until last one is read
stringState = LINE;
qTimeString = new QString;
qTempDataString = new QString;
vTime_t = 0;
vTm = new tm;
while(stringState != END && !feof(srcFile))
{
sscanf(dataString, "%*s %*s %*s %s", dataBlock);
for(int j = 39 + strlen(dataBlock); j < strlen(dataString) - 17; j++)
{
qTempDataString->append(dataString[j]);
}
fgets(dataString, 65535, srcFile);
qTimeString->append(dataString);
stringState = parse(dataString, stringState);
}
stringState = END;
qTimeString->truncate(15);
vTm->tm_year = 114;
strptime(qTimeString->toLatin1().data(),"%h %d %H:%M:%S",vTm);
vTime_t = mktime(vTm);
deqTgrPacket.push_back(createPacket(&vTime_t, qTempDataString, qTempDataString->length()));
break;
}
}
return deqTgrPacket;
}
答案 0 :(得分:0)
虽然我真的不了解PCAP,但我会做出有根据的猜测:pcap_dump
函数需要将数据(作为最后一个参数传递)作为实际的二进制文件数据包的数据。由于您以字符串形式读取和存储数据,因此pcap_dump
将转储ASCII值。
您应该将数据解析为二进制数据的字节而不是字符串。使用标准库(因为我不太了解Qt)你可能会做这样的事情:
std::istringstream istr(qTempDataString->toStdString());
std::string value;
std::string data;
while (istr >> value)
data += static_cast<char>(std::stoi(value, nullptr, 16));
*qTempDataString = QString::fromStdString(data);
这里的重要部分是istr >> value
,它提取了一个空格分隔的&#34;字&#34;从流中并将其放入字符串value
和std::stoi(value, nullptr, 16)
,它接受字符串并将其转换为数字(16
是基数,它是十六进制的。)