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

CIsForCookies
  • 12,097
  • 11
  • 59
  • 124
alan
  • 33
  • 4

2 Answers2

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

CIsForCookies
  • 12,097
  • 11
  • 59
  • 124
  • 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. – alan Jan 01 '18 at 17:16
  • Exactly so. This way you can access `iphdr->some_member` instead of accessing `out_packet_buffer[M]` to `out_packet_buffer[N]` – CIsForCookies Jan 01 '18 at 17:20
  • 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? – alan Jan 01 '18 at 17:41
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

Pam
  • 1,146
  • 1
  • 14
  • 18
  • 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. – alan Jan 01 '18 at 17:36
  • 1
    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. – Pam Jan 01 '18 at 17:56