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 | |
| 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')
| -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; | ||
