【发布时间】:2014-04-23 09:12:32
【问题描述】:
我正在编写一个程序,应该将 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* 变量中。我正在尝试转储这样的数据包,但它以某种方式弄乱了位置
. 在这种情况下,我试图用谷歌搜索正确的倾销方式,但似乎找不到解决方案。有谁知道我做错了什么?
=============================================
更新: 带有数据的双端队列包含以下元素:
struct TgrPacket
{
pcap_pkthdr header;
QString data;
TgrPacket(pcap_pkthdr pHeader, QString pData);
};
因此数据存储在单个 QString 中。在扫描文本文件时,我正在寻找第一个数据字符串(看起来像“... 0: 23 D9 25...”)并从“:”中剪切所有内容并将其附加到 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;
}
【问题讨论】:
-
问题可能在于您如何读取源日志文件以及如何在现有结构中存储数据。请显示所涉及的结构以及如何从日志文件中读取/解析实际数据。
-
为您添加了更多信息,希望这将有助于我们找到解决方案
-
首先,您的代码中有 undefined behavior:您为
dataString分配了 255 个字符,但随后最多允许读取 65535 个字节。此外,您永远不应该while (!feof(...)),因为在您尝试从文件之外读取之前不会设置 EOF 标志。在这种情况下,请执行while (fgets(...) != NULL)。为什么你使用 C 文件 I/O 而不是 C++ 流?以及为什么指向QString对象的指针(您分配了两次并且从不释放)。而且你也永远不会释放vTm对象(这里也不需要指针)。 -
即使有些函数需要指针,你实际上也不必使用指针和
new。以您的mktime调用为例,它希望您提供指向struct tm的指针,因此您创建一个指针并为其分配内存。相反,您可以只声明一个非指针变量并使用地址运算符来创建它的指针,例如tm vTm; ...; vTime_t = mktime(&vTm);没有指针,没有分配,没有内存泄漏。 -
感谢所有的建议,我肯定会在未来继续努力。但是,目前的主要问题仍然是不正确的数据写入。对此有什么想法吗?
标签: c++ wireshark packet dump libpcap