clinuxsocketspacking

Unexpected value after type casting in c


I was implementing the code for sending data through a raw socket. As part of that, I have to construct an IP packet. But I am facing the problem as explained below using a sample program.

#include <stdio.h>

struct iph {
    unsigned char ihl:4;
    unsigned char ver:4;
    unsigned char data;
    unsigned char data1;
};

int main()
{
    char buff[3] = {0};

    struct iph *ptr = (struct iph *)buff;
    ptr->ihl = 5;
    ptr->ver = 4;
    ptr->data = 0xAB;
    ptr->data1 = 0xCD;

    printf("%x %x %x\n", buff[0], buff[1], buff[2]);
}

Here the output I am expecting is 45 ab cd But I am getting 45 ffffffab ffffffcd. Can anyone explain how this is happening and share a solution to get the expected value?


Solution

  • char is signed on your machine and 0xab is a negative value for 8bit signed data types. So when it gets promoted, it gets promoted to the same negative value and that's 0xffffffab as an int.

    Solution: use unsigned char