From: Kirill Isakov Date: Mon, 28 Mar 2022 07:46:46 +0000 (+0600) Subject: Add __packed__ attribute on drop-in structs X-Git-Url: https://tinc-vpn.org/git/browse?a=commitdiff_plain;h=244002d83466a85ac4fbb5327e26a60fe44168fd;p=tinc Add __packed__ attribute on drop-in structs --- diff --git a/src/ethernet.h b/src/ethernet.h index ddb0a7c6..cb9d5274 100644 --- a/src/ethernet.h +++ b/src/ethernet.h @@ -61,24 +61,23 @@ #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 diff --git a/src/have.h b/src/have.h index 2428151a..1d1bedfc 100644 --- a/src/have.h +++ b/src/have.h @@ -51,6 +51,16 @@ #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 #elif defined(HAVE_NETBSD) diff --git a/src/ipv4.h b/src/ipv4.h index 004f4e5d..cd4c372b 100644 --- a/src/ipv4.h +++ b/src/ipv4.h @@ -64,26 +64,30 @@ #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"); diff --git a/src/ipv6.h b/src/ipv6.h index 6f1e2211..e9c4d265 100644 --- a/src/ipv6.h +++ b/src/ipv6.h @@ -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"); diff --git a/src/meson.build b/src/meson.build index b1796af2..484b514a 100644 --- a/src/meson.build +++ b/src/meson.build @@ -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('''