static inline bool
is_mac_mcast_maddr (const struct mroute_addr *addr)
{
- return (addr->type & MR_ADDR_MASK) == MR_ADDR_ETHER && is_mac_mcast_addr (addr->addr);
+ return (addr->type & MR_ADDR_MASK) == MR_ADDR_ETHER &&
+ is_mac_mcast_addr (addr->eth_addr);
}
/*
for (i = 0; i < addr->len; ++i)
{
- int b = addr->addr[i];
+ int b = addr->raw_addr[i];
if (b != 0x00)
not_all_zeros = true;
if (b != 0xFF)
ma->type = MR_ADDR_IPV4 | mask;
ma->netbits = 0;
ma->len = 4;
- *(in_addr_t*)ma->addr = src;
+ ma->v4.addr = src;
}
}
ma->type = MR_ADDR_IPV6 | mask;
ma->netbits = 0;
ma->len = 16;
- *(struct in6_addr *)ma->addr = src;
+ ma->v6.addr = src;
}
}
src->type = MR_ADDR_ETHER;
src->netbits = 0;
src->len = 6;
- memcpy (src->addr, eth->source, 6);
+ memcpy (src->eth_addr, eth->source, sizeof(dest->eth_addr));
}
if (dest)
{
dest->type = MR_ADDR_ETHER;
dest->netbits = 0;
dest->len = 6;
- memcpy (dest->addr, eth->dest, 6);
+ memcpy (dest->eth_addr, eth->dest, sizeof(dest->eth_addr));
/* ethernet broadcast/multicast packet? */
if (is_mac_mcast_addr (eth->dest))
addr->type = MR_ADDR_IPV4 | MR_WITH_PORT;
addr->netbits = 0;
addr->len = 6;
- memcpy (addr->addr, &osaddr->addr.in4.sin_addr.s_addr, 4);
- memcpy (addr->addr + 4, &osaddr->addr.in4.sin_port, 2);
+ addr->v4.addr = osaddr->addr.in4.sin_addr.s_addr;
+ addr->v4.port = osaddr->addr.in4.sin_port;
}
else
{
addr->type = MR_ADDR_IPV4;
addr->netbits = 0;
addr->len = 4;
- memcpy (addr->addr, &osaddr->addr.in4.sin_addr.s_addr, 4);
+ addr->v4.addr = osaddr->addr.in4.sin_addr.s_addr;
}
return true;
}
addr->type = MR_ADDR_IPV6 | MR_WITH_PORT;
addr->netbits = 0;
addr->len = 18;
- memcpy (addr->addr, &osaddr->addr.in6.sin6_addr, 16);
- memcpy (addr->addr + 16, &osaddr->addr.in6.sin6_port, 2);
+ addr->v6.addr = osaddr->addr.in6.sin6_addr;
+ addr->v6.port = osaddr->addr.in6.sin6_port;
}
else
{
addr->type = MR_ADDR_IPV6;
addr->netbits = 0;
addr->len = 16;
- memcpy (addr->addr, &osaddr->addr.in6.sin6_addr, 16);
+ addr->v6.addr = osaddr->addr.in6.sin6_addr;
}
return true;
}
void
mroute_addr_mask_host_bits (struct mroute_addr *ma)
{
- in_addr_t addr = ntohl(*(in_addr_t*)ma->addr);
if ((ma->type & MR_ADDR_MASK) == MR_ADDR_IPV4)
{
+ in_addr_t addr = ntohl (ma->v4.addr);
addr &= netbits_to_netmask (ma->netbits);
- *(in_addr_t*)ma->addr = htonl (addr);
+ ma->v4.addr = htonl (addr);
}
else if ((ma->type & MR_ADDR_MASK) == MR_ADDR_IPV6)
{
- int byte = ma->len-1; /* rightmost byte in address */
+ int byte = sizeof (ma->v6.addr) - 1; /* rightmost byte in address */
int bits_to_clear = 128 - ma->netbits;
while( byte >= 0 && bits_to_clear > 0 )
{
if ( bits_to_clear >= 8 )
- { ma->addr[byte--] = 0; bits_to_clear -= 8; }
+ {
+ ma->v6.addr.s6_addr[byte--] = 0;
+ bits_to_clear -= 8;
+ }
else
- { ma->addr[byte--] &= (IPV4_NETMASK_HOST << bits_to_clear); bits_to_clear = 0; }
+ {
+ ma->v6.addr.s6_addr[byte--] &= (IPV4_NETMASK_HOST << bits_to_clear);
+ bits_to_clear = 0;
+ }
}
ASSERT( bits_to_clear == 0 );
}
switch (maddr.type & MR_ADDR_MASK)
{
case MR_ADDR_ETHER:
- buf_printf (&out, "%s", format_hex_ex (ma->addr, 6, 0, 1, ":", gc));
+ buf_printf (&out, "%s", format_hex_ex (ma->eth_addr,
+ sizeof(ma->eth_addr), 0, 1, ":", gc));
break;
case MR_ADDR_IPV4:
{
- struct buffer buf;
- in_addr_t addr;
- int port;
- bool status;
- buf_set_read (&buf, maddr.addr, maddr.len);
- addr = buf_read_u32 (&buf, &status);
- if (status)
+ if ((flags & MAPF_SHOW_ARP) && (maddr.type & MR_ARP))
+ buf_printf (&out, "ARP/");
+ buf_printf (&out, "%s", print_in_addr_t (ntohl (maddr.v4.addr),
+ (flags & MAPF_IA_EMPTY_IF_UNDEF) ? IA_EMPTY_IF_UNDEF : 0, gc));
+ if (maddr.type & MR_WITH_NETBITS)
{
- if ((flags & MAPF_SHOW_ARP) && (maddr.type & MR_ARP))
- buf_printf (&out, "ARP/");
- buf_printf (&out, "%s", print_in_addr_t (addr, (flags & MAPF_IA_EMPTY_IF_UNDEF) ? IA_EMPTY_IF_UNDEF : 0, gc));
- if (maddr.type & MR_WITH_NETBITS)
+ if (flags & MAPF_SUBNET)
{
- if (flags & MAPF_SUBNET)
- {
- const in_addr_t netmask = netbits_to_netmask (maddr.netbits);
- buf_printf (&out, "/%s", print_in_addr_t (netmask, 0, gc));
- }
- else
- buf_printf (&out, "/%d", maddr.netbits);
+ const in_addr_t netmask = netbits_to_netmask (maddr.netbits);
+ buf_printf (&out, "/%s", print_in_addr_t (netmask, 0, gc));
}
+ else
+ buf_printf (&out, "/%d", maddr.netbits);
}
if (maddr.type & MR_WITH_PORT)
{
- port = buf_read_u16 (&buf);
- if (port >= 0)
- buf_printf (&out, ":%d", port);
+ buf_printf (&out, ":%d", ntohs (maddr.v4.port));
}
}
break;
case MR_ADDR_IPV6:
{
- if ( IN6_IS_ADDR_V4MAPPED( (struct in6_addr*)&maddr.addr ) )
+ if ( IN6_IS_ADDR_V4MAPPED( &maddr.v6.addr ) )
{
- buf_printf (&out, "%s",
- print_in_addr_t( *(in_addr_t*)(&maddr.addr[12]), IA_NET_ORDER, gc));
+ buf_printf (&out, "%s", print_in_addr_t (maddr.v4mappedv6.addr,
+ IA_NET_ORDER, gc));
}
else
{
- buf_printf (&out, "%s",
- print_in6_addr( *(struct in6_addr*)&maddr.addr, 0, gc));
+ buf_printf (&out, "%s", print_in6_addr (maddr.v6.addr, 0, gc));
}
if (maddr.type & MR_WITH_NETBITS)
{
#include "list.h"
#include "route.h"
+#include <stddef.h>
+
#define IP_MCAST_SUBNET_MASK ((in_addr_t)240<<24)
#define IP_MCAST_NETWORK ((in_addr_t)224<<24)
uint8_t type; /* MR_ADDR/MR_WITH flags */
uint8_t netbits; /* number of bits in network part of address,
valid if MR_WITH_NETBITS is set */
- uint8_t addr[MR_MAX_ADDR_LEN]; /* actual address */
+ union {
+ uint8_t raw_addr[MR_MAX_ADDR_LEN]; /* actual address */
+ uint8_t eth_addr[OPENVPN_ETH_ALEN];
+ struct {
+ in_addr_t addr; /* _network order_ IPv4 address */
+ in_port_t port; /* _network order_ TCP/UDP port */
+ } v4;
+ struct {
+ struct in6_addr addr;
+ in_port_t port; /* _network order_ TCP/UDP port */
+ } v6;
+ struct {
+ uint8_t prefix[12];
+ in_addr_t addr; /* _network order_ IPv4 address */
+ } v4mappedv6;
+ };
};
+/* Double-check that struct packing works as expected */
+static_assert (offsetof(struct mroute_addr, v4.port) ==
+ offsetof(struct mroute_addr, v4) + 4,
+ "Unexpected struct packing of v4");
+static_assert (offsetof(struct mroute_addr, v6.port) ==
+ offsetof(struct mroute_addr, v6) + 16,
+ "Unexpected struct packing of v6");
+static_assert (offsetof(struct mroute_addr, v4mappedv6.addr) ==
+ offsetof(struct mroute_addr, v4mappedv6) + 12,
+ "Unexpected struct packing of v4mappedv6");
+
/*
* Number of bits in an address. Should be raised for IPv6.
*/
return false;
if (a1->len != a2->len)
return false;
- return memcmp (a1->addr, a2->addr, a1->len) == 0;
+ return memcmp (a1->raw_addr, a2->raw_addr, a1->len) == 0;
}
static inline const uint8_t *
dest->type = MR_ADDR_IPV4;
dest->netbits = 0;
dest->len = 4;
- *(in_addr_t*)dest->addr = htonl (src);
+ dest->v4.addr = htonl (src);
}
static inline in_addr_t
in_addr_t_from_mroute_addr (const struct mroute_addr *addr)
{
- if ((addr->type & MR_ADDR_MASK) == MR_ADDR_IPV4 && addr->netbits == 0 && addr->len == 4)
- return ntohl(*(in_addr_t*)addr->addr);
- else
+ if ((addr->type & MR_ADDR_MASK) == MR_ADDR_IPV4 && addr->netbits == 0 && addr->len == 4) {
+ return ntohl(addr->v4.addr);
+ } else {
return 0;
+ }
}
static inline void
if (socket_defined (sd_send))
{
- *((socket_descriptor_t*)CMSG_DATA(h)) = sd_send;
+ memcpy (CMSG_DATA(h), &sd_send, sizeof (sd_send));
}
else
{
socketpair (PF_UNIX, SOCK_DGRAM, 0, sd_null);
- *((socket_descriptor_t*)CMSG_DATA(h)) = sd_null[0];
+ memcpy (CMSG_DATA(h), &sd_null[0], sizeof (sd_null[0]));
}
status = sendmsg (sd, &mesg, MSG_NOSIGNAL);
h->cmsg_len = CMSG_LEN(sizeof(socket_descriptor_t));
h->cmsg_level = SOL_SOCKET;
h->cmsg_type = SCM_RIGHTS;
- *((socket_descriptor_t*)CMSG_DATA(h)) = SOCKET_UNDEFINED;
+ static const socket_descriptor_t socket_undefined = SOCKET_UNDEFINED;
+ memcpy (CMSG_DATA(h), &socket_undefined, sizeof(socket_undefined));
status = recvmsg (sd_control, &mesg, MSG_NOSIGNAL);
if (status != -1)
}
else
{
- const socket_descriptor_t received_fd = *((socket_descriptor_t*)CMSG_DATA(h));
+ socket_descriptor_t received_fd;
+ memcpy (&received_fd, CMSG_DATA(h), sizeof(received_fd));
dmsg (D_PS_PROXY_DEBUG, "PORT SHARE PROXY: RECEIVED sd=%d", (int)received_fd);
if (status >= 2 && command == COMMAND_REDIRECT)