I'm writing a program that should convert strongSwan log to WireShark packets. So, for instance, we have a sequence like this one in a text file.
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
I have my own class that performs all the actions via 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;
}
So, we have that packet. We have the header for packet made, data (strings from 0: to 112:) is being stored in char* variable. I'm trying to dump a packet like this, but it messes up positions somehow
.
I tried to google a proper way of dumping in a situation like this, but can't seem to find a solution. Anyone knows what I'm doing wrong?
============================================
UPD: The deque with data contains elements of this:
struct TgrPacket
{
pcap_pkthdr header;
QString data;
TgrPacket(pcap_pkthdr pHeader, QString pData);
};
So the data is stored in a single QString. While scanning the text file, I'm looking for the first string of data (that looks like "... 0: 23 D9 25...") and cut everything from ": " and append it to the QString data. Then I get data from next strings until I reach the last line of this packet, then I start looking for new packets again. After I finished appending my QString, I get the time of the packet, convert it to time_val and create a structure with time_val field and QString with data. The function is like this if you want to have a look:
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;
}
dataStringbut then allow up to 65535 bytes to be read into it. Also you should never towhile (!feof(...)), as the EOF flag is not set until after you try to read from beyond the file. In this case dowhile (fgets(...) != NULL). And why are you using C file I/O instead of C++ streams? And why pointers for theQStringobjects (which you allocate twice and never free). And you never free thevTmobject either (no pointer needed here too). - Some programmer dudenew. Take for example yourmktimecall, it wants you to provide a pointer to astruct tm, so you make a pointer and allocate memory for it. Instead you can just declare a non-pointer variable and use the address-of operator to make a pointer of it, liketm vTm; ...; vTime_t = mktime(&vTm);No pointer, no allocation, no memory leak. - Some programmer dude