---
Makefile.am | 5 +-
tools/ippool-test.c | 291 +++++++++++++++++++++++++++++++++++++++++++++++++++
2 files changed, 295 insertions(+), 1 deletions(-)
create mode 100644 tools/ippool-test.c
diff --git a/Makefile.am b/Makefile.am
index cacfa48..f6f5119 100644
--- a/Makefile.am
+++ b/Makefile.am
@@ -146,7 +146,10 @@ noinst_PROGRAMS += tools/wispr tools/supplicant-test \
tools/dbus-test tools/polkit-test \
tools/iptables-test tools/tap-test tools/wpad-test \
tools/stats-tool tools/private-network-test \
- tools/alg-test unit/test-session
+ tools/alg-test unit/test-session \
+ tools/ippool-test
+
+tools_ippool_test_LDADD = @GLIB_LIBS@ @DBUS_LIBS@
tools_wispr_SOURCES = $(gweb_sources) tools/wispr.c
tools_wispr_LDADD = @GLIB_LIBS@ @GNUTLS_LIBS@ -lresolv
diff --git a/tools/ippool-test.c b/tools/ippool-test.c
new file mode 100644
index 0000000..602633b
--- /dev/null
+++ b/tools/ippool-test.c
@@ -0,0 +1,291 @@
+/*
+ *
+ * Connection Manager
+ *
+ * Copyright (C) 2007-2011 Intel Corporation. All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+ *
+ */
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#include <glib.h>
+#include <stdio.h>
+#include <arpa/inet.h>
+#include <sys/errno.h>
+
+#define SUBNET_MASK_24 inet_addr("255.255.255.0")
+
+#define BLOCK_24_BITS inet_addr("10.0.0.0")
+#define BLOCK_20_BITS inet_addr("172.16.0.0")
+/* We start at 254 by default to avoid common addresses */
+#define BLOCK_16_BITS inet_addr("192.168.254.0")
+
+#define MAX_POOL 255
+
+struct connman_ippool {
+ char *name;
+ uint16_t size;
+ uint32_t start_ip;
+ uint32_t end_ip;
+ uint32_t subnet_mask;
+};
+
+static GHashTable *hash_pool;
+
+static void __connman_ippool_remove(struct connman_ippool *pool)
+{
+ g_hash_table_remove(hash_pool, &pool->start_ip);
+}
+
+static char *get_ip(uint32_t ip)
+{
+ struct in_addr addr;
+
+ addr.s_addr = ip;
+
+ return g_strdup(inet_ntoa(addr));
+}
+
+static gboolean next_block(uint32_t *block)
+{
+ uint32_t next;
+
+ next = (*block & 0x0000ff00) >> 8;
+ if (next < 255) {
+ next++;
+ if (next == 255 && ((*block & 0xffffff00) ==
+ ntohl(BLOCK_16_BITS))) {
+ *block = ntohl(BLOCK_20_BITS);
+
+ return TRUE;
+ } else if (next == 255 && ((*block & 0xffff0000) >=
+ ntohl(BLOCK_20_BITS))) {
+ next = (*block & 0x00ff0000) >> 16;
+ if (next >= 16 && next < 33) {
+ next++;
+ if (next == 33) {
+ *block = ntohl(BLOCK_24_BITS);
+
+ return TRUE;
+ }
+
+ *block = (*block & 0xff000000) |
+ ((next << 16) & 0x00ff0000);
+ }
+ } else if (next == 255 && ((*block & 0xff000000) ==
+ ntohl(BLOCK_24_BITS))) {
+ next = (*block & 0x00ff0000) >> 16;
+ if (next < 255) {
+ next++;
+ if (next == 255)
+ return FALSE;
+
+ *block = (*block & 0xff000000) |
+ ((next << 16) & 0x00ff0000);
+
+ return TRUE;
+ }
+ }
+
+ *block = (*block & 0xffff0000) | ((next << 8) & 0x0000ff00);
+
+ return TRUE;
+ }
+
+ return FALSE;
+}
+
+static uint32_t test_next_block()
+{
+ uint32_t new_block = ntohl(BLOCK_16_BITS);
+
+ printf("%s\n", get_ip(htonl(new_block + 1)));
+
+ while (next_block(&new_block) == TRUE) {
+ uint32_t key = htonl(new_block + 1);
+
+ printf("%s\n", get_ip(key));
+ }
+
+ return 0;
+}
+
+static uint32_t find_free_block()
+{
+ struct connman_ippool *pool;
+ uint32_t new_block = ntohl(BLOCK_16_BITS);
+ uint32_t first_block = htonl(new_block + 1);
+
+ pool = g_hash_table_lookup(hash_pool, &first_block);
+ if (pool == NULL)
+ return first_block;
+
+ while (next_block(&new_block) == TRUE) {
+ uint32_t key = htonl(new_block + 1);
+ pool = g_hash_table_lookup(hash_pool, &key);
+ if (pool != NULL)
+ continue;
+
+ return key;
+ }
+
+ return 0;
+}
+
+static struct connman_ippool *__connman_ippool_create(const char *name,
+ uint16_t size,
+ const char **start_ip,
+ const char **end_ip,
+ const char **subnet_mask,
+ int *err)
+{
+ struct connman_ippool *pool;
+ uint32_t block;
+
+ /* TODO: manage block size > 254 to set subnet mask appropriately */
+ if (size > 254)
+ goto error;
+
+ block = find_free_block();
+ if (block == 0)
+ goto error;
+
+ pool = g_try_new0(struct connman_ippool, 1);
+ if (pool == NULL) {
+ *err = -ENOMEM;
+ return NULL;
+ }
+
+ pool->name = g_strdup(name);
+ pool->size = size;
+ pool->start_ip = block;
+ pool->end_ip = htonl(ntohl(block) + (size - 1));
+ pool->subnet_mask = SUBNET_MASK_24;
+
+ g_hash_table_insert(hash_pool, &pool->start_ip, pool);
+
+ *start_ip = get_ip(pool->start_ip);
+ *end_ip = get_ip(pool->end_ip);
+ *subnet_mask = get_ip(pool->subnet_mask);
+
+ *err = 0;
+
+ return pool;
+
+error:
+ *err = -EINVAL;
+ return NULL;
+}
+
+static void pool_free(gpointer data)
+{
+ struct connman_ippool *pool = data;
+
+ g_free(pool->name);
+ g_free(pool);
+ pool = NULL;
+}
+
+int main(int argc, char *argv[])
+{
+ struct connman_ippool *pool[MAX_POOL];
+ int i, err;
+
+ printf("Printing all pools...\n\n");
+
+ test_next_block();
+
+ printf("\n\nIP pool test has started...\n\n");
+
+ hash_pool = g_hash_table_new_full(g_int_hash, g_int_equal, NULL,
+ pool_free);
+
+ for (i = 0; i < MAX_POOL; i++) {
+ const char *start_ip;
+ const char *end_ip;
+ const char *subnet_mask;
+ char *name = g_strdup_printf("Pool %d", i);
+ if (name == NULL) {
+ err = -ENOMEM;
+ goto error;
+ }
+
+ printf("Allocating %s\n", name);
+
+ pool[i] = __connman_ippool_create(name, 254, &start_ip,
+ &end_ip, &subnet_mask,
+ &err);
+ if (pool[i] == NULL) {
+ g_free(name);
+ goto error;
+ }
+ printf("created %s with IP range %s --> %s and SUBNET %s\n\n",
+ name, start_ip, end_ip, subnet_mask);
+ g_free(name);
+ }
+
+ printf("\n");
+
+ for (i = 0; i < MAX_POOL; i++) {
+ if (i%7 == 0) {
+ printf("Removing %s %s\n", pool[i]->name,
+ get_ip(pool[i]->start_ip));
+ __connman_ippool_remove(pool[i]);
+ }
+ }
+
+ printf("\n");
+
+ for (i = 0; i < MAX_POOL; i++) {
+ if (i%14 == 0) {
+ const char *start_ip;
+ const char *end_ip;
+ const char *subnet_mask;
+ char *name = g_strdup_printf("Pool %d", i);
+ if (name == NULL) {
+ err = -ENOMEM;
+ goto error;
+ }
+
+ printf("Allocating %s\n", name);
+
+ pool[i] = __connman_ippool_create(name, 254, &start_ip,
+ &end_ip,
+ &subnet_mask,
+ &err);
+ if (pool[i] == NULL) {
+ g_free(name);
+ goto error;
+ }
+
+ printf("created %s with IP range %s --> %s "
+ "and SUBNET %s\n\n", name, start_ip, end_ip,
+ subnet_mask);
+
+ g_free(name);
+ }
+ }
+
+error:
+ if (err < 0)
+ printf("Failed to create Pool%d with error %d\n", i, err);
+
+ g_hash_table_destroy(hash_pool);
+
+ return err;
+}
--
1.7.1
_______________________________________________
connman mailing list
[email protected]
http://lists.connman.net/listinfo/connman