Completed more functionality

This commit is contained in:
Fabrizio Bertocci 2021-06-22 20:12:09 +02:00
parent 08765c0850
commit 5704b03d26
2 changed files with 125 additions and 38 deletions

View file

@ -38,6 +38,8 @@
#define MAX_INTERFACES 32 #define MAX_INTERFACES 32
static int insertAdapterName(NtPIpAdapterAddresses aa);
/* Reference: /* Reference:
* - Description of ioctls: https://docs.microsoft.com/en-us/windows/win32/winsock/winsock-ioctls * - Description of ioctls: https://docs.microsoft.com/en-us/windows/win32/winsock/winsock-ioctls
* - Structure INTERFACE_INFO: https://docs.microsoft.com/en-us/windows/win32/api/ws2ipdef/ns-ws2ipdef-interface_info * - Structure INTERFACE_INFO: https://docs.microsoft.com/en-us/windows/win32/api/ws2ipdef/ns-ws2ipdef-interface_info
@ -59,6 +61,7 @@
struct HostAdapterDesc { struct HostAdapterDesc {
char name[IFNAMSIZ]; /* Given name */ char name[IFNAMSIZ]; /* Given name */
NtIpAdapterAddresses * addresses; /* NULL = invalid record */ NtIpAdapterAddresses * addresses; /* NULL = invalid record */
short flags; /* Holds the same value as ifr_flags */
}; };
NtIpAdapterAddresses * theHostAdapterAddress; NtIpAdapterAddresses * theHostAdapterAddress;
@ -91,10 +94,13 @@ static void freeAdapterInfo(void) {
} }
/* Sets theHostAdapterAddress. /* Sets theHostAdapterAddress.
* Returns -1 in case of failure (setting errno appropriately), 0 if success */ * Returns -1 in case of failure (setting errno appropriately), 0 if success */
static int _readAdapterAddresses(void) { static int _readAdapterAddresses(void) {
NtPIpAdapterAddresses aa;
uint32_t size, rc; uint32_t size, rc;
short flags;
int i;
PRINTF("FABDEBUG> _readAdapterAddresses:\n"); PRINTF("FABDEBUG> _readAdapterAddresses:\n");
assert(theHostAdapterAddress == NULL); assert(theHostAdapterAddress == NULL);
@ -132,11 +138,47 @@ static int _readAdapterAddresses(void) {
freeAdapterInfo(); freeAdapterInfo();
return efault(); return efault();
} }
/* Iterate through all the adapters and populate theAdapterName */
for (aa = theHostAdapterAddress; aa != NULL; aa = aa->Next) {
i = insertAdapterName(aa);
if (i == -1) {
PRINTF("FABDEBUG> Too many adapters\n");
freeAdapterInfo();
return enomem();
}
/* Calculate the flags for this adapter. Flags to consider:
* IFF_UP
* IFF_BROADCAST ** TODO: We need to validate
* IFF_LOOPBACK
* IFF_POINTOPOINT
* IFF_MULTICAST
* IFF_RUNNING ** Same as IFF_UP for now
* IFF_PROMISC ** NOT SUPPORTED, unknown how to retrieve it
*/
flags = 0;
if (aa->OperStatus == IfOperStatusUp) flags |= IFF_UP | IFF_RUNNING;
if (aa->IfType == NT_IF_TYPE_PPP) flags |= IFF_POINTOPOINT;
//if (aa->TunnelType != TUNNEL_TYPE_NONE) flags |= IFF_POINTOPOINT;
if (aa->NoMulticast == 0) flags |= IFF_MULTICAST;
if (aa->IfType == NT_IF_TYPE_SOFTWARE_LOOPBACK) flags |= IFF_LOOPBACK;
if (aa->FirstPrefix != NULL) flags |= IFF_BROADCAST;
/* Broadcast - Broadcast address should be detectable though the FirstPrefix
* linked list
*/
flags |= IFF_BROADCAST; /* Assume yes for all the interfaces */
theAdapterName[i].flags = flags;
}
PRINTF("FABDEBUG> \tDone reading.\n"); PRINTF("FABDEBUG> \tDone reading.\n");
return 0; return 0;
} }
#if 1
void printUnicastAddressList(NtPIpAdapterUnicastAddress addr) { void printUnicastAddressList(NtPIpAdapterUnicastAddress addr) {
const char * sep = ""; const char * sep = "";
for(; addr; addr=addr->Next) { for(; addr; addr=addr->Next) {
@ -148,6 +190,8 @@ void printUnicastAddressList(NtPIpAdapterUnicastAddress addr) {
} }
} }
#endif
static int insertAdapterName(NtPIpAdapterAddresses aa) { static int insertAdapterName(NtPIpAdapterAddresses aa) {
char name[IFNAMSIZ]; char name[IFNAMSIZ];
int i; int i;
@ -186,6 +230,28 @@ static int insertAdapterName(NtPIpAdapterAddresses aa) {
/* Returns the index in theAdapterName if found or -1 if
* an error occurred
*/
static int findOrInitAdapter(const char *name) {
int i;
if (!theHostAdapterAddress) {
/* Never invoked GetAdaptersAddresses */
if (_readAdapterAddresses() == -1) {
return -1;
}
}
i = findAdapterByName(name);
if (i == -1) {
PRINTF("FABDEBUG> Bad adapter\n");
return ebadf();
}
return i;
}
textwindows int ioctl_siocgifconf_nt(int fd, struct ifconf *ifc) { textwindows int ioctl_siocgifconf_nt(int fd, struct ifconf *ifc) {
NtPIpAdapterAddresses aa; NtPIpAdapterAddresses aa;
struct ifreq *ptr; struct ifreq *ptr;
@ -214,26 +280,24 @@ textwindows int ioctl_siocgifconf_nt(int fd, struct ifconf *ifc) {
return -1; return -1;
} }
for (ptr = ifc->ifc_req, aa = theHostAdapterAddress; for (ptr = ifc->ifc_req, i=0;
(aa != NULL) && ((char *)(ptr+1) - ifc->ifc_buf) < ifc->ifc_len; ((char *)(ptr+1) - ifc->ifc_buf) < ifc->ifc_len;
aa = aa->Next, ptr++) { ++i, ptr++) {
i = insertAdapterName(aa); aa = theAdapterName[i].addresses;
if (i == -1) { if (!aa) {
PRINTF("FABDEBUG> Too many adapters\n"); break;
freeAdapterInfo();
return enomem();
} }
strncpy(ptr->ifr_name, theAdapterName[i].name, IFNAMSIZ-1); memcpy(ptr->ifr_name, theAdapterName[i].name, IFNAMSIZ);
ptr->ifr_name[IFNAMSIZ-1]='\0';
PRINTF("FABDEBUG> Adapter name = %s\n", ptr->ifr_name); PRINTF("FABDEBUG> #%d: Adapter name = %s\n", i, ptr->ifr_name);
if (aa->FirstUnicastAddress) { if (aa->FirstUnicastAddress) {
ptr->ifr_addr = *aa->FirstUnicastAddress->Address.lpSockaddr; /* Windows sockaddr is compatible with Linux */ ptr->ifr_addr = *aa->FirstUnicastAddress->Address.lpSockaddr; /* Windows sockaddr is compatible with Linux */
PRINTF("FABDEBUG> \tIP="); PRINTF("FABDEBUG> \tIP=");
printUnicastAddressList(aa->FirstUnicastAddress); printUnicastAddressList(aa->FirstUnicastAddress);
PRINTF("\n"); PRINTF("\n");
} }
} }
ifc->ifc_len = (char *)ptr - ifc->ifc_buf; ifc->ifc_len = (char *)ptr - ifc->ifc_buf;
@ -245,11 +309,10 @@ textwindows int ioctl_siocgifconf_nt(int fd, struct ifconf *ifc) {
int ioctl_siocgifaddr_nt(int fd, struct ifreq *ifr) { int ioctl_siocgifaddr_nt(int fd, struct ifreq *ifr) {
NtPIpAdapterAddresses aa; NtPIpAdapterAddresses aa;
int i; int i;
i = findAdapterByName(ifr->ifr_name); i = findOrInitAdapter(ifr->ifr_name);
if (i == -1) { if (i == -1) {
PRINTF("FABDEBUG> Bad adapter\n"); return -1;
return ebadf();
} }
aa = theAdapterName[i].addresses; aa = theAdapterName[i].addresses;
@ -261,34 +324,58 @@ int ioctl_siocgifaddr_nt(int fd, struct ifreq *ifr) {
/* Performs the SIOCGIFFLAGS operation */ /* Performs the SIOCGIFFLAGS operation */
int ioctl_siocgifflags_nt(int fd, struct ifreq *ifr) { int ioctl_siocgifflags_nt(int fd, struct ifreq *ifr) {
NtPIpAdapterAddresses aa;
int i; int i;
i = findAdapterByName(ifr->ifr_name); i = findOrInitAdapter(ifr->ifr_name);
if (i == -1) { if (i == -1) {
PRINTF("FABDEBUG> Bad adapter\n"); return -1;
return ebadf();
} }
aa = theAdapterName[i].addresses; PRINTF(">>>>CAZZO=%d - %d\n", i, theAdapterName[i].flags);
ifr->ifr_flags = 0; ifr->ifr_flags = theAdapterName[i].flags;
/* Flags to consider:
* IFF_UP
* IFF_BROADCAST ** TODO: We need to validate
* IFF_LOOPBACK
* IFF_POINTOPOINT
* IFF_RUNNING ** Same as IFF_UP for now
* IFF_PROMISC ** NOT SUPPORTED, unknown how to retrieve it
*/
if (aa->OperStatus == IfOperStatusUp) ifr->ifr_flags |= IFF_UP | IFF_RUNNING;
if (aa->IfType == NT_IF_TYPE_PPP) ifr->ifr_flags |= IFF_POINTOPOINT;
//if (aa->TunnelType != TUNNEL_TYPE_NONE) ifr->ifr_flags |= IFF_POINTOPOINT;
if (aa->IfType == NT_IF_TYPE_SOFTWARE_LOOPBACK) ifr->ifr_flags |= IFF_LOOPBACK;
if (aa->FirstPrefix != NULL) ifr->ifr_flags |= IFF_BROADCAST;
return 0; return 0;
} }
/* Performs the SIOCGIFNETMASK operation */
int ioctl_siocgifnetmask_nt(int fd, struct ifreq *ifr) {
NtPIpAdapterAddresses aa;
int i;
i = findOrInitAdapter(ifr->ifr_name);
if (i == -1) {
return -1;
}
PRINTF("FABDEBUG>>>> NETMASK\n");
aa = theAdapterName[i].addresses;
/* According to the doc:
* ... On Windows Vista and later, the linked IP_ADAPTER_PREFIX structures pointed to
* by the FirstPrefix member include three IP adapter prefixes for each IP address
* assigned to the adapter. These include the host IP address prefix, the subnet IP
* address prefix, and the subnet broadcast IP address prefix. In addition, for each
* adapter there is a multicast address prefix and a broadcast address prefix.
*
* So, in short, for each of the assigned addresses, the IP_ADAPTER_PREFIX objects are:
* #0: Host IP Address
* #1: Subnet
* #2: Broadcast
* #3: Multicast
* #4: Broadcast
*/
if (aa->FirstPrefix) {
int count;
NtPIpAdapterPrefix prefix;
for (count=0, prefix=aa->FirstPrefix; prefix; prefix=prefix->Next, ++count) {
PRINTF("FABDEBUG>>>>\t%d: %s/%d\n", count, weaken(inet_ntoa)(
((struct sockaddr_in *)(prefix->Address.lpSockaddr))->sin_addr), prefix->PrefixLength);
if (count == 4) {
ifr->ifr_netmask = *prefix->Address.lpSockaddr;
}
}
}
return 0;
}

View file

@ -37,6 +37,7 @@ int ioctl_default(int, uint64_t, void *) hidden;
int ioctl_siocgifconf_nt(int, struct ifconf *) hidden; int ioctl_siocgifconf_nt(int, struct ifconf *) hidden;
int ioctl_siocgifaddr_nt(int, struct ifreq *) hidden; int ioctl_siocgifaddr_nt(int, struct ifreq *) hidden;
int ioctl_siocgifflags_nt(int, struct ifreq *) hidden; int ioctl_siocgifflags_nt(int, struct ifreq *) hidden;
int ioctl_siocgifnetmask_nt(int, struct ifreq *) hidden;
static int ioctl_siocgifconf_sysv(int fd, struct ifconf *ifc) { static int ioctl_siocgifconf_sysv(int fd, struct ifconf *ifc) {
if (IsBsd()) { if (IsBsd()) {
@ -140,8 +141,7 @@ int ioctl_siocgifnetmask(int fd, void *ifr) {
if (!IsWindows()) { if (!IsWindows()) {
return ioctl_siocgifaddr_sysv(fd, SIOCGIFNETMASK, (struct ifreq *)ifr); return ioctl_siocgifaddr_sysv(fd, SIOCGIFNETMASK, (struct ifreq *)ifr);
} else { } else {
return enotsup(); return ioctl_siocgifnetmask_nt(fd, (struct ifreq *)ifr);
//return ioctl_siocgifnetmask_nt(fd, ifc);
} }
} }