Forums before death by AOL, social media and spammers... "We can't have nice things"
|    comp.protocols.tcp-ip    |    TCP and IP network protocols.    |    14,669 messages    |
[   << oldest   |   < older   |   list   |   newer >   |   newest >>   ]
|    Message 14,374 of 14,669    |
|    Jorgen Grahn to All    |
|    Re: IPv4 header and memory alignment...    |
|    12 Mar 19 09:20:52    |
   
   From: grahn+nntp@snipabacken.se   
      
   On Mon, 2019-03-11, TDH1978 wrote:   
   > This question is in regards to the iphdr struct that can be found in   
   > /usr/include/linux/ip.h and /usr/include/netinet/ip.h. In some   
   > open-source projects, I have seen this header mapped onto packet data,   
   > to extract individual IPv4 header fields, like so:   
   >   
   >   
   > struct iphdr   
   > {   
   > unsigned int ihl:4;   
   > unsigned int version:4;   
   > uint8_t tos;   
   > uint16_t tot_len;   
   > uint16_t id;   
   > uint16_t frag_off;   
   > uint8_t ttl;   
   > uint8_t protocol;   
   > uint16_t check;   
   > uint32_t saddr;   
   > uint32_t daddr;   
   > };   
   >   
   >   
   > struct iphdr* hdr = (struct iphdr*) packet_data;   
   >    
   > uint32_t ipv4_src_addr = hdr->saddr;   
   > uint32_t ipv4_dst_addr = hdr->daddr;   
   >    
   >    
   > Is this safe? Given that the packet data could start at any memory   
   > location, what guarantee is there that the 32-bit 'saddr' and 'daddr'   
   > fields are properly aligned in memory at 32-bit boundaries?   
      
   In the Linux kernel, they make sure it's safe by aligning that memory,   
   and knowing things about how the compiler treats structs, more than   
   what the C language guarantees.   
      
   In my own code, I prefer not to rely on such things. It gets messy,   
   and you still need to take care of endianness. I write my own accessor   
   functions instead:   
      
    /* assuming buf points to a full IPv4 header   
    */   
    struct in_addr get_saddr(const unsigned char* buf);   
      
   As a bonus, you get a better type than uint32_t.   
      
   /Jorgen   
      
   --   
    // Jorgen Grahn
|
[   << oldest   |   < older   |   list   |   newer >   |   newest >>   ]
(c) 1994, bbs@darkrealms.ca