---
Makefile.am | 3 +-
src/connman.h | 11 +++
src/ippool.c | 207 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++
src/main.c | 2 +
4 files changed, 222 insertions(+), 1 deletions(-)
create mode 100644 src/ippool.c
diff --git a/Makefile.am b/Makefile.am
index 9c08453..cacfa48 100644
--- a/Makefile.am
+++ b/Makefile.am
@@ -80,7 +80,8 @@ src_connmand_SOURCES = $(gdbus_sources) $(gdhcp_sources) \
src/storage.c src/dbus.c src/config.c \
src/technology.c src/counter.c src/location.c \
src/session.c src/tethering.c src/wpad.c src/wispr.c \
- src/stats.c src/iptables.c src/dnsproxy.c src/6to4.c
+ src/stats.c src/iptables.c src/dnsproxy.c src/6to4.c \
+ src/ippool.c
src_connmand_LDADD = $(builtin_libadd) @GLIB_LIBS@ @DBUS_LIBS@ \
@CAPNG_LIBS@ @XTABLES_LIBS@ -lresolv -ldl
diff --git a/src/connman.h b/src/connman.h
index 6e68c99..10a6ca7 100644
--- a/src/connman.h
+++ b/src/connman.h
@@ -683,3 +683,14 @@ void __connman_dnsproxy_flush(void);
int __connman_6to4_probe(struct connman_service *service);
void __connman_6to4_remove(struct connman_ipconfig *ipconfig);
int __connman_6to4_check(struct connman_ipconfig *ipconfig);
+
+struct connman_ippool;
+int __connman_ippool_init(void);
+void __connman_ippool_cleanup(void);
+void __connman_ippool_remove(struct connman_ippool *pool);
+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);
diff --git a/src/ippool.c b/src/ippool.c
new file mode 100644
index 0000000..10f29d9
--- /dev/null
+++ b/src/ippool.c
@@ -0,0 +1,207 @@
+/*
+ *
+ * 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 <getopt.h>
+#include <stdlib.h>
+#include <stdio.h>
+#include <string.h>
+#include <unistd.h>
+#include <sys/errno.h>
+#include <sys/socket.h>
+
+#include "connman.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")
+
+struct connman_ippool {
+ char *name;
+ uint16_t size;
+ uint32_t start_ip;
+ uint32_t end_ip;
+ uint32_t subnet_mask;
+};
+
+static GHashTable *hash_pool;
+
+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 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;
+}
+
+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 __connman_ippool_init(void)
+{
+ DBG("");
+
+ hash_pool = g_hash_table_new_full(g_int_hash, g_int_equal, NULL,
+ pool_free);
+
+ return 0;
+}
+
+void __connman_ippool_cleanup(void)
+{
+ DBG("");
+
+ g_hash_table_destroy(hash_pool);
+}
diff --git a/src/main.c b/src/main.c
index cb78e12..d59e01c 100644
--- a/src/main.c
+++ b/src/main.c
@@ -344,6 +344,7 @@ int main(int argc, char *argv[])
__connman_device_init(option_device, option_nodevice);
__connman_agent_init();
+ __connman_ippool_init();
__connman_iptables_init();
__connman_tethering_init();
__connman_counter_init();
@@ -407,6 +408,7 @@ int main(int argc, char *argv[])
__connman_agent_cleanup();
__connman_tethering_cleanup();
__connman_iptables_cleanup();
+ __connman_ippool_cleanup();
__connman_device_cleanup();
__connman_network_cleanup();
__connman_service_cleanup();
--
1.7.1
_______________________________________________
connman mailing list
[email protected]
http://lists.connman.net/listinfo/connman