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