我有一个char *data,它是一个数据报,代表我想发送的数据包,但我需要在它上面插入一个uint8_t数组。
// Datagram to represent the packet
char datagram[4096], source_ip[32], *data, *pseudogram;
// zero out the packet buffer
memset(datagram, 0, 4096);
// IP header
struct iphdr *iph = (struct iphdr *)datagram;
// UDP header
struct udphdr *udph = (struct udphdr *)(datagram + sizeof(struct ip));
// Data part
data = datagram + sizeof(struct iphdr) + sizeof(struct udphdr);
uint8_t packet_bytes[] = { 0xff, 0xff, 0x81, 0x01, 0x01 };
memcpy(data, packet_bytes, 5);
这样做允许我插入我需要的东西,它可以工作,但问题是我有一个中间有0x00的uint8_t数组,这比我想象的要困难,因为0x00十六进制也意味着数组的终止,我如何让它使用这个数组呢?
char packet_bytes[] = {
0xff, 0xff, 0x81, 0x00, 0x00, 0x00, 0x00, 0x30,
0x13, 0x43, 0x00, 0x01, 0x01, 0x01, 0x02, 0x00,
0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10,
0x06, 0x00, 0x00, 0x10, 0x01, 0x01, 0x00, 0x63,
0x02, 0x00, 0x00, 0x03, 0x00, 0x01, 0x00, 0x05,
0x00, 0x00, 0x00, 0x0c, 0x00, 0x09, 0x04, 0x00,
0x0a, 0x00, 0x03, 0x01, 0x00, 0x11, 0x77, 0x25
};
1条答案
按热度按时间t1rydlwq1#
问题是,我有一个中间带有0x 00的uint8_t数组,这比我想象的要困难,因为十六进制的0x 00也意味着数组的终止
在C语言中没有“数组终止”这样的东西。字符数组 * 用作字符串 * 时有空终止,但这在这里不适用。所以
memcpy
部分将工作得很好。但是,您还有一些其他问题:
char datagram[4096]
、char packet_bytes[]
等char
不适合、危险且不可移植用于保存原始二进制数据。请改用uint8_t
。请参见Is char signed or unsigned by default?struct iphdr *iph = (struct iphdr *)datagram;
由于对齐和严格的别名,这将导致未定义的行为。What is the strict aliasing rule?您不能通过指针强制转换将pun从一个字符数组广泛地输入到另一个类型(尽管从“any type”到字符类型的相反方式是可能的)。此外,您的struct可能包含填充,在这种情况下,它是额外的不可移植的,您不希望到处发送填充字节。
(struct udphdr *)(datagram + sizeof(struct ip));
与上述问题相同。唯一可靠的方法是禁用struct padding,然后
memcpy
in/out该结构。或者编写序列化/反序列化例程,一次访问一个struct成员,将其移到原始数据中或从原始数据中移出。