[PATCH v0 1/2] dhcp: Add dhcp server functions

Daniel Wagner wagi at monom.org
Mon Feb 13 07:13:19 PST 2012


From: Daniel Wagner <daniel.wagner at bmw-carit.de>

---
 src/connman.h |   21 +++++++++
 src/dhcp.c    |  126 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++
 2 files changed, 147 insertions(+), 0 deletions(-)

diff --git a/src/connman.h b/src/connman.h
index da4affd..a2dc7b2 100644
--- a/src/connman.h
+++ b/src/connman.h
@@ -325,6 +325,27 @@ int __connman_timeserver_sync(struct connman_service *service);
 void __connman_timeserver_sync_next();
 void __connman_timeserver_stop();
 
+struct connman_dhcp_server;
+
+#define __connman_dhcp_server_ref(dhcp_server) \
+	__connman_dhcp_server_ref_debug(dhcp_server, __FILE__, __LINE__, __func__)
+#define __connman_dhcp_server_unref(dhcp_server) \
+	__connman_dhcp_server_unref_debug(dhcp_server, __FILE__, __LINE__, __func__)
+
+struct connman_dhcp_server *__connman_dhcp_server_ref_debug(
+			struct connman_dhcp_server *dhcp_server,
+			const char *file, int line, const char *caller);
+void __connman_dhcp_server_unref_debug(
+			struct connman_dhcp_server *dhcp_server,
+			const char *file, int line, const char *caller);
+
+struct connman_dhcp_server *__connman_dhcp_server_create(int index);
+int __connman_dhcp_server_start(struct connman_dhcp_server *dhcp_server,
+				const char *router, const char* subnet,
+				const char *start_ip, const char *end_ip,
+				unsigned int lease_time, const char *dns);
+void __connman_dhcp_server_stop(struct connman_dhcp_server *server);
+
 typedef void (* dhcp_cb) (struct connman_network *network,
 				connman_bool_t success);
 int __connman_dhcp_start(struct connman_network *network, dhcp_cb callback);
diff --git a/src/dhcp.c b/src/dhcp.c
index f84e394..7dae8ed 100644
--- a/src/dhcp.c
+++ b/src/dhcp.c
@@ -46,7 +46,14 @@ struct connman_dhcp {
 	GDHCPClient *dhcp_client;
 };
 
+struct connman_dhcp_server {
+	unsigned int refcount;
+
+	GDHCPServer *dhcp_server;
+};
+
 static GHashTable *network_table;
+static GHashTable *server_hash;
 
 static void dhcp_free(struct connman_dhcp *dhcp)
 {
@@ -503,6 +510,119 @@ void __connman_dhcp_stop(struct connman_network *network)
 		connman_network_unref(network);
 }
 
+struct connman_dhcp_server *
+__connman_dhcp_server_ref_debug(struct connman_dhcp_server *dhcp_server,
+				const char *file, int line, const char *caller)
+{
+	DBG("%p ref %d by %s:%d:%s()", dhcp_server, dhcp_server->refcount + 1,
+		file, line, caller);
+
+	__sync_fetch_and_add(&dhcp_server->refcount, 1);
+
+	return dhcp_server;
+}
+
+void __connman_dhcp_server_unref_debug(struct connman_dhcp_server *dhcp_server,
+				const char *file, int line, const char *caller)
+{
+	if (dhcp_server == NULL)
+		return;
+
+	DBG("%p ref %d by %s:%d:%s()", dhcp_server, dhcp_server->refcount - 1,
+		file, line, caller);
+
+	if (__sync_fetch_and_sub(&dhcp_server->refcount, 1) != 1)
+		return;
+
+	g_hash_table_remove(server_hash, dhcp_server);
+}
+
+static void dhcp_server_debug(const char *str, void *data)
+{
+	connman_info("%s: %s\n", (const char *) data, str);
+}
+
+static void dhcp_server_error(GDHCPServerError error)
+{
+	switch (error) {
+	case G_DHCP_SERVER_ERROR_NONE:
+		connman_error("OK");
+		break;
+	case G_DHCP_SERVER_ERROR_INTERFACE_UNAVAILABLE:
+		connman_error("Interface unavailable");
+		break;
+	case G_DHCP_SERVER_ERROR_INTERFACE_IN_USE:
+		connman_error("Interface in use");
+		break;
+	case G_DHCP_SERVER_ERROR_INTERFACE_DOWN:
+		connman_error("Interface down");
+		break;
+	case G_DHCP_SERVER_ERROR_NOMEM:
+		connman_error("No memory");
+		break;
+	case G_DHCP_SERVER_ERROR_INVALID_INDEX:
+		connman_error("Invalid index");
+		break;
+	case G_DHCP_SERVER_ERROR_INVALID_OPTION:
+		connman_error("Invalid option");
+		break;
+	case G_DHCP_SERVER_ERROR_IP_ADDRESS_INVALID:
+		connman_error("Invalid address");
+		break;
+	}
+}
+
+struct connman_dhcp_server *__connman_dhcp_server_create(int index)
+{
+	GDHCPServerError error;
+	struct connman_dhcp_server *dhcp_server;
+
+	dhcp_server = g_try_new0(struct connman_dhcp_server, 1);
+	if (dhcp_server == NULL)
+		return NULL;
+
+	dhcp_server->refcount = 1;
+	dhcp_server->dhcp_server = g_dhcp_server_new(G_DHCP_IPV4, index, &error);
+	if (dhcp_server == NULL) {
+		dhcp_server_error(error);
+		g_free(dhcp_server);
+		return NULL;
+	}
+
+	g_dhcp_server_set_debug(dhcp_server->dhcp_server,
+				dhcp_server_debug, "DHCP server");
+
+	return dhcp_server;
+}
+
+int __connman_dhcp_server_start(struct connman_dhcp_server *dhcp_server,
+				const char *router, const char* subnet,
+				const char *start_ip, const char *end_ip,
+				unsigned int lease_time, const char *dns)
+{
+	g_dhcp_server_set_lease_time(dhcp_server->dhcp_server, lease_time);
+	g_dhcp_server_set_option(dhcp_server->dhcp_server, G_DHCP_SUBNET, subnet);
+	g_dhcp_server_set_option(dhcp_server->dhcp_server, G_DHCP_ROUTER, router);
+	g_dhcp_server_set_option(dhcp_server->dhcp_server, G_DHCP_DNS_SERVER, dns);
+	g_dhcp_server_set_ip_range(dhcp_server->dhcp_server, start_ip, end_ip);
+
+	return g_dhcp_server_start(dhcp_server->dhcp_server);
+}
+
+void __connman_dhcp_server_stop(struct connman_dhcp_server *dhcp_server)
+{
+	g_dhcp_server_stop(dhcp_server->dhcp_server);
+}
+
+static void remove_server(gpointer user_data)
+{
+	struct connman_dhcp_server *dhcp_server = user_data;
+
+	DBG("dhcp_server %p", dhcp_server);
+
+	g_dhcp_server_unref(dhcp_server->dhcp_server);
+}
+
 int __connman_dhcp_init(void)
 {
 	DBG("");
@@ -510,6 +630,9 @@ int __connman_dhcp_init(void)
 	network_table = g_hash_table_new_full(g_direct_hash, g_direct_equal,
 							NULL, remove_network);
 
+	server_hash = g_hash_table_new_full(g_direct_hash, g_direct_equal,
+							NULL, remove_server);
+
 	return 0;
 }
 
@@ -519,4 +642,7 @@ void __connman_dhcp_cleanup(void)
 
 	g_hash_table_destroy(network_table);
 	network_table = NULL;
+
+	g_hash_table_destroy(server_hash);
+	server_hash = NULL;
 }
-- 
1.7.9.48.g85da4d




More information about the connman mailing list