Tools: hv: Implement the KVP verb - KVP_OP_GET_IP_INFO
authorK. Y. Srinivasan <kys@microsoft.com>
Wed, 5 Sep 2012 20:50:15 +0000 (13:50 -0700)
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>
Mon, 10 Sep 2012 23:42:33 +0000 (16:42 -0700)
Now implement the KVP verb - KVP_OP_GET_IP_INFO. This operation retrieves IP
information for the specified interface.

Signed-off-by: K. Y. Srinivasan <kys@microsoft.com>
Reviewed-by: Haiyang Zhang <haiyangz@microsoft.com>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
tools/hv/hv_kvp_daemon.c

index 849c43817a2d3f3ce31e3ecbcfceee68e482a54d..c8e101363735fdbff8bf6e6067edb8d6c14b4d87 100644 (file)
@@ -603,6 +603,69 @@ static char *kvp_if_name_to_mac(char *if_name)
 }
 
 
+/*
+ * Retrieve the interface name given tha MAC address.
+ */
+
+static char *kvp_mac_to_if_name(char *mac)
+{
+       DIR *dir;
+       struct dirent *entry;
+       FILE    *file;
+       char    *p, *q, *x;
+       char    *if_name = NULL;
+       char    buf[256];
+       char *kvp_net_dir = "/sys/class/net/";
+       char dev_id[256];
+       int i;
+
+       dir = opendir(kvp_net_dir);
+       if (dir == NULL)
+               return NULL;
+
+       snprintf(dev_id, sizeof(dev_id), kvp_net_dir);
+       q = dev_id + strlen(kvp_net_dir);
+
+       while ((entry = readdir(dir)) != NULL) {
+               /*
+                * Set the state for the next pass.
+                */
+               *q = '\0';
+
+               strcat(dev_id, entry->d_name);
+               strcat(dev_id, "/address");
+
+               file = fopen(dev_id, "r");
+               if (file == NULL)
+                       continue;
+
+               p = fgets(buf, sizeof(buf), file);
+               if (p) {
+                       x = strchr(p, '\n');
+                       if (x)
+                               *x = '\0';
+
+                       for (i = 0; i < strlen(p); i++)
+                               p[i] = toupper(p[i]);
+
+                       if (!strcmp(p, mac)) {
+                               /*
+                                * Found the MAC match; return the interface
+                                * name. The caller will free the memory.
+                                */
+                               if_name = strdup(entry->d_name);
+                               fclose(file);
+                               break;
+                       }
+               }
+               fclose(file);
+       }
+
+       closedir(dir);
+       return if_name;
+}
+
+
 static void kvp_process_ipconfig_file(char *cmd,
                                        char *config_buf, int len,
                                        int element_size, int offset)
@@ -749,10 +812,10 @@ static int kvp_process_ip_address(void *addrp,
        }
 
        if ((length - *offset) < addr_length + 1)
-               return 1;
+               return HV_E_FAIL;
        if (str == NULL) {
                strcpy(buffer, "inet_ntop failed\n");
-               return 1;
+               return HV_E_FAIL;
        }
        if (*offset == 0)
                strcpy(buffer, tmp);
@@ -796,7 +859,7 @@ kvp_get_ip_info(int family, char *if_name, int op,
 
        if (getifaddrs(&ifap)) {
                strcpy(buffer, "getifaddrs failed\n");
-               return 1;
+               return HV_E_FAIL;
        }
 
        curp = ifap;
@@ -1386,6 +1449,30 @@ int main(void)
                }
 
                switch (op) {
+               case KVP_OP_GET_IP_INFO:
+                       kvp_ip_val = &hv_msg->body.kvp_ip_val;
+                       if_name =
+                       kvp_mac_to_if_name((char *)kvp_ip_val->adapter_id);
+
+                       if (if_name == NULL) {
+                               /*
+                                * We could not map the mac address to an
+                                * interface name; return error.
+                                */
+                               hv_msg->error = HV_E_FAIL;
+                               break;
+                       }
+                       error = kvp_get_ip_info(
+                                               0, if_name, KVP_OP_GET_IP_INFO,
+                                               kvp_ip_val,
+                                               (MAX_IP_ADDR_SIZE * 2));
+
+                       if (error)
+                               hv_msg->error = error;
+
+                       free(if_name);
+                       break;
+
                case KVP_OP_SET_IP_INFO:
                        kvp_ip_val = &hv_msg->body.kvp_ip_val;
                        if_name = kvp_get_if_name(