Add __packed__ attribute on drop-in structs
authorKirill Isakov <bootctl@gmail.com>
Mon, 28 Mar 2022 07:46:46 +0000 (13:46 +0600)
committerKirill Isakov <bootctl@gmail.com>
Mon, 28 Mar 2022 15:38:29 +0000 (21:38 +0600)
src/ethernet.h
src/have.h
src/ipv4.h
src/ipv6.h
src/meson.build

index ddb0a7c..cb9d527 100644 (file)
 #endif
 
 #ifndef HAVE_STRUCT_ETHER_HEADER
-struct ether_header {
+PACKED(struct ether_header {
        uint8_t ether_dhost[ETH_ALEN];
        uint8_t ether_shost[ETH_ALEN];
        uint16_t ether_type;
-};
+});
 #endif
 
 STATIC_ASSERT(sizeof(struct ether_header) == 14, "ether_header has incorrect size");
 
 #ifndef HAVE_STRUCT_ARPHDR
-struct arphdr {
+PACKED(struct arphdr {
        uint16_t ar_hrd;
        uint16_t ar_pro;
        uint8_t ar_hln;
        uint8_t ar_pln;
        uint16_t ar_op;
-};
-
+});
 #define ARPOP_REQUEST 1
 #define ARPOP_REPLY 2
 #define ARPOP_RREQUEST 3
@@ -91,13 +90,13 @@ struct arphdr {
 STATIC_ASSERT(sizeof(struct arphdr) == 8, "arphdr has incorrect size");
 
 #ifndef HAVE_STRUCT_ETHER_ARP
-struct  ether_arp {
+PACKED(struct ether_arp {
        struct  arphdr ea_hdr;
        uint8_t arp_sha[ETH_ALEN];
        uint8_t arp_spa[4];
        uint8_t arp_tha[ETH_ALEN];
        uint8_t arp_tpa[4];
-};
+});
 #define arp_hrd ea_hdr.ar_hrd
 #define arp_pro ea_hdr.ar_pro
 #define arp_hln ea_hdr.ar_hln
index 2428151..1d1bedf 100644 (file)
 #define STATIC_ASSERT(check, msg)
 #endif
 
+#ifdef HAVE_ATTR_PACKED
+#define PACKED(...) __VA_ARGS__ __attribute__((__packed__))
+#else
+#ifdef _MSC_VER
+#define PACKED(...) __pragma(pack(push, 1)) __VA_ARGS__ __pragma(pack(pop))
+#else
+#warning Your compiler does not support __packed__. Use at your own risk.
+#endif
+#endif
+
 #ifdef HAVE_ALLOCA_H
 #include <alloca.h>
 #elif defined(HAVE_NETBSD)
index 004f4e5..cd4c372 100644 (file)
 #endif
 
 #ifndef HAVE_STRUCT_IP
-struct ip {
 #if __BYTE_ORDER == __LITTLE_ENDIAN
-       unsigned int ip_hl: 4;
-       unsigned int ip_v: 4;
+#define IP_NIBBLE1 ip_hl
+#define IP_NIBBLE2 ip_v
 #else
-       unsigned int ip_v: 4;
-       unsigned int ip_hl: 4;
+#define IP_NIBBLE1 ip_v
+#define IP_NIBBLE2 ip_hl
 #endif
+PACKED(struct ip {
+       uint8_t IP_NIBBLE1: 4;
+       uint8_t IP_NIBBLE2: 4;
        uint8_t ip_tos;
        uint16_t ip_len;
        uint16_t ip_id;
        uint16_t ip_off;
-#define IP_RF 0x8000
-#define IP_DF 0x4000
-#define IP_MF 0x2000
        uint8_t ip_ttl;
        uint8_t ip_p;
        uint16_t ip_sum;
        struct in_addr ip_src, ip_dst;
-};
+});
+#undef IP_NIBBLE1
+#undef IP_NIBBLE2
+#define IP_RF 0x8000
+#define IP_DF 0x4000
+#define IP_MF 0x2000
 #endif
 
 STATIC_ASSERT(sizeof(struct ip) == 20, "ip has incorrect size");
@@ -93,7 +97,7 @@ STATIC_ASSERT(sizeof(struct ip) == 20, "ip has incorrect size");
 #endif
 
 #ifndef HAVE_STRUCT_ICMP
-struct icmp {
+PACKED(struct icmp {
        uint8_t icmp_type;
        uint8_t icmp_code;
        uint16_t icmp_cksum;
@@ -118,16 +122,6 @@ struct icmp {
                        uint16_t irt_lifetime;
                } ih_rtradv;
        } icmp_hun;
-#define icmp_pptr icmp_hun.ih_pptr
-#define icmp_gwaddr icmp_hun.ih_gwaddr
-#define icmp_id icmp_hun.ih_idseq.icd_id
-#define icmp_seq icmp_hun.ih_idseq.icd_seq
-#define icmp_void icmp_hun.ih_void
-#define icmp_pmvoid icmp_hun.ih_pmtu.ipm_void
-#define icmp_nextmtu icmp_hun.ih_pmtu.ipm_nextmtu
-#define icmp_num_addrs icmp_hun.ih_rtradv.irt_num_addrs
-#define icmp_wpa icmp_hun.ih_rtradv.irt_wpa
-#define icmp_lifetime icmp_hun.ih_rtradv.irt_lifetime
        union {
                struct {
                        uint32_t its_otime;
@@ -140,6 +134,17 @@ struct icmp {
                uint32_t id_mask;
                uint8_t id_data[1];
        } icmp_dun;
+});
+#define icmp_pptr icmp_hun.ih_pptr
+#define icmp_gwaddr icmp_hun.ih_gwaddr
+#define icmp_id icmp_hun.ih_idseq.icd_id
+#define icmp_seq icmp_hun.ih_idseq.icd_seq
+#define icmp_void icmp_hun.ih_void
+#define icmp_pmvoid icmp_hun.ih_pmtu.ipm_void
+#define icmp_nextmtu icmp_hun.ih_pmtu.ipm_nextmtu
+#define icmp_num_addrs icmp_hun.ih_rtradv.irt_num_addrs
+#define icmp_wpa icmp_hun.ih_rtradv.irt_wpa
+#define icmp_lifetime icmp_hun.ih_rtradv.irt_lifetime
 #define icmp_otime icmp_dun.id_ts.its_otime
 #define icmp_rtime icmp_dun.id_ts.its_rtime
 #define icmp_ttime icmp_dun.id_ts.its_ttime
@@ -147,7 +152,6 @@ struct icmp {
 #define icmp_radv icmp_dun.id_radv
 #define icmp_mask icmp_dun.id_mask
 #define icmp_data icmp_dun.id_data
-};
 #endif
 
 STATIC_ASSERT(sizeof(struct icmp) == 28, "icmp has incorrect size");
index 6f1e221..e9c4d26 100644 (file)
@@ -39,7 +39,7 @@
 #endif
 
 #ifndef HAVE_STRUCT_IP6_HDR
-struct ip6_hdr {
+PACKED(struct ip6_hdr {
        union {
                struct ip6_hdrctl {
                        uint32_t ip6_un1_flow;
@@ -51,7 +51,7 @@ struct ip6_hdr {
        } ip6_ctlun;
        struct in6_addr ip6_src;
        struct in6_addr ip6_dst;
-};
+});
 #define ip6_vfc ip6_ctlun.ip6_un2_vfc
 #define ip6_flow ip6_ctlun.ip6_un1.ip6_un1_flow
 #define ip6_plen ip6_ctlun.ip6_un1.ip6_un1_plen
@@ -63,7 +63,7 @@ struct ip6_hdr {
 STATIC_ASSERT(sizeof(struct ip6_hdr) == 40, "ip6_hdr has incorrect size");
 
 #ifndef HAVE_STRUCT_ICMP6_HDR
-struct icmp6_hdr {
+PACKED(struct icmp6_hdr {
        uint8_t icmp6_type;
        uint8_t icmp6_code;
        uint16_t icmp6_cksum;
@@ -72,7 +72,7 @@ struct icmp6_hdr {
                uint16_t icmp6_un_data16[2];
                uint8_t icmp6_un_data8[4];
        } icmp6_dataun;
-};
+});
 #define ICMP6_DST_UNREACH_NOROUTE 0
 #define ICMP6_DST_UNREACH 1
 #define ICMP6_PACKET_TOO_BIG 2
@@ -91,10 +91,10 @@ struct icmp6_hdr {
 STATIC_ASSERT(sizeof(struct icmp6_hdr) == 8, "icmp6_hdr has incorrect size");
 
 #ifndef HAVE_STRUCT_ND_NEIGHBOR_SOLICIT
-struct nd_neighbor_solicit {
+PACKED(struct nd_neighbor_solicit {
        struct icmp6_hdr nd_ns_hdr;
        struct in6_addr nd_ns_target;
-};
+});
 #define ND_OPT_SOURCE_LINKADDR 1
 #define ND_OPT_TARGET_LINKADDR 2
 #define nd_ns_type nd_ns_hdr.icmp6_type
@@ -106,10 +106,10 @@ struct nd_neighbor_solicit {
 STATIC_ASSERT(sizeof(struct nd_neighbor_solicit) == 24, "nd_neighbor_solicit has incorrect size");
 
 #ifndef HAVE_STRUCT_ND_OPT_HDR
-struct nd_opt_hdr {
+PACKED(struct nd_opt_hdr {
        uint8_t nd_opt_type;
        uint8_t nd_opt_len;
-};
+});
 #endif
 
 STATIC_ASSERT(sizeof(struct nd_opt_hdr) == 2, "nd_opt_hdr has incorrect size");
index b1796af..484b514 100644 (file)
@@ -11,8 +11,11 @@ cdata.set_quoted('SBINDIR', dir_sbin)
 
 cdata.set('HAVE_' + os_name.to_upper(), 1)
 
-foreach attr : ['malloc', 'nonnull', 'warn_unused_result']
-  cc.has_function_attribute(attr)
+foreach attr : ['malloc', 'nonnull', 'warn_unused_result', 'packed']
+  if cc.has_function_attribute(attr)
+    cdata.set('HAVE_ATTR_' + attr.to_upper(), 1,
+              description: '__attribute__(@0@)'.format(attr))
+  endif
 endforeach
 
 if cc.compiles('''