tags:

views:

44

answers:

2

I'm writing some C code to parse IEEE 802.11 frames, but I'm stuck trying to create a new variable whose length depends on the size of the frame itself.

Here's the code I currently have:

int frame_body_len = pkt_hdr->len - radio_hdr->len - wifi_hdr_len - 4;
u_char *frame_body = (u_char *) (packet + radio_hdr->len + wifi_hdr_len);

Basically, the frame consists of a header, a body, and a checksum at the end. I can calculate the length of the frame body by taking the length of the packet and subtracting the length of the two headers that appear before it (radio_hdr->len and wifi_hdr_len respectively), plus 4 bytes at the end for the checksum.

However, how can I create the frame_body variable without the trailing checksum? Right now, I'm initializing it with the contents of the packet starting at the position after the two headers, but is there some way to start at that position and end 4 bytes before the end of packet? packet is a pointer to a u_char, if it helps.

I'm a new C programmer, so any and all advice about my code you can give me would be much appreciated. Thanks!

+1  A: 

I think this is what you are describing:

u_char newVar[frame_body_len];
memcpy(newVar, frame_body, frame_body_len);

It creates a new array that contains just the frame body less the headers and the checksum.

EDIT: I just remembered C might not allow declaring an array of a non-literal size.

u_char *newVar = (u_char *)malloc(frame_body_len);

if (newVar != NULL)
{
    memcpy(newVar, frame_body, frame_body_len);
}
else
{
    /* handle allocation error here */
}
Amardeep
This is not much different than using the u_char* he's talking about; besides, I don't think it's a good idea to copy the packet's contents for performance reasons.
Unknown
+1  A: 

Your frame_body is just a pointer to the start of the frame, pointing into an existing buffer where the data is.

That's fine, you can just pass that around together with your frame_body_len and have everyone that cares about the data only inspect the data starting from frame_body and don't care about anything beyond frame_body_len - which is what you'll have to do anyhow.

Thus, you don't really need to have a frame_body that doesn't include the trailing checksum.

If you do need such a buffer, e.g. dynamically allocated, you'll have to make space for the data, and copy the data there:

u_char *frame_body = malloc(frame_body_len);
if(frame_body == NULL) {
   //deal with error
}

memcpy(frame_body,&packet[radio_hdr->len + wifi_hdr_len],frame_body_len );
nos
Thanks, this works perfectly!
Alex Kloss