Example #1
0
static int setup_prefix_delegation(struct connman_service *service)
{
	struct connman_ipconfig *ipconfig;
	char *interface;
	int err = 0, ifindex;

	if (service == NULL) {
		/*
		 * We do not have uplink connection. We just wait until
		 * default interface is updated.
		 */
		return -EINPROGRESS;
	}

	interface = connman_service_get_interface(service);

	DBG("interface %s bridge_index %d", interface, bridge_index);

	if (default_interface != NULL) {
		stop_ra(bridge_index);

		ifindex = connman_inet_ifindex(default_interface);
		__connman_dhcpv6_stop_pd(ifindex);
	}

	g_free(default_interface);

	ipconfig = __connman_service_get_ip6config(service);
	if (__connman_ipconfig_ipv6_is_enabled(ipconfig) == FALSE) {
		g_free(interface);
		default_interface = NULL;
		return -EPFNOSUPPORT;
	}

	default_interface = interface;

	if (default_interface != NULL) {
		ifindex = connman_inet_ifindex(default_interface);

		/*
		 * Try to get a IPv6 prefix so we can start to advertise it.
		 */
		err = __connman_dhcpv6_start_pd(ifindex, prefixes,
						dhcpv6_callback);
		if (err < 0)
			DBG("prefix delegation %d/%s", err, strerror(-err));
	}

	return err;
}
Example #2
0
static GDHCPServer *dhcp_server_start(const char *bridge,
				const char *router, const char* subnet,
				const char *start_ip, const char *end_ip,
				unsigned int lease_time, const char *dns)
{
	GDHCPServerError error;
	GDHCPServer *dhcp_server;
	int index;

	DBG("");

	index = connman_inet_ifindex(bridge);
	if (index < 0)
		return NULL;

	dhcp_server = g_dhcp_server_new(G_DHCP_IPV4, index, &error);
	if (dhcp_server == NULL) {
		dhcp_server_error(error);
		return NULL;
	}

	g_dhcp_server_set_debug(dhcp_server, dhcp_server_debug, "DHCP server");

	g_dhcp_server_set_lease_time(dhcp_server, lease_time);
	g_dhcp_server_set_option(dhcp_server, G_DHCP_SUBNET, subnet);
	g_dhcp_server_set_option(dhcp_server, G_DHCP_ROUTER, router);
	g_dhcp_server_set_option(dhcp_server, G_DHCP_DNS_SERVER, dns);
	g_dhcp_server_set_ip_range(dhcp_server, start_ip, end_ip);

	g_dhcp_server_start(dhcp_server);

	return dhcp_server;
}
Example #3
0
static connman_bool_t pan_connect(struct bluetooth_pan *pan,
		const char *iface)
{
	int index;

	if (iface == NULL) {
		if (proxy_get_bool(pan->btnetwork_proxy, "Connected") == FALSE)
			return FALSE;
		iface = proxy_get_string(pan->btnetwork_proxy, "Interface");
	}

	if (iface == NULL)
		return FALSE;

	index = connman_inet_ifindex(iface);
	if (index < 0) {
		DBG("network %p invalid index %d", pan->network, index);
		return FALSE;
	}

	connman_network_set_index(pan->network, index);
	connman_network_set_connected(pan->network, TRUE);

	return TRUE;
}
Example #4
0
static void update_ipconfig(struct connman_service *service,
				struct connman_ipconfig *ipconfig)
{
	if (service == NULL || service != __connman_service_get_default())
		return;

	if (ipconfig != __connman_service_get_ip6config(service))
		return;

	if (__connman_ipconfig_ipv6_is_enabled(ipconfig) == FALSE) {
		if (default_interface != NULL) {
			int ifindex;

			ifindex = connman_inet_ifindex(default_interface);
			__connman_dhcpv6_stop_pd(ifindex);

			g_free(default_interface);
			default_interface = NULL;
		}
		DBG("No IPv6 support for interface %s",
				__connman_ipconfig_get_ifname(ipconfig));
		return;
	}

	/*
	 * Did we had PD activated already? If not, then start it.
	 */
	if (default_interface == NULL) {
		DBG("IPv6 ipconfig %p changed for interface %s", ipconfig,
			__connman_ipconfig_get_ifname(ipconfig));

		setup_prefix_delegation(service);
	}
}
Example #5
0
static gboolean resolver_refresh_cb(gpointer user_data)
{
	struct entry_data *entry = user_data;
	int index;
	unsigned int interval;
	struct connman_service *service = NULL;

	/* Round up what we have left from lifetime */
	interval = entry->lifetime *
		(1 - RESOLVER_LIFETIME_REFRESH_THRESHOLD) + 1.0;

	DBG("RDNSS start interface %s domain %s "
			"server %s remaining lifetime %d",
			entry->interface, entry->domain,
			entry->server, interval);

	entry->timeout = g_timeout_add_seconds(interval,
			resolver_expire_cb, entry);

	index = connman_inet_ifindex(entry->interface);
	if (index >= 0) {
		service = __connman_service_lookup_from_index(index);
		if (service != NULL) {
			/*
			 * Send Router Solicitation to refresh RDNSS entries
			 * before their lifetime expires
			 */
			__connman_refresh_rs_ipv6(
					__connman_service_get_network(service),
					index);
		}
	}
	return FALSE;
}
Example #6
0
void __connman_ipv6pd_cleanup(void)
{
	int ifindex;

	if (connman_inet_is_ipv6_supported() == FALSE)
		return;

	connman_notifier_unregister(&pd_notifier);

	__connman_inet_ipv6_stop_recv_rs(rs_context);
	rs_context = NULL;

	cleanup();

	stop_ra(bridge_index);

	if (default_interface != NULL) {
		ifindex = connman_inet_ifindex(default_interface);
		__connman_dhcpv6_stop_pd(ifindex);
		g_free(default_interface);
		default_interface = NULL;
	}

	bridge_index = -1;
}
Example #7
0
static void connect_reply(DBusPendingCall *call, void *user_data)
{
	char *path = user_data;
	struct connman_network *network;
	DBusMessage *reply;
	DBusError error;
	const char *interface = NULL;
	int index;

	network = g_hash_table_lookup(bluetooth_networks, path);
	if (!network)
		return;

	DBG("network %p", network);

	reply = dbus_pending_call_steal_reply(call);

	dbus_error_init(&error);

	if (dbus_set_error_from_message(&error, reply)) {
		connman_error("%s", error.message);
		dbus_error_free(&error);

		goto err;
	}

	if (!dbus_message_get_args(reply, &error, DBUS_TYPE_STRING,
					&interface, DBUS_TYPE_INVALID)) {
		if (dbus_error_is_set(&error)) {
			connman_error("%s", error.message);
			dbus_error_free(&error);
		} else
			connman_error("Wrong arguments for connect");
		goto err;
	}

	if (!interface)
		goto err;

	DBG("interface %s", interface);

	index = connman_inet_ifindex(interface);

	connman_network_set_index(network, index);

	connman_network_set_connected(network, true);

	dbus_message_unref(reply);

	dbus_pending_call_unref(call);

	return;
err:

	connman_network_set_connected(network, false);

	dbus_message_unref(reply);

	dbus_pending_call_unref(call);
}
Example #8
0
void __connman_tethering_set_disabled(void)
{
	int index;

	DBG("enabled %d", tethering_enabled - 1);

	__connman_ipv6pd_cleanup();

	index = connman_inet_ifindex(BRIDGE_NAME);
	__connman_dnsproxy_remove_listener(index);

	if (__sync_fetch_and_sub(&tethering_enabled, 1) != 1)
		return;

	__connman_nat_disable(BRIDGE_NAME);

	dhcp_server_stop(tethering_dhcp_server);

	tethering_dhcp_server = NULL;

	__connman_bridge_disable(BRIDGE_NAME);

	__connman_ippool_unref(dhcp_ippool);

	__connman_bridge_remove(BRIDGE_NAME);

	g_free(private_network_primary_dns);
	private_network_primary_dns = NULL;
	g_free(private_network_secondary_dns);
	private_network_secondary_dns = NULL;

	DBG("tethering stopped");
}
Example #9
0
static bool pan_connect(struct bluetooth_pan *pan,
		const char *iface)
{
	int index;

	if (!iface) {
		if (!proxy_get_bool(pan->btnetwork_proxy, "Connected"))
			return false;
		iface = proxy_get_string(pan->btnetwork_proxy, "Interface");
	}

	if (!iface)
		return false;

	index = connman_inet_ifindex(iface);
	if (index < 0) {
		DBG("network %p invalid index %d", pan->network, index);
		return false;
	}

	connman_network_set_index(pan->network, index);
	connman_network_set_connected(pan->network, true);

	return true;
}
Example #10
0
static int append_resolver(const char *interface, const char *domain,
				const char *server, unsigned int lifetime,
							unsigned int flags)
{
	struct entry_data *entry;
	unsigned int interval;

	DBG("interface %s domain %s server %s lifetime %d flags %d",
				interface, domain, server, lifetime, flags);

	if (server == NULL && domain == NULL)
		return -EINVAL;

	entry = g_try_new0(struct entry_data, 1);
	if (entry == NULL)
		return -ENOMEM;

	entry->interface = g_strdup(interface);
	entry->domain = g_strdup(domain);
	entry->server = g_strdup(server);
	entry->flags = flags;
	entry->lifetime = lifetime;

	if (server != NULL)
		entry->family = connman_inet_check_ipaddress(server);

	if (lifetime) {
		int index;
		interval = lifetime * RESOLVER_LIFETIME_REFRESH_THRESHOLD;

		DBG("RDNSS start interface %s domain %s "
				"server %s lifetime threshold %d",
				interface, domain, server, interval);

		entry->timeout = g_timeout_add_seconds(interval,
				resolver_refresh_cb, entry);

		/*
		 * We update the service only for those nameservers
		 * that are automagically added via netlink (lifetime > 0)
		 */
		index = connman_inet_ifindex(interface);
		if (server != NULL && index >= 0) {
			struct connman_service *service;
			service = __connman_service_lookup_from_index(index);
			if (service != NULL)
				__connman_service_nameserver_append(service,
								server, TRUE);
		}
	}
	entry_list = g_slist_append(entry_list, entry);

	if (dnsproxy_enabled == TRUE)
		__connman_dnsproxy_append(interface, domain, server);
	else
		__connman_resolvfile_append(interface, domain, server);

	return 0;
}
Example #11
0
static void connect_reply(DBusPendingCall *call, void *user_data)
{
	struct connman_network *network = user_data;
	DBusMessage *reply;
	DBusError error;
	const char *interface = NULL;
	int index;

	DBG("network %p", network);

	reply = dbus_pending_call_steal_reply(call);

	dbus_error_init(&error);

	if (dbus_set_error_from_message(&error, reply) == TRUE) {
		connman_error("%s", error.message);
		dbus_error_free(&error);

		goto err;
	}

	if (dbus_message_get_args(reply, &error,
					DBUS_TYPE_STRING, &interface,
						DBUS_TYPE_INVALID) == FALSE) {
		if (dbus_error_is_set(&error) == TRUE) {
			connman_error("%s", error.message);
			dbus_error_free(&error);
		} else
			connman_error("Wrong arguments for connect");
		goto err;
	}

	if (interface == NULL)
		goto err;

	DBG("interface %s", interface);

	index = connman_inet_ifindex(interface);

	connman_network_set_index(network, index);

	connman_network_set_connected(network, TRUE);

	dbus_message_unref(reply);

	dbus_pending_call_unref(call);

	return;
err:

	connman_network_set_connected(network, FALSE);

	dbus_message_unref(reply);

	dbus_pending_call_unref(call);
}
Example #12
0
int __connman_bridge_disable(const char *name)
{
	int index;

	index = connman_inet_ifindex(name);
	if (index < 0)
		return index;

	return connman_inet_ifdown(index);
}
Example #13
0
static int enable_bridge(const char *name)
{
	int err, index;

	index = connman_inet_ifindex(name);
	if (index < 0)
		return index;

	err = __connman_inet_modify_address(RTM_NEWADDR,
			NLM_F_REPLACE | NLM_F_ACK, index, AF_INET,
					BRIDGE_IP, NULL, 24, BRIDGE_BCAST);
	if (err < 0)
		return err;

	return connman_inet_ifup(index);
}
Example #14
0
static int append_resolver(const char *interface, const char *domain,
				const char *server, unsigned int lifetime,
							unsigned int flags)
{
	struct entry_data *entry;

	DBG("interface %s domain %s server %s lifetime %d flags %d",
				interface, domain, server, lifetime, flags);

	if (server == NULL && domain == NULL)
		return -EINVAL;

	entry = g_try_new0(struct entry_data, 1);
	if (entry == NULL)
		return -ENOMEM;

	entry->interface = g_strdup(interface);
	entry->domain = g_strdup(domain);
	entry->server = g_strdup(server);
	entry->flags = flags;
	if (lifetime) {
		int index;
		entry->timeout = g_timeout_add_seconds(lifetime,
						resolver_expire_cb, entry);

		/*
		 * We update the service only for those nameservers
		 * that are automagically added via netlink (lifetime > 0)
		 */
		index = connman_inet_ifindex(interface);
		if (index >= 0) {
			struct connman_service *service;
			service = __connman_service_lookup_from_index(index);
			if (service != NULL)
				__connman_service_nameserver_append(service,
								server, TRUE);
		}
	}
	entry_list = g_slist_append(entry_list, entry);

	if (dnsproxy_enabled == TRUE)
		__connman_dnsproxy_append(interface, domain, server);
	else
		__connman_resolvfile_append(interface, domain, server);

	return 0;
}
Example #15
0
static void cleanup_devices(void)
{
	/*
	 * Check what interfaces are currently up and if connman is
	 * suppose to handle the interface, then cleanup the mess
	 * related to that interface. There might be weird routes etc
	 * that are related to that interface and that might confuse
	 * connmand. So in this case we just turn the interface down
	 * so that kernel removes routes/addresses automatically and
	 * then proceed the startup.
	 *
	 * Note that this cleanup must be done before rtnl/detect code
	 * has activated interface watches.
	 */

	char **interfaces;
	int i;

	interfaces = __connman_inet_get_running_interfaces();

	if (interfaces == NULL)
		return;

	for (i = 0; interfaces[i] != NULL; i++) {
		connman_bool_t filtered;
		int index;

		filtered = __connman_device_isfiltered(interfaces[i]);
		if (filtered == TRUE)
			continue;

		index = connman_inet_ifindex(interfaces[i]);
		if (index < 0)
			continue;

		DBG("cleaning up %s index %d", interfaces[i], index);

		connman_inet_ifdown(index);

		/*
		 * ConnMan will turn the interface UP automatically so
		 * no need to do it here.
		 */
	}

	g_strfreev(interfaces);
}
Example #16
0
int __connman_bridge_enable(const char *name, const char *gateway,
				const char *broadcast)
{
	int err, index;

	index = connman_inet_ifindex(name);
	if (index < 0)
		return index;

	err = __connman_inet_modify_address(RTM_NEWADDR,
			NLM_F_REPLACE | NLM_F_ACK, index, AF_INET,
					gateway, NULL, 24, broadcast);
	if (err < 0)
		return err;

	return connman_inet_ifup(index);
}
Example #17
0
int __connman_ipv6pd_setup(const char *bridge)
{
	struct connman_service *service;
	int err;

	if (connman_inet_is_ipv6_supported() == FALSE)
		return -EPFNOSUPPORT;

	if (bridge_index >= 0) {
		DBG("Prefix delegation already running");
		return -EALREADY;
	}

	err = connman_notifier_register(&pd_notifier);
	if (err < 0)
		return err;

	bridge_index = connman_inet_ifindex(bridge);

	timer_hash = g_hash_table_new_full(g_direct_hash, g_direct_equal,
						NULL, cleanup_timer);

	err = __connman_inet_ipv6_start_recv_rs(bridge_index, rs_received,
						NULL, &rs_context);
	if (err < 0)
		DBG("Cannot receive router solicitation %d/%s",
			err, strerror(-err));

	service = __connman_service_get_default();
	if (service != NULL) {
		/*
		 * We have an uplink connection already, try to use it.
		 */
		return setup_prefix_delegation(service);
	}

	/*
	 * The prefix delegation is started after have got the uplink
	 * connection up i.e., when the default service is setup in which
	 * case the update_default_interface() will be called.
	 */
	return -EINPROGRESS;
}
Example #18
0
int vpn_set_ifname(struct connman_provider *provider, const char *ifname)
{
    struct vpn_data *data = connman_provider_get_data(provider);
    int index;

    if (ifname == NULL || data == NULL)
        return  -EIO;

    index = connman_inet_ifindex(ifname);
    if (index < 0)
        return  -EIO;

    if (data->if_name != NULL)
        g_free(data->if_name);

    data->if_name = (char *)g_strdup(ifname);
    connman_provider_set_index(provider, index);

    return 0;
}
Example #19
0
static gboolean resolver_expire_cb(gpointer user_data)
{
	struct entry_data *entry = user_data;
	GSList *list;
	int index;

	DBG("interface %s domain %s server %s",
			entry->interface, entry->domain, entry->server);

	list = g_slist_append(NULL, entry);

	index = connman_inet_ifindex(entry->interface);
	if (index >= 0) {
		struct connman_service *service;
		service = __connman_service_lookup_from_index(index);
		if (service != NULL)
			__connman_service_nameserver_remove(service,
							entry->server, TRUE);
	}

	remove_entries(list);

	return FALSE;
}
Example #20
0
static int vpn_create_tun(struct connman_provider *provider)
{
    struct vpn_data *data = connman_provider_get_data(provider);
    struct ifreq ifr;
    int i, fd, index;
    int ret = 0;

    if (data == NULL)
        return -EISCONN;

    fd = open("/dev/net/tun", O_RDWR | O_CLOEXEC);
    if (fd < 0) {
        i = -errno;
        connman_error("Failed to open /dev/net/tun: %s",
                      strerror(errno));
        ret = i;
        goto exist_err;
    }

    memset(&ifr, 0, sizeof(ifr));
    ifr.ifr_flags = IFF_TUN | IFF_NO_PI;

    for (i = 0; i < 256; i++) {
        sprintf(ifr.ifr_name, "vpn%d", i);

        if (!ioctl(fd, TUNSETIFF, (void *)&ifr))
            break;
    }

    if (i == 256) {
        connman_error("Failed to find available tun device");
        close(fd);
        ret = -ENODEV;
        goto exist_err;
    }

    data->if_name = (char *)g_strdup(ifr.ifr_name);
    if (data->if_name == NULL) {
        connman_error("Failed to allocate memory");
        close(fd);
        ret = -ENOMEM;
        goto exist_err;
    }

    if (ioctl(fd, TUNSETPERSIST, 1)) {
        i = -errno;
        connman_error("Failed to set tun persistent: %s",
                      strerror(errno));
        close(fd);
        ret = i;
        goto exist_err;
    }

    close(fd);

    index = connman_inet_ifindex(data->if_name);
    if (index < 0) {
        connman_error("Failed to get tun ifindex");
        stop_vpn(provider);
        ret = -EIO;
        goto exist_err;
    }
    connman_provider_set_index(provider, index);

    return 0;

exist_err:
    return ret;
}
Example #21
0
File: wispr.c Project: igaw/connman
static int wispr_portal_detect(struct connman_wispr_portal_context *wp_context)
{
	enum connman_service_proxy_method proxy_method;
	enum connman_service_type service_type;
	char *interface = NULL;
	char **nameservers = NULL;
	int if_index;
	int err = 0;
	int i;

	DBG("wispr/portal context %p service %p", wp_context,
		wp_context->service);

	service_type = connman_service_get_type(wp_context->service);

	switch (service_type) {
	case CONNMAN_SERVICE_TYPE_ETHERNET:
	case CONNMAN_SERVICE_TYPE_WIFI:
	case CONNMAN_SERVICE_TYPE_BLUETOOTH:
	case CONNMAN_SERVICE_TYPE_CELLULAR:
	case CONNMAN_SERVICE_TYPE_GADGET:
		break;
	case CONNMAN_SERVICE_TYPE_UNKNOWN:
	case CONNMAN_SERVICE_TYPE_SYSTEM:
	case CONNMAN_SERVICE_TYPE_GPS:
	case CONNMAN_SERVICE_TYPE_VPN:
	case CONNMAN_SERVICE_TYPE_P2P:
		return -EOPNOTSUPP;
	}

	interface = connman_service_get_interface(wp_context->service);
	if (!interface)
		return -EINVAL;

	DBG("interface %s", interface);

	if_index = connman_inet_ifindex(interface);
	if (if_index < 0) {
		DBG("Could not get ifindex");
		err = -EINVAL;
		goto done;
	}

	nameservers = connman_service_get_nameservers(wp_context->service);
	if (!nameservers) {
		DBG("Could not get nameservers");
		err = -EINVAL;
		goto done;
	}

	wp_context->web = g_web_new(if_index);
	if (!wp_context->web) {
		DBG("Could not set up GWeb");
		err = -ENOMEM;
		goto done;
	}

	if (getenv("CONNMAN_WEB_DEBUG"))
		g_web_set_debug(wp_context->web, web_debug, "WEB");

	if (wp_context->type == CONNMAN_IPCONFIG_TYPE_IPV4) {
		g_web_set_address_family(wp_context->web, AF_INET);
		wp_context->status_url = STATUS_URL_IPV4;
	} else {
		g_web_set_address_family(wp_context->web, AF_INET6);
		wp_context->status_url = STATUS_URL_IPV6;
	}

	for (i = 0; nameservers[i]; i++)
		g_web_add_nameserver(wp_context->web, nameservers[i]);

	proxy_method = connman_service_get_proxy_method(wp_context->service);

	if (proxy_method != CONNMAN_SERVICE_PROXY_METHOD_DIRECT) {
		wp_context->token = connman_proxy_lookup(interface,
						wp_context->status_url,
						wp_context->service,
						proxy_callback, wp_context);

		if (wp_context->token == 0) {
			err = -EINVAL;
			free_connman_wispr_portal_context(wp_context);
		}
	} else if (wp_context->timeout == 0) {
		wp_context->timeout = g_idle_add(no_proxy_callback, wp_context);
	}

done:
	g_strfreev(nameservers);

	g_free(interface);
	return err;
}
Example #22
0
int __connman_private_network_request(DBusMessage *msg, const char *owner)
{
	struct connman_private_network *pn;
	char *iface = NULL;
	char *path = NULL;
	int index, fd, err;

	if (DBUS_TYPE_UNIX_FD < 0)
		return -EINVAL;

	fd = connman_inet_create_tunnel(&iface);
	if (fd < 0)
		return fd;

	path = g_strdup_printf("/tethering/%s", iface);

	pn = g_hash_table_lookup(pn_hash, path);
	if (pn) {
		g_free(path);
		g_free(iface);
		close(fd);
		return -EEXIST;
	}

	index = connman_inet_ifindex(iface);
	if (index < 0) {
		err = -ENODEV;
		goto error;
	}
	DBG("interface %s", iface);

	err = connman_inet_set_mtu(index, DEFAULT_MTU);

	pn = g_try_new0(struct connman_private_network, 1);
	if (pn == NULL) {
		err = -ENOMEM;
		goto error;
	}

	pn->owner = g_strdup(owner);
	pn->path = path;
	pn->watch = g_dbus_add_disconnect_watch(connection, pn->owner,
					owner_disconnect, pn, NULL);
	pn->msg = msg;
	pn->reply = dbus_message_new_method_return(pn->msg);
	if (pn->reply == NULL)
		goto error;

	pn->fd = fd;
	pn->interface = iface;
	pn->index = index;
	pn->server_ip = PRIVATE_NETWORK_IP;
	pn->peer_ip = PRIVATE_NETWORK_PEER_IP;
	pn->primary_dns = PRIVATE_NETWORK_PRIMARY_DNS;
	pn->secondary_dns = PRIVATE_NETWORK_SECONDARY_DNS;

	pn->iface_watch = connman_rtnl_add_newlink_watch(index,
						setup_tun_interface, pn);

	g_hash_table_insert(pn_hash, pn->path, pn);

	return 0;

error:
	close(fd);
	g_free(iface);
	g_free(path);
	g_free(pn);
	return err;
}
Example #23
0
static void cleanup_devices(void)
{
	/*
	 * Check what interfaces are currently up and if connman is
	 * suppose to handle the interface, then cleanup the mess

         * related to that interface. There might be weird routes etc
	 * that are related to that interface and that might confuse
	 * connmand. So in this case we just turn the interface down
	 * so that kernel removes routes/addresses automatically and
	 * then proceed the startup.
	 *
	 * Note that this cleanup must be done before rtnl/detect code
	 * has activated interface watches.
	 */

	char **interfaces;
	int i;

	interfaces = __connman_inet_get_running_interfaces();

	if (!interfaces)
		return;

	for (i = 0; interfaces[i]; i++) {
		bool filtered;
		int index;
		struct sockaddr_in sin_addr, sin_mask;

		filtered = __connman_device_isfiltered(interfaces[i]);
		if (filtered)
			continue;

		index = connman_inet_ifindex(interfaces[i]);
		if (index < 0)
			continue;

		if (!__connman_inet_get_address_netmask(index, &sin_addr,
							&sin_mask)) {
			char *address = g_strdup(inet_ntoa(sin_addr.sin_addr));
			char *netmask = g_strdup(inet_ntoa(sin_mask.sin_addr));

			if (__connman_config_address_provisioned(address,
								netmask)) {
				DBG("Skip %s which is already provisioned "
					"with %s/%s", interfaces[i], address,
					netmask);
				g_free(address);
				g_free(netmask);
				continue;
			}

			g_free(address);
			g_free(netmask);
		}

		DBG("cleaning up %s index %d", interfaces[i], index);

		connman_inet_ifdown(index);

		/*
		 * ConnMan will turn the interface UP automatically so
		 * no need to do it here.
		 */
	}

	g_strfreev(interfaces);
}
Example #24
0
void __connman_tethering_set_enabled(void)
{
	int index;
	int err;
	const char *gateway;
	const char *broadcast;
	const char *subnet_mask;
	const char *start_ip;
	const char *end_ip;
	const char *dns;
	unsigned char prefixlen;
	char **ns;

	DBG("enabled %d", tethering_enabled + 1);

	if (__sync_fetch_and_add(&tethering_enabled, 1) != 0)
		return;

	err = __connman_bridge_create(BRIDGE_NAME);
	if (err < 0) {
		__sync_fetch_and_sub(&tethering_enabled, 1);
		return;
	}

	index = connman_inet_ifindex(BRIDGE_NAME);
	dhcp_ippool = __connman_ippool_create(index, 2, 252,
						tethering_restart, NULL);
	if (dhcp_ippool == NULL) {
		connman_error("Fail to create IP pool");
		__connman_bridge_remove(BRIDGE_NAME);
		__sync_fetch_and_sub(&tethering_enabled, 1);
		return;
	}

	gateway = __connman_ippool_get_gateway(dhcp_ippool);
	broadcast = __connman_ippool_get_broadcast(dhcp_ippool);
	subnet_mask = __connman_ippool_get_subnet_mask(dhcp_ippool);
	start_ip = __connman_ippool_get_start_ip(dhcp_ippool);
	end_ip = __connman_ippool_get_end_ip(dhcp_ippool);

	err = __connman_bridge_enable(BRIDGE_NAME, gateway,
			__connman_ipaddress_netmask_prefix_len(subnet_mask),
			broadcast);
	if (err < 0 && err != -EALREADY) {
		__connman_ippool_unref(dhcp_ippool);
		__connman_bridge_remove(BRIDGE_NAME);
		__sync_fetch_and_sub(&tethering_enabled, 1);
		return;
	}

	ns = connman_setting_get_string_list("FallbackNameservers");
	if (ns != NULL) {
		if (ns[0] != NULL) {
			g_free(private_network_primary_dns);
			private_network_primary_dns = g_strdup(ns[0]);
		}
		if (ns[1] != NULL) {
			g_free(private_network_secondary_dns);
			private_network_secondary_dns = g_strdup(ns[1]);
		}

		DBG("Fallback ns primary %s secondary %s",
			private_network_primary_dns,
			private_network_secondary_dns);
	}

	dns = gateway;
	if (__connman_dnsproxy_add_listener(index) < 0) {
		connman_error("Can't add listener %s to DNS proxy",
								BRIDGE_NAME);
		dns = private_network_primary_dns;
		DBG("Serving %s nameserver to clients", dns);
	}

	tethering_dhcp_server = dhcp_server_start(BRIDGE_NAME,
						gateway, subnet_mask,
						start_ip, end_ip,
						24 * 3600, dns);
	if (tethering_dhcp_server == NULL) {
		__connman_bridge_disable(BRIDGE_NAME);
		__connman_ippool_unref(dhcp_ippool);
		__connman_bridge_remove(BRIDGE_NAME);
		__sync_fetch_and_sub(&tethering_enabled, 1);
		return;
	}

	prefixlen =
		__connman_ipaddress_netmask_prefix_len(subnet_mask);
	__connman_nat_enable(BRIDGE_NAME, start_ip, prefixlen);

	err = __connman_ipv6pd_setup(BRIDGE_NAME);
	if (err < 0 && err != -EINPROGRESS)
		DBG("Cannot setup IPv6 prefix delegation %d/%s", err,
			strerror(-err));

	DBG("tethering started");
}