Esempio n. 1
0
static void ipv4ll_available_cb(GDHCPClient *ipv4ll_client, gpointer user_data)
{
	struct connman_dhcp *dhcp = user_data;
	char *address, *netmask;
	unsigned char prefixlen;

	DBG("IPV4LL available");

	address = g_dhcp_client_get_address(ipv4ll_client);
	netmask = g_dhcp_client_get_netmask(ipv4ll_client);

	prefixlen = connman_ipaddress_calc_netmask_len(netmask);

	__connman_ipconfig_set_method(dhcp->ipconfig,
						CONNMAN_IPCONFIG_METHOD_DHCP);
	__connman_ipconfig_set_local(dhcp->ipconfig, address);
	__connman_ipconfig_set_prefixlen(dhcp->ipconfig, prefixlen);
	__connman_ipconfig_set_gateway(dhcp->ipconfig, NULL);

	dhcp_valid(dhcp);

	g_free(address);
	g_free(netmask);
}
Esempio n. 2
0
static void lease_available_cb(GDHCPClient *dhcp_client, gpointer user_data)
{
	struct connman_dhcp *dhcp = user_data;
	GList *option = NULL;
	char *address, *netmask = NULL, *gateway = NULL;
	const char *c_address, *c_gateway;
	unsigned char prefixlen, c_prefixlen;
	bool ip_change = false;

	DBG("Lease available");

	if (dhcp->ipv4ll_client) {
		ipv4ll_stop_client(dhcp);
		dhcp_invalidate(dhcp, false);
	}

	c_address = __connman_ipconfig_get_local(dhcp->ipconfig);
	c_gateway = __connman_ipconfig_get_gateway(dhcp->ipconfig);
	c_prefixlen = __connman_ipconfig_get_prefixlen(dhcp->ipconfig);

	address = g_dhcp_client_get_address(dhcp_client);

	__connman_ipconfig_set_dhcp_address(dhcp->ipconfig, address);
	DBG("last address %s", address);

	option = g_dhcp_client_get_option(dhcp_client, G_DHCP_SUBNET);
	if (option)
		netmask = g_strdup(option->data);

	option = g_dhcp_client_get_option(dhcp_client, G_DHCP_ROUTER);
	if (option)
		gateway = g_strdup(option->data);

	prefixlen = connman_ipaddress_calc_netmask_len(netmask);
	if (prefixlen == 255)
		connman_warn("netmask: %s is invalid", netmask);

	DBG("c_address %s", c_address);

	if (g_strcmp0(address, c_address)) {
		ip_change = true;
		if (c_address) {
			/* Remove old ip address */
			__connman_ipconfig_address_remove(dhcp->ipconfig);
		}
	}
	if (g_strcmp0(gateway, c_gateway)) {
		ip_change = true;
		if (c_gateway) {
			/* Remove gateway ip address */
			__connman_ipconfig_gateway_remove(dhcp->ipconfig);
		}
	} else if (prefixlen != c_prefixlen)
		ip_change = true;

	__connman_ipconfig_set_method(dhcp->ipconfig,
						CONNMAN_IPCONFIG_METHOD_DHCP);
	if (ip_change) {
		__connman_ipconfig_set_local(dhcp->ipconfig, address);
		__connman_ipconfig_set_prefixlen(dhcp->ipconfig, prefixlen);
		__connman_ipconfig_set_gateway(dhcp->ipconfig, gateway);
	}

	if (!apply_lease_available_on_network(dhcp_client, dhcp))
		goto done;

	if (ip_change)
		dhcp_valid(dhcp);

done:
	g_free(address);
	g_free(netmask);
	g_free(gateway);
}
Esempio n. 3
0
static void setup_tun_interface(unsigned int flags, unsigned change,
		void *data)
{
	struct connman_private_network *pn = data;
	unsigned char prefixlen;
	DBusMessageIter array, dict;
	const char *server_ip;
	const char *peer_ip;
	const char *subnet_mask;
	int err;

	DBG("index %d flags %d change %d", pn->index,  flags, change);

	if (flags & IFF_UP)
		return;

	subnet_mask = __connman_ippool_get_subnet_mask(pn->pool);
	server_ip = __connman_ippool_get_start_ip(pn->pool);
	peer_ip = __connman_ippool_get_end_ip(pn->pool);
	prefixlen = connman_ipaddress_calc_netmask_len(subnet_mask);

	if ((__connman_inet_modify_address(RTM_NEWADDR,
				NLM_F_REPLACE | NLM_F_ACK, pn->index, AF_INET,
				server_ip, peer_ip, prefixlen, NULL)) < 0) {
		DBG("address setting failed");
		return;
	}

	connman_inet_ifup(pn->index);

	err = __connman_nat_enable(BRIDGE_NAME, server_ip, prefixlen);
	if (err < 0) {
		connman_error("failed to enable NAT");
		goto error;
	}

	dbus_message_iter_init_append(pn->reply, &array);

	dbus_message_iter_append_basic(&array, DBUS_TYPE_OBJECT_PATH,
						&pn->path);

	connman_dbus_dict_open(&array, &dict);

	connman_dbus_dict_append_basic(&dict, "ServerIPv4",
					DBUS_TYPE_STRING, &server_ip);
	connman_dbus_dict_append_basic(&dict, "PeerIPv4",
					DBUS_TYPE_STRING, &peer_ip);
	if (pn->primary_dns)
		connman_dbus_dict_append_basic(&dict, "PrimaryDNS",
					DBUS_TYPE_STRING, &pn->primary_dns);

	if (pn->secondary_dns)
		connman_dbus_dict_append_basic(&dict, "SecondaryDNS",
					DBUS_TYPE_STRING, &pn->secondary_dns);

	connman_dbus_dict_close(&array, &dict);

	dbus_message_iter_append_basic(&array, DBUS_TYPE_UNIX_FD, &pn->fd);

	g_dbus_send_message(connection, pn->reply);

	return;

error:
	pn->reply = __connman_error_failed(pn->msg, -err);
	g_dbus_send_message(connection, pn->reply);

	g_hash_table_remove(pn_hash, pn->path);
}
Esempio n. 4
0
static int start_dhcp_server(struct connman_peer *peer)
{
	const char *start_ip, *end_ip;
	GDHCPServerError dhcp_error;
	const char *broadcast;
	const char *gateway;
	const char *subnet;
	int prefixlen;
	int index;
	int err;

	DBG("");

	err = -ENOMEM;

	if (peer->sub_device)
		index = connman_device_get_index(peer->sub_device);
	else
		index = connman_device_get_index(peer->device);

	peer->ip_pool = __connman_ippool_create(index, 2, 1, NULL, NULL);
	if (!peer->ip_pool)
		goto error;

	gateway = __connman_ippool_get_gateway(peer->ip_pool);
	subnet = __connman_ippool_get_subnet_mask(peer->ip_pool);
	broadcast = __connman_ippool_get_broadcast(peer->ip_pool);
	start_ip = __connman_ippool_get_start_ip(peer->ip_pool);
	end_ip = __connman_ippool_get_end_ip(peer->ip_pool);

	prefixlen = connman_ipaddress_calc_netmask_len(subnet);

	err = __connman_inet_modify_address(RTM_NEWADDR,
				NLM_F_REPLACE | NLM_F_ACK, index, AF_INET,
				gateway, NULL, prefixlen, broadcast);
	if (err < 0)
		goto error;

	peer->dhcp_server = g_dhcp_server_new(G_DHCP_IPV4, index, &dhcp_error);
	if (!peer->dhcp_server)
		goto error;

	g_dhcp_server_set_debug(peer->dhcp_server,
					dhcp_server_debug, "Peer DHCP server");
	g_dhcp_server_set_lease_time(peer->dhcp_server, 3600);
	g_dhcp_server_set_option(peer->dhcp_server, G_DHCP_SUBNET, subnet);
	g_dhcp_server_set_option(peer->dhcp_server, G_DHCP_ROUTER, gateway);
	g_dhcp_server_set_option(peer->dhcp_server, G_DHCP_DNS_SERVER, NULL);
	g_dhcp_server_set_ip_range(peer->dhcp_server, start_ip, end_ip);

	err = g_dhcp_server_start(peer->dhcp_server);
	if (err < 0)
		goto error;

	g_timeout_add_seconds(0, dhcp_server_started, connman_peer_ref(peer));

	return 0;

error:
	stop_dhcp_server(peer);
	return err;
}
Esempio n. 5
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) {
		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_calc_netmask_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) {
		if (ns[0]) {
			g_free(private_network_primary_dns);
			private_network_primary_dns = g_strdup(ns[0]);
		}
		if (ns[1]) {
			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) {
		__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_calc_netmask_len(subnet_mask);
	err = __connman_nat_enable(BRIDGE_NAME, start_ip, prefixlen);
	if (err < 0) {
		connman_error("Cannot enable NAT %d/%s", err, strerror(-err));
		dhcp_server_stop(tethering_dhcp_server);
		__connman_bridge_disable(BRIDGE_NAME);
		__connman_ippool_unref(dhcp_ippool);
		__connman_bridge_remove(BRIDGE_NAME);
		__sync_fetch_and_sub(&tethering_enabled, 1);
		return;
	}

	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");
}