#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
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
#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)
#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");
#endif
#ifndef HAVE_STRUCT_ICMP
-struct icmp {
+PACKED(struct icmp {
uint8_t icmp_type;
uint8_t icmp_code;
uint16_t icmp_cksum;
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;
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
#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");
#endif
#ifndef HAVE_STRUCT_IP6_HDR
-struct ip6_hdr {
+PACKED(struct ip6_hdr {
union {
struct ip6_hdrctl {
uint32_t ip6_un1_flow;
} 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
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;
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
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
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");
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('''