Пример #1
0
static struct in6_addr
ifconfig_pool_handle_to_ipv6_base(const struct ifconfig_pool *pool, ifconfig_pool_handle hand)
{
    struct in6_addr ret = in6addr_any;

    /* IPv6 pools are always INDIV (--linear) */
    if (hand >= 0 && hand < pool->size_ipv6)
    {
        ret = add_in6_addr( pool->base_ipv6, hand );
    }
    return ret;
}
Пример #2
0
ifconfig_pool_handle
ifconfig_pool_acquire(struct ifconfig_pool *pool, in_addr_t *local, in_addr_t *remote, struct in6_addr *remote_ipv6, const char *common_name)
{
    int i;

    i = ifconfig_pool_find(pool, common_name);
    if (i >= 0)
    {
        struct ifconfig_pool_entry *ipe = &pool->list[i];
        ASSERT(!ipe->in_use);
        ifconfig_pool_entry_free(ipe, true);
        ipe->in_use = true;
        if (common_name)
        {
            ipe->common_name = string_alloc(common_name, NULL);
        }

        switch (pool->type)
        {
            case IFCONFIG_POOL_30NET:
            {
                in_addr_t b = pool->base + (i << 2);
                *local = b + 1;
                *remote = b + 2;
                break;
            }

            case IFCONFIG_POOL_INDIV:
            {
                in_addr_t b = pool->base + i;
                *local = 0;
                *remote = b;
                break;
            }

            default:
                ASSERT(0);
        }

        /* IPv6 pools are always INDIV (--linear) */
        if (pool->ipv6 && remote_ipv6)
        {
            *remote_ipv6 = add_in6_addr( pool->base_ipv6, i );
        }
    }
    return i;
}
Пример #3
0
/*
 * Process server, server-bridge, and client helper
 * directives after the parameters themselves have been
 * parsed and placed in struct options.
 */
void
helper_client_server (struct options *o)
{
  struct gc_arena gc = gc_new ();

#if P2MP
#if P2MP_SERVER

/*
   * Get tun/tap/null device type
   */
  const int dev = dev_type_enum (o->dev, o->dev_type);
  const int topology = o->topology;

  /* 
   *
   * HELPER DIRECTIVE for IPv6
   *
   * server-ipv6 2001:db8::/64
   *
   * EXPANDS TO:
   *
   * tun-ipv6
   * push "tun-ipv6"
   * ifconfig-ipv6 2001:db8::1 2001:db8::2
   * if !nopool: 
   *   ifconfig-ipv6-pool 2001:db8::1:0/64
   * 
   */
   if ( o->server_ipv6_defined )
     {
	if ( ! o->server_defined )
	  {
	    msg (M_USAGE, "--server-ipv6 must be used together with --server");
	  }
	if ( o->server_flags & SF_NOPOOL )
	  {
	    msg( M_USAGE, "--server-ipv6 is incompatible with 'nopool' option" );
	  }
	if ( o->ifconfig_ipv6_pool_defined )
	  {
	    msg( M_USAGE, "--server-ipv6 already defines an ifconfig-ipv6-pool, so you can't also specify --ifconfig-pool explicitly");
	  }

        /* local ifconfig is "base address + 1" and "+2" */
	o->ifconfig_ipv6_local = 
		print_in6_addr( add_in6_addr( o->server_network_ipv6, 1), 0, &o->gc );
	o->ifconfig_ipv6_remote = 
		print_in6_addr( add_in6_addr( o->server_network_ipv6, 2), 0, &o->gc );
	o->ifconfig_ipv6_netbits = o->server_netbits_ipv6;

	/* pool starts at "base address + 0x1000" - leave enough room */
	ASSERT( o->server_netbits_ipv6 <= 112 );	/* want 16 bits */

	o->ifconfig_ipv6_pool_defined = true;
	o->ifconfig_ipv6_pool_base = 
		add_in6_addr( o->server_network_ipv6, 0x1000 );
	o->ifconfig_ipv6_pool_netbits = o->server_netbits_ipv6;

	o->tun_ipv6 = true;

	push_option( o, "tun-ipv6", M_USAGE );
     }

  /*
   *
   * HELPER DIRECTIVE:
   *
   * server 10.8.0.0 255.255.255.0
   *
   * EXPANDS TO:
   *
   * mode server
   * tls-server
   * push "topology [topology]"
   *
   * if tun AND (topology == net30 OR topology == p2p):
   *   ifconfig 10.8.0.1 10.8.0.2
   *   if !nopool: 
   *     ifconfig-pool 10.8.0.4 10.8.0.251
   *   route 10.8.0.0 255.255.255.0
   *   if client-to-client:
   *     push "route 10.8.0.0 255.255.255.0"
   *   else if topology == net30:
   *     push "route 10.8.0.1"
   *
   * if tap OR (tun AND topology == subnet):
   *   ifconfig 10.8.0.1 255.255.255.0
   *   if !nopool: 
   *     ifconfig-pool 10.8.0.2 10.8.0.254 255.255.255.0
   *   push "route-gateway 10.8.0.1"
   *   if route-gateway unset:
   *     route-gateway 10.8.0.2
   */

  if (o->server_defined)
    {
      int netbits = -2;
      bool status = false;

      if (o->client)
	msg (M_USAGE, "--server and --client cannot be used together");

      if (o->server_bridge_defined || o->server_bridge_proxy_dhcp)
	msg (M_USAGE, "--server and --server-bridge cannot be used together");

      if (o->shared_secret_file)
	msg (M_USAGE, "--server and --secret cannot be used together (you must use SSL/TLS keys)");

      if (!(o->server_flags & SF_NOPOOL) && o->ifconfig_pool_defined)
	msg (M_USAGE, "--server already defines an ifconfig-pool, so you can't also specify --ifconfig-pool explicitly");

      if (!(dev == DEV_TYPE_TAP || dev == DEV_TYPE_TUN))
	msg (M_USAGE, "--server directive only makes sense with --dev tun or --dev tap");

      status = netmask_to_netbits (o->server_network, o->server_netmask, &netbits);
      if (!status)
	msg (M_USAGE, "--server directive network/netmask combination is invalid");

      if (netbits < 0)
	msg (M_USAGE, "--server directive netmask is invalid");

      if (netbits < IFCONFIG_POOL_MIN_NETBITS)
	msg (M_USAGE, "--server directive netmask allows for too many host addresses (subnet must be %s or higher)",
	     print_netmask (IFCONFIG_POOL_MIN_NETBITS, &gc));

      if (dev == DEV_TYPE_TUN)
	{
	  int pool_end_reserve = 4;

	  if (netbits > 29)
	    msg (M_USAGE, "--server directive when used with --dev tun must define a subnet of %s or lower",
		 print_netmask (29, &gc));

	  if (netbits == 29)
	    pool_end_reserve = 0;

	  o->mode = MODE_SERVER;
	  o->tls_server = true;

	  if (topology == TOP_NET30 || topology == TOP_P2P)
	    {
	      o->ifconfig_local = print_in_addr_t (o->server_network + 1, 0, &o->gc);
	      o->ifconfig_remote_netmask = print_in_addr_t (o->server_network + 2, 0, &o->gc);

	      if (!(o->server_flags & SF_NOPOOL))
		{
		  o->ifconfig_pool_defined = true;
		  o->ifconfig_pool_start = o->server_network + 4;
		  o->ifconfig_pool_end = (o->server_network | ~o->server_netmask) - pool_end_reserve;
		  ifconfig_pool_verify_range (M_USAGE, o->ifconfig_pool_start, o->ifconfig_pool_end);
		}

	      helper_add_route (o->server_network, o->server_netmask, o);
	      if (o->enable_c2c)
		push_option (o, print_opt_route (o->server_network, o->server_netmask, &o->gc), M_USAGE);
	      else if (topology == TOP_NET30)
		push_option (o, print_opt_route (o->server_network + 1, 0, &o->gc), M_USAGE);
	    }
	  else if (topology == TOP_SUBNET)
	    {
	      o->ifconfig_local = print_in_addr_t (o->server_network + 1, 0, &o->gc);
	      o->ifconfig_remote_netmask = print_in_addr_t (o->server_netmask, 0, &o->gc);

	      if (!(o->server_flags & SF_NOPOOL))
		{
		  o->ifconfig_pool_defined = true;
		  o->ifconfig_pool_start = o->server_network + 2;
		  o->ifconfig_pool_end = (o->server_network | ~o->server_netmask) - 2;
		  ifconfig_pool_verify_range (M_USAGE, o->ifconfig_pool_start, o->ifconfig_pool_end);
		}
	      o->ifconfig_pool_netmask = o->server_netmask;

	      push_option (o, print_opt_route_gateway (o->server_network + 1, &o->gc), M_USAGE);
	      if (!o->route_default_gateway)
		o->route_default_gateway = print_in_addr_t (o->server_network + 2, 0, &o->gc);
	    }
	  else
	    ASSERT (0);

	  push_option (o, print_opt_topology (topology, &o->gc), M_USAGE);
	}
      else if (dev == DEV_TYPE_TAP)
	{
	  if (netbits > 30)
	    msg (M_USAGE, "--server directive when used with --dev tap must define a subnet of %s or lower",
		 print_netmask (30, &gc));

	  o->mode = MODE_SERVER;
	  o->tls_server = true;
	  o->ifconfig_local = print_in_addr_t (o->server_network + 1, 0, &o->gc);
	  o->ifconfig_remote_netmask = print_in_addr_t (o->server_netmask, 0, &o->gc);

	  if (!(o->server_flags & SF_NOPOOL))
	    {
	      o->ifconfig_pool_defined = true;
	      o->ifconfig_pool_start = o->server_network + 2;
	      o->ifconfig_pool_end = (o->server_network | ~o->server_netmask) - 1;
	      ifconfig_pool_verify_range (M_USAGE, o->ifconfig_pool_start, o->ifconfig_pool_end);
	    }
	  o->ifconfig_pool_netmask = o->server_netmask;

	  push_option (o, print_opt_route_gateway (o->server_network + 1, &o->gc), M_USAGE);
	}
      else
	{
	  ASSERT (0);
	}

      /* set push-ifconfig-constraint directive */
      if ((dev == DEV_TYPE_TAP || topology == TOP_SUBNET))
	{
	  o->push_ifconfig_constraint_defined = true;
	  o->push_ifconfig_constraint_network = o->server_network;
	  o->push_ifconfig_constraint_netmask = o->server_netmask;
	}
    }

  /*
   * HELPER DIRECTIVE:
   *
   * server-bridge 10.8.0.4 255.255.255.0 10.8.0.128 10.8.0.254
   *
   * EXPANDS TO:
   *
   * mode server
   * tls-server
   *
   * ifconfig-pool 10.8.0.128 10.8.0.254 255.255.255.0
   * push "route-gateway 10.8.0.4"
   *
   * OR
   *
   * server-bridge
   *
   * EXPANDS TO:
   *
   * mode server
   * tls-server
   *
   * if !nogw:
   *   push "route-gateway dhcp"
   */
  else if (o->server_bridge_defined | o->server_bridge_proxy_dhcp)
    {
      if (o->client)
	msg (M_USAGE, "--server-bridge and --client cannot be used together");

      if (!(o->server_flags & SF_NOPOOL) && o->ifconfig_pool_defined)
	msg (M_USAGE, "--server-bridge already defines an ifconfig-pool, so you can't also specify --ifconfig-pool explicitly");

      if (o->shared_secret_file)
	msg (M_USAGE, "--server-bridge and --secret cannot be used together (you must use SSL/TLS keys)");

      if (dev != DEV_TYPE_TAP)
	msg (M_USAGE, "--server-bridge directive only makes sense with --dev tap");

      if (o->server_bridge_defined)
	{
	  verify_common_subnet ("--server-bridge", o->server_bridge_ip, o->server_bridge_pool_start, o->server_bridge_netmask); 
	  verify_common_subnet ("--server-bridge", o->server_bridge_pool_start, o->server_bridge_pool_end, o->server_bridge_netmask); 
	  verify_common_subnet ("--server-bridge", o->server_bridge_ip, o->server_bridge_pool_end, o->server_bridge_netmask); 
	}

      o->mode = MODE_SERVER;
      o->tls_server = true;

      if (o->server_bridge_defined)
	{
	  o->ifconfig_pool_defined = true;
	  o->ifconfig_pool_start = o->server_bridge_pool_start;
	  o->ifconfig_pool_end = o->server_bridge_pool_end;
	  ifconfig_pool_verify_range (M_USAGE, o->ifconfig_pool_start, o->ifconfig_pool_end);
	  o->ifconfig_pool_netmask = o->server_bridge_netmask;
	  push_option (o, print_opt_route_gateway (o->server_bridge_ip, &o->gc), M_USAGE);
	}
      else if (o->server_bridge_proxy_dhcp && !(o->server_flags & SF_NO_PUSH_ROUTE_GATEWAY))
	{
	  push_option (o, print_opt_route_gateway_dhcp (&o->gc), M_USAGE);
	}
    }
  else
#endif /* P2MP_SERVER */

  /*
   * HELPER DIRECTIVE:
   *
   * client
   *
   * EXPANDS TO:
   *
   * pull
   * tls-client
   */
  if (o->client)
    {
      if (o->key_method != 2)
	msg (M_USAGE, "--client requires --key-method 2");

      o->pull = true;
      o->tls_client = true;
    }

#endif /* P2MP */

  gc_free (&gc);
}