Tethering: Add interface that save lease in DHCP information
authorChengyi Zhao <chengyi1.zhao@archermind.com>
Wed, 10 Jul 2013 11:17:02 +0000 (19:17 +0800)
committerZhang zhengguang <zhengguang.zhang@intel.com>
Thu, 31 Jul 2014 07:51:58 +0000 (15:51 +0800)
Change-Id: Ia09c875954d8a20a3e6c39f87076780d8a6582e4

gdhcp/client.c
gdhcp/common.c
gdhcp/common.h
gdhcp/gdhcp.h
gdhcp/server.c

index 2b7202a..9998569 100644 (file)
@@ -1790,71 +1790,6 @@ static char *get_ip(uint32_t ip)
        return g_strdup(inet_ntoa(addr));
 }
 
-/* get a rough idea of how long an option will be */
-static const uint8_t len_of_option_as_string[] = {
-       [OPTION_IP] = sizeof("255.255.255.255 "),
-       [OPTION_STRING] = 1,
-       [OPTION_U8] = sizeof("255 "),
-       [OPTION_U16] = sizeof("65535 "),
-       [OPTION_U32] = sizeof("4294967295 "),
-};
-
-static int sprint_nip(char *dest, const char *pre, const uint8_t *ip)
-{
-       return sprintf(dest, "%s%u.%u.%u.%u", pre, ip[0], ip[1], ip[2], ip[3]);
-}
-
-/* Create "opt_value1 option_value2 ..." string */
-static char *malloc_option_value_string(uint8_t *option, GDHCPOptionType type)
-{
-       unsigned upper_length;
-       int len, optlen;
-       char *dest, *ret;
-
-       len = option[OPT_LEN - OPT_DATA];
-       type &= OPTION_TYPE_MASK;
-       optlen = dhcp_option_lengths[type];
-       if (optlen == 0)
-               return NULL;
-       upper_length = len_of_option_as_string[type] *
-                       ((unsigned)len / (unsigned)optlen);
-       dest = ret = g_malloc(upper_length + 1);
-       if (!ret)
-               return NULL;
-
-       while (len >= optlen) {
-               switch (type) {
-               case OPTION_IP:
-                       dest += sprint_nip(dest, "", option);
-                       break;
-               case OPTION_U16: {
-                       uint16_t val_u16 = get_be16(option);
-                       dest += sprintf(dest, "%u", val_u16);
-                       break;
-               }
-               case OPTION_U32: {
-                       uint32_t val_u32 = get_be32(option);
-                       dest += sprintf(dest, "%u", val_u32);
-                       break;
-               }
-               case OPTION_STRING:
-                       memcpy(dest, option, len);
-                       dest[len] = '\0';
-                       return ret;
-               default:
-                       break;
-               }
-               option += optlen;
-               len -= optlen;
-               if (len <= 0)
-                       break;
-               *dest++ = ' ';
-               *dest = '\0';
-       }
-
-       return ret;
-}
-
 static GList *get_option_value_list(char *value, GDHCPOptionType type)
 {
        char *pos = value;
index e111150..d37dc77 100644 (file)
@@ -144,6 +144,71 @@ int dhcp_end_option(uint8_t *optionptr)
        return i;
 }
 
+/* get a rough idea of how long an option will be */
+static const uint8_t len_of_option_as_string[] = {
+       [OPTION_IP] = sizeof("255.255.255.255 "),
+       [OPTION_STRING] = 1,
+       [OPTION_U8] = sizeof("255 "),
+       [OPTION_U16] = sizeof("65535 "),
+       [OPTION_U32] = sizeof("4294967295 "),
+};
+
+static int sprint_nip(char *dest, const char *pre, const uint8_t *ip)
+{
+       return sprintf(dest, "%s%u.%u.%u.%u", pre, ip[0], ip[1], ip[2], ip[3]);
+}
+
+/* Create "opt_value1 option_value2 ..." string */
+char *malloc_option_value_string(uint8_t *option, GDHCPOptionType type)
+{
+       unsigned upper_length;
+       int len, optlen;
+       char *dest, *ret;
+
+       len = option[OPT_LEN - OPT_DATA];
+       type &= OPTION_TYPE_MASK;
+       optlen = dhcp_option_lengths[type];
+       if (optlen == 0)
+               return NULL;
+       upper_length = len_of_option_as_string[type] *
+                       ((unsigned)len / (unsigned)optlen);
+       dest = ret = g_malloc(upper_length + 1);
+       if (ret == NULL)
+               return NULL;
+
+       while (len >= optlen) {
+               switch (type) {
+               case OPTION_IP:
+                       dest += sprint_nip(dest, "", option);
+                       break;
+               case OPTION_U16: {
+                       uint16_t val_u16 = get_be16(option);
+                       dest += sprintf(dest, "%u", val_u16);
+                       break;
+               }
+               case OPTION_U32: {
+                       uint32_t val_u32 = get_be32(option);
+                       dest += sprintf(dest, "%u", val_u32);
+                       break;
+               }
+               case OPTION_STRING:
+                       memcpy(dest, option, len);
+                       dest[len] = '\0';
+                       return ret;
+               default:
+                       break;
+               }
+               option += optlen;
+               len -= optlen;
+               if (len <= 0)
+                       break;
+               *dest++ = ' ';
+               *dest = '\0';
+       }
+
+       return ret;
+}
+
 uint8_t *dhcpv6_get_option(struct dhcpv6_packet *packet, uint16_t pkt_len,
                        int code, uint16_t *option_len, int *option_count)
 {
index e4a4251..a6e7a65 100644 (file)
@@ -170,6 +170,7 @@ static const uint8_t dhcp_option_lengths[] = {
        [OPTION_U32]    = 4,
 };
 
+char *malloc_option_value_string(uint8_t *option, GDHCPOptionType type);
 uint8_t *dhcp_get_option(struct dhcp_packet *packet, int code);
 uint8_t *dhcpv6_get_option(struct dhcpv6_packet *packet, uint16_t pkt_len,
                        int code, uint16_t *option_len, int *option_count);
index f3e47bf..f4ef292 100644 (file)
@@ -205,6 +205,9 @@ struct _GDHCPServer;
 
 typedef struct _GDHCPServer GDHCPServer;
 
+typedef void (*GDHCPSaveACKLeaseFunc) (char *hostname,
+                       unsigned char *mac, unsigned int nip);
+
 GDHCPServer *g_dhcp_server_new(GDHCPType type,
                int ifindex, GDHCPServerError *error);
 int g_dhcp_server_start(GDHCPServer *server);
@@ -223,6 +226,8 @@ void g_dhcp_server_set_lease_time(GDHCPServer *dhcp_server,
                                                unsigned int lease_time);
 void g_dhcp_server_set_save_lease(GDHCPServer *dhcp_server,
                                GDHCPSaveLeaseFunc func, gpointer user_data);
+void g_dhcp_server_set_save_ack_lease(GDHCPServer *dhcp_server,
+                               GDHCPSaveACKLeaseFunc func, gpointer user_data);
 #ifdef __cplusplus
 }
 #endif
index 728992d..7bda4e5 100644 (file)
@@ -65,6 +65,7 @@ struct _GDHCPServer {
        GHashTable *nip_lease_hash;
        GHashTable *option_hash; /* Options send to client */
        GDHCPSaveLeaseFunc save_lease_func;
+       GDHCPSaveACKLeaseFunc save_ack_lease_func;
        GDHCPDebugFunc debug_func;
        gpointer debug_data;
 };
@@ -398,6 +399,7 @@ GDHCPServer *g_dhcp_server_new(GDHCPType type,
        dhcp_server->listener_watch = -1;
        dhcp_server->listener_channel = NULL;
        dhcp_server->save_lease_func = NULL;
+       dhcp_server->save_ack_lease_func = NULL;
        dhcp_server->debug_func = NULL;
        dhcp_server->debug_data = NULL;
 
@@ -646,9 +648,12 @@ static gboolean listener_event(GIOChannel *channel, GIOCondition condition,
        struct dhcp_packet packet;
        struct dhcp_lease *lease;
        uint32_t requested_nip = 0;
-       uint8_t type, *server_id_option, *request_ip_option;
+       uint8_t type, *server_id_option, *request_ip_option, *host_name;
        int re;
 
+       GDHCPOptionType option_type;
+       char *option_value;
+
        if (condition & (G_IO_NVAL | G_IO_ERR | G_IO_HUP)) {
                dhcp_server->listener_watch = 0;
                return FALSE;
@@ -693,8 +698,21 @@ static gboolean listener_event(GIOChannel *channel, GIOCondition condition,
 
                if (lease && requested_nip == lease->lease_nip) {
                        debug(dhcp_server, "Sending ACK");
+
+                       host_name = dhcp_get_option(&packet, DHCP_HOST_NAME);
+                       option_type = dhcp_get_code_type(DHCP_HOST_NAME);
+                       option_value = malloc_option_value_string(host_name,
+                                                               option_type);
                        send_ACK(dhcp_server, &packet,
                                lease->lease_nip);
+
+                       if (dhcp_server->save_ack_lease_func)
+                               dhcp_server->save_ack_lease_func(
+                                                       option_value,
+                                                       lease->lease_mac,
+                                                       lease->lease_nip);
+                       g_free(option_value);
+
                        break;
                }
 
@@ -814,6 +832,15 @@ void g_dhcp_server_set_save_lease(GDHCPServer *dhcp_server,
        dhcp_server->save_lease_func = func;
 }
 
+void g_dhcp_server_set_save_ack_lease(GDHCPServer *dhcp_server,
+                               GDHCPSaveACKLeaseFunc func, gpointer user_data)
+{
+       if (dhcp_server == NULL)
+               return;
+
+       dhcp_server->save_ack_lease_func = func;
+}
+
 GDHCPServer *g_dhcp_server_ref(GDHCPServer *dhcp_server)
 {
        if (!dhcp_server)