|
@@ -491,6 +491,15 @@ done:
|
|
|
return;
|
|
|
}
|
|
|
|
|
|
+static unsigned int hweight32(unsigned int *w)
|
|
|
+{
|
|
|
+ unsigned int res = *w - ((*w >> 1) & 0x55555555);
|
|
|
+ res = (res & 0x33333333) + ((res >> 2) & 0x33333333);
|
|
|
+ res = (res + (res >> 4)) & 0x0F0F0F0F;
|
|
|
+ res = res + (res >> 8);
|
|
|
+ return (res + (res >> 16)) & 0x000000FF;
|
|
|
+}
|
|
|
+
|
|
|
static int kvp_process_ip_address(void *addrp,
|
|
|
int family, char *buffer,
|
|
|
int length, int *offset)
|
|
@@ -535,10 +544,15 @@ kvp_get_ip_address(int family, char *if_name, int op,
|
|
|
struct ifaddrs *curp;
|
|
|
int offset = 0;
|
|
|
int sn_offset = 0;
|
|
|
- const char *str;
|
|
|
int error = 0;
|
|
|
char *buffer;
|
|
|
struct hv_kvp_ipaddr_value *ip_buffer;
|
|
|
+ char cidr_mask[5]; /* /xyz */
|
|
|
+ int weight;
|
|
|
+ int i;
|
|
|
+ unsigned int *w;
|
|
|
+ char *sn_str;
|
|
|
+ struct sockaddr_in6 *addr6;
|
|
|
|
|
|
if (op == KVP_OP_ENUMERATE) {
|
|
|
buffer = out_buffer;
|
|
@@ -611,18 +625,30 @@ kvp_get_ip_address(int family, char *if_name, int op,
|
|
|
goto gather_ipaddr;
|
|
|
} else {
|
|
|
ip_buffer->addr_family |= ADDR_FAMILY_IPV6;
|
|
|
+
|
|
|
/*
|
|
|
- * Get subnet info.
|
|
|
+ * Get subnet info in CIDR format.
|
|
|
*/
|
|
|
- error = kvp_process_ip_address(
|
|
|
- curp->ifa_netmask,
|
|
|
- AF_INET6,
|
|
|
- (char *)
|
|
|
- ip_buffer->sub_net,
|
|
|
- length,
|
|
|
- &sn_offset);
|
|
|
- if (error)
|
|
|
+ weight = 0;
|
|
|
+ sn_str = (char *)ip_buffer->sub_net;
|
|
|
+ addr6 = (struct sockaddr_in6 *)
|
|
|
+ curp->ifa_netmask;
|
|
|
+ w = addr6->sin6_addr.s6_addr32;
|
|
|
+
|
|
|
+ for (i = 0; i < 4; i++)
|
|
|
+ weight += hweight32(&w[i]);
|
|
|
+
|
|
|
+ sprintf(cidr_mask, "/%d", weight);
|
|
|
+ if ((length - sn_offset) <
|
|
|
+ (strlen(cidr_mask) + 1))
|
|
|
goto gather_ipaddr;
|
|
|
+
|
|
|
+ if (sn_offset == 0)
|
|
|
+ strcpy(sn_str, cidr_mask);
|
|
|
+ else
|
|
|
+ strcat(sn_str, cidr_mask);
|
|
|
+ strcat((char *)ip_buffer->sub_net, ";");
|
|
|
+ sn_offset += strlen(sn_str) + 1;
|
|
|
}
|
|
|
}
|
|
|
|