[prev in list] [next in list] [prev in thread] [next in thread]
List: wine-patches
Subject: wsock32: implement arp query
From: Juan Lang <juan_lang () yahoo ! com>
Date: 2003-08-31 16:47:11
[Download RAW message or body]
ChangeLog: implement arp table querying through
WsControl, and fix problem I introduced getting IP
addresses for multiple interfaces
Dang it, I can only go so long without forgetting to
attach a patch. Sorry.
--Juan
__________________________________
Do you Yahoo!?
Yahoo! SiteBuilder - Free, easy-to-use web site design software
http://sitebuilder.yahoo.com
["wsock32.arp.patch" (application/octet-stream)]
Index: dlls/wsock32/socket.c
===================================================================
RCS file: /home/wine/wine/dlls/wsock32/socket.c,v
retrieving revision 1.26
diff -u -r1.26 socket.c
--- dlls/wsock32/socket.c 29 Aug 2003 22:14:28 -0000 1.26
+++ dlls/wsock32/socket.c 31 Aug 2003 03:27:03 -0000
@@ -1,4 +1,4 @@
-/*
+/* vim:ts=3:sw=3
* WSOCK32 specific functions
*
* Copyright (C) 1993,1994,1996,1997 John Brezak, Erik Bos, Alex Korobka.
@@ -161,7 +161,7 @@
}
GetNumberOfInterfaces(&numInt);
- spaceNeeded = sizeof(TDIEntityID) * (numInt + 4);
+ spaceNeeded = sizeof(TDIEntityID) * (numInt * 2 + 3);
if (*pcbResponseInfoLen < spaceNeeded)
return (ERROR_LOCK_VIOLATION);
@@ -184,10 +184,10 @@
for (i = 0; i < table->dwNumEntries; i++)
{
- /* Return IF_GENERIC on every interface, and AT_ENTITY,
- * CL_NL_ENTITY, CL_TL_ENTITY, and CO_TL_ENTITY on the first
- * interface. MS returns them only on the loopback
- * interface, but it doesn't seem to matter.
+ /* Return IF_GENERIC and CL_NL_ENTITY on every interface, and
+ * AT_ENTITY, CL_TL_ENTITY, and CO_TL_ENTITY on the first
+ * interface. MS returns them only on the loopback interface,
+ * but it doesn't seem to matter.
*/
if (i == 0)
{
@@ -197,13 +197,13 @@
baseptr->tei_entity = CL_TL_ENTITY;
baseptr->tei_instance = table->table[i].dwIndex;
baseptr++;
- baseptr->tei_entity = CL_NL_ENTITY;
- baseptr->tei_instance = table->table[i].dwIndex;
- baseptr++;
baseptr->tei_entity = AT_ENTITY;
baseptr->tei_instance = table->table[i].dwIndex;
baseptr++;
}
+ baseptr->tei_entity = CL_NL_ENTITY;
+ baseptr->tei_instance = table->table[i].dwIndex;
+ baseptr++;
baseptr->tei_entity = IF_GENERIC;
baseptr->tei_instance = table->table[i].dwIndex;
baseptr++;
@@ -242,9 +242,18 @@
ret = GetIfEntry(&row);
if (ret != NO_ERROR)
{
- ERR ("Error retrieving data for interface index %lu\n",
- index);
- return ret;
+ /* 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",
+ index);
+ return ret;
}
size = sizeof(row) - sizeof(row.wszName) -
sizeof(row.bDescr) + row.dwDescrLen;
@@ -257,8 +266,6 @@
/* Returns address-translation related data. In our case, this is
* 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:
if (pcommand->toi_class == INFO_CLASS_GENERIC)
@@ -397,12 +404,14 @@
GetIpAddrTable(table, &tableSize, FALSE);
for (i = 0; i < table->dwNumEntries; i++)
{
- if (table->table[i].dwIndex == index)
- {
- memcpy(baseIPInfo, &table->table[i],
- sizeof(MIB_IPADDRROW));
- break;
- }
+ if (table->table[i].dwIndex == index)
+ {
+ TRACE("Found IP info for tei_instance 0x%lx:\n", index);
+ 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;
+ }
}
free(table);
@@ -410,59 +419,113 @@
break;
}
- /* This call returns the routing table.
- * No official documentation found, even the name of the command is \
unknown.
- * Work is based on
- * 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 \
*/ + /* 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:
{
- DWORD routeTableSize, numRoutes, ndx;
- PMIB_IPFORWARDTABLE table;
- IPRouteEntry *winRouteTable = (IPRouteEntry *) pResponseInfo;
+ switch (pcommand->toi_entity.tei_entity)
+ {
+ /* This call returns the routing table.
+ * No official documentation found, even the name of the command is \
unknown. + * Work is based on
+ * 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 CL_NL_ENTITY:
+ {
+ DWORD routeTableSize, numRoutes, ndx;
+ 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);
+ 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++;
- }
+ 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;
+ /* calculate the length of the data in the output buffer */
+ *pcbResponseInfoLen = sizeof(IPRouteEntry) *
+ table->dwNumEntries;
- free(table);
- break;
+ 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);
+ }
+ }
}
+ break;
default:
[prev in list] [next in list] [prev in thread] [next in thread]
Configure |
About |
News |
Add a list |
Sponsored by KoreLogic