3

I am trying to understand the following casting from this code

char out_packet_buffer[4500] ;  
struct ip6_hdr *iphdr ;

iphdr = (struct ip6_hdr *) &out_packet_buffer[0]; 

Is my understanding correct that the member variables of the struct iphdr are stored in char array out_packet_buffer? Later in the code, out_packet_buffer is never used. Instead, iphdr is memcpyied to an uint8_t memory location (ether_frame). But iphdr is not uint8_t.

I'd appreciate any guidance for me to understand what is happening here.

Thanks

2
  • 4
    I'm pretty sure this breaks strict aliasing. Commented Jan 1, 2018 at 16:58
  • @ChristianGibbons Thanks for pointing that out. Helps me coding an improved version of it. Commented Jan 1, 2018 at 17:27

2 Answers 2

1

Is my understanding correct that the member variables of the struct iphdr are stored in char array out_packet_buffer?

Kind of. What happens in this casting is that we start "looking" at the memory chunk that starts from &out_packet_buffer[0] (or just out_packet_buffer) as a struct ip6_hdr instead of a char[].

Any later usage of iphdr is using the same memory, but splits it into struct ip6_hdr members instead of into char

As @Christian Gibbons said, I also think this violates strict aliasing which is UB

Sign up to request clarification or add additional context in comments.

3 Comments

Thanks. As far as I understand, it provides the developer a convenient and organized (as a struct) access to the char buffer. However, I expect output_packet_buffer to be memcopied and passed to the sendto function, but it is not. So I dont see the use of output_packet_buffer.
Exactly so. This way you can access iphdr->some_member instead of accessing out_packet_buffer[M] to out_packet_buffer[N]
Then later in the code, one expects out_packet_buffer to be copied into the ether_frame and send the frame out, however it is not the case. So why use/cast the char array out_packet_buffer at all?
1

It looks like the code is preparing a packet for transmission over a network. The packet will consist of a header and a payload. The whole packet is, presumably, stored in out_packet_buffer. The ip6_header structure is the first few bytes of this, the data payload follows after. Using a structure for the header makes the code more readable but there’ll probably be a "structure order to network order" function just before it’s sent to a socket.

In any case, the data packet is just a sequence of bytes, so casting it to any 8-bit type is feasible

2 Comments

Correct. Lines 588-592 copies packet elements (IP header and the payload) into the ethernet frame, which gets sent out. However in line 588, it is the iphdr that gets copied. Therefore I can't see the need for out_packet_buffer at all.
It’s a cheap way of assigning a big byte buffer with no danger of unfreed pointers. It’ll exist as long as it is in scope. Maybe the original intention was to put the data payload in that big buffer...? Copying only the ip header would be a smaller copy than that large buffer.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.