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