diff options
author | K. Y. Srinivasan <kys@microsoft.com> | 2012-08-16 21:32:13 -0400 |
---|---|---|
committer | Greg Kroah-Hartman <gregkh@linuxfoundation.org> | 2012-08-17 11:23:57 -0400 |
commit | 0ecaa1985e39344ab308190063f8a60cb2a96155 (patch) | |
tree | e4dcea34e5516a20baaf82d44a208a9fa495dc0c /tools/hv | |
parent | 03db7724af1315f644ddc26e9539789eac4a016a (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.c | 129 |
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 | ||
494 | static int | 494 | static int |
495 | kvp_get_ip_address(int family, char *buffer, int length) | 495 | kvp_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: |