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