- reduce resource usage in hv_kvp_daemon (175c71c2) - reduce resouce usage in hv_get_dns_info helper (a4d024fe) - hv_kvp_daemon: Pass NIC name to hv_get_dns_info as well (07dfa6e8) - terminate fcopy daemon if read from uio fails (a9640fcd) - change permissions of NetworkManager configuration file (91ae69c7) - Fix a complier warning in the fcopy uio daemon (cb1b78f1) - remove obsolete kvptest.ps1.txt which failed since a decade - remove obsolete rpm postinstall code for SLE11SP2 OBS-URL: https://build.opensuse.org/package/show/Virtualization/hyper-v?expand=0&rev=162
150 lines
4.3 KiB
Diff
150 lines
4.3 KiB
Diff
--- a/hyper-v.tools.hv.hv_kvp_daemon.c
|
|
+++ b/hyper-v.tools.hv.hv_kvp_daemon.c
|
|
@@ -24,6 +24,7 @@
|
|
|
|
#include <sys/poll.h>
|
|
#include <sys/utsname.h>
|
|
+#include <stdbool.h>
|
|
#include <stdio.h>
|
|
#include <stdlib.h>
|
|
#include <unistd.h>
|
|
@@ -677,6 +678,83 @@ static void kvp_process_ipconfig_file(ch
|
|
pclose(file);
|
|
}
|
|
|
|
+static bool kvp_verify_ip_address(void *address_string)
|
|
+{
|
|
+ char verify_buf[sizeof(struct in6_addr)];
|
|
+
|
|
+ if (inet_pton(AF_INET, address_string, verify_buf) == 1)
|
|
+ return true;
|
|
+ if (inet_pton(AF_INET6, address_string, verify_buf) == 1)
|
|
+ return true;
|
|
+ return false;
|
|
+}
|
|
+
|
|
+static void kvp_extract_routes(void **output, size_t *output_len, char *line)
|
|
+{
|
|
+ static const char needle[] = "via ";
|
|
+ char *match, *haystack = line;
|
|
+
|
|
+ while ((match = strstr(haystack, needle))) {
|
|
+ char *address, *end;
|
|
+
|
|
+ /* Address starts after needle. */
|
|
+ address = match + strlen(needle);
|
|
+
|
|
+ /* The char following address is a space or end of line. */
|
|
+ end = strpbrk(address, " \t\\");
|
|
+ if (!end)
|
|
+ end = address + strlen(address) + 1;
|
|
+
|
|
+ /* Enough room for address and semicolon. */
|
|
+ if (*output_len >= (end - address) + 1) {
|
|
+ memcpy(*output, address, end - address);
|
|
+ /* Terminate string for verification. */
|
|
+ memcpy(*output + (end - address), "", 1);
|
|
+ if (kvp_verify_ip_address(*output)) {
|
|
+ /* Advance output buffer. */
|
|
+ *output += end - address;
|
|
+ *output_len -= end - address;
|
|
+
|
|
+ /* Each address needs a trailing semicolon. */
|
|
+ memcpy(*output, ";", 1);
|
|
+ *output += 1;
|
|
+ *output_len -= 1;
|
|
+ }
|
|
+ }
|
|
+ haystack = end;
|
|
+ }
|
|
+}
|
|
+
|
|
+static void kvp_get_gateway(void *buffer, size_t buffer_len)
|
|
+{
|
|
+ static const char needle[] = "default ";
|
|
+ FILE *f;
|
|
+ void *output = buffer;
|
|
+ char *line = NULL;
|
|
+ size_t alloc_size = 0, output_len = buffer_len - 1;
|
|
+ ssize_t num_chars;
|
|
+
|
|
+ /* Show route information in a single line, for each address family */
|
|
+ f = popen("ip --oneline -4 route show;exec ip --oneline -6 route show", "r");
|
|
+ while ((num_chars = getline(&line, &alloc_size, f)) > 0) {
|
|
+ /* Skip short lines. */
|
|
+ if (num_chars <= strlen(needle))
|
|
+ continue;
|
|
+ /* Skip lines without default route. */
|
|
+ if (memcmp(line, needle, strlen(needle)))
|
|
+ continue;
|
|
+ /* Remove trailing newline to simplify further parsing. */
|
|
+ if (line[num_chars - 1] == '\n')
|
|
+ line[num_chars - 1] = '\0';
|
|
+ /* Search routes after match. */
|
|
+ kvp_extract_routes(&output, &output_len, line + strlen(needle));
|
|
+ }
|
|
+ /* Convert buffer into C-String. */
|
|
+ memcpy(output, "", 1);
|
|
+ free(line);
|
|
+ pclose(f);
|
|
+}
|
|
+
|
|
static void kvp_get_ipconfig_info(char *if_name,
|
|
struct hv_kvp_ipaddr_value *buffer)
|
|
{
|
|
@@ -684,32 +762,7 @@ static void kvp_get_ipconfig_info(char *
|
|
char dhcp_info[128];
|
|
char *p;
|
|
FILE *file;
|
|
-
|
|
- /*
|
|
- * Get the address of default gateway (ipv4).
|
|
- */
|
|
- sprintf(cmd, "%s %s", "ip route show dev", if_name);
|
|
- strcat(cmd, " | awk '/default/ {print $3 }'");
|
|
-
|
|
- /*
|
|
- * Execute the command to gather gateway info.
|
|
- */
|
|
- kvp_process_ipconfig_file(cmd, (char *)buffer->gate_way,
|
|
- (MAX_GATEWAY_SIZE * 2), INET_ADDRSTRLEN, 0);
|
|
-
|
|
- /*
|
|
- * Get the address of default gateway (ipv6).
|
|
- */
|
|
- sprintf(cmd, "%s %s", "ip -f inet6 route show dev", if_name);
|
|
- strcat(cmd, " | awk '/default/ {print $3 }'");
|
|
-
|
|
- /*
|
|
- * Execute the command to gather gateway info (ipv6).
|
|
- */
|
|
- kvp_process_ipconfig_file(cmd, (char *)buffer->gate_way,
|
|
- (MAX_GATEWAY_SIZE * 2), INET6_ADDRSTRLEN, 1);
|
|
-
|
|
-
|
|
+ kvp_get_gateway(buffer->gate_way, sizeof(buffer->gate_way));
|
|
/*
|
|
* Gather the DNS state.
|
|
* Since there is no standard way to get this information
|
|
@@ -1335,6 +1335,7 @@ kvp_get_domain_name(char *buffer, int le
|
|
struct addrinfo hints, *info ;
|
|
int error = 0;
|
|
|
|
+ return;
|
|
gethostname(buffer, length);
|
|
memset(&hints, 0, sizeof(hints));
|
|
hints.ai_family = AF_INET; /*Get only ipv4 addrinfo. */
|
|
@@ -1572,6 +1573,12 @@ int main(int argc, char *argv[])
|
|
|
|
switch (hv_msg->body.kvp_enum_data.index) {
|
|
case FullyQualifiedDomainName:
|
|
+ /*
|
|
+ * The API is undocumented.
|
|
+ * The Host can not possibly care about DNS within the guest network
|
|
+ * The time it takes to get the hostname is much shorter than a DNS lookup.
|
|
+ */
|
|
+ gethostname(full_domain_name, sizeof(full_domain_name));
|
|
strcpy(key_value, full_domain_name);
|
|
strcpy(key_name, "FullyQualifiedDomainName");
|
|
break;
|