1

I'm trying to create an IP header in C.

typedef struct header
{
    //IP-Header
    unsigned char ip_v:4, ip_hl:4;/* this means that each member is 4 bits */
    unsigned char ip_tos;       //1 Byte
    unsigned short int ip_len;  //2 Byte
    unsigned short int ip_id;   //2 Byte
    unsigned short int ip_off;  //2 Byte
    unsigned char ip_ttl;       //1 Byte
    unsigned char ip_p;         //1 Byte
    unsigned short int ip_sum;  //2 Byte
    unsigned int ip_src;        //4 Byte
    unsigned int ip_dst;        //4 Byte


} __attribute__((packed)) ipheader;

Now I would like to use the struct and save hex values in the variables.

int main()
{
    ipheader iph;

    iph.ip_v='\x4';
    iph.ip_hl='\x5';
    iph.ip_tos='\x00';

    return 0;
}

How can I write 103C into iph.ip_len? And is this structure a good way to store an IP header?

Alexis Wilke
  • 19,179
  • 10
  • 84
  • 156
John Smithv1
  • 673
  • 5
  • 14
  • 33

3 Answers3

2

How about using the iphdr struct?

Other than that you should be careful regarding endianess (see ntohl and htonl functions), depending on what you want to do with the data in it (you don't say). Also see why endianess matters among bits inside a byte? regarding endianess in the iphdr.

For writing the values itself, you can do so in any format permitted by the standard / compiler you use, e.g. binary literal if you use the right GCC version with appropriate flags, or octal, or decimal, or character arrays, or ...

Here's some examples of different literal formats:

Hexadezimal: 0x103C

Char array: (char *){ 10, 60 } or (char *){ 10, '<' }

Octal: 010074

Binary: 0b1000000111100

If you don't move the value around between different types or do some funky math with them, you shouldn't even need a cast - otherwise the compiler will interpret the values as an int which might be a problem for you, especially because of the different signedness. In that case just prefix (uint16_t) or whatever you need (you should either use the same types as defined in the system - see the suggestion about iphdr at the top of my answer - or fixed length definitions, to avoid portabiity issues or problems with future updates)

Community
  • 1
  • 1
griffin
  • 1,261
  • 8
  • 24
0

You could just assign the value to it:

iph.ip_len = (unsigned short int)0x103C;

The others you were actually assigning as characters. I'm not sure if that was you intention.

So in iph.ip_v='\x4', the '\x4' actually represents a character which is then assigned to the ip_v member (truncated to 4 bits). But you could have just written iph.ip_v=0x04.

Mike Dinescu
  • 54,171
  • 16
  • 118
  • 151
0

Use:

unsigned char ip_hl:4, ip_v:4;

or

int ip_vhl; // version and header togather
#define IP_HL(ip) (((ip)->ip_vhl) & 0x0f) //split header length
#define IP_V(ip) (((ip)->ip_vhl) >> 4) //split IP version

Kothari
  • 91
  • 1
  • 9