PDA

View Full Version : Data Structure help!



darshan
13th February 2009, 17:38
Hello all,

I have a thread that calls a pcap loop function which is then called from a class to add items to a table.

Thread class:


void PcapThread::startCaptureOnInterface()
{
int r;

while(captureOn){
struct pcap_pkthdr *header;
const u_char *pkt_data;

r = pcap_next_ex(descr,&header,&pkt_data);

emit addToWidget(header,pkt_data);

}

PacketTable class:


void PacketTable::addToWidget(struct pcap_pkthdr* pkthdr, const u_char* packet)

so far this method adds items to a table such as source IP, destination IP, packet length etc but there is no storage.

However i would like to store this in a data structure by using const u_char *packet as this is how the packet headers are declared:


struct ether_header *ethernet = (struct ether_header*)packet;
struct iphdr *ip = (struct iphdr*)(packet + sizeof(struct ether_header));
struct tcphdr *tcp = (struct tcphdr*)(packet + sizeof(struct ether_header) + sizeof(struct iphdr));
payload = (u_char *)(packet + sizeof(struct ether_header) + sizeof(struct iphdr) + sizeof(struct tcphdr));

Im not sure how to go about this as i would to declare methods in a seperate class then iterate and call the methods to get data out.

Darshan

darshan
15th February 2009, 12:33
update:

I have created a vector and added an object of class type Packet which contains the following:


Packet::Packet(const u_char *packet)
{

ethernet = (struct ether_header*)packet;
ip = (struct iphdr*)(packet + sizeof(struct ether_header));

}


QString Packet::getSourceIp()
{
struct in_addr saddr;

saddr.s_addr = ip->saddr;
char *sourceip = inet_ntoa(saddr);

return QString::fromUtf8(sourceip);

}

and in the Packet Table class i have added vector which adds the Packet class with the constructor const u_char *packet. So for every packet a new Packet object is created and added to the vector. Im not sure if this i right please correct me if its wrong :confused:


void PacketTable::addToWidget(struct pcap_pkthdr* pkthdr, const u_char* packet)
{
vector.append(new Packet(packet));
}


QVectorIterator<Packet*> i(vector);
while (i.hasNext()){
Packet *temp = i.next();
QString s = temp->getSourceIp();
qDebug() << s;

however when i iterate over the vector to get the sourceip out of each element i only get the ip address from the last packet not the others.

Can anyone please help i don't know whats wrong :(

Darshan

darshan
16th February 2009, 16:57
anyone? :)

darshan
17th February 2009, 10:34
Please anyone this is really urgent! I can't seem to figure out what the problem is or how to solve it.

wysota
17th February 2009, 17:01
You suffer from a classical C problem of storing pointers.

You assign something to some area of memory. Then you take the address of that area and store it somewhere. Then you assign some other data to the same area of memory and store a pointer to it somewhere else. Then suddenly all previously stored pointers point to the data stored the most recently. Why? Because all pointers point to the same area of memory! Check out values of those pointers (by casting them to int) - they will all be exactly the same!

At some point you need to copy the data and store it somewhere. So far you are only copying pointers to data. I suggest you use QByteArray to store your packets. You can use it just like char * (i.e. using constDat() and data() methods) and it will take care of copying the data when you copy the byte array object.

darshan
17th February 2009, 20:15
is there a way to convert the u_char for the QByteArray to be able to read the data?

i have tried this QByteArray b = QByteArray((const char*)packet)
but will need to convert it back to u_char to be able to read the data.

wysota
17th February 2009, 23:03
If I understand correctly u_char is the same as "unsigned char" which in turn can safely be cast to char back and forth. Does that answer your question?

darshan
18th February 2009, 09:28
i have tried this but the output i get consists of random numbers when getting the ip address

QByteArray b;
b.append((const char*)pkt);

const u_char* packet = (unsigned char*)b.data(); is this the correct way to do it?

wysota
18th February 2009, 12:47
It depends on the context, but if some conditions are met, the code looks ok.