---
 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

Reply via email to