---
src/connman.h | 6 ++++
src/ippool.c | 76 +++++++++++++++++++++++++++++++++++++++++++++++++++++++
src/tethering.c | 9 +++---
3 files changed, 87 insertions(+), 4 deletions(-)
diff --git a/src/connman.h b/src/connman.h
index 47f29b7..7f113f9 100644
--- a/src/connman.h
+++ b/src/connman.h
@@ -652,15 +652,21 @@ void __connman_6to4_remove(struct connman_ipconfig
*ipconfig);
int __connman_6to4_check(struct connman_ipconfig *ipconfig);
struct connman_ippool;
+typedef void (*ippool_cb_t) (void *user_data);
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 static_range,
uint16_t range,
+ ippool_cb_t cb,
+ void *user_data,
const char **gateway,
const char **broadcast,
const char **start_ip,
const char **end_ip,
const char **subnet_mask,
int *err);
+struct connman_ippool *__connman_ippool_notify(const char *name,
+ const char *ip,
+ int *err);
diff --git a/src/ippool.c b/src/ippool.c
index 1f47029..4c09dae 100644
--- a/src/ippool.c
+++ b/src/ippool.c
@@ -37,15 +37,20 @@
#define BLOCK_24_BITS inet_addr("10.0.0.0")
#define BLOCK_20_BITS inet_addr("172.16.0.0")
+#define BLOCK_20_BITS_END inet_addr("172.32.0.0")
/* We start at 254 by default to avoid common addresses */
#define BLOCK_16_BITS inet_addr("192.168.254.0")
+#define REAL_BLOCK_16_BITS inet_addr("192.168.0.0")
struct connman_ippool {
char *name;
uint16_t static_range; /* Number of static adresses */
uint16_t range; /* Number of dynamic addresses */
+ uint8_t refcount;
uint32_t block;
uint32_t subnet_mask;
+ ippool_cb_t cb;
+ void *user_data;
};
static GHashTable *hash_pool;
@@ -135,9 +140,73 @@ static uint32_t find_free_block()
return 0;
}
+static gboolean is_private_block(uint32_t block)
+{
+ return ((block & 0xffff0000) == ntohl(REAL_BLOCK_16_BITS)) ||
+ ((block & 0xff000000) == ntohl(BLOCK_24_BITS)) ||
+ (((block & 0xffff0000) >= ntohl(BLOCK_20_BITS)) &&
+ ((block & 0xffff0000) <= ntohl(BLOCK_20_BITS_END)));
+}
+
+struct connman_ippool *__connman_ippool_notify(const char *name,
+ const char *ip,
+ int *err)
+{
+ struct connman_ippool *pool;
+ struct in_addr inp;
+ uint32_t block;
+
+ if (inet_aton(ip, &inp) == 0) {
+ *err = -ENXIO;
+ return NULL;
+ }
+
+ /*
+ * In case of connection to a cellular network, ConnMan will be
+ * notified by oFono of the public IP used, so there is no need to
+ * store such IP address into the hash_pool.
+ */
+ if (is_private_block(ntohl(inp.s_addr)) == FALSE) {
+ connman_info("IP %s is not a private\n", ip);
+ return NULL;
+ }
+
+ block = htonl(ntohl(inp.s_addr) & 0xffffff00);
+ pool = g_hash_table_lookup(hash_pool, &block);
+ if (pool == NULL) {
+ pool = g_try_new0(struct connman_ippool, 1);
+ if (pool == NULL) {
+ *err = -ENOMEM;
+ return NULL;
+ }
+
+ pool->refcount++;
+ } else {
+ pool->refcount++;
+ if (pool->cb != NULL)
+ pool->cb(pool->user_data);
+
+ g_free(pool->name);
+ pool->name = g_strdup(name);
+ }
+
+ pool->static_range = 1;
+ pool->range = 0;
+ pool->cb = NULL;
+ pool->user_data = NULL;
+ pool->block = block;
+ pool->subnet_mask = SUBNET_MASK_24;
+
+ g_hash_table_insert(hash_pool, &pool->block, pool);
+
+ return pool;
+}
+
struct connman_ippool *__connman_ippool_create(const char *name,
uint16_t static_range,
uint16_t range,
+ ippool_cb_t cb,
+ void *user_data,
const char **gateway,
const char **broadcast,
const char **start_ip,
@@ -162,9 +231,12 @@ struct connman_ippool *__connman_ippool_create(const char
*name,
return NULL;
}
+ pool->refcount++;
pool->name = g_strdup(name);
pool->static_range = static_range;
pool->range = range;
+ pool->cb = cb;
+ pool->user_data = user_data;
pool->block = block;
pool->subnet_mask = SUBNET_MASK_24;
@@ -195,6 +267,10 @@ static void pool_free(gpointer data)
{
struct connman_ippool *pool = data;
+ pool->refcount--;
+ if (pool->refcount > 0)
+ return;
+
g_free(pool->name);
g_free(pool);
pool = NULL;
diff --git a/src/tethering.c b/src/tethering.c
index 75dcce2..c1a10ee 100644
--- a/src/tethering.c
+++ b/src/tethering.c
@@ -348,9 +348,10 @@ void __connman_tethering_set_enabled(void)
return;
dhcp_pool = __connman_ippool_create(BRIDGE_NAME, 100, 100,
- &gateway, &broadcast,
- &start_ip, &end_ip,
- &subnet, &err);
+ NULL, NULL, &gateway,
+ &broadcast, &start_ip,
+ &end_ip, &subnet,
+ &err);
if (dhcp_pool == NULL) {
connman_error("Fail to create pool with error %d",
err);
@@ -576,7 +577,7 @@ int __connman_private_network_request(DBusMessage *msg,
const char *owner)
pn->fd = fd;
pn->interface = iface;
pn->index = index;
- pn->pool = __connman_ippool_create(iface, 1, 0, NULL, NULL,
+ pn->pool = __connman_ippool_create(iface, 1, 0, NULL, NULL, NULL, NULL,
&pn->server_ip, &pn->peer_ip,
&pn->subnet_mask, &err);
if (pn->pool == NULL)
--
1.7.1
_______________________________________________
connman mailing list
[email protected]
http://lists.connman.net/listinfo/connman