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.
On 2019-03-12 09:20:52 +0000, Jorgen Grahn said:
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.
Thank you for your reply. I agree your method is safer but I assume
that, by calling your accessor functions, you will incur a slight
run-time overhead. If you do this for, say, a billion incoming
packets, this overhead may become significant.
Sysop: | Keyop |
---|---|
Location: | Huddersfield, West Yorkshire, UK |
Users: | 293 |
Nodes: | 16 (3 / 13) |
Uptime: | 215:39:46 |
Calls: | 6,620 |
Calls today: | 2 |
Files: | 12,169 |
Messages: | 5,317,547 |