static void test_ippool_exhaust0(void) { struct connman_ippool *pool; const char *gateway; const char *broadcast; const char *subnet_mask; const char *start_ip; const char *end_ip; GSList *list = NULL, *it; int i = 0; __connman_ippool_init(); /* Allocate all possible pools */ /* * Number of addresses * 24-bit block 10.0.0.0 – 10.255.255.255 16,777,216 * 20-bit block 172.16.0.0 – 172.31.255.255 1,048,576 * 16-bit block 192.168.0.0 – 192.168.255.255 65,536 * * Total 17,891,328 * * Total numbers of 256 blocks: 69,888 */ while (TRUE) { pool = __connman_ippool_create(23, 1, 100, NULL, NULL); if (pool == NULL) break; i += 1; g_assert(i < 69888); list = g_slist_prepend(list, pool); gateway = __connman_ippool_get_gateway(pool); broadcast = __connman_ippool_get_broadcast(pool); subnet_mask = __connman_ippool_get_subnet_mask(pool); start_ip = __connman_ippool_get_start_ip(pool); end_ip = __connman_ippool_get_end_ip(pool); g_assert(gateway); g_assert(broadcast); g_assert(subnet_mask); g_assert(start_ip); g_assert(end_ip); } LOG("Number of blocks %d", i); for (it = list; it != NULL; it = it->next) { pool = it->data; __connman_ippool_unref(pool); } g_slist_free(list); __connman_ippool_cleanup(); }
static void append_dhcp_server_ipv4(DBusMessageIter *iter, void *user_data) { struct connman_peer *peer = user_data; const char *str = "dhcp"; const char *gateway; const char *subnet; if (!peer->ip_pool) return; gateway = __connman_ippool_get_gateway(peer->ip_pool); subnet = __connman_ippool_get_subnet_mask(peer->ip_pool); connman_dbus_dict_append_basic(iter, "Method", DBUS_TYPE_STRING, &str); connman_dbus_dict_append_basic(iter, "Address", DBUS_TYPE_STRING, &gateway); connman_dbus_dict_append_basic(iter, "Netmask", DBUS_TYPE_STRING, &subnet); connman_dbus_dict_append_basic(iter, "Gateway", DBUS_TYPE_STRING, &gateway); }
static void test_case_2(void) { struct connman_ippool *pool; const char *gateway; const char *broadcast; const char *subnet_mask; const char *start_ip; const char *end_ip; int i; __connman_ippool_init(); /* Test the IP range */ for (i = 1; i < 254; i++) { pool = __connman_ippool_create(23, 1, i, NULL, NULL); g_assert(pool); gateway = __connman_ippool_get_gateway(pool); broadcast = __connman_ippool_get_broadcast(pool); subnet_mask = __connman_ippool_get_subnet_mask(pool); start_ip = __connman_ippool_get_start_ip(pool); end_ip = __connman_ippool_get_end_ip(pool); g_assert(gateway); g_assert(broadcast); g_assert(subnet_mask); g_assert(start_ip); g_assert(end_ip); LOG("\n\tIP range %s --> %s\n" "\tgateway %s broadcast %s mask %s", start_ip, end_ip, gateway, broadcast, subnet_mask); __connman_ippool_unref(pool); } __connman_ippool_cleanup(); }
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; }
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"); }
static void test_case_6(void) { struct connman_ippool *pool; const char *gateway; const char *broadcast; const char *subnet_mask; const char *start_ip; const char *end_ip; int flag; __connman_ippool_init(); /* Test the IP range collision */ flag = 0; start_ip = "192.168.1.2"; __connman_ippool_newaddr(25, start_ip, 24); g_assert(flag == 0); flag = 0; start_ip = "192.168.0.2"; __connman_ippool_newaddr(25, start_ip, 24); g_assert(flag == 0); /* pool should return 192.168.2.1 now */ pool = __connman_ippool_create(26, 1, 100, collision_cb, &flag); g_assert(pool); gateway = __connman_ippool_get_gateway(pool); broadcast = __connman_ippool_get_broadcast(pool); subnet_mask = __connman_ippool_get_subnet_mask(pool); start_ip = __connman_ippool_get_start_ip(pool); end_ip = __connman_ippool_get_end_ip(pool); g_assert(gateway); g_assert(broadcast); g_assert(subnet_mask); g_assert(start_ip); g_assert(end_ip); g_assert_cmpstr(gateway, ==, "192.168.2.1"); g_assert_cmpstr(broadcast, ==, "192.168.2.255"); g_assert_cmpstr(subnet_mask, ==, "255.255.255.0"); g_assert_cmpstr(start_ip, ==, "192.168.2.1"); g_assert_cmpstr(end_ip, ==, "192.168.2.101"); LOG("\n\tIP range %s --> %s\n" "\tgateway %s broadcast %s mask %s", start_ip, end_ip, gateway, broadcast, subnet_mask); __connman_ippool_unref(pool); /* * Now create the pool again, we should not get collision * with existing allocated address. */ /* pool should return 192.168.3.1 now */ flag = 0; pool = __connman_ippool_create(23, 1, 100, collision_cb, &flag); g_assert(pool); gateway = __connman_ippool_get_gateway(pool); broadcast = __connman_ippool_get_broadcast(pool); subnet_mask = __connman_ippool_get_subnet_mask(pool); start_ip = __connman_ippool_get_start_ip(pool); end_ip = __connman_ippool_get_end_ip(pool); g_assert(gateway); g_assert(broadcast); g_assert(subnet_mask); g_assert(start_ip); g_assert(end_ip); g_assert_cmpstr(gateway, ==, "192.168.3.1"); g_assert_cmpstr(broadcast, ==, "192.168.3.255"); g_assert_cmpstr(subnet_mask, ==, "255.255.255.0"); g_assert_cmpstr(start_ip, ==, "192.168.3.1"); g_assert_cmpstr(end_ip, ==, "192.168.3.101"); LOG("\n\tIP range %s --> %s\n" "\tgateway %s broadcast %s mask %s", start_ip, end_ip, gateway, broadcast, subnet_mask); g_assert(flag == 0); flag = 0; start_ip = "192.168.3.2"; __connman_ippool_newaddr(25, start_ip, 24); g_assert(flag == 1); __connman_ippool_unref(pool); __connman_ippool_cleanup(); }
static void test_case_4(void) { struct connman_ippool *pool; const char *gateway; const char *broadcast; const char *subnet_mask; const char *start_ip; const char *end_ip; int flag; __connman_ippool_init(); /* Test the IP range collision */ flag = 0; pool = __connman_ippool_create(23, 1, 100, collision_cb, &flag); g_assert(pool); gateway = __connman_ippool_get_gateway(pool); broadcast = __connman_ippool_get_broadcast(pool); subnet_mask = __connman_ippool_get_subnet_mask(pool); start_ip = __connman_ippool_get_start_ip(pool); end_ip = __connman_ippool_get_end_ip(pool); g_assert(gateway); g_assert(broadcast); g_assert(subnet_mask); g_assert(start_ip); g_assert(end_ip); LOG("\n\tIP range %s --> %s\n" "\tgateway %s broadcast %s mask %s", start_ip, end_ip, gateway, broadcast, subnet_mask); __connman_ippool_newaddr(23, start_ip, 24); g_assert(flag == 0); __connman_ippool_newaddr(42, start_ip, 16); g_assert(flag == 1); __connman_ippool_unref(pool); flag = 0; pool = __connman_ippool_create(23, 1, 100, collision_cb, &flag); g_assert(pool); gateway = __connman_ippool_get_gateway(pool); broadcast = __connman_ippool_get_broadcast(pool); subnet_mask = __connman_ippool_get_subnet_mask(pool); start_ip = __connman_ippool_get_start_ip(pool); end_ip = __connman_ippool_get_end_ip(pool); g_assert(gateway); g_assert(broadcast); g_assert(subnet_mask); g_assert(start_ip); g_assert(end_ip); LOG("\n\tIP range %s --> %s\n" "\tgateway %s broadcast %s mask %s", start_ip, end_ip, gateway, broadcast, subnet_mask); __connman_ippool_newaddr(45, start_ip, 22); g_assert(flag == 1); __connman_ippool_unref(pool); __connman_ippool_cleanup(); }
static void test_case_3(void) { struct connman_ippool *pool; const char *gateway; const char *broadcast; const char *subnet_mask; const char *start_ip; const char *end_ip; GSList *list = NULL, *it; int i = 0; __connman_ippool_init(); /* * Number of addresses * 24-bit block 10.0.0.0 – 10.255.255.255 16,777,216 * 20-bit block 172.16.0.0 – 172.31.255.255 1,048,576 * 16-bit block 192.168.0.0 – 192.168.255.255 65,536 * * Total 17,891,328 * * Total numbers of 256 blocks: 69,888 */ /* * Completely exhaust the first two pools because they are a bit * too large. */ __connman_ippool_newaddr(45, "10.0.0.1", 8); __connman_ippool_newaddr(46, "172.16.0.1", 11); while (TRUE) { pool = __connman_ippool_create(23, 1, 100, NULL, NULL); if (pool == NULL) break; i += 1; list = g_slist_prepend(list, pool); gateway = __connman_ippool_get_gateway(pool); broadcast = __connman_ippool_get_broadcast(pool); subnet_mask = __connman_ippool_get_subnet_mask(pool); start_ip = __connman_ippool_get_start_ip(pool); end_ip = __connman_ippool_get_end_ip(pool); g_assert(gateway); g_assert(broadcast); g_assert(subnet_mask); g_assert(start_ip); g_assert(end_ip); } g_assert(i == 255); LOG("Number of blocks %d", i); for (it = list; it != NULL; it = it->next) { pool = it->data; __connman_ippool_unref(pool); } g_slist_free(list); __connman_ippool_cleanup(); }