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