zos: add uv_interface_addresses() netmask support (#3640 2/3)
Use SIOCGIFNETMASK ioctl to retrieve the netmask for IPv4. However, this approach is not supported for IPv6. For IPv6 netmask, z/OS currently only provides the prefix length through the __nif6e_prefixlen in __net_ifconf6entry_t struct, but this can be used to calculate the IPv6 netmask similar to android implementation. Co-authored-by: Igor Todorovski <itodorov@ca.ibm.com>
This commit is contained in:
parent
75ad046bfb
commit
524c5ed87d
@ -279,6 +279,7 @@ static int uv__interface_addresses_v6(uv_interface_address_t** addresses,
|
|||||||
__net_ifconf6entry_t* ifr;
|
__net_ifconf6entry_t* ifr;
|
||||||
__net_ifconf6entry_t* p;
|
__net_ifconf6entry_t* p;
|
||||||
unsigned int i;
|
unsigned int i;
|
||||||
|
unsigned char netmask[16] = {0};
|
||||||
|
|
||||||
*count = 0;
|
*count = 0;
|
||||||
/* Assume maximum buffer size allowable */
|
/* Assume maximum buffer size allowable */
|
||||||
@ -303,8 +304,7 @@ static int uv__interface_addresses_v6(uv_interface_address_t** addresses,
|
|||||||
p = ifr;
|
p = ifr;
|
||||||
ifr = (__net_ifconf6entry_t*)((char*)ifr + ifc.__nif6h_entrylen);
|
ifr = (__net_ifconf6entry_t*)((char*)ifr + ifc.__nif6h_entrylen);
|
||||||
|
|
||||||
if (!(p->__nif6e_addr.sin6_family == AF_INET6 ||
|
if (!(p->__nif6e_addr.sin6_family == AF_INET6))
|
||||||
p->__nif6e_addr.sin6_family == AF_INET))
|
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
if (!(p->__nif6e_flags & _NIF6E_FLAGS_ON_LINK_ACTIVE))
|
if (!(p->__nif6e_flags & _NIF6E_FLAGS_ON_LINK_ACTIVE))
|
||||||
@ -326,8 +326,7 @@ static int uv__interface_addresses_v6(uv_interface_address_t** addresses,
|
|||||||
p = ifr;
|
p = ifr;
|
||||||
ifr = (__net_ifconf6entry_t*)((char*)ifr + ifc.__nif6h_entrylen);
|
ifr = (__net_ifconf6entry_t*)((char*)ifr + ifc.__nif6h_entrylen);
|
||||||
|
|
||||||
if (!(p->__nif6e_addr.sin6_family == AF_INET6 ||
|
if (!(p->__nif6e_addr.sin6_family == AF_INET6))
|
||||||
p->__nif6e_addr.sin6_family == AF_INET))
|
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
if (!(p->__nif6e_flags & _NIF6E_FLAGS_ON_LINK_ACTIVE))
|
if (!(p->__nif6e_flags & _NIF6E_FLAGS_ON_LINK_ACTIVE))
|
||||||
@ -350,7 +349,15 @@ static int uv__interface_addresses_v6(uv_interface_address_t** addresses,
|
|||||||
|
|
||||||
address->address.address6 = *((struct sockaddr_in6*) &p->__nif6e_addr);
|
address->address.address6 = *((struct sockaddr_in6*) &p->__nif6e_addr);
|
||||||
|
|
||||||
/* TODO: Retrieve netmask using SIOCGIFNETMASK ioctl */
|
for (i = 0; i < (p->__nif6e_prefixlen / 8); i++)
|
||||||
|
netmask[i] = 0xFF;
|
||||||
|
|
||||||
|
if (p->__nif6e_prefixlen % 8)
|
||||||
|
netmask[i] = 0xFF << (8 - (p->__nif6e_prefixlen % 8));
|
||||||
|
|
||||||
|
address->netmask.netmask6.sin6_len = p->__nif6e_prefixlen;
|
||||||
|
memcpy(&(address->netmask.netmask6.sin6_addr), netmask, 16);
|
||||||
|
address->netmask.netmask6.sin6_family = AF_INET6;
|
||||||
|
|
||||||
address->is_internal = p->__nif6e_flags & _NIF6E_FLAGS_LOOPBACK ? 1 : 0;
|
address->is_internal = p->__nif6e_flags & _NIF6E_FLAGS_LOOPBACK ? 1 : 0;
|
||||||
memset(address->phys_addr, 0, sizeof(address->phys_addr));
|
memset(address->phys_addr, 0, sizeof(address->phys_addr));
|
||||||
@ -479,6 +486,13 @@ int uv_interface_addresses(uv_interface_address_t** addresses, int* count) {
|
|||||||
|
|
||||||
address->address.address4 = *((struct sockaddr_in*) &p->ifr_addr);
|
address->address.address4 = *((struct sockaddr_in*) &p->ifr_addr);
|
||||||
|
|
||||||
|
if (ioctl(sockfd, SIOCGIFNETMASK, p) == -1) {
|
||||||
|
uv__close(sockfd);
|
||||||
|
return UV__ERR(errno);
|
||||||
|
}
|
||||||
|
|
||||||
|
address->netmask.netmask4 = *((struct sockaddr_in*) &p->ifr_addr);
|
||||||
|
address->netmask.netmask4.sin_family = AF_INET;
|
||||||
address->is_internal = flg.ifr_flags & IFF_LOOPBACK ? 1 : 0;
|
address->is_internal = flg.ifr_flags & IFF_LOOPBACK ? 1 : 0;
|
||||||
memset(address->phys_addr, 0, sizeof(address->phys_addr));
|
memset(address->phys_addr, 0, sizeof(address->phys_addr));
|
||||||
address++;
|
address++;
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user