将字符数组转换为结构体指针

3
我正在尝试理解从这段代码中的强制类型转换。
char out_packet_buffer[4500] ;  
struct ip6_hdr *iphdr ;

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

我的理解是,结构体iphdr的成员变量存储在char数组out_packet_buffer中。但是,在代码的后面,out_packet_buffer没有被使用。相反,iphdr被memcpy到一个uint8_t类型的内存位置(ether_frame)。但是,iphdr不是uint8_t类型的。
我希望能给出任何指导,帮助我理解这里发生了什么。
谢谢。

4
我很确定这违反了严格别名规则。 - Christian Gibbons
@ChristianGibbons 感谢您指出这一点。这有助于我编写一个改进版本。 - alan
2个回答

1
我的理解是,struct iphdr的成员变量存储在char数组out_packet_buffer中,这种类型转换的作用是,我们开始将从&out_packet_buffer[0](或者只是out_packet_buffer)开始的内存块视为struct ip6_hdr而不是char[]。
以后对iphdr的任何使用都使用相同的内存,但将其拆分为struct ip6_hdr成员而不是char。
正如@Christian Gibbons所说,我也认为这违反了严格别名strict aliasing,这是UB。

谢谢。据我所知,它为开发人员提供了一个方便和有组织的(作为结构体)访问char缓冲区的方式。然而,我期望output_packet_buffer被memcopied并传递给sendto函数,但实际上并没有这样做。因此,我看不出output_packet_buffer的用处。 - alan
没错。这样你就可以访问 iphdr->some_member 而不是访问 out_packet_buffer[M]out_packet_buffer[N] - CIsForCookies
然后在代码的后面,人们期望将out_packet_buffer复制到ether_frame并发送帧,但事实并非如此。那么为什么要使用/转换char数组out_packet_buffer呢? - alan

1
看起来代码正在准备通过网络传输数据包。该数据包将由标头和有效载荷组成。整个数据包可能存储在out_packet_buffer中。ip6_header结构体是其中的前几个字节,数据有效载荷在其后。使用结构体来表示标头可以使代码更易读,但在发送到套接字之前可能需要进行“结构体顺序到网络顺序”的转换函数。
无论如何,数据包只是一系列字节,因此将其强制转换为任何8位类型都是可行的。

正确。第588-592行将数据包元素(IP头和有效载荷)复制到以太网帧中,然后发送出去。但是在第588行,只复制了iphdr。因此我完全看不出需要out_packet_buffer的原因。 - alan
1
这是一种廉价的方法,可以分配一个大的字节缓冲区,而不会有未释放指针的危险。只要它在范围内,它就会存在。也许最初的意图是将数据负载放入该大缓冲区中...? 仅复制IP头比那个大缓冲区更小。 - Pam

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接