1 From 5bd77bc62bc47d5752a9060cb887883a9d1b9844 Mon Sep 17 00:00:00 2001
2 From: Chengyi Zhao <chengyi1.zhao@archermind.com>
3 Date: Wed, 10 Jul 2013 19:17:02 +0800
4 Subject: [PATCH 18/32] Tethering: Add interface that save lease in DHCP
7 Change-Id: Ia09c875954d8a20a3e6c39f87076780d8a6582e4
9 gdhcp/client.c | 65 ----------------------------------------------------------
10 gdhcp/common.c | 65 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
12 gdhcp/gdhcp.h | 5 +++++
13 gdhcp/server.c | 29 +++++++++++++++++++++++++-
14 5 files changed, 99 insertions(+), 66 deletions(-)
16 diff --git a/gdhcp/client.c b/gdhcp/client.c
17 index 66c3a90..a72efb4 100644
20 @@ -1808,71 +1808,6 @@ static char *get_ip(uint32_t ip)
21 return g_strdup(inet_ntoa(addr));
24 -/* get a rough idea of how long an option will be */
25 -static const uint8_t len_of_option_as_string[] = {
26 - [OPTION_IP] = sizeof("255.255.255.255 "),
27 - [OPTION_STRING] = 1,
28 - [OPTION_U8] = sizeof("255 "),
29 - [OPTION_U16] = sizeof("65535 "),
30 - [OPTION_U32] = sizeof("4294967295 "),
33 -static int sprint_nip(char *dest, const char *pre, const uint8_t *ip)
35 - return sprintf(dest, "%s%u.%u.%u.%u", pre, ip[0], ip[1], ip[2], ip[3]);
38 -/* Create "opt_value1 option_value2 ..." string */
39 -static char *malloc_option_value_string(uint8_t *option, GDHCPOptionType type)
41 - unsigned upper_length;
45 - len = option[OPT_LEN - OPT_DATA];
46 - type &= OPTION_TYPE_MASK;
47 - optlen = dhcp_option_lengths[type];
50 - upper_length = len_of_option_as_string[type] *
51 - ((unsigned)len / (unsigned)optlen);
52 - dest = ret = g_malloc(upper_length + 1);
56 - while (len >= optlen) {
59 - dest += sprint_nip(dest, "", option);
62 - uint16_t val_u16 = get_be16(option);
63 - dest += sprintf(dest, "%u", val_u16);
67 - uint32_t val_u32 = get_be32(option);
68 - dest += sprintf(dest, "%u", val_u32);
72 - memcpy(dest, option, len);
89 static GList *get_option_value_list(char *value, GDHCPOptionType type)
92 diff --git a/gdhcp/common.c b/gdhcp/common.c
93 index 45278a8..ac6b125 100644
96 @@ -144,6 +144,71 @@ int dhcp_end_option(uint8_t *optionptr)
100 +/* get a rough idea of how long an option will be */
101 +static const uint8_t len_of_option_as_string[] = {
102 + [OPTION_IP] = sizeof("255.255.255.255 "),
103 + [OPTION_STRING] = 1,
104 + [OPTION_U8] = sizeof("255 "),
105 + [OPTION_U16] = sizeof("65535 "),
106 + [OPTION_U32] = sizeof("4294967295 "),
109 +static int sprint_nip(char *dest, const char *pre, const uint8_t *ip)
111 + return sprintf(dest, "%s%u.%u.%u.%u", pre, ip[0], ip[1], ip[2], ip[3]);
114 +/* Create "opt_value1 option_value2 ..." string */
115 +char *malloc_option_value_string(uint8_t *option, GDHCPOptionType type)
117 + unsigned upper_length;
121 + len = option[OPT_LEN - OPT_DATA];
122 + type &= OPTION_TYPE_MASK;
123 + optlen = dhcp_option_lengths[type];
126 + upper_length = len_of_option_as_string[type] *
127 + ((unsigned)len / (unsigned)optlen);
128 + dest = ret = g_malloc(upper_length + 1);
132 + while (len >= optlen) {
135 + dest += sprint_nip(dest, "", option);
138 + uint16_t val_u16 = get_be16(option);
139 + dest += sprintf(dest, "%u", val_u16);
143 + uint32_t val_u32 = get_be32(option);
144 + dest += sprintf(dest, "%u", val_u32);
147 + case OPTION_STRING:
148 + memcpy(dest, option, len);
165 uint8_t *dhcpv6_get_option(struct dhcpv6_packet *packet, uint16_t pkt_len,
166 int code, uint16_t *option_len, int *option_count)
168 diff --git a/gdhcp/common.h b/gdhcp/common.h
169 index c692799..1ab9a7c 100644
172 @@ -170,6 +170,7 @@ static const uint8_t dhcp_option_lengths[] = {
176 +char *malloc_option_value_string(uint8_t *option, GDHCPOptionType type);
177 uint8_t *dhcp_get_option(struct dhcp_packet *packet, int code);
178 uint8_t *dhcpv6_get_option(struct dhcpv6_packet *packet, uint16_t pkt_len,
179 int code, uint16_t *option_len, int *option_count);
180 diff --git a/gdhcp/gdhcp.h b/gdhcp/gdhcp.h
181 index f3e47bf..f4ef292 100644
184 @@ -205,6 +205,9 @@ struct _GDHCPServer;
186 typedef struct _GDHCPServer GDHCPServer;
188 +typedef void (*GDHCPSaveACKLeaseFunc) (char *hostname,
189 + unsigned char *mac, unsigned int nip);
191 GDHCPServer *g_dhcp_server_new(GDHCPType type,
192 int ifindex, GDHCPServerError *error);
193 int g_dhcp_server_start(GDHCPServer *server);
194 @@ -223,6 +226,8 @@ void g_dhcp_server_set_lease_time(GDHCPServer *dhcp_server,
195 unsigned int lease_time);
196 void g_dhcp_server_set_save_lease(GDHCPServer *dhcp_server,
197 GDHCPSaveLeaseFunc func, gpointer user_data);
198 +void g_dhcp_server_set_save_ack_lease(GDHCPServer *dhcp_server,
199 + GDHCPSaveACKLeaseFunc func, gpointer user_data);
203 diff --git a/gdhcp/server.c b/gdhcp/server.c
204 index aa40488..0171b5f 100644
207 @@ -65,6 +65,7 @@ struct _GDHCPServer {
208 GHashTable *nip_lease_hash;
209 GHashTable *option_hash; /* Options send to client */
210 GDHCPSaveLeaseFunc save_lease_func;
211 + GDHCPSaveACKLeaseFunc save_ack_lease_func;
212 GDHCPDebugFunc debug_func;
215 @@ -398,6 +399,7 @@ GDHCPServer *g_dhcp_server_new(GDHCPType type,
216 dhcp_server->listener_watch = -1;
217 dhcp_server->listener_channel = NULL;
218 dhcp_server->save_lease_func = NULL;
219 + dhcp_server->save_ack_lease_func = NULL;
220 dhcp_server->debug_func = NULL;
221 dhcp_server->debug_data = NULL;
223 @@ -646,9 +648,12 @@ static gboolean listener_event(GIOChannel *channel, GIOCondition condition,
224 struct dhcp_packet packet;
225 struct dhcp_lease *lease;
226 uint32_t requested_nip = 0;
227 - uint8_t type, *server_id_option, *request_ip_option;
228 + uint8_t type, *server_id_option, *request_ip_option, *host_name;
231 + GDHCPOptionType option_type;
232 + char *option_value;
234 if (condition & (G_IO_NVAL | G_IO_ERR | G_IO_HUP)) {
235 dhcp_server->listener_watch = 0;
237 @@ -693,8 +698,21 @@ static gboolean listener_event(GIOChannel *channel, GIOCondition condition,
239 if (lease && requested_nip == lease->lease_nip) {
240 debug(dhcp_server, "Sending ACK");
242 + host_name = dhcp_get_option(&packet, DHCP_HOST_NAME);
243 + option_type = dhcp_get_code_type(DHCP_HOST_NAME);
244 + option_value = malloc_option_value_string(host_name,
246 send_ACK(dhcp_server, &packet,
249 + if (dhcp_server->save_ack_lease_func)
250 + dhcp_server->save_ack_lease_func(
254 + g_free(option_value);
259 @@ -814,6 +832,15 @@ void g_dhcp_server_set_save_lease(GDHCPServer *dhcp_server,
260 dhcp_server->save_lease_func = func;
263 +void g_dhcp_server_set_save_ack_lease(GDHCPServer *dhcp_server,
264 + GDHCPSaveACKLeaseFunc func, gpointer user_data)
266 + if (dhcp_server == NULL)
269 + dhcp_server->save_ack_lease_func = func;
272 GDHCPServer *g_dhcp_server_ref(GDHCPServer *dhcp_server)