Well, I'm taking packets straight off the wire and extracting TCP streams from them.
In the short, this means stripping off the various headers (eg, eth->IP->TCP->stream data).
In the function that is called when I've finally gotten through all the headers, I am experiencing a strange error.
/*Meta is a pointer to the IP header, pkt is a pointer to the TCP header*/
virtual const u_char* processPacket(const u_char* pkt, const u_char* meta) {
//Extract IP info from meta.
iphdr* metaHdr = (iphdr*)meta;
//Form TCP header from the current offset, hdr.
const tcphdr* hdr = (const tcphdr*)pkt;
//Do pointer math to figure out the size of the stream data.
u_int32_t len = ntohs(metaHdr->tot_len) - metaHdr->ihl*4 - hdr->doff*4;
if(len > 0)
{
//Store TCP stream data in a queue, mapped to it's IP source.
TCPStream* stream = new TCPStream();
stream->seqNumber = ntohl(hdr->seq);
stream->streamData = new u_char(len);
//memcpy(stream->streamData, offset(pkt), len);
for(u_int32_t i = 0; i < len; i++)
{
printf("k%i-%i",len, i); //Used to figure out when the segfault occurs.
stream->streamData[i] = offset(pkt)[i]; //Offset returns a pointer to the data under the TCP header
}
//streams[metaHdr->saddr].push(stream);
}
return offset(pkt);
};
TCP stream is simply a u_int32_t
and a u_char*
pointing to a copy of the packet's data.
So, when I was using memcpy it segfaulted.
Obviously, either my pointers were invalid, or I was messing up my length.
In this particular packet's case, the length of the data is 1380 bytes (confirmed by Wireshark), so len is correctly computed.
Ok, so I must have my pointers messed up (but not NULL). I did the following experiment:
stream->streamData[0] = offset(pkt)[0]; //Works
stream->streamData[0] = offset(pkt)[len]; //Works, odd.
stream->streamData[len] = offset(pkt)[0]; //Fails, scary
stream->streamData[len] = offset(pkt)[len]; //Fails
So, I segfault when dereferencing too far into streamData (index 1236 to be specific)! But streamData is instantiated as:
stream->streamData = new u_char(len);
I start iterating through streamData at i=0, so I'm not skipping a bunch of my data.
streamData is u_char*
and offset(pkt)
is u_char*
so I'm not messing up my types.
This fails at a particular packet, after successfully iterating through 3000+ other packets. The dump file is 27 megs, and I've got 4 gigs of ram, so I don't think I'm running out or anything... So I'm forced to conclude that new is not allocating enough memory, but why?