route add and route delete now work on real windows with our iphlpapi.

svn path=/trunk/; revision=8544
This commit is contained in:
Art Yerkes 2004-03-05 04:50:01 +00:00
parent 1f2169eb29
commit a57c52276e
6 changed files with 221 additions and 76 deletions

View file

@ -13,7 +13,7 @@
/* ID to use for requesting the route table */
#define IP_MIB_ROUTETABLE_ENTRY_ID 0x101
#define IP_MIB_ADDRTABLE_ENTRY_ID 102
#define IP_MIB_ADDRTABLE_ENTRY_ID 0x102
typedef struct IFEntry {
ULONG if_index;
@ -41,20 +41,22 @@ typedef struct IFEntry {
UCHAR if_descr[1];
} IFEntry;
// As in the mib from RFC 1213
typedef struct _IPRouteEntry {
ULONG ire_dest;
ULONG ire_index; //matches if_index in IFEntry and iae_index in IPAddrEntry
ULONG ire_metric;
ULONG ire_unk1; //??
ULONG ire_unk2; //??
ULONG ire_unk3; //??
ULONG ire_metric1;
ULONG ire_metric2;
ULONG ire_metric3;
ULONG ire_metric4;
ULONG ire_gw;
ULONG ire_unk4; //??
ULONG ire_unk5; //??
ULONG ire_unk6; //??
ULONG ire_type;
ULONG ire_proto;
ULONG ire_age;
ULONG ire_mask;
ULONG ire_unk7; //??
ULONG ire_unk8; //??
ULONG ire_metric5;
ULONG ire_info;
} IPRouteEntry;
typedef struct _IPAddrEntry {

View file

@ -15,7 +15,7 @@ C_SRCS = \
media.c \
registry.c \
resinfo_reactos.c \
route.c
route_reactos.c
RC_SRCS = iphlpapi.rc
RC_BINSRC = iphlpapi.rc

View file

@ -359,6 +359,7 @@ static NTSTATUS getInterfaceInfoSet( HANDLE tcpFile,
( tcpFile,
&entIDSet[i],
&infoSetInt[curInterf].if_info );
DPRINT("tdiGetMibForIfEntity: %08x\n", status);
if( NT_SUCCESS(status) ) {
DWORD numAddrs;
IPAddrEntry *addrs;
@ -366,25 +367,22 @@ static NTSTATUS getInterfaceInfoSet( HANDLE tcpFile,
int j,k;
interfaceInfoComplete = FALSE;
for( j = 0; NT_SUCCESS(status); j++ ) {
status = getNthIpEntity( tcpFile, j, &ip_ent );
if( NT_SUCCESS(status) )
status = tdiGetIpAddrsForIpEntity
( tcpFile, &ip_ent, &addrs, &numAddrs );
for( k = 0; k < numAddrs && NT_SUCCESS(status); k++ ) {
if( addrs[k].iae_index ==
infoSetInt[curInterf].if_info.ent.if_index ) {
memcpy( &infoSetInt[curInterf].ip_addr,
&addrs[k],
sizeof( addrs[k] ) );
interfaceInfoComplete = TRUE;
break;
}
}
if( interfaceInfoComplete ) break;
}
status = getNthIpEntity( tcpFile, 0, &ip_ent );
if( NT_SUCCESS(status) )
status = tdiGetIpAddrsForIpEntity
( tcpFile, &ip_ent, &addrs, &numAddrs );
for( k = 0; k < numAddrs && NT_SUCCESS(status); k++ ) {
DPRINT("ADDR %d: index %d (target %d)\n", k, addrs[k].iae_index, infoSetInt[curInterf].if_info.ent.if_index);
if( addrs[k].iae_index ==
infoSetInt[curInterf].if_info.ent.if_index ) {
memcpy( &infoSetInt[curInterf].ip_addr,
&addrs[k],
sizeof( addrs[k] ) );
curInterf++;
break;
}
}
}
if( NT_SUCCESS(status) ) curInterf++;
}
}
}
@ -572,6 +570,11 @@ InterfaceIndexTable *getInterfaceIndexTableInt( BOOL nonLoopbackOnly ) {
if( NT_SUCCESS(status) ) {
status = getInterfaceInfoSet( tcpFile, &ifInfo, &numInterfaces );
DPRINT("InterfaceInfoSet: %08x, %04x:%08x\n",
status,
ifInfo->entity_id.tei_entity,
ifInfo->entity_id.tei_instance);
if( NT_SUCCESS(status) ) {
ret = (InterfaceIndexTable *)
calloc(1,
@ -580,14 +583,17 @@ InterfaceIndexTable *getInterfaceIndexTableInt( BOOL nonLoopbackOnly ) {
if (ret) {
ret->numAllocated = numInterfaces;
DPRINT("NumInterfaces = %d\n", numInterfaces);
for( i = 0; i < numInterfaces; i++ ) {
DPRINT("Examining interface %d\n", i);
if( !nonLoopbackOnly ||
!isLoopback( tcpFile, &ifInfo[i].entity_id ) ) {
DPRINT("Interface %d matches (%d)\n", i, curInterface);
ret->indexes[curInterface++] =
ifInfo[i].if_info.ent.if_index;
}
}
}
ret->numIndexes = curInterface;
}
@ -789,48 +795,3 @@ char *toIPAddressString(unsigned int addr, char string[16])
}
return string;
}
DWORD createIpForwardEntryOS( PMIB_IPFORWARDROW pRoute ) {
HANDLE tcpFile = INVALID_HANDLE_VALUE;
NTSTATUS status = openTcpFile( &tcpFile );
TCP_REQUEST_SET_INFORMATION_EX_SAFELY_SIZED req =
TCP_REQUEST_SET_INFORMATION_INIT;
IPRouteEntry *rte;
TDIEntityID id;
DWORD returnSize = 0;
DPRINT("Called.\n");
if( NT_SUCCESS(status) )
status = getNthIpEntity( tcpFile, 0, &id );
if( NT_SUCCESS(status) ) {
req.Req.ID.toi_class = INFO_CLASS_PROTOCOL;
req.Req.ID.toi_type = INFO_TYPE_PROVIDER;
req.Req.ID.toi_id = IP_MIB_ROUTETABLE_ENTRY_ID;
req.Req.ID.toi_entity = id;
req.Req.BufferSize = sizeof(*rte);
rte =
(IPRouteEntry *)&req.Req.Buffer[0];
rte->ire_dest = pRoute->dwForwardDest;
rte->ire_index = pRoute->dwForwardIfIndex;
rte->ire_metric = pRoute->dwForwardMetric1;
rte->ire_gw = pRoute->dwForwardNextHopAS;
rte->ire_mask = pRoute->dwForwardMask;
status = DeviceIoControl( tcpFile,
IOCTL_TCP_SET_INFORMATION_EX,
&req,
sizeof(req),
NULL,
0,
&returnSize,
NULL );
}
if( tcpFile != INVALID_HANDLE_VALUE )
closeTcpFile( tcpFile );
return status;
}

View file

@ -116,4 +116,9 @@ BOOL WINAPI
GetComputerNameExA(COMPUTER_NAME_FORMAT,LPSTR,LPDWORD);
#endif
#ifdef FORCE_DEBUG
#undef DPRINT
#define DPRINT(fmt,x...) DbgPrint("%s:%d:%s: " fmt, __FILE__, __LINE__, __FUNCTION__, ## x)
#endif
#endif/*IPPRIVATE_H*/

View file

@ -446,6 +446,8 @@ RouteTable *getRouteTable(void)
if( !NT_SUCCESS(status) )
return 0;
DPRINT("GETTING ROUTE TABLE\n");
out_route_table = HeapAlloc( GetProcessHeap(), 0,
sizeof(RouteTable) +
(sizeof(RouteEntry) * (numRoutes - 1)) );
@ -487,7 +489,7 @@ RouteTable *getRouteTable(void)
out_route_table->routes[routeNum].ifIndex =
route_set[j].ire_index;
out_route_table->routes[routeNum].metric =
route_set[j].ire_metric;
route_set[j].ire_metric1;
}
if( route_set ) tdiFreeThingSet( route_set );
@ -495,6 +497,8 @@ RouteTable *getRouteTable(void)
routesAdded += snmpInfo.ipsi_numroutes;
}
DPRINT("Return: %08x, %08x\n", status, out_route_table);
return out_route_table;
}

View file

@ -0,0 +1,173 @@
/*
* iphlpapi dll implementation -- Setting and storing route information
*
* These are stubs for functions that set routing information on the target
* operating system. They are grouped here because their implementation will
* vary widely by operating system.
*
* Copyright (C) 2004 Art Yerkes
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2.1 of the License, or (at your option) any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
#include "config.h"
#include "iphlpapi_private.h"
#include <stdarg.h>
#include <stdlib.h>
#include <sys/types.h>
#ifdef HAVE_NETINET_IN_H
# include <netinet/in.h>
#endif
#ifdef HAVE_ARPA_INET_H
# include <arpa/inet.h>
#endif
#ifdef HAVE_ARPA_NAMESER_H
# include <arpa/nameser.h>
#endif
#ifdef HAVE_RESOLV_H
# include <resolv.h>
#endif
#include "windef.h"
#include "winbase.h"
#include "winreg.h"
#include "resinfo.h"
#include "iphlpapi.h"
#include "wine/debug.h"
WINE_DEFAULT_DEBUG_CHANNEL(iphlpapi);
DWORD createIpForwardEntry( PMIB_IPFORWARDROW pRoute ) {
HANDLE tcpFile = INVALID_HANDLE_VALUE;
NTSTATUS status = openTcpFile( &tcpFile );
TCP_REQUEST_SET_INFORMATION_EX_SAFELY_SIZED req =
TCP_REQUEST_SET_INFORMATION_INIT;
IPRouteEntry *rte;
TDIEntityID id;
DWORD returnSize = 0;
DPRINT("Called.\n");
if( NT_SUCCESS(status) )
status = getNthIpEntity( tcpFile, 0, &id );
if( NT_SUCCESS(status) ) {
req.Req.ID.toi_class = INFO_CLASS_PROTOCOL;
req.Req.ID.toi_type = INFO_TYPE_PROVIDER;
req.Req.ID.toi_id = IP_MIB_ROUTETABLE_ENTRY_ID;
req.Req.ID.toi_entity = id;
req.Req.BufferSize = sizeof(*rte);
rte =
(IPRouteEntry *)&req.Req.Buffer[0];
// dwForwardPolicy
// dwForwardNextHopAS
rte->ire_dest = pRoute->dwForwardDest;
rte->ire_mask = pRoute->dwForwardMask;
rte->ire_gw = pRoute->dwForwardNextHop;
rte->ire_index = pRoute->dwForwardIfIndex;
rte->ire_type = pRoute->dwForwardType;
rte->ire_proto = pRoute->dwForwardProto;
rte->ire_age = pRoute->dwForwardAge;
rte->ire_metric1 = pRoute->dwForwardMetric1;
rte->ire_metric2 = pRoute->dwForwardMetric2;
rte->ire_metric3 = pRoute->dwForwardMetric3;
rte->ire_metric4 = pRoute->dwForwardMetric4;
rte->ire_metric5 = pRoute->dwForwardMetric5;
status = DeviceIoControl( tcpFile,
IOCTL_TCP_SET_INFORMATION_EX,
&req,
sizeof(req),
NULL,
0,
&returnSize,
NULL );
}
if( tcpFile != INVALID_HANDLE_VALUE )
closeTcpFile( tcpFile );
DPRINT("Returning: %08x (IOCTL was %08x)\n", status, IOCTL_TCP_SET_INFORMATION_EX);
if( NT_SUCCESS(status) )
return NO_ERROR;
else
return status;
}
DWORD setIpForwardEntry( PMIB_IPFORWARDROW pRoute ) {
FIXME(":stub\n");
return (DWORD) 0;
}
DWORD deleteIpForwardEntry( PMIB_IPFORWARDROW pRoute ) {
HANDLE tcpFile = INVALID_HANDLE_VALUE;
NTSTATUS status = openTcpFile( &tcpFile );
TCP_REQUEST_SET_INFORMATION_EX_SAFELY_SIZED req =
TCP_REQUEST_SET_INFORMATION_INIT;
IPRouteEntry *rte;
TDIEntityID id;
DWORD returnSize = 0;
DPRINT("Called.\n");
if( NT_SUCCESS(status) )
status = getNthIpEntity( tcpFile, 0, &id );
if( NT_SUCCESS(status) ) {
req.Req.ID.toi_class = INFO_CLASS_PROTOCOL;
req.Req.ID.toi_type = INFO_TYPE_PROVIDER;
req.Req.ID.toi_id = IP_MIB_ROUTETABLE_ENTRY_ID;
req.Req.ID.toi_entity = id;
req.Req.BufferSize = sizeof(*rte);
rte =
(IPRouteEntry *)&req.Req.Buffer[0];
// dwForwardPolicy
// dwForwardNextHopAS
rte->ire_dest = pRoute->dwForwardDest;
rte->ire_mask = INADDR_NONE;
rte->ire_gw = pRoute->dwForwardNextHop;
rte->ire_index = pRoute->dwForwardIfIndex;
rte->ire_type = 2; /*pRoute->dwForwardType;*/
rte->ire_proto = pRoute->dwForwardProto;
rte->ire_age = pRoute->dwForwardAge;
rte->ire_metric1 = pRoute->dwForwardMetric1;
rte->ire_metric2 = INADDR_NONE;
rte->ire_metric3 = INADDR_NONE;
rte->ire_metric4 = INADDR_NONE;
rte->ire_metric5 = INADDR_NONE;
status = DeviceIoControl( tcpFile,
IOCTL_TCP_SET_INFORMATION_EX,
&req,
sizeof(req),
NULL,
0,
&returnSize,
NULL );
}
if( tcpFile != INVALID_HANDLE_VALUE )
closeTcpFile( tcpFile );
DPRINT("Returning: %08x (IOCTL was %08x)\n", status, IOCTL_TCP_SET_INFORMATION_EX);
if( NT_SUCCESS(status) )
return NO_ERROR;
else
return status;
}