Implemented arp table querying through WsControl, and fixed problem I
introduced getting IP addresses for multiple interfaces.
This commit is contained in:
parent
1b5c4135e2
commit
b9ed79c965
@ -161,7 +161,7 @@ DWORD WINAPI WsControl(DWORD protocol,
|
|||||||
}
|
}
|
||||||
|
|
||||||
GetNumberOfInterfaces(&numInt);
|
GetNumberOfInterfaces(&numInt);
|
||||||
spaceNeeded = sizeof(TDIEntityID) * (numInt + 4);
|
spaceNeeded = sizeof(TDIEntityID) * (numInt * 2 + 3);
|
||||||
|
|
||||||
if (*pcbResponseInfoLen < spaceNeeded)
|
if (*pcbResponseInfoLen < spaceNeeded)
|
||||||
return (ERROR_LOCK_VIOLATION);
|
return (ERROR_LOCK_VIOLATION);
|
||||||
@ -184,10 +184,10 @@ DWORD WINAPI WsControl(DWORD protocol,
|
|||||||
|
|
||||||
for (i = 0; i < table->dwNumEntries; i++)
|
for (i = 0; i < table->dwNumEntries; i++)
|
||||||
{
|
{
|
||||||
/* Return IF_GENERIC on every interface, and AT_ENTITY,
|
/* Return IF_GENERIC and CL_NL_ENTITY on every interface, and
|
||||||
* CL_NL_ENTITY, CL_TL_ENTITY, and CO_TL_ENTITY on the first
|
* AT_ENTITY, CL_TL_ENTITY, and CO_TL_ENTITY on the first
|
||||||
* interface. MS returns them only on the loopback
|
* interface. MS returns them only on the loopback interface,
|
||||||
* interface, but it doesn't seem to matter.
|
* but it doesn't seem to matter.
|
||||||
*/
|
*/
|
||||||
if (i == 0)
|
if (i == 0)
|
||||||
{
|
{
|
||||||
@ -197,13 +197,13 @@ DWORD WINAPI WsControl(DWORD protocol,
|
|||||||
baseptr->tei_entity = CL_TL_ENTITY;
|
baseptr->tei_entity = CL_TL_ENTITY;
|
||||||
baseptr->tei_instance = table->table[i].dwIndex;
|
baseptr->tei_instance = table->table[i].dwIndex;
|
||||||
baseptr++;
|
baseptr++;
|
||||||
baseptr->tei_entity = CL_NL_ENTITY;
|
|
||||||
baseptr->tei_instance = table->table[i].dwIndex;
|
|
||||||
baseptr++;
|
|
||||||
baseptr->tei_entity = AT_ENTITY;
|
baseptr->tei_entity = AT_ENTITY;
|
||||||
baseptr->tei_instance = table->table[i].dwIndex;
|
baseptr->tei_instance = table->table[i].dwIndex;
|
||||||
baseptr++;
|
baseptr++;
|
||||||
}
|
}
|
||||||
|
baseptr->tei_entity = CL_NL_ENTITY;
|
||||||
|
baseptr->tei_instance = table->table[i].dwIndex;
|
||||||
|
baseptr++;
|
||||||
baseptr->tei_entity = IF_GENERIC;
|
baseptr->tei_entity = IF_GENERIC;
|
||||||
baseptr->tei_instance = table->table[i].dwIndex;
|
baseptr->tei_instance = table->table[i].dwIndex;
|
||||||
baseptr++;
|
baseptr++;
|
||||||
@ -242,9 +242,18 @@ DWORD WINAPI WsControl(DWORD protocol,
|
|||||||
ret = GetIfEntry(&row);
|
ret = GetIfEntry(&row);
|
||||||
if (ret != NO_ERROR)
|
if (ret != NO_ERROR)
|
||||||
{
|
{
|
||||||
ERR ("Error retrieving data for interface index %lu\n",
|
/* FIXME: Win98's arp.exe insists on querying index 1 for
|
||||||
index);
|
* its MIB-II stats, regardless of the tei_instances
|
||||||
return ret;
|
* returned in the ENTITY_LIST query above. If the query
|
||||||
|
* fails, arp.exe fails. So, I do this hack return value
|
||||||
|
* if index is 1 and the query failed just to get arp.exe
|
||||||
|
* to continue.
|
||||||
|
*/
|
||||||
|
if (index == 1)
|
||||||
|
return NO_ERROR;
|
||||||
|
ERR ("Error retrieving data for interface index %lu\n",
|
||||||
|
index);
|
||||||
|
return ret;
|
||||||
}
|
}
|
||||||
size = sizeof(row) - sizeof(row.wszName) -
|
size = sizeof(row) - sizeof(row.wszName) -
|
||||||
sizeof(row.bDescr) + row.dwDescrLen;
|
sizeof(row.bDescr) + row.dwDescrLen;
|
||||||
@ -257,8 +266,6 @@ DWORD WINAPI WsControl(DWORD protocol,
|
|||||||
|
|
||||||
/* Returns address-translation related data. In our case, this is
|
/* Returns address-translation related data. In our case, this is
|
||||||
* ARP.
|
* ARP.
|
||||||
* FIXME: Win98 seems to assume ARP will always be on interface
|
|
||||||
* index 1, so arp.exe fails when this isn't the case.
|
|
||||||
*/
|
*/
|
||||||
case AT_ENTITY:
|
case AT_ENTITY:
|
||||||
if (pcommand->toi_class == INFO_CLASS_GENERIC)
|
if (pcommand->toi_class == INFO_CLASS_GENERIC)
|
||||||
@ -397,12 +404,14 @@ DWORD WINAPI WsControl(DWORD protocol,
|
|||||||
GetIpAddrTable(table, &tableSize, FALSE);
|
GetIpAddrTable(table, &tableSize, FALSE);
|
||||||
for (i = 0; i < table->dwNumEntries; i++)
|
for (i = 0; i < table->dwNumEntries; i++)
|
||||||
{
|
{
|
||||||
if (table->table[i].dwIndex == index)
|
if (table->table[i].dwIndex == index)
|
||||||
{
|
{
|
||||||
memcpy(baseIPInfo, &table->table[i],
|
TRACE("Found IP info for tei_instance 0x%lx:\n", index);
|
||||||
sizeof(MIB_IPADDRROW));
|
TRACE("IP 0x%08lx, mask 0x%08lx\n", table->table[i].dwAddr,
|
||||||
break;
|
table->table[i].dwMask);
|
||||||
}
|
memcpy(baseIPInfo, &table->table[i], sizeof(MIB_IPADDRROW));
|
||||||
|
break;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
free(table);
|
free(table);
|
||||||
|
|
||||||
@ -410,59 +419,113 @@ DWORD WINAPI WsControl(DWORD protocol,
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* This call returns the routing table.
|
/* FIXME: not real name. Value is 0x101. Obviously it's a bad name,
|
||||||
* No official documentation found, even the name of the command is unknown.
|
* too, because it can be used to get the ARP table--see below. */
|
||||||
* Work is based on
|
case IP_MIB_ROUTETABLE_ENTRY_ID:
|
||||||
* http://www.cyberport.com/~tangent/programming/winsock/articles/wscontrol.html
|
|
||||||
* and testings done with winipcfg.exe, route.exe and ipconfig.exe.
|
|
||||||
* pcommand->toi_entity.tei_instance seems to be the interface number
|
|
||||||
* but route.exe outputs only the information for the last interface
|
|
||||||
* if only the routes for the pcommand->toi_entity.tei_instance
|
|
||||||
* interface are returned. */
|
|
||||||
case IP_MIB_ROUTETABLE_ENTRY_ID: /* FIXME: not real name. Value is 0x101 */
|
|
||||||
{
|
{
|
||||||
DWORD routeTableSize, numRoutes, ndx;
|
switch (pcommand->toi_entity.tei_entity)
|
||||||
PMIB_IPFORWARDTABLE table;
|
|
||||||
IPRouteEntry *winRouteTable = (IPRouteEntry *) pResponseInfo;
|
|
||||||
|
|
||||||
if (!pcbResponseInfoLen)
|
|
||||||
return ERROR_BAD_ENVIRONMENT;
|
|
||||||
GetIpForwardTable(NULL, &routeTableSize, FALSE);
|
|
||||||
numRoutes = min(routeTableSize - sizeof(MIB_IPFORWARDTABLE), 0)
|
|
||||||
/ sizeof(MIB_IPFORWARDROW) + 1;
|
|
||||||
if (*pcbResponseInfoLen < sizeof(IPRouteEntry) * numRoutes)
|
|
||||||
return (ERROR_LOCK_VIOLATION);
|
|
||||||
table = (PMIB_IPFORWARDTABLE)calloc(1, routeTableSize);
|
|
||||||
if (!table)
|
|
||||||
return ERROR_NOT_ENOUGH_MEMORY;
|
|
||||||
GetIpForwardTable(table, &routeTableSize, FALSE);
|
|
||||||
|
|
||||||
memset(pResponseInfo, 0, sizeof(IPRouteEntry) * numRoutes);
|
|
||||||
for (ndx = 0; ndx < table->dwNumEntries; ndx++)
|
|
||||||
{
|
{
|
||||||
winRouteTable->ire_addr = table->table[ndx].dwForwardDest;
|
/* This call returns the routing table.
|
||||||
winRouteTable->ire_index = table->table[ndx].dwForwardIfIndex;
|
* No official documentation found, even the name of the command is unknown.
|
||||||
winRouteTable->ire_metric =
|
* Work is based on
|
||||||
table->table[ndx].dwForwardMetric1;
|
* http://www.cyberport.com/~tangent/programming/winsock/articles/wscontrol.html
|
||||||
/* winRouteTable->ire_option4 =
|
* and testings done with winipcfg.exe, route.exe and ipconfig.exe.
|
||||||
winRouteTable->ire_option5 =
|
* pcommand->toi_entity.tei_instance seems to be the interface number
|
||||||
winRouteTable->ire_option6 = */
|
* but route.exe outputs only the information for the last interface
|
||||||
winRouteTable->ire_gw = table->table[ndx].dwForwardNextHop;
|
* if only the routes for the pcommand->toi_entity.tei_instance
|
||||||
/* winRouteTable->ire_option8 =
|
* interface are returned. */
|
||||||
winRouteTable->ire_option9 =
|
case CL_NL_ENTITY:
|
||||||
winRouteTable->ire_option10 = */
|
{
|
||||||
winRouteTable->ire_mask = table->table[ndx].dwForwardMask;
|
DWORD routeTableSize, numRoutes, ndx;
|
||||||
/* winRouteTable->ire_option12 = */
|
PMIB_IPFORWARDTABLE table;
|
||||||
winRouteTable++;
|
IPRouteEntry *winRouteTable = (IPRouteEntry *) pResponseInfo;
|
||||||
|
|
||||||
|
if (!pcbResponseInfoLen)
|
||||||
|
return ERROR_BAD_ENVIRONMENT;
|
||||||
|
GetIpForwardTable(NULL, &routeTableSize, FALSE);
|
||||||
|
numRoutes = min(routeTableSize - sizeof(MIB_IPFORWARDTABLE),
|
||||||
|
0) / sizeof(MIB_IPFORWARDROW) + 1;
|
||||||
|
if (*pcbResponseInfoLen < sizeof(IPRouteEntry) * numRoutes)
|
||||||
|
return (ERROR_LOCK_VIOLATION);
|
||||||
|
table = (PMIB_IPFORWARDTABLE)calloc(1, routeTableSize);
|
||||||
|
if (!table)
|
||||||
|
return ERROR_NOT_ENOUGH_MEMORY;
|
||||||
|
GetIpForwardTable(table, &routeTableSize, FALSE);
|
||||||
|
|
||||||
|
memset(pResponseInfo, 0, sizeof(IPRouteEntry) * numRoutes);
|
||||||
|
for (ndx = 0; ndx < table->dwNumEntries; ndx++)
|
||||||
|
{
|
||||||
|
winRouteTable->ire_addr = table->table[ndx].dwForwardDest;
|
||||||
|
winRouteTable->ire_index =
|
||||||
|
table->table[ndx].dwForwardIfIndex;
|
||||||
|
winRouteTable->ire_metric =
|
||||||
|
table->table[ndx].dwForwardMetric1;
|
||||||
|
/* winRouteTable->ire_option4 =
|
||||||
|
winRouteTable->ire_option5 =
|
||||||
|
winRouteTable->ire_option6 = */
|
||||||
|
winRouteTable->ire_gw = table->table[ndx].dwForwardNextHop;
|
||||||
|
/* winRouteTable->ire_option8 =
|
||||||
|
winRouteTable->ire_option9 =
|
||||||
|
winRouteTable->ire_option10 = */
|
||||||
|
winRouteTable->ire_mask = table->table[ndx].dwForwardMask;
|
||||||
|
/* winRouteTable->ire_option12 = */
|
||||||
|
winRouteTable++;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* calculate the length of the data in the output buffer */
|
||||||
|
*pcbResponseInfoLen = sizeof(IPRouteEntry) *
|
||||||
|
table->dwNumEntries;
|
||||||
|
|
||||||
|
free(table);
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
|
||||||
|
case AT_ARP:
|
||||||
|
{
|
||||||
|
DWORD arpTableSize, numEntries, ret;
|
||||||
|
PMIB_IPNETTABLE table;
|
||||||
|
|
||||||
|
if (!pcbResponseInfoLen)
|
||||||
|
return ERROR_BAD_ENVIRONMENT;
|
||||||
|
GetIpNetTable(NULL, &arpTableSize, FALSE);
|
||||||
|
numEntries = min(arpTableSize - sizeof(MIB_IPNETTABLE),
|
||||||
|
0) / sizeof(MIB_IPNETROW) + 1;
|
||||||
|
if (*pcbResponseInfoLen < sizeof(MIB_IPNETROW) * numEntries)
|
||||||
|
return (ERROR_LOCK_VIOLATION);
|
||||||
|
table = (PMIB_IPNETTABLE)calloc(1, arpTableSize);
|
||||||
|
if (!table)
|
||||||
|
return ERROR_NOT_ENOUGH_MEMORY;
|
||||||
|
ret = GetIpNetTable(table, &arpTableSize, FALSE);
|
||||||
|
if (ret != NO_ERROR)
|
||||||
|
return ret;
|
||||||
|
if (*pcbResponseInfoLen < sizeof(MIB_IPNETROW) *
|
||||||
|
table->dwNumEntries)
|
||||||
|
{
|
||||||
|
free(table);
|
||||||
|
return ERROR_LOCK_VIOLATION;
|
||||||
|
}
|
||||||
|
memcpy(pResponseInfo, table->table, sizeof(MIB_IPNETROW) *
|
||||||
|
table->dwNumEntries);
|
||||||
|
|
||||||
|
/* calculate the length of the data in the output buffer */
|
||||||
|
*pcbResponseInfoLen = sizeof(MIB_IPNETROW) *
|
||||||
|
table->dwNumEntries;
|
||||||
|
|
||||||
|
free(table);
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
|
||||||
|
default:
|
||||||
|
{
|
||||||
|
FIXME ("Command ID Not Supported -> toi_id=0x%lx, toi_entity={tei_entity=0x%lx, tei_instance=0x%lx}, toi_class=0x%lx\n",
|
||||||
|
pcommand->toi_id, pcommand->toi_entity.tei_entity,
|
||||||
|
pcommand->toi_entity.tei_instance, pcommand->toi_class);
|
||||||
|
|
||||||
|
return (ERROR_BAD_ENVIRONMENT);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/* calculate the length of the data in the output buffer */
|
|
||||||
*pcbResponseInfoLen = sizeof(IPRouteEntry) *
|
|
||||||
table->dwNumEntries;
|
|
||||||
|
|
||||||
free(table);
|
|
||||||
break;
|
|
||||||
}
|
}
|
||||||
|
break;
|
||||||
|
|
||||||
|
|
||||||
default:
|
default:
|
||||||
|
Loading…
x
Reference in New Issue
Block a user