OpenVPN
mroute.c
Go to the documentation of this file.
1 /*
2  * OpenVPN -- An application to securely tunnel IP networks
3  * over a single TCP/UDP port, with support for SSL/TLS-based
4  * session authentication and key exchange,
5  * packet encryption, packet authentication, and
6  * packet compression.
7  *
8  * Copyright (C) 2002-2018 OpenVPN Inc <sales@openvpn.net>
9  *
10  * This program is free software; you can redistribute it and/or modify
11  * it under the terms of the GNU General Public License version 2
12  * as published by the Free Software Foundation.
13  *
14  * This program is distributed in the hope that it will be useful,
15  * but WITHOUT ANY WARRANTY; without even the implied warranty of
16  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17  * GNU General Public License for more details.
18  *
19  * You should have received a copy of the GNU General Public License along
20  * with this program; if not, write to the Free Software Foundation, Inc.,
21  * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
22  */
23 
24 #ifdef HAVE_CONFIG_H
25 #include "config.h"
26 #elif defined(_MSC_VER)
27 #include "config-msvc.h"
28 #endif
29 
30 #include "syshead.h"
31 
32 #if P2MP_SERVER
33 
34 #include "mroute.h"
35 #include "proto.h"
36 #include "error.h"
37 #include "socket.h"
38 
39 #include "memdbg.h"
40 
41 void
43 {
44  CLEAR(*addr);
45 }
46 
47 /*
48  * Ethernet multicast addresses.
49  */
50 
51 static inline bool
53 {
54  return (bool) (mac[0] & 1);
55 }
56 
57 static inline bool
58 is_mac_mcast_maddr(const struct mroute_addr *addr)
59 {
60  return (addr->type & MR_ADDR_MASK) == MR_ADDR_ETHER
61  && is_mac_mcast_addr(addr->eth_addr);
62 }
63 
64 /*
65  * Don't learn certain addresses.
66  */
67 bool
68 mroute_learnable_address(const struct mroute_addr *addr, struct gc_arena *gc)
69 {
70  int i;
71  bool all_zeros = true;
72  bool all_ones = true;
73 
74  for (i = 0; i < addr->len; ++i)
75  {
76  int b = addr->raw_addr[i];
77  if (b != 0x00)
78  {
79  all_zeros = false;
80  }
81  if (b != 0xFF)
82  {
83  all_ones = false;
84  }
85  }
86 
87  /* only networkss shorter than 8 bits are allowed to be all 0s. */
88  if (all_zeros
89  && !((addr->type & MR_WITH_NETBITS) && (addr->netbits < 8)))
90  {
91  msg(D_MULTI_LOW, "Can't learn %s: network is all 0s, but netbits >= 8",
92  mroute_addr_print(addr, gc));
93  return false;
94  }
95 
96  if (all_ones)
97  {
98  msg(D_MULTI_LOW, "Can't learn %s: network is all 1s",
99  mroute_addr_print(addr, gc));
100  return false;
101  }
102 
103  if (is_mac_mcast_maddr(addr))
104  {
105  msg(D_MULTI_LOW, "Can't learn %s: network is a multicast address",
106  mroute_addr_print(addr, gc));
107  return false;
108  }
109 
110  return true;
111 }
112 
113 static inline void
114 mroute_get_in_addr_t(struct mroute_addr *ma, const in_addr_t src, unsigned int mask)
115 {
116  if (ma)
117  {
118  ma->type = MR_ADDR_IPV4 | mask;
119  ma->netbits = 0;
120  ma->len = 4;
121  ma->v4.addr = src;
122  }
123 }
124 
125 static inline void
126 mroute_get_in6_addr(struct mroute_addr *ma, const struct in6_addr src, unsigned int mask)
127 {
128  if (ma)
129  {
130  ma->type = MR_ADDR_IPV6 | mask;
131  ma->netbits = 0;
132  ma->len = 16;
133  ma->v6.addr = src;
134  }
135 }
136 
137 static inline bool
139 {
140  return ((addr & htonl(IP_MCAST_SUBNET_MASK)) == htonl(IP_MCAST_NETWORK));
141 }
142 
143 /* RFC 4291, 2.7, "binary 11111111 at the start of an address identifies
144  * the address as being a multicast address"
145  */
146 static inline bool
147 mroute_is_mcast_ipv6(const struct in6_addr addr)
148 {
149  return (addr.s6_addr[0] == 0xff);
150 }
151 
152 #ifdef ENABLE_PF
153 
154 static unsigned int
155 mroute_extract_addr_arp(struct mroute_addr *src,
156  struct mroute_addr *dest,
157  const struct buffer *buf)
158 {
159  unsigned int ret = 0;
160  if (BLEN(buf) >= (int) sizeof(struct openvpn_arp))
161  {
162  const struct openvpn_arp *arp = (const struct openvpn_arp *) BPTR(buf);
163  if (arp->mac_addr_type == htons(0x0001)
164  && arp->proto_addr_type == htons(0x0800)
165  && arp->mac_addr_size == 0x06
166  && arp->proto_addr_size == 0x04)
167  {
168  mroute_get_in_addr_t(src, arp->ip_src, MR_ARP);
169  mroute_get_in_addr_t(dest, arp->ip_dest, MR_ARP);
170 
171  /* multicast packet? */
172  if (mroute_is_mcast(arp->ip_dest))
173  {
174  ret |= MROUTE_EXTRACT_MCAST;
175  }
176 
178  }
179  }
180  return ret;
181 }
182 
183 #endif /* ifdef ENABLE_PF */
184 
185 unsigned int
187  const struct buffer *buf)
188 {
189  unsigned int ret = 0;
190  if (BLEN(buf) >= 1)
191  {
192  switch (OPENVPN_IPH_GET_VER(*BPTR(buf)))
193  {
194  case 4:
195  if (BLEN(buf) >= (int) sizeof(struct openvpn_iphdr))
196  {
197  const struct openvpn_iphdr *ip = (const struct openvpn_iphdr *) BPTR(buf);
198 
199  mroute_get_in_addr_t(src, ip->saddr, 0);
200  mroute_get_in_addr_t(dest, ip->daddr, 0);
201 
202  /* multicast packet? */
203  if (mroute_is_mcast(ip->daddr))
204  {
205  ret |= MROUTE_EXTRACT_MCAST;
206  }
207 
208  /* IGMP message? */
209  if (ip->protocol == OPENVPN_IPPROTO_IGMP)
210  {
211  ret |= MROUTE_EXTRACT_IGMP;
212  }
213 
215  }
216  break;
217 
218  case 6:
219  if (BLEN(buf) >= (int) sizeof(struct openvpn_ipv6hdr))
220  {
221  const struct openvpn_ipv6hdr *ipv6 = (const struct openvpn_ipv6hdr *) BPTR(buf);
222 #if 0 /* very basic debug */
223  struct gc_arena gc = gc_new();
224  msg( M_INFO, "IPv6 packet! src=%s, dst=%s",
225  print_in6_addr( ipv6->saddr, 0, &gc ),
226  print_in6_addr( ipv6->daddr, 0, &gc ));
227  gc_free(&gc);
228 #endif
229 
230  mroute_get_in6_addr(src, ipv6->saddr, 0);
231  mroute_get_in6_addr(dest, ipv6->daddr, 0);
232 
233  if (mroute_is_mcast_ipv6(ipv6->daddr))
234  {
235  ret |= MROUTE_EXTRACT_MCAST;
236  }
237 
239  }
240  break;
241 
242  default:
243  msg(M_WARN, "IP packet with unknown IP version=%d seen",
244  OPENVPN_IPH_GET_VER(*BPTR(buf)));
245  }
246  }
247  return ret;
248 }
249 
250 unsigned int
252  struct mroute_addr *dest,
253  struct mroute_addr *esrc,
254  struct mroute_addr *edest,
255  const struct buffer *buf)
256 {
257  unsigned int ret = 0;
258  if (BLEN(buf) >= (int) sizeof(struct openvpn_ethhdr))
259  {
260  const struct openvpn_ethhdr *eth = (const struct openvpn_ethhdr *) BPTR(buf);
261  if (src)
262  {
263  src->type = MR_ADDR_ETHER;
264  src->netbits = 0;
265  src->len = 6;
266  memcpy(src->eth_addr, eth->source, sizeof(dest->eth_addr));
267  }
268  if (dest)
269  {
270  dest->type = MR_ADDR_ETHER;
271  dest->netbits = 0;
272  dest->len = 6;
273  memcpy(dest->eth_addr, eth->dest, sizeof(dest->eth_addr));
274 
275  /* ethernet broadcast/multicast packet? */
276  if (is_mac_mcast_addr(eth->dest))
277  {
278  ret |= MROUTE_EXTRACT_BCAST;
279  }
280  }
281 
283 
284 #ifdef ENABLE_PF
285  if (esrc || edest)
286  {
287  struct buffer b = *buf;
288  if (buf_advance(&b, sizeof(struct openvpn_ethhdr)))
289  {
290  switch (ntohs(eth->proto))
291  {
292  case OPENVPN_ETH_P_IPV4:
293  ret |= (mroute_extract_addr_ip(esrc, edest, &b) << MROUTE_SEC_SHIFT);
294  break;
295 
296  case OPENVPN_ETH_P_ARP:
297  ret |= (mroute_extract_addr_arp(esrc, edest, &b) << MROUTE_SEC_SHIFT);
298  break;
299  }
300  }
301  }
302 #endif
303  }
304  return ret;
305 }
306 
307 /*
308  * Translate a struct openvpn_sockaddr (osaddr)
309  * to a struct mroute_addr (addr).
310  */
311 bool
313  const struct openvpn_sockaddr *osaddr,
314  bool use_port)
315 {
316  switch (osaddr->addr.sa.sa_family)
317  {
318  case AF_INET:
319  {
320  if (use_port)
321  {
322  addr->type = MR_ADDR_IPV4 | MR_WITH_PORT;
323  addr->netbits = 0;
324  addr->len = 6;
325  addr->v4.addr = osaddr->addr.in4.sin_addr.s_addr;
326  addr->v4.port = osaddr->addr.in4.sin_port;
327  }
328  else
329  {
330  addr->type = MR_ADDR_IPV4;
331  addr->netbits = 0;
332  addr->len = 4;
333  addr->v4.addr = osaddr->addr.in4.sin_addr.s_addr;
334  }
335  return true;
336  }
337 
338  case AF_INET6:
339  if (use_port)
340  {
341  addr->type = MR_ADDR_IPV6 | MR_WITH_PORT;
342  addr->netbits = 0;
343  addr->len = 18;
344  addr->v6.addr = osaddr->addr.in6.sin6_addr;
345  addr->v6.port = osaddr->addr.in6.sin6_port;
346  }
347  else
348  {
349  addr->type = MR_ADDR_IPV6;
350  addr->netbits = 0;
351  addr->len = 16;
352  addr->v6.addr = osaddr->addr.in6.sin6_addr;
353  }
354  return true;
355  }
356  return false;
357 }
358 
359 /*
360  * Zero off the host bits in an address, leaving
361  * only the network bits, using the netbits member of
362  * struct mroute_addr as the controlling parameter.
363  *
364  * TODO: this is called for route-lookup for every yet-unhashed
365  * destination address, so for lots of active net-iroutes, this
366  * might benefit from some "zeroize 32 bit at a time" improvements
367  */
368 void
370 {
371  if ((ma->type & MR_ADDR_MASK) == MR_ADDR_IPV4)
372  {
373  in_addr_t addr = ntohl(ma->v4.addr);
374  addr &= netbits_to_netmask(ma->netbits);
375  ma->v4.addr = htonl(addr);
376  }
377  else if ((ma->type & MR_ADDR_MASK) == MR_ADDR_IPV6)
378  {
379  int byte = sizeof(ma->v6.addr) - 1; /* rightmost byte in address */
380  int bits_to_clear = 128 - ma->netbits;
381 
382  while (byte >= 0 && bits_to_clear > 0)
383  {
384  if (bits_to_clear >= 8)
385  {
386  ma->v6.addr.s6_addr[byte--] = 0;
387  bits_to_clear -= 8;
388  }
389  else
390  {
391  ma->v6.addr.s6_addr[byte--] &= (IPV4_NETMASK_HOST << bits_to_clear);
392  bits_to_clear = 0;
393  }
394  }
395  ASSERT( bits_to_clear == 0 );
396  }
397  else
398  {
399  ASSERT(0);
400  }
401 }
402 
403 /*
404  * The mroute_addr hash function takes into account the
405  * address type, number of bits in the network address,
406  * and the actual address.
407  */
408 uint32_t
410 {
411  return hash_func(mroute_addr_hash_ptr((const struct mroute_addr *) key),
412  mroute_addr_hash_len((const struct mroute_addr *) key),
413  iv);
414 }
415 
416 bool
417 mroute_addr_compare_function(const void *key1, const void *key2)
418 {
419  return mroute_addr_equal((const struct mroute_addr *) key1,
420  (const struct mroute_addr *) key2);
421 }
422 
423 const char *
425  struct gc_arena *gc)
426 {
428 }
429 
430 const char *
432  const unsigned int flags,
433  struct gc_arena *gc)
434 {
435  struct buffer out = alloc_buf_gc(64, gc);
436  if (ma)
437  {
438  struct mroute_addr maddr = *ma;
439 
440  switch (maddr.type & MR_ADDR_MASK)
441  {
442  case MR_ADDR_ETHER:
443  buf_printf(&out, "%s", format_hex_ex(ma->eth_addr,
444  sizeof(ma->eth_addr), 0, 1, ":", gc));
445  break;
446 
447  case MR_ADDR_IPV4:
448  {
449  if ((flags & MAPF_SHOW_ARP) && (maddr.type & MR_ARP))
450  {
451  buf_printf(&out, "ARP/");
452  }
453  buf_printf(&out, "%s", print_in_addr_t(ntohl(maddr.v4.addr),
454  (flags & MAPF_IA_EMPTY_IF_UNDEF) ? IA_EMPTY_IF_UNDEF : 0, gc));
455  if (maddr.type & MR_WITH_NETBITS)
456  {
457  if (flags & MAPF_SUBNET)
458  {
459  const in_addr_t netmask = netbits_to_netmask(maddr.netbits);
460  buf_printf(&out, "/%s", print_in_addr_t(netmask, 0, gc));
461  }
462  else
463  {
464  buf_printf(&out, "/%d", maddr.netbits);
465  }
466  }
467  if (maddr.type & MR_WITH_PORT)
468  {
469  buf_printf(&out, ":%d", ntohs(maddr.v4.port));
470  }
471  }
472  break;
473 
474  case MR_ADDR_IPV6:
475  {
476  if (IN6_IS_ADDR_V4MAPPED( &maddr.v6.addr ) )
477  {
478  buf_printf(&out, "%s", print_in_addr_t(maddr.v4mappedv6.addr,
479  IA_NET_ORDER, gc));
480  }
481  else
482  {
483  buf_printf(&out, "%s", print_in6_addr(maddr.v6.addr, 0, gc));
484  }
485  if (maddr.type & MR_WITH_NETBITS)
486  {
487  buf_printf(&out, "/%d", maddr.netbits);
488  }
489  }
490  break;
491 
492  default:
493  buf_printf(&out, "UNKNOWN");
494  break;
495  }
496  return BSTR(&out);
497  }
498  else
499  {
500  return "[NULL]";
501  }
502 }
503 
504 /*
505  * mroute_helper's main job is keeping track of
506  * currently used CIDR netlengths, so we don't
507  * have to cycle through all 33.
508  */
509 
510 struct mroute_helper *
512 {
513  struct mroute_helper *mh;
514  ALLOC_OBJ_CLEAR(mh, struct mroute_helper);
516  return mh;
517 }
518 
519 static void
521 {
522  int i, j = 0;
523  for (i = MR_HELPER_NET_LEN - 1; i >= 0; --i)
524  {
525  if (mh->net_len_refcount[i] > 0)
526  {
527  mh->net_len[j++] = (uint8_t) i;
528  }
529  }
530  mh->n_net_len = j;
531 
532 #ifdef ENABLE_DEBUG
534  {
535  struct gc_arena gc = gc_new();
536  struct buffer out = alloc_buf_gc(256, &gc);
537  buf_printf(&out, "MROUTE CIDR netlen:");
538  for (i = 0; i < mh->n_net_len; ++i)
539  {
540  buf_printf(&out, " /%d", mh->net_len[i]);
541  }
542  dmsg(D_MULTI_DEBUG, "%s", BSTR(&out));
543  gc_free(&gc);
544  }
545 #endif
546 }
547 
548 void
550 {
551  if (netbits >= 0)
552  {
553  ASSERT(netbits < MR_HELPER_NET_LEN);
554  ++mh->cache_generation;
555  ++mh->net_len_refcount[netbits];
556  if (mh->net_len_refcount[netbits] == 1)
557  {
559  }
560  }
561 }
562 
563 void
565 {
566  if (netbits >= 0)
567  {
568  ASSERT(netbits < MR_HELPER_NET_LEN);
569  ++mh->cache_generation;
570  --mh->net_len_refcount[netbits];
571  ASSERT(mh->net_len_refcount[netbits] >= 0);
572  if (!mh->net_len_refcount[netbits])
573  {
575  }
576  }
577 }
578 
579 void
581 {
582  free(mh);
583 }
584 
585 #else /* if P2MP_SERVER */
586 static void
587 dummy(void)
588 {
589 }
590 #endif /* P2MP_SERVER */
uint8_t type
Definition: mroute.h:80
#define MR_WITH_NETBITS
Definition: mroute.h:72
uint32_t daddr
Definition: proto.h:105
static bool mroute_is_mcast_ipv6(const struct in6_addr addr)
Definition: mroute.c:147
uint8_t protocol
Definition: proto.h:101
void mroute_addr_mask_host_bits(struct mroute_addr *ma)
Definition: mroute.c:369
static bool buf_advance(struct buffer *buf, int size)
Definition: buffer.h:622
#define IPV4_NETMASK_HOST
Definition: basic.h:35
const char * print_in6_addr(struct in6_addr a6, unsigned int flags, struct gc_arena *gc)
Definition: socket.c:2872
#define M_INFO
Definition: errlevel.h:55
#define MR_ADDR_ETHER
Definition: mroute.h:63
static void gc_free(struct gc_arena *a)
Definition: buffer.h:999
static bool check_debug_level(unsigned int level)
Definition: error.h:245
static void mroute_get_in6_addr(struct mroute_addr *ma, const struct in6_addr src, unsigned int mask)
Definition: mroute.c:126
#define MROUTE_EXTRACT_MCAST
Definition: mroute.h:42
bool mroute_addr_compare_function(const void *key1, const void *key2)
Definition: mroute.c:417
union openvpn_sockaddr::@8 addr
#define ASSERT(x)
Definition: error.h:221
static uint32_t mroute_addr_hash_len(const struct mroute_addr *a)
Definition: mroute.h:234
void mroute_helper_del_iroute46(struct mroute_helper *mh, int netbits)
Definition: mroute.c:564
#define MR_ADDR_MASK
Definition: mroute.h:66
static in_addr_t netbits_to_netmask(const int netbits)
Definition: route.h:369
uint32_t mroute_addr_hash_function(const void *key, uint32_t iv)
Definition: mroute.c:409
bool buf_printf(struct buffer *buf, const char *format,...)
Definition: buffer.c:243
#define CLEAR(x)
Definition: basic.h:33
const char * mroute_addr_print_ex(const struct mroute_addr *ma, const unsigned int flags, struct gc_arena *gc)
Definition: mroute.c:431
#define in_addr_t
Definition: config-msvc.h:103
#define MR_WITH_PORT
Definition: mroute.h:69
static void dummy(void)
Definition: comp-lz4.c:319
static bool mroute_is_mcast(const in_addr_t addr)
Definition: mroute.c:138
unsigned int cache_generation
Definition: mroute.h:131
struct mroute_addr::@0::@2 v6
uint8_t mac_addr_size
Definition: proto.h:71
#define IA_NET_ORDER
Definition: socket.h:394
#define OPENVPN_IPH_GET_VER(v)
Definition: proto.h:85
uint16_t proto
Definition: proto.h:63
#define IP_MCAST_SUBNET_MASK
Definition: mroute.h:35
struct in6_addr daddr
Definition: proto.h:120
void mroute_addr_init(struct mroute_addr *addr)
Definition: mroute.c:42
#define MROUTE_EXTRACT_IGMP
Definition: mroute.h:43
in_addr_t ip_src
Definition: proto.h:79
struct sockaddr_in6 in6
Definition: socket.h:70
list flags
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)
Definition: mroute.c:251
#define BPTR(buf)
Definition: buffer.h:124
#define IA_EMPTY_IF_UNDEF
Definition: socket.h:393
int net_len_refcount[MR_HELPER_NET_LEN]
Definition: mroute.h:135
#define MAPF_SHOW_ARP
Definition: mroute.h:158
const char * mroute_addr_print(const struct mroute_addr *ma, struct gc_arena *gc)
Definition: mroute.c:424
#define OPENVPN_ETH_P_IPV4
Definition: proto.h:60
int ageable_ttl_secs
Definition: mroute.h:132
static struct gc_arena gc_new(void)
Definition: buffer.h:991
#define ALLOC_OBJ_CLEAR(dptr, type)
Definition: buffer.h:1026
const char * print_in_addr_t(in_addr_t addr, unsigned int flags, struct gc_arena *gc)
Definition: socket.c:2852
bool mroute_extract_openvpn_sockaddr(struct mroute_addr *addr, const struct openvpn_sockaddr *osaddr, bool use_port)
Definition: mroute.c:312
#define MR_ARP
Definition: mroute.h:75
struct sockaddr_in in4
Definition: socket.h:69
#define D_MULTI_DEBUG
Definition: errlevel.h:123
unsigned __int32 uint32_t
Definition: config-msvc.h:120
uint8_t len
Definition: mroute.h:78
void mroute_helper_free(struct mroute_helper *mh)
Definition: mroute.c:580
struct in6_addr saddr
Definition: proto.h:119
#define MROUTE_EXTRACT_BCAST
Definition: mroute.h:41
char * format_hex_ex(const uint8_t *data, int size, int maxoutput, unsigned int space_break_flags, const char *separator, struct gc_arena *gc)
Definition: buffer.c:497
#define IP_MCAST_NETWORK
Definition: mroute.h:36
static bool is_mac_mcast_maddr(const struct mroute_addr *addr)
Definition: mroute.c:58
#define MAPF_IA_EMPTY_IF_UNDEF
Definition: mroute.h:157
#define OPENVPN_ETH_P_ARP
Definition: proto.h:62
uint8_t proto_addr_size
Definition: proto.h:72
static void mroute_get_in_addr_t(struct mroute_addr *ma, const in_addr_t src, unsigned int mask)
Definition: mroute.c:114
#define dmsg
Definition: error.h:174
#define MR_ADDR_IPV4
Definition: mroute.h:64
uint8_t source[OPENVPN_ETH_ALEN]
Definition: proto.h:58
Container for bidirectional cipher and HMAC key material.
Definition: crypto.h:181
uint8_t dest[OPENVPN_ETH_ALEN]
Definition: proto.h:57
#define BLEN(buf)
Definition: buffer.h:127
in_addr_t ip_dest
Definition: proto.h:81
uint8_t raw_addr[MR_MAX_ADDR_LEN]
Definition: mroute.h:84
uint16_t proto_addr_type
Definition: proto.h:70
uint32_t hash_func(const uint8_t *k, uint32_t length, uint32_t initval)
Definition: list.c:602
unsigned __int8 uint8_t
Definition: config-msvc.h:122
uint32_t saddr
Definition: proto.h:104
#define MROUTE_EXTRACT_SUCCEEDED
Definition: mroute.h:40
struct mroute_helper * mroute_helper_init(int ageable_ttl_secs)
Definition: mroute.c:511
static const uint8_t * mroute_addr_hash_ptr(const struct mroute_addr *a)
Definition: mroute.h:227
#define msg
Definition: error.h:173
Wrapper structure for dynamically allocated memory.
Definition: buffer.h:60
void mroute_helper_add_iroute46(struct mroute_helper *mh, int netbits)
Definition: mroute.c:549
uint16_t mac_addr_type
Definition: proto.h:68
#define OPENVPN_IPPROTO_IGMP
Definition: proto.h:98
int n_net_len
Definition: mroute.h:133
#define MR_ADDR_IPV6
Definition: mroute.h:65
struct buffer alloc_buf_gc(size_t size, struct gc_arena *gc)
Definition: buffer.c:88
uint8_t eth_addr[OPENVPN_ETH_ALEN]
Definition: mroute.h:85
static bool is_mac_mcast_addr(const uint8_t *mac)
Definition: mroute.c:52
#define free
Definition: cmocka.c:1850
Garbage collection arena used to keep track of dynamically allocated memory.
Definition: buffer.h:116
static void mroute_helper_regenerate(struct mroute_helper *mh)
Definition: mroute.c:520
static bool mroute_addr_equal(const struct mroute_addr *a1, const struct mroute_addr *a2)
Definition: mroute.h:209
#define MROUTE_SEC_SHIFT
Definition: mroute.h:50
#define BSTR(buf)
Definition: buffer.h:129
unsigned int mroute_extract_addr_ip(struct mroute_addr *src, struct mroute_addr *dest, const struct buffer *buf)
Definition: mroute.c:186
#define MAPF_SUBNET
Definition: mroute.h:156
uint8_t net_len[MR_HELPER_NET_LEN]
Definition: mroute.h:134
uint8_t netbits
Definition: mroute.h:81
char * dest
Definition: compat-lz4.h:431
struct sockaddr sa
Definition: socket.h:68
struct mroute_addr::@0::@3 v4mappedv6
#define D_MULTI_LOW
Definition: errlevel.h:86
#define M_WARN
Definition: error.h:96
#define MR_HELPER_NET_LEN
Definition: mroute.h:125
bool mroute_learnable_address(const struct mroute_addr *addr, struct gc_arena *gc)
Definition: mroute.c:68
struct mroute_addr::@0::@1 v4
Container for unidirectional cipher and HMAC key material.
Definition: crypto.h:151