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-2022 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
mroute_addr_init(struct mroute_addr * addr)41 mroute_addr_init(struct mroute_addr *addr)
42 {
43 CLEAR(*addr);
44 }
45
46 /*
47 * Ethernet multicast addresses.
48 */
49
50 static inline bool
is_mac_mcast_addr(const uint8_t * mac)51 is_mac_mcast_addr(const uint8_t *mac)
52 {
53 return (bool) (mac[0] & 1);
54 }
55
56 static inline bool
is_mac_mcast_maddr(const struct mroute_addr * addr)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
mroute_learnable_address(const struct mroute_addr * addr,struct gc_arena * gc)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
mroute_get_in_addr_t(struct mroute_addr * ma,const in_addr_t src,unsigned int mask)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
mroute_get_in6_addr(struct mroute_addr * ma,const struct in6_addr src,unsigned int mask)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
mroute_is_mcast(const in_addr_t addr)137 mroute_is_mcast(const in_addr_t addr)
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
mroute_is_mcast_ipv6(const struct in6_addr addr)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
mroute_extract_addr_arp(struct mroute_addr * src,struct mroute_addr * dest,const struct buffer * buf)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
176 ret |= MROUTE_EXTRACT_SUCCEEDED;
177 }
178 }
179 return ret;
180 }
181
182 #endif /* ifdef ENABLE_PF */
183
184 unsigned int
mroute_extract_addr_ip(struct mroute_addr * src,struct mroute_addr * dest,const struct buffer * buf)185 mroute_extract_addr_ip(struct mroute_addr *src, struct mroute_addr *dest,
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
213 ret |= MROUTE_EXTRACT_SUCCEEDED;
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
237 ret |= MROUTE_EXTRACT_SUCCEEDED;
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
mroute_copy_ether_to_addr(struct mroute_addr * maddr,const uint8_t * ether_addr,uint16_t vid)250 mroute_copy_ether_to_addr(struct mroute_addr *maddr,
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
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)263 mroute_extract_addr_ether(struct mroute_addr *src,
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
289 ret |= MROUTE_EXTRACT_SUCCEEDED;
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 {
303 if (!buf_advance(&b, SIZE_ETH_TO_8021Q_HDR))
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
mroute_extract_openvpn_sockaddr(struct mroute_addr * addr,const struct openvpn_sockaddr * osaddr,bool use_port)336 mroute_extract_openvpn_sockaddr(struct mroute_addr *addr,
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
mroute_addr_mask_host_bits(struct mroute_addr * ma)393 mroute_addr_mask_host_bits(struct mroute_addr *ma)
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
mroute_addr_hash_function(const void * key,uint32_t iv)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
mroute_addr_compare_function(const void * key1,const void * key2)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 *
mroute_addr_print(const struct mroute_addr * ma,struct gc_arena * gc)448 mroute_addr_print(const struct mroute_addr *ma,
449 struct gc_arena *gc)
450 {
451 return mroute_addr_print_ex(ma, MAPF_IA_EMPTY_IF_UNDEF, gc);
452 }
453
454 const char *
mroute_addr_print_ex(const struct mroute_addr * ma,const unsigned int flags,struct gc_arena * gc)455 mroute_addr_print_ex(const struct mroute_addr *ma,
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 *
mroute_helper_init(int ageable_ttl_secs)543 mroute_helper_init(int ageable_ttl_secs)
544 {
545 struct mroute_helper *mh;
546 ALLOC_OBJ_CLEAR(mh, struct mroute_helper);
547 mh->ageable_ttl_secs = ageable_ttl_secs;
548 return mh;
549 }
550
551 static void
mroute_helper_regenerate(struct mroute_helper * mh)552 mroute_helper_regenerate(struct mroute_helper *mh)
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
565 if (check_debug_level(D_MULTI_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
mroute_helper_add_iroute46(struct mroute_helper * mh,int netbits)581 mroute_helper_add_iroute46(struct mroute_helper *mh, int netbits)
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 {
590 mroute_helper_regenerate(mh);
591 }
592 }
593 }
594
595 void
mroute_helper_del_iroute46(struct mroute_helper * mh,int netbits)596 mroute_helper_del_iroute46(struct mroute_helper *mh, int netbits)
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 {
606 mroute_helper_regenerate(mh);
607 }
608 }
609 }
610
611 void
mroute_helper_free(struct mroute_helper * mh)612 mroute_helper_free(struct mroute_helper *mh)
613 {
614 free(mh);
615 }
616