Implemented arp table querying through WsControl, and fixed problem I

introduced getting IP addresses for multiple interfaces.
This commit is contained in:
Juan Lang 2003-09-02 00:55:19 +00:00 committed by Alexandre Julliard
parent 1b5c4135e2
commit b9ed79c965

View File

@ -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,6 +242,15 @@ DWORD WINAPI WsControl(DWORD protocol,
ret = GetIfEntry(&row); ret = GetIfEntry(&row);
if (ret != NO_ERROR) if (ret != NO_ERROR)
{ {
/* FIXME: Win98's arp.exe insists on querying index 1 for
* its MIB-II stats, regardless of the tei_instances
* 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", ERR ("Error retrieving data for interface index %lu\n",
index); index);
return ret; return ret;
@ -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)
@ -399,8 +406,10 @@ DWORD WINAPI WsControl(DWORD protocol,
{ {
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,
table->table[i].dwMask);
memcpy(baseIPInfo, &table->table[i], sizeof(MIB_IPADDRROW));
break; break;
} }
} }
@ -410,6 +419,12 @@ DWORD WINAPI WsControl(DWORD protocol,
break; break;
} }
/* FIXME: not real name. Value is 0x101. Obviously it's a bad name,
* too, because it can be used to get the ARP table--see below. */
case IP_MIB_ROUTETABLE_ENTRY_ID:
{
switch (pcommand->toi_entity.tei_entity)
{
/* This call returns the routing table. /* This call returns the routing table.
* No official documentation found, even the name of the command is unknown. * No official documentation found, even the name of the command is unknown.
* Work is based on * Work is based on
@ -419,7 +434,7 @@ DWORD WINAPI WsControl(DWORD protocol,
* but route.exe outputs only the information for the last interface * but route.exe outputs only the information for the last interface
* if only the routes for the pcommand->toi_entity.tei_instance * if only the routes for the pcommand->toi_entity.tei_instance
* interface are returned. */ * interface are returned. */
case IP_MIB_ROUTETABLE_ENTRY_ID: /* FIXME: not real name. Value is 0x101 */ case CL_NL_ENTITY:
{ {
DWORD routeTableSize, numRoutes, ndx; DWORD routeTableSize, numRoutes, ndx;
PMIB_IPFORWARDTABLE table; PMIB_IPFORWARDTABLE table;
@ -428,8 +443,8 @@ DWORD WINAPI WsControl(DWORD protocol,
if (!pcbResponseInfoLen) if (!pcbResponseInfoLen)
return ERROR_BAD_ENVIRONMENT; return ERROR_BAD_ENVIRONMENT;
GetIpForwardTable(NULL, &routeTableSize, FALSE); GetIpForwardTable(NULL, &routeTableSize, FALSE);
numRoutes = min(routeTableSize - sizeof(MIB_IPFORWARDTABLE), 0) numRoutes = min(routeTableSize - sizeof(MIB_IPFORWARDTABLE),
/ sizeof(MIB_IPFORWARDROW) + 1; 0) / sizeof(MIB_IPFORWARDROW) + 1;
if (*pcbResponseInfoLen < sizeof(IPRouteEntry) * numRoutes) if (*pcbResponseInfoLen < sizeof(IPRouteEntry) * numRoutes)
return (ERROR_LOCK_VIOLATION); return (ERROR_LOCK_VIOLATION);
table = (PMIB_IPFORWARDTABLE)calloc(1, routeTableSize); table = (PMIB_IPFORWARDTABLE)calloc(1, routeTableSize);
@ -441,7 +456,8 @@ DWORD WINAPI WsControl(DWORD protocol,
for (ndx = 0; ndx < table->dwNumEntries; ndx++) for (ndx = 0; ndx < table->dwNumEntries; ndx++)
{ {
winRouteTable->ire_addr = table->table[ndx].dwForwardDest; winRouteTable->ire_addr = table->table[ndx].dwForwardDest;
winRouteTable->ire_index = table->table[ndx].dwForwardIfIndex; winRouteTable->ire_index =
table->table[ndx].dwForwardIfIndex;
winRouteTable->ire_metric = winRouteTable->ire_metric =
table->table[ndx].dwForwardMetric1; table->table[ndx].dwForwardMetric1;
/* winRouteTable->ire_option4 = /* winRouteTable->ire_option4 =
@ -461,8 +477,55 @@ DWORD WINAPI WsControl(DWORD protocol,
table->dwNumEntries; table->dwNumEntries;
free(table); free(table);
break;
} }
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);
}
}
}
break;
default: default: