summaryrefslogtreecommitdiff
path: root/src/openvpn/mroute.c
diff options
context:
space:
mode:
authorAlberto Gonzalez Iniesta <agi@inittab.org>2016-12-27 18:25:47 +0100
committerAlberto Gonzalez Iniesta <agi@inittab.org>2016-12-27 18:25:47 +0100
commit79f3537f69e125f19f59c36aa090120a63186a54 (patch)
tree2089a3b7dac990841dbc2e4d9b2f535b82dbb0af /src/openvpn/mroute.c
parentf2137fedb30cb87448eb03b2f288920df6187571 (diff)
parent3a2bbdb05ca6a6996e424c9fb225cb0d53804125 (diff)
Merge tag 'upstream/2.4.0'
Upstream version 2.4.0
Diffstat (limited to 'src/openvpn/mroute.c')
-rw-r--r--src/openvpn/mroute.c686
1 files changed, 362 insertions, 324 deletions
diff --git a/src/openvpn/mroute.c b/src/openvpn/mroute.c
index c905af7..8b466b6 100644
--- a/src/openvpn/mroute.c
+++ b/src/openvpn/mroute.c
@@ -5,7 +5,7 @@
* packet encryption, packet authentication, and
* packet compression.
*
- * Copyright (C) 2002-2010 OpenVPN Technologies, Inc. <sales@openvpn.net>
+ * Copyright (C) 2002-2017 OpenVPN Technologies, Inc. <sales@openvpn.net>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2
@@ -40,9 +40,9 @@
#include "memdbg.h"
void
-mroute_addr_init (struct mroute_addr *addr)
+mroute_addr_init(struct mroute_addr *addr)
{
- CLEAR (*addr);
+ CLEAR(*addr);
}
/*
@@ -50,269 +50,288 @@ mroute_addr_init (struct mroute_addr *addr)
*/
static inline bool
-is_mac_mcast_addr (const uint8_t *mac)
+is_mac_mcast_addr(const uint8_t *mac)
{
- return (bool) (mac[0] & 1);
+ return (bool) (mac[0] & 1);
}
static inline bool
-is_mac_mcast_maddr (const struct mroute_addr *addr)
+is_mac_mcast_maddr(const struct mroute_addr *addr)
{
- return (addr->type & MR_ADDR_MASK) == MR_ADDR_ETHER &&
- is_mac_mcast_addr (addr->eth_addr);
+ return (addr->type & MR_ADDR_MASK) == MR_ADDR_ETHER
+ && is_mac_mcast_addr(addr->eth_addr);
}
/*
* Don't learn certain addresses.
*/
bool
-mroute_learnable_address (const struct mroute_addr *addr)
+mroute_learnable_address(const struct mroute_addr *addr)
{
- int i;
- bool not_all_zeros = false;
- bool not_all_ones = false;
+ int i;
+ bool not_all_zeros = false;
+ bool not_all_ones = false;
- for (i = 0; i < addr->len; ++i)
+ for (i = 0; i < addr->len; ++i)
{
- int b = addr->raw_addr[i];
- if (b != 0x00)
- not_all_zeros = true;
- if (b != 0xFF)
- not_all_ones = true;
+ int b = addr->raw_addr[i];
+ if (b != 0x00)
+ {
+ not_all_zeros = true;
+ }
+ if (b != 0xFF)
+ {
+ not_all_ones = true;
+ }
}
- return not_all_zeros && not_all_ones && !is_mac_mcast_maddr (addr);
+ return not_all_zeros && not_all_ones && !is_mac_mcast_maddr(addr);
}
static inline void
-mroute_get_in_addr_t (struct mroute_addr *ma, const in_addr_t src, unsigned int mask)
+mroute_get_in_addr_t(struct mroute_addr *ma, const in_addr_t src, unsigned int mask)
{
- if (ma)
+ if (ma)
{
- ma->type = MR_ADDR_IPV4 | mask;
- ma->netbits = 0;
- ma->len = 4;
- ma->v4.addr = src;
+ ma->type = MR_ADDR_IPV4 | mask;
+ ma->netbits = 0;
+ ma->len = 4;
+ ma->v4.addr = src;
}
}
static inline void
-mroute_get_in6_addr (struct mroute_addr *ma, const struct in6_addr src, unsigned int mask)
+mroute_get_in6_addr(struct mroute_addr *ma, const struct in6_addr src, unsigned int mask)
{
- if (ma)
+ if (ma)
{
- ma->type = MR_ADDR_IPV6 | mask;
- ma->netbits = 0;
- ma->len = 16;
- ma->v6.addr = src;
+ ma->type = MR_ADDR_IPV6 | mask;
+ ma->netbits = 0;
+ ma->len = 16;
+ ma->v6.addr = src;
}
}
static inline bool
-mroute_is_mcast (const in_addr_t addr)
+mroute_is_mcast(const in_addr_t addr)
{
- return ((addr & htonl(IP_MCAST_SUBNET_MASK)) == htonl(IP_MCAST_NETWORK));
+ return ((addr & htonl(IP_MCAST_SUBNET_MASK)) == htonl(IP_MCAST_NETWORK));
}
-/* RFC 4291, 2.7, "binary 11111111 at the start of an address identifies
+/* RFC 4291, 2.7, "binary 11111111 at the start of an address identifies
* the address as being a multicast address"
*/
static inline bool
-mroute_is_mcast_ipv6 (const struct in6_addr addr)
+mroute_is_mcast_ipv6(const struct in6_addr addr)
{
- return (addr.s6_addr[0] == 0xff);
+ return (addr.s6_addr[0] == 0xff);
}
#ifdef ENABLE_PF
static unsigned int
-mroute_extract_addr_arp (struct mroute_addr *src,
- struct mroute_addr *dest,
- const struct buffer *buf)
+mroute_extract_addr_arp(struct mroute_addr *src,
+ struct mroute_addr *dest,
+ const struct buffer *buf)
{
- unsigned int ret = 0;
- if (BLEN (buf) >= (int) sizeof (struct openvpn_arp))
+ unsigned int ret = 0;
+ if (BLEN(buf) >= (int) sizeof(struct openvpn_arp))
{
- const struct openvpn_arp *arp = (const struct openvpn_arp *) BPTR (buf);
- if (arp->mac_addr_type == htons(0x0001)
- && arp->proto_addr_type == htons(0x0800)
- && arp->mac_addr_size == 0x06
- && arp->proto_addr_size == 0x04)
- {
- mroute_get_in_addr_t (src, arp->ip_src, MR_ARP);
- mroute_get_in_addr_t (dest, arp->ip_dest, MR_ARP);
-
- /* multicast packet? */
- if (mroute_is_mcast (arp->ip_dest))
- ret |= MROUTE_EXTRACT_MCAST;
-
- ret |= MROUTE_EXTRACT_SUCCEEDED;
- }
+ const struct openvpn_arp *arp = (const struct openvpn_arp *) BPTR(buf);
+ if (arp->mac_addr_type == htons(0x0001)
+ && arp->proto_addr_type == htons(0x0800)
+ && arp->mac_addr_size == 0x06
+ && arp->proto_addr_size == 0x04)
+ {
+ mroute_get_in_addr_t(src, arp->ip_src, MR_ARP);
+ mroute_get_in_addr_t(dest, arp->ip_dest, MR_ARP);
+
+ /* multicast packet? */
+ if (mroute_is_mcast(arp->ip_dest))
+ {
+ ret |= MROUTE_EXTRACT_MCAST;
+ }
+
+ ret |= MROUTE_EXTRACT_SUCCEEDED;
+ }
}
- return ret;
+ return ret;
}
-#endif
+#endif /* ifdef ENABLE_PF */
unsigned int
-mroute_extract_addr_ipv4 (struct mroute_addr *src,
- struct mroute_addr *dest,
- const struct buffer *buf)
+mroute_extract_addr_ipv4(struct mroute_addr *src,
+ struct mroute_addr *dest,
+ const struct buffer *buf)
{
- unsigned int ret = 0;
- if (BLEN (buf) >= 1)
+ unsigned int ret = 0;
+ if (BLEN(buf) >= 1)
{
- switch (OPENVPN_IPH_GET_VER (*BPTR(buf)))
- {
- case 4:
- if (BLEN (buf) >= (int) sizeof (struct openvpn_iphdr))
- {
- const struct openvpn_iphdr *ip = (const struct openvpn_iphdr *) BPTR (buf);
-
- mroute_get_in_addr_t (src, ip->saddr, 0);
- mroute_get_in_addr_t (dest, ip->daddr, 0);
-
- /* multicast packet? */
- if (mroute_is_mcast (ip->daddr))
- ret |= MROUTE_EXTRACT_MCAST;
-
- /* IGMP message? */
- if (ip->protocol == OPENVPN_IPPROTO_IGMP)
- ret |= MROUTE_EXTRACT_IGMP;
-
- ret |= MROUTE_EXTRACT_SUCCEEDED;
- }
- break;
- case 6:
- if (BLEN (buf) >= (int) sizeof (struct openvpn_ipv6hdr))
- {
- const struct openvpn_ipv6hdr *ipv6 = (const struct openvpn_ipv6hdr *) BPTR (buf);
-#if 0 /* very basic debug */
- struct gc_arena gc = gc_new ();
- msg( M_INFO, "IPv6 packet! src=%s, dst=%s",
- print_in6_addr( ipv6->saddr, 0, &gc ),
- print_in6_addr( ipv6->daddr, 0, &gc ));
- gc_free (&gc);
+ switch (OPENVPN_IPH_GET_VER(*BPTR(buf)))
+ {
+ case 4:
+ if (BLEN(buf) >= (int) sizeof(struct openvpn_iphdr))
+ {
+ const struct openvpn_iphdr *ip = (const struct openvpn_iphdr *) BPTR(buf);
+
+ mroute_get_in_addr_t(src, ip->saddr, 0);
+ mroute_get_in_addr_t(dest, ip->daddr, 0);
+
+ /* multicast packet? */
+ if (mroute_is_mcast(ip->daddr))
+ {
+ ret |= MROUTE_EXTRACT_MCAST;
+ }
+
+ /* IGMP message? */
+ if (ip->protocol == OPENVPN_IPPROTO_IGMP)
+ {
+ ret |= MROUTE_EXTRACT_IGMP;
+ }
+
+ ret |= MROUTE_EXTRACT_SUCCEEDED;
+ }
+ break;
+
+ case 6:
+ if (BLEN(buf) >= (int) sizeof(struct openvpn_ipv6hdr))
+ {
+ const struct openvpn_ipv6hdr *ipv6 = (const struct openvpn_ipv6hdr *) BPTR(buf);
+#if 0 /* very basic debug */
+ struct gc_arena gc = gc_new();
+ msg( M_INFO, "IPv6 packet! src=%s, dst=%s",
+ print_in6_addr( ipv6->saddr, 0, &gc ),
+ print_in6_addr( ipv6->daddr, 0, &gc ));
+ gc_free(&gc);
#endif
- mroute_get_in6_addr (src, ipv6->saddr, 0);
- mroute_get_in6_addr (dest, ipv6->daddr, 0);
+ mroute_get_in6_addr(src, ipv6->saddr, 0);
+ mroute_get_in6_addr(dest, ipv6->daddr, 0);
+
+ if (mroute_is_mcast_ipv6(ipv6->daddr))
+ {
+ ret |= MROUTE_EXTRACT_MCAST;
+ }
- if (mroute_is_mcast_ipv6 (ipv6->daddr))
- ret |= MROUTE_EXTRACT_MCAST;
+ ret |= MROUTE_EXTRACT_SUCCEEDED;
+ }
+ break;
- ret |= MROUTE_EXTRACT_SUCCEEDED;
- }
- break;
- default:
- msg (M_WARN, "IP packet with unknown IP version=%d seen",
- OPENVPN_IPH_GET_VER (*BPTR(buf)));
- }
+ default:
+ msg(M_WARN, "IP packet with unknown IP version=%d seen",
+ OPENVPN_IPH_GET_VER(*BPTR(buf)));
+ }
}
- return ret;
+ return ret;
}
unsigned int
-mroute_extract_addr_ether (struct mroute_addr *src,
- struct mroute_addr *dest,
- struct mroute_addr *esrc,
- struct mroute_addr *edest,
- const struct buffer *buf)
+mroute_extract_addr_ether(struct mroute_addr *src,
+ struct mroute_addr *dest,
+ struct mroute_addr *esrc,
+ struct mroute_addr *edest,
+ const struct buffer *buf)
{
- unsigned int ret = 0;
- if (BLEN (buf) >= (int) sizeof (struct openvpn_ethhdr))
+ unsigned int ret = 0;
+ if (BLEN(buf) >= (int) sizeof(struct openvpn_ethhdr))
{
- const struct openvpn_ethhdr *eth = (const struct openvpn_ethhdr *) BPTR (buf);
- if (src)
- {
- src->type = MR_ADDR_ETHER;
- src->netbits = 0;
- src->len = 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->eth_addr, eth->dest, sizeof(dest->eth_addr));
-
- /* ethernet broadcast/multicast packet? */
- if (is_mac_mcast_addr (eth->dest))
- ret |= MROUTE_EXTRACT_BCAST;
- }
-
- ret |= MROUTE_EXTRACT_SUCCEEDED;
+ const struct openvpn_ethhdr *eth = (const struct openvpn_ethhdr *) BPTR(buf);
+ if (src)
+ {
+ src->type = MR_ADDR_ETHER;
+ src->netbits = 0;
+ src->len = 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->eth_addr, eth->dest, sizeof(dest->eth_addr));
+
+ /* ethernet broadcast/multicast packet? */
+ if (is_mac_mcast_addr(eth->dest))
+ {
+ ret |= MROUTE_EXTRACT_BCAST;
+ }
+ }
+
+ ret |= MROUTE_EXTRACT_SUCCEEDED;
#ifdef ENABLE_PF
- if (esrc || edest)
- {
- struct buffer b = *buf;
- if (buf_advance (&b, sizeof (struct openvpn_ethhdr)))
- {
- switch (ntohs (eth->proto))
- {
- case OPENVPN_ETH_P_IPV4:
- ret |= (mroute_extract_addr_ipv4 (esrc, edest, &b) << MROUTE_SEC_SHIFT);
- break;
- case OPENVPN_ETH_P_ARP:
- ret |= (mroute_extract_addr_arp (esrc, edest, &b) << MROUTE_SEC_SHIFT);
- break;
- }
- }
- }
+ if (esrc || edest)
+ {
+ struct buffer b = *buf;
+ if (buf_advance(&b, sizeof(struct openvpn_ethhdr)))
+ {
+ switch (ntohs(eth->proto))
+ {
+ case OPENVPN_ETH_P_IPV4:
+ ret |= (mroute_extract_addr_ipv4(esrc, edest, &b) << MROUTE_SEC_SHIFT);
+ break;
+
+ case OPENVPN_ETH_P_ARP:
+ ret |= (mroute_extract_addr_arp(esrc, edest, &b) << MROUTE_SEC_SHIFT);
+ break;
+ }
+ }
+ }
#endif
}
- return ret;
+ return ret;
}
/*
* Translate a struct openvpn_sockaddr (osaddr)
* to a struct mroute_addr (addr).
*/
-bool mroute_extract_openvpn_sockaddr (struct mroute_addr *addr,
- const struct openvpn_sockaddr *osaddr,
- bool use_port)
+bool
+mroute_extract_openvpn_sockaddr(struct mroute_addr *addr,
+ const struct openvpn_sockaddr *osaddr,
+ bool use_port)
{
- switch (osaddr->addr.sa.sa_family)
- {
- case AF_INET:
+ switch (osaddr->addr.sa.sa_family)
{
- if (use_port)
- {
- addr->type = MR_ADDR_IPV4 | MR_WITH_PORT;
- addr->netbits = 0;
- addr->len = 6;
- 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;
- addr->v4.addr = osaddr->addr.in4.sin_addr.s_addr;
- }
- return true;
+ case AF_INET:
+ {
+ if (use_port)
+ {
+ addr->type = MR_ADDR_IPV4 | MR_WITH_PORT;
+ addr->netbits = 0;
+ addr->len = 6;
+ 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;
+ addr->v4.addr = osaddr->addr.in4.sin_addr.s_addr;
+ }
+ return true;
+ }
+
+ case AF_INET6:
+ if (use_port)
+ {
+ addr->type = MR_ADDR_IPV6 | MR_WITH_PORT;
+ addr->netbits = 0;
+ addr->len = 18;
+ 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;
+ addr->v6.addr = osaddr->addr.in6.sin6_addr;
+ }
+ return true;
}
- case AF_INET6:
- if (use_port)
- {
- addr->type = MR_ADDR_IPV6 | MR_WITH_PORT;
- addr->netbits = 0;
- addr->len = 18;
- 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;
- addr->v6.addr = osaddr->addr.in6.sin6_addr;
- }
- return true;
- }
- return false;
+ return false;
}
/*
@@ -325,36 +344,38 @@ bool mroute_extract_openvpn_sockaddr (struct mroute_addr *addr,
* might benefit from some "zeroize 32 bit at a time" improvements
*/
void
-mroute_addr_mask_host_bits (struct mroute_addr *ma)
+mroute_addr_mask_host_bits(struct mroute_addr *ma)
{
- if ((ma->type & MR_ADDR_MASK) == MR_ADDR_IPV4)
+ if ((ma->type & MR_ADDR_MASK) == MR_ADDR_IPV4)
{
- in_addr_t addr = ntohl (ma->v4.addr);
- addr &= netbits_to_netmask (ma->netbits);
- ma->v4.addr = htonl (addr);
+ in_addr_t addr = ntohl(ma->v4.addr);
+ addr &= netbits_to_netmask(ma->netbits);
+ ma->v4.addr = htonl(addr);
}
- else if ((ma->type & MR_ADDR_MASK) == MR_ADDR_IPV6)
+ else if ((ma->type & MR_ADDR_MASK) == MR_ADDR_IPV6)
{
- int byte = sizeof (ma->v6.addr) - 1; /* rightmost byte in address */
- int bits_to_clear = 128 - ma->netbits;
+ 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 )
+ while (byte >= 0 && bits_to_clear > 0)
{
- if ( bits_to_clear >= 8 )
- {
- ma->v6.addr.s6_addr[byte--] = 0;
- bits_to_clear -= 8;
- }
- else
- {
- ma->v6.addr.s6_addr[byte--] &= (IPV4_NETMASK_HOST << bits_to_clear);
- bits_to_clear = 0;
- }
+ if (bits_to_clear >= 8)
+ {
+ ma->v6.addr.s6_addr[byte--] = 0;
+ bits_to_clear -= 8;
+ }
+ else
+ {
+ ma->v6.addr.s6_addr[byte--] &= (IPV4_NETMASK_HOST << bits_to_clear);
+ bits_to_clear = 0;
+ }
}
- ASSERT( bits_to_clear == 0 );
+ ASSERT( bits_to_clear == 0 );
+ }
+ else
+ {
+ ASSERT(0);
}
- else
- ASSERT(0);
}
/*
@@ -363,91 +384,100 @@ mroute_addr_mask_host_bits (struct mroute_addr *ma)
* and the actual address.
*/
uint32_t
-mroute_addr_hash_function (const void *key, uint32_t iv)
+mroute_addr_hash_function(const void *key, uint32_t iv)
{
- return hash_func (mroute_addr_hash_ptr ((const struct mroute_addr *) key),
- mroute_addr_hash_len ((const struct mroute_addr *) key),
- iv);
+ return hash_func(mroute_addr_hash_ptr((const struct mroute_addr *) key),
+ mroute_addr_hash_len((const struct mroute_addr *) key),
+ iv);
}
bool
-mroute_addr_compare_function (const void *key1, const void *key2)
+mroute_addr_compare_function(const void *key1, const void *key2)
{
- return mroute_addr_equal ((const struct mroute_addr *) key1,
- (const struct mroute_addr *) key2);
+ return mroute_addr_equal((const struct mroute_addr *) key1,
+ (const struct mroute_addr *) key2);
}
const char *
-mroute_addr_print (const struct mroute_addr *ma,
- struct gc_arena *gc)
+mroute_addr_print(const struct mroute_addr *ma,
+ struct gc_arena *gc)
{
- return mroute_addr_print_ex (ma, MAPF_IA_EMPTY_IF_UNDEF, gc);
+ return mroute_addr_print_ex(ma, MAPF_IA_EMPTY_IF_UNDEF, gc);
}
const char *
-mroute_addr_print_ex (const struct mroute_addr *ma,
- const unsigned int flags,
- struct gc_arena *gc)
+mroute_addr_print_ex(const struct mroute_addr *ma,
+ const unsigned int flags,
+ struct gc_arena *gc)
{
- struct buffer out = alloc_buf_gc (64, gc);
- if (ma)
+ struct buffer out = alloc_buf_gc(64, gc);
+ if (ma)
{
- struct mroute_addr maddr = *ma;
-
- switch (maddr.type & MR_ADDR_MASK)
- {
- case MR_ADDR_ETHER:
- buf_printf (&out, "%s", format_hex_ex (ma->eth_addr,
- sizeof(ma->eth_addr), 0, 1, ":", gc));
- break;
- case MR_ADDR_IPV4:
- {
- 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_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);
- }
- if (maddr.type & MR_WITH_PORT)
- {
- buf_printf (&out, ":%d", ntohs (maddr.v4.port));
- }
- }
- break;
- case MR_ADDR_IPV6:
- {
- if ( IN6_IS_ADDR_V4MAPPED( &maddr.v6.addr ) )
- {
- buf_printf (&out, "%s", print_in_addr_t (maddr.v4mappedv6.addr,
- IA_NET_ORDER, gc));
- }
- else
- {
- buf_printf (&out, "%s", print_in6_addr (maddr.v6.addr, 0, gc));
- }
- if (maddr.type & MR_WITH_NETBITS)
- {
- buf_printf (&out, "/%d", maddr.netbits);
- }
- }
- break;
- default:
- buf_printf (&out, "UNKNOWN");
- break;
- }
- return BSTR (&out);
- }
+ struct mroute_addr maddr = *ma;
+
+ switch (maddr.type & MR_ADDR_MASK)
+ {
+ case MR_ADDR_ETHER:
+ buf_printf(&out, "%s", format_hex_ex(ma->eth_addr,
+ sizeof(ma->eth_addr), 0, 1, ":", gc));
+ break;
+
+ case MR_ADDR_IPV4:
+ {
+ 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_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);
+ }
+ }
+ if (maddr.type & MR_WITH_PORT)
+ {
+ buf_printf(&out, ":%d", ntohs(maddr.v4.port));
+ }
+ }
+ break;
+
+ case MR_ADDR_IPV6:
+ {
+ if (IN6_IS_ADDR_V4MAPPED( &maddr.v6.addr ) )
+ {
+ buf_printf(&out, "%s", print_in_addr_t(maddr.v4mappedv6.addr,
+ IA_NET_ORDER, gc));
+ }
+ else
+ {
+ buf_printf(&out, "%s", print_in6_addr(maddr.v6.addr, 0, gc));
+ }
+ if (maddr.type & MR_WITH_NETBITS)
+ {
+ buf_printf(&out, "/%d", maddr.netbits);
+ }
+ }
+ break;
+
+ default:
+ buf_printf(&out, "UNKNOWN");
+ break;
+ }
+ return BSTR(&out);
+ }
else
- return "[NULL]";
- }
+ {
+ return "[NULL]";
+ }
+}
/*
* mroute_helper's main job is keeping track of
@@ -456,74 +486,82 @@ mroute_addr_print_ex (const struct mroute_addr *ma,
*/
struct mroute_helper *
-mroute_helper_init (int ageable_ttl_secs)
+mroute_helper_init(int ageable_ttl_secs)
{
- struct mroute_helper *mh;
- ALLOC_OBJ_CLEAR (mh, struct mroute_helper);
- mh->ageable_ttl_secs = ageable_ttl_secs;
- return mh;
+ struct mroute_helper *mh;
+ ALLOC_OBJ_CLEAR(mh, struct mroute_helper);
+ mh->ageable_ttl_secs = ageable_ttl_secs;
+ return mh;
}
static void
-mroute_helper_regenerate (struct mroute_helper *mh)
+mroute_helper_regenerate(struct mroute_helper *mh)
{
- int i, j = 0;
- for (i = MR_HELPER_NET_LEN - 1; i >= 0; --i)
+ int i, j = 0;
+ for (i = MR_HELPER_NET_LEN - 1; i >= 0; --i)
{
- if (mh->net_len_refcount[i] > 0)
- mh->net_len[j++] = (uint8_t) i;
+ if (mh->net_len_refcount[i] > 0)
+ {
+ mh->net_len[j++] = (uint8_t) i;
+ }
}
- mh->n_net_len = j;
+ mh->n_net_len = j;
#ifdef ENABLE_DEBUG
- if (check_debug_level (D_MULTI_DEBUG))
+ if (check_debug_level(D_MULTI_DEBUG))
{
- struct gc_arena gc = gc_new ();
- struct buffer out = alloc_buf_gc (256, &gc);
- buf_printf (&out, "MROUTE CIDR netlen:");
- for (i = 0; i < mh->n_net_len; ++i)
- {
- buf_printf (&out, " /%d", mh->net_len[i]);
- }
- dmsg (D_MULTI_DEBUG, "%s", BSTR (&out));
- gc_free (&gc);
+ struct gc_arena gc = gc_new();
+ struct buffer out = alloc_buf_gc(256, &gc);
+ buf_printf(&out, "MROUTE CIDR netlen:");
+ for (i = 0; i < mh->n_net_len; ++i)
+ {
+ buf_printf(&out, " /%d", mh->net_len[i]);
+ }
+ dmsg(D_MULTI_DEBUG, "%s", BSTR(&out));
+ gc_free(&gc);
}
#endif
}
void
-mroute_helper_add_iroute46 (struct mroute_helper *mh, int netbits)
+mroute_helper_add_iroute46(struct mroute_helper *mh, int netbits)
{
- if (netbits >= 0)
+ if (netbits >= 0)
{
- ASSERT (netbits < MR_HELPER_NET_LEN);
- ++mh->cache_generation;
- ++mh->net_len_refcount[netbits];
- if (mh->net_len_refcount[netbits] == 1)
- mroute_helper_regenerate (mh);
+ ASSERT(netbits < MR_HELPER_NET_LEN);
+ ++mh->cache_generation;
+ ++mh->net_len_refcount[netbits];
+ if (mh->net_len_refcount[netbits] == 1)
+ {
+ mroute_helper_regenerate(mh);
+ }
}
}
void
-mroute_helper_del_iroute46 (struct mroute_helper *mh, int netbits)
+mroute_helper_del_iroute46(struct mroute_helper *mh, int netbits)
{
- if (netbits >= 0)
+ if (netbits >= 0)
{
- ASSERT (netbits < MR_HELPER_NET_LEN);
- ++mh->cache_generation;
- --mh->net_len_refcount[netbits];
- ASSERT (mh->net_len_refcount[netbits] >= 0);
- if (!mh->net_len_refcount[netbits])
- mroute_helper_regenerate (mh);
+ ASSERT(netbits < MR_HELPER_NET_LEN);
+ ++mh->cache_generation;
+ --mh->net_len_refcount[netbits];
+ ASSERT(mh->net_len_refcount[netbits] >= 0);
+ if (!mh->net_len_refcount[netbits])
+ {
+ mroute_helper_regenerate(mh);
+ }
}
}
void
-mroute_helper_free (struct mroute_helper *mh)
+mroute_helper_free(struct mroute_helper *mh)
{
- free (mh);
+ free(mh);
}
-#else
-static void dummy(void) {}
+#else /* if P2MP_SERVER */
+static void
+dummy(void) {
+}
#endif /* P2MP_SERVER */