mirror of
https://github.com/reactos/reactos.git
synced 2025-08-05 02:25:40 +00:00
route add and route delete now work on real windows with our iphlpapi.
svn path=/trunk/; revision=8544
This commit is contained in:
parent
1f2169eb29
commit
a57c52276e
6 changed files with 221 additions and 76 deletions
|
@ -13,7 +13,7 @@
|
||||||
|
|
||||||
/* ID to use for requesting the route table */
|
/* ID to use for requesting the route table */
|
||||||
#define IP_MIB_ROUTETABLE_ENTRY_ID 0x101
|
#define IP_MIB_ROUTETABLE_ENTRY_ID 0x101
|
||||||
#define IP_MIB_ADDRTABLE_ENTRY_ID 102
|
#define IP_MIB_ADDRTABLE_ENTRY_ID 0x102
|
||||||
|
|
||||||
typedef struct IFEntry {
|
typedef struct IFEntry {
|
||||||
ULONG if_index;
|
ULONG if_index;
|
||||||
|
@ -41,20 +41,22 @@ typedef struct IFEntry {
|
||||||
UCHAR if_descr[1];
|
UCHAR if_descr[1];
|
||||||
} IFEntry;
|
} IFEntry;
|
||||||
|
|
||||||
|
// As in the mib from RFC 1213
|
||||||
|
|
||||||
typedef struct _IPRouteEntry {
|
typedef struct _IPRouteEntry {
|
||||||
ULONG ire_dest;
|
ULONG ire_dest;
|
||||||
ULONG ire_index; //matches if_index in IFEntry and iae_index in IPAddrEntry
|
ULONG ire_index; //matches if_index in IFEntry and iae_index in IPAddrEntry
|
||||||
ULONG ire_metric;
|
ULONG ire_metric1;
|
||||||
ULONG ire_unk1; //??
|
ULONG ire_metric2;
|
||||||
ULONG ire_unk2; //??
|
ULONG ire_metric3;
|
||||||
ULONG ire_unk3; //??
|
ULONG ire_metric4;
|
||||||
ULONG ire_gw;
|
ULONG ire_gw;
|
||||||
ULONG ire_unk4; //??
|
ULONG ire_type;
|
||||||
ULONG ire_unk5; //??
|
ULONG ire_proto;
|
||||||
ULONG ire_unk6; //??
|
ULONG ire_age;
|
||||||
ULONG ire_mask;
|
ULONG ire_mask;
|
||||||
ULONG ire_unk7; //??
|
ULONG ire_metric5;
|
||||||
ULONG ire_unk8; //??
|
ULONG ire_info;
|
||||||
} IPRouteEntry;
|
} IPRouteEntry;
|
||||||
|
|
||||||
typedef struct _IPAddrEntry {
|
typedef struct _IPAddrEntry {
|
||||||
|
|
|
@ -15,7 +15,7 @@ C_SRCS = \
|
||||||
media.c \
|
media.c \
|
||||||
registry.c \
|
registry.c \
|
||||||
resinfo_reactos.c \
|
resinfo_reactos.c \
|
||||||
route.c
|
route_reactos.c
|
||||||
|
|
||||||
RC_SRCS = iphlpapi.rc
|
RC_SRCS = iphlpapi.rc
|
||||||
RC_BINSRC = iphlpapi.rc
|
RC_BINSRC = iphlpapi.rc
|
||||||
|
|
|
@ -359,6 +359,7 @@ static NTSTATUS getInterfaceInfoSet( HANDLE tcpFile,
|
||||||
( tcpFile,
|
( tcpFile,
|
||||||
&entIDSet[i],
|
&entIDSet[i],
|
||||||
&infoSetInt[curInterf].if_info );
|
&infoSetInt[curInterf].if_info );
|
||||||
|
DPRINT("tdiGetMibForIfEntity: %08x\n", status);
|
||||||
if( NT_SUCCESS(status) ) {
|
if( NT_SUCCESS(status) ) {
|
||||||
DWORD numAddrs;
|
DWORD numAddrs;
|
||||||
IPAddrEntry *addrs;
|
IPAddrEntry *addrs;
|
||||||
|
@ -366,26 +367,23 @@ static NTSTATUS getInterfaceInfoSet( HANDLE tcpFile,
|
||||||
int j,k;
|
int j,k;
|
||||||
|
|
||||||
interfaceInfoComplete = FALSE;
|
interfaceInfoComplete = FALSE;
|
||||||
for( j = 0; NT_SUCCESS(status); j++ ) {
|
status = getNthIpEntity( tcpFile, 0, &ip_ent );
|
||||||
status = getNthIpEntity( tcpFile, j, &ip_ent );
|
|
||||||
if( NT_SUCCESS(status) )
|
if( NT_SUCCESS(status) )
|
||||||
status = tdiGetIpAddrsForIpEntity
|
status = tdiGetIpAddrsForIpEntity
|
||||||
( tcpFile, &ip_ent, &addrs, &numAddrs );
|
( tcpFile, &ip_ent, &addrs, &numAddrs );
|
||||||
for( k = 0; k < numAddrs && NT_SUCCESS(status); k++ ) {
|
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 ==
|
if( addrs[k].iae_index ==
|
||||||
infoSetInt[curInterf].if_info.ent.if_index ) {
|
infoSetInt[curInterf].if_info.ent.if_index ) {
|
||||||
memcpy( &infoSetInt[curInterf].ip_addr,
|
memcpy( &infoSetInt[curInterf].ip_addr,
|
||||||
&addrs[k],
|
&addrs[k],
|
||||||
sizeof( addrs[k] ) );
|
sizeof( addrs[k] ) );
|
||||||
interfaceInfoComplete = TRUE;
|
curInterf++;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if( interfaceInfoComplete ) break;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if( NT_SUCCESS(status) ) curInterf++;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -572,6 +570,11 @@ InterfaceIndexTable *getInterfaceIndexTableInt( BOOL nonLoopbackOnly ) {
|
||||||
if( NT_SUCCESS(status) ) {
|
if( NT_SUCCESS(status) ) {
|
||||||
status = getInterfaceInfoSet( tcpFile, &ifInfo, &numInterfaces );
|
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) ) {
|
if( NT_SUCCESS(status) ) {
|
||||||
ret = (InterfaceIndexTable *)
|
ret = (InterfaceIndexTable *)
|
||||||
calloc(1,
|
calloc(1,
|
||||||
|
@ -580,10 +583,13 @@ InterfaceIndexTable *getInterfaceIndexTableInt( BOOL nonLoopbackOnly ) {
|
||||||
|
|
||||||
if (ret) {
|
if (ret) {
|
||||||
ret->numAllocated = numInterfaces;
|
ret->numAllocated = numInterfaces;
|
||||||
|
DPRINT("NumInterfaces = %d\n", numInterfaces);
|
||||||
|
|
||||||
for( i = 0; i < numInterfaces; i++ ) {
|
for( i = 0; i < numInterfaces; i++ ) {
|
||||||
|
DPRINT("Examining interface %d\n", i);
|
||||||
if( !nonLoopbackOnly ||
|
if( !nonLoopbackOnly ||
|
||||||
!isLoopback( tcpFile, &ifInfo[i].entity_id ) ) {
|
!isLoopback( tcpFile, &ifInfo[i].entity_id ) ) {
|
||||||
|
DPRINT("Interface %d matches (%d)\n", i, curInterface);
|
||||||
ret->indexes[curInterface++] =
|
ret->indexes[curInterface++] =
|
||||||
ifInfo[i].if_info.ent.if_index;
|
ifInfo[i].if_info.ent.if_index;
|
||||||
}
|
}
|
||||||
|
@ -789,48 +795,3 @@ char *toIPAddressString(unsigned int addr, char string[16])
|
||||||
}
|
}
|
||||||
return string;
|
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;
|
|
||||||
}
|
|
||||||
|
|
|
@ -116,4 +116,9 @@ BOOL WINAPI
|
||||||
GetComputerNameExA(COMPUTER_NAME_FORMAT,LPSTR,LPDWORD);
|
GetComputerNameExA(COMPUTER_NAME_FORMAT,LPSTR,LPDWORD);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#ifdef FORCE_DEBUG
|
||||||
|
#undef DPRINT
|
||||||
|
#define DPRINT(fmt,x...) DbgPrint("%s:%d:%s: " fmt, __FILE__, __LINE__, __FUNCTION__, ## x)
|
||||||
|
#endif
|
||||||
|
|
||||||
#endif/*IPPRIVATE_H*/
|
#endif/*IPPRIVATE_H*/
|
||||||
|
|
|
@ -446,6 +446,8 @@ RouteTable *getRouteTable(void)
|
||||||
if( !NT_SUCCESS(status) )
|
if( !NT_SUCCESS(status) )
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
|
DPRINT("GETTING ROUTE TABLE\n");
|
||||||
|
|
||||||
out_route_table = HeapAlloc( GetProcessHeap(), 0,
|
out_route_table = HeapAlloc( GetProcessHeap(), 0,
|
||||||
sizeof(RouteTable) +
|
sizeof(RouteTable) +
|
||||||
(sizeof(RouteEntry) * (numRoutes - 1)) );
|
(sizeof(RouteEntry) * (numRoutes - 1)) );
|
||||||
|
@ -487,7 +489,7 @@ RouteTable *getRouteTable(void)
|
||||||
out_route_table->routes[routeNum].ifIndex =
|
out_route_table->routes[routeNum].ifIndex =
|
||||||
route_set[j].ire_index;
|
route_set[j].ire_index;
|
||||||
out_route_table->routes[routeNum].metric =
|
out_route_table->routes[routeNum].metric =
|
||||||
route_set[j].ire_metric;
|
route_set[j].ire_metric1;
|
||||||
}
|
}
|
||||||
|
|
||||||
if( route_set ) tdiFreeThingSet( route_set );
|
if( route_set ) tdiFreeThingSet( route_set );
|
||||||
|
@ -495,6 +497,8 @@ RouteTable *getRouteTable(void)
|
||||||
routesAdded += snmpInfo.ipsi_numroutes;
|
routesAdded += snmpInfo.ipsi_numroutes;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
DPRINT("Return: %08x, %08x\n", status, out_route_table);
|
||||||
|
|
||||||
return out_route_table;
|
return out_route_table;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
173
reactos/lib/iphlpapi/route_reactos.c
Normal file
173
reactos/lib/iphlpapi/route_reactos.c
Normal 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;
|
||||||
|
}
|
Loading…
Add table
Add a link
Reference in a new issue