Home > Blockchain >  How to add a uint8_t array into a char*
How to add a uint8_t array into a char*

Time:12-14

I have a char *data that is a Datagram to represent the packet I want to send in but I need to insert on that an uint8_t array.

// 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);

Doing this allows me to insert what I need and it works but the problem is that I have and uint8_t array with 0x00 in the middle making this harder than I thought because the 0x00 hex also means a termination of an array, how can I make it to work with this array instead ?

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
};

CodePudding user response:

the problem is that I have and uint8_t array with 0x00 in the middle making this harder than I thought because the 0x00 hex also means a termination of an array

There is no such thing as "termination of an array" in C. There is null termination of character arrays used as strings, but that isn't applicable here. So the memcpy part will work just fine.

You have some other problems however:

  • char datagram[4096], char packet_bytes[] etc
    char is unsuitable, dangerous and non-portable for the purpose of holding raw binary data. Use uint8_t instead. See Is char signed or unsigned by default?

  • struct iphdr *iph = (struct iphdr *)datagram;
    This will lead to undefined behavior because of alignment and strict aliasing. What is the strict aliasing rule? You cannot wildly type pun from a character array to another type by pointer casts (though the other way around from "any type" to character type is possible). Furthermore, your struct may contain padding, in which case it is extra non-portable and you don't want to be sending padding bytes around.

  • (struct udphdr *)(datagram sizeof(struct ip)); Same problem as above.

The only reliable way to do this is either to disable struct padding and then memcpy in/out of the struct. Or alternatively write serialization/deserialization routines accessing one struct member at a time, moving it to/from the raw data.

  • Related