aboutsummaryrefslogtreecommitdiffstats
path: root/tools/hv
diff options
context:
space:
mode:
authorK. Y. Srinivasan <kys@microsoft.com>2012-08-16 21:32:13 -0400
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>2012-08-17 11:23:57 -0400
commit0ecaa1985e39344ab308190063f8a60cb2a96155 (patch)
treee4dcea34e5516a20baaf82d44a208a9fa495dc0c /tools/hv
parent03db7724af1315f644ddc26e9539789eac4a016a (diff)
Tools: hv: Prepare to expand kvp_get_ip_address() functionality
kvp_get_ip_address() implemented the functionality to retrieve IP address info. Make this function more generic so that we could retrieve additional per-interface information. 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>
Diffstat (limited to 'tools/hv')
-rw-r--r--tools/hv/hv_kvp_daemon.c129
1 files changed, 84 insertions, 45 deletions
diff --git a/tools/hv/hv_kvp_daemon.c b/tools/hv/hv_kvp_daemon.c
index 069e2b38decb..3af37f0060f4 100644
--- a/tools/hv/hv_kvp_daemon.c
+++ b/tools/hv/hv_kvp_daemon.c
@@ -492,7 +492,8 @@ done:
492} 492}
493 493
494static int 494static int
495kvp_get_ip_address(int family, char *buffer, int length) 495kvp_get_ip_address(int family, char *if_name, int op,
496 void *out_buffer, int length)
496{ 497{
497 struct ifaddrs *ifap; 498 struct ifaddrs *ifap;
498 struct ifaddrs *curp; 499 struct ifaddrs *curp;
@@ -502,10 +503,19 @@ kvp_get_ip_address(int family, char *buffer, int length)
502 const char *str; 503 const char *str;
503 char tmp[50]; 504 char tmp[50];
504 int error = 0; 505 int error = 0;
505 506 char *buffer;
507 struct hv_kvp_ipaddr_value *ip_buffer;
508
509 if (op == KVP_OP_ENUMERATE) {
510 buffer = out_buffer;
511 } else {
512 ip_buffer = out_buffer;
513 buffer = (char *)ip_buffer->ip_addr;
514 ip_buffer->addr_family = 0;
515 }
506 /* 516 /*
507 * On entry into this function, the buffer is capable of holding the 517 * On entry into this function, the buffer is capable of holding the
508 * maximum key value (2048 bytes). 518 * maximum key value.
509 */ 519 */
510 520
511 if (getifaddrs(&ifap)) { 521 if (getifaddrs(&ifap)) {
@@ -515,58 +525,87 @@ kvp_get_ip_address(int family, char *buffer, int length)
515 525
516 curp = ifap; 526 curp = ifap;
517 while (curp != NULL) { 527 while (curp != NULL) {
518 if ((curp->ifa_addr != NULL) && 528 if (curp->ifa_addr == NULL) {
519 (curp->ifa_addr->sa_family == family)) { 529 curp = curp->ifa_next;
520 if (family == AF_INET) { 530 continue;
521 struct sockaddr_in *addr = 531 }
522 (struct sockaddr_in *) curp->ifa_addr;
523
524 str = inet_ntop(family, &addr->sin_addr,
525 tmp, 50);
526 if (str == NULL) {
527 strcpy(buffer, "inet_ntop failed\n");
528 error = 1;
529 goto getaddr_done;
530 }
531 if (offset == 0)
532 strcpy(buffer, tmp);
533 else
534 strcat(buffer, tmp);
535 strcat(buffer, ";");
536 532
537 offset += strlen(str) + 1; 533 if ((if_name != NULL) &&
538 if ((length - offset) < (ipv4_len + 1)) 534 (strncmp(curp->ifa_name, if_name, strlen(if_name)))) {
539 goto getaddr_done; 535 /*
536 * We want info about a specific interface;
537 * just continue.
538 */
539 curp = curp->ifa_next;
540 continue;
541 }
540 542
541 } else { 543 /*
544 * We only support two address families: AF_INET and AF_INET6.
545 * If a family value of 0 is specified, we collect both
546 * supported address families; if not we gather info on
547 * the specified address family.
548 */
549 if ((family != 0) && (curp->ifa_addr->sa_family != family)) {
550 curp = curp->ifa_next;
551 continue;
552 }
553 if ((curp->ifa_addr->sa_family != AF_INET) &&
554 (curp->ifa_addr->sa_family != AF_INET6)) {
555 curp = curp->ifa_next;
556 continue;
557 }
558
559 if ((curp->ifa_addr->sa_family == AF_INET) &&
560 ((family == AF_INET) || (family == 0))) {
561 struct sockaddr_in *addr =
562 (struct sockaddr_in *) curp->ifa_addr;
563
564 str = inet_ntop(AF_INET, &addr->sin_addr, tmp, 50);
565 if (str == NULL) {
566 strcpy(buffer, "inet_ntop failed\n");
567 error = 1;
568 goto getaddr_done;
569 }
570 if (offset == 0)
571 strcpy(buffer, tmp);
572 else
573 strcat(buffer, tmp);
574 strcat(buffer, ";");
575
576 offset += strlen(str) + 1;
577 if ((length - offset) < (ipv4_len + 1))
578 goto getaddr_done;
579
580 } else if ((family == AF_INET6) || (family == 0)) {
542 581
543 /* 582 /*
544 * We only support AF_INET and AF_INET6 583 * We only support AF_INET and AF_INET6
545 * and the list of addresses is separated by a ";". 584 * and the list of addresses is separated by a ";".
546 */ 585 */
547 struct sockaddr_in6 *addr = 586 struct sockaddr_in6 *addr =
548 (struct sockaddr_in6 *) curp->ifa_addr; 587 (struct sockaddr_in6 *) curp->ifa_addr;
549 588
550 str = inet_ntop(family, 589 str = inet_ntop(AF_INET6,
551 &addr->sin6_addr.s6_addr, 590 &addr->sin6_addr.s6_addr,
552 tmp, 50); 591 tmp, 50);
553 if (str == NULL) { 592 if (str == NULL) {
554 strcpy(buffer, "inet_ntop failed\n"); 593 strcpy(buffer, "inet_ntop failed\n");
555 error = 1; 594 error = 1;
556 goto getaddr_done; 595 goto getaddr_done;
557 }
558 if (offset == 0)
559 strcpy(buffer, tmp);
560 else
561 strcat(buffer, tmp);
562 strcat(buffer, ";");
563 offset += strlen(str) + 1;
564 if ((length - offset) < (ipv6_len + 1))
565 goto getaddr_done;
566
567 } 596 }
597 if (offset == 0)
598 strcpy(buffer, tmp);
599 else
600 strcat(buffer, tmp);
601 strcat(buffer, ";");
602 offset += strlen(str) + 1;
603 if ((length - offset) < (ipv6_len + 1))
604 goto getaddr_done;
568 605
569 } 606 }
607
608
570 curp = curp->ifa_next; 609 curp = curp->ifa_next;
571 } 610 }
572 611
@@ -811,13 +850,13 @@ int main(void)
811 strcpy(key_value, lic_version); 850 strcpy(key_value, lic_version);
812 break; 851 break;
813 case NetworkAddressIPv4: 852 case NetworkAddressIPv4:
814 kvp_get_ip_address(AF_INET, key_value, 853 kvp_get_ip_address(AF_INET, NULL, KVP_OP_ENUMERATE,
815 HV_KVP_EXCHANGE_MAX_VALUE_SIZE); 854 key_value, HV_KVP_EXCHANGE_MAX_VALUE_SIZE);
816 strcpy(key_name, "NetworkAddressIPv4"); 855 strcpy(key_name, "NetworkAddressIPv4");
817 break; 856 break;
818 case NetworkAddressIPv6: 857 case NetworkAddressIPv6:
819 kvp_get_ip_address(AF_INET6, key_value, 858 kvp_get_ip_address(AF_INET6, NULL, KVP_OP_ENUMERATE,
820 HV_KVP_EXCHANGE_MAX_VALUE_SIZE); 859 key_value, HV_KVP_EXCHANGE_MAX_VALUE_SIZE);
821 strcpy(key_name, "NetworkAddressIPv6"); 860 strcpy(key_name, "NetworkAddressIPv6");
822 break; 861 break;
823 case OSBuildNumber: 862 case OSBuildNumber: