mirror of https://github.com/tongzx/nt5src
You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
2699 lines
60 KiB
2699 lines
60 KiB
/*++
|
|
|
|
Copyright (c) 1995 Microsoft Corporation
|
|
|
|
Module Name:
|
|
net\routing\iphlpapi.c
|
|
|
|
Abstract:
|
|
This files contains the public APIs are that exported by IPHLPAPI.DLL
|
|
|
|
Revision History:
|
|
|
|
Amritansh Raghav
|
|
|
|
--*/
|
|
|
|
#include "inc.h"
|
|
#pragma hdrstop
|
|
|
|
#define CLASSA_ADDR(a) (( (*((uchar *)&(a))) & 0x80) == 0)
|
|
#define CLASSB_ADDR(a) (( (*((uchar *)&(a))) & 0xc0) == 0x80)
|
|
#define CLASSC_ADDR(a) (( (*((uchar *)&(a))) & 0xe0) == 0xc0)
|
|
#define CLASSD_ADDR(a) (( (*((uchar *)&(a))) & 0xf0) == 0xe0)
|
|
#define CLASSE_ADDR(a) ((( (*((uchar *)&(a))) & 0xf0) == 0xf0) && \
|
|
((a) != 0xffffffff))
|
|
|
|
#define CLASSA_MASK 0x000000FF
|
|
#define CLASSB_MASK 0x0000FFFF
|
|
#define CLASSC_MASK 0x00FFFFFF
|
|
#define CLASSD_MASK 0x000000E0
|
|
#define CLASSE_MASK 0xFFFFFFFF
|
|
|
|
#define GetClassMask(a) \
|
|
(CLASSA_ADDR(a) ? CLASSA_MASK : \
|
|
(CLASSB_ADDR(a) ? CLASSB_MASK : \
|
|
(CLASSC_ADDR(a) ? CLASSC_MASK : \
|
|
(CLASSD_ADDR(a) ? CLASSD_MASK : CLASSE_MASK))))
|
|
|
|
PIP_ADAPTER_ORDER_MAP g_adapterOrderMap = NULL;
|
|
extern PIP_ADAPTER_ORDER_MAP APIENTRY GetAdapterOrderMap();
|
|
|
|
DWORD
|
|
GetArpEntryCount(
|
|
OUT PDWORD pdwNumEntries
|
|
);
|
|
|
|
BOOL
|
|
IsRouterRunning(VOID);
|
|
|
|
DWORD
|
|
GetBestInterfaceFromIpv6Stack(
|
|
IN LPSOCKADDR_IN6 pSockAddr,
|
|
OUT PDWORD pdwBestIfIndex
|
|
);
|
|
|
|
DWORD
|
|
WINAPI
|
|
GetNumberOfInterfaces(
|
|
OUT PDWORD pdwNumIf
|
|
)
|
|
{
|
|
PMIB_OPAQUE_INFO pInfo;
|
|
PMIB_IFNUMBER pIfNum;
|
|
MIB_OPAQUE_QUERY mqQuery;
|
|
DWORD dwResult, dwOutEntrySize;
|
|
MIB_IPSTATS IpSnmpInfo;
|
|
|
|
TraceEnter("GetIfNumber");
|
|
|
|
CheckTcpipState();
|
|
|
|
if(!g_bIpConfigured)
|
|
{
|
|
Trace0(ERR, "GetIfNumber: No IP Stack on machine\n");
|
|
|
|
TraceLeave("GetIfNumber");
|
|
|
|
return ERROR_NOT_SUPPORTED;
|
|
}
|
|
|
|
if (!pdwNumIf)
|
|
{
|
|
return ERROR_INVALID_PARAMETER;
|
|
}
|
|
|
|
*pdwNumIf = 0;
|
|
|
|
#ifndef CHICAGO
|
|
if(IsRouterRunning())
|
|
{
|
|
mqQuery.dwVarId = IF_NUMBER;
|
|
|
|
dwResult = MprAdminMIBEntryGet(g_hMIBServer,
|
|
PID_IP,
|
|
IPRTRMGR_PID,
|
|
(PVOID)&mqQuery,
|
|
sizeof(MIB_OPAQUE_QUERY),
|
|
(PVOID)&pInfo,
|
|
&dwOutEntrySize);
|
|
|
|
if(dwResult isnot NO_ERROR)
|
|
{
|
|
Trace1(ERR,"GetIfNumber: MprAdminMIBEntryGet failed with error %x",
|
|
dwResult);
|
|
|
|
TraceLeave("GetIfNumber");
|
|
|
|
return dwResult;
|
|
}
|
|
|
|
CAST_MIB_INFO(pInfo, PMIB_IFNUMBER, pIfNum);
|
|
|
|
*pdwNumIf = pIfNum->dwValue;
|
|
|
|
MprAdminMIBBufferFree((PVOID)pInfo);
|
|
}
|
|
else
|
|
{
|
|
#endif
|
|
dwResult = GetIpStatsFromStack(&IpSnmpInfo);
|
|
|
|
if(dwResult isnot NO_ERROR)
|
|
{
|
|
Trace1(ERR,"GetIfNumber: GetIpStatsFromStack failed with error %x",
|
|
dwResult);
|
|
|
|
TraceLeave("GetIfNumber");
|
|
|
|
return dwResult;
|
|
}
|
|
|
|
*pdwNumIf = IpSnmpInfo.dwNumIf;
|
|
#ifndef CHICAGO
|
|
}
|
|
#endif
|
|
|
|
TraceLeave("GetIfNumber");
|
|
|
|
return NO_ERROR;
|
|
}
|
|
|
|
|
|
DWORD
|
|
WINAPI
|
|
GetIfTable(
|
|
OUT PMIB_IFTABLE pIfTable,
|
|
IN OUT PULONG pdwSize,
|
|
IN BOOL bOrder
|
|
)
|
|
{
|
|
DWORD dwNumIf, dwResult, dwOutEntrySize;
|
|
|
|
PMIB_IFTABLE pTable;
|
|
MIB_OPAQUE_QUERY mqQuery;
|
|
PMIB_OPAQUE_INFO pInfo;
|
|
BOOL bForceUpdate = FALSE;
|
|
|
|
TraceEnter("GetIfTable");
|
|
|
|
CheckTcpipState();
|
|
|
|
if(!g_bIpConfigured)
|
|
{
|
|
Trace0(ERR, "GetIfTable: No IP Stack on machine\n");
|
|
|
|
TraceLeave("GetIfTable");
|
|
|
|
return ERROR_NOT_SUPPORTED;
|
|
}
|
|
|
|
if(pdwSize is NULL)
|
|
{
|
|
Trace0(ERR,"GetIfTable: pdwSize is NULL");
|
|
|
|
TraceLeave("GetIfTable");
|
|
|
|
return ERROR_INVALID_PARAMETER;
|
|
}
|
|
|
|
if (IsBadWritePtr(pdwSize, sizeof(ULONG))) {
|
|
return ERROR_INVALID_PARAMETER;
|
|
}
|
|
|
|
if (IsBadWritePtr(pIfTable, *pdwSize)) {
|
|
return ERROR_INVALID_PARAMETER;
|
|
}
|
|
|
|
dwResult = GetNumberOfInterfaces(&dwNumIf);
|
|
|
|
if(dwResult isnot NO_ERROR)
|
|
{
|
|
Trace1(ERR,"GetIfTable: GetIfNumber returned error %d",
|
|
dwResult);
|
|
|
|
TraceLeave("GetIfTable");
|
|
|
|
return dwResult;
|
|
}
|
|
|
|
if(dwNumIf is 0)
|
|
{
|
|
Trace0(ERR,"GetIfTable: No interfaces");
|
|
|
|
TraceLeave("GetIfTable");
|
|
|
|
return ERROR_NO_DATA;
|
|
}
|
|
|
|
if( (*pdwSize < SIZEOF_IFTABLE(dwNumIf)) || (pIfTable is NULL) )
|
|
{
|
|
Trace3(TRACE,"GetIfTable: In size %d. Required %d. With overflow %d",
|
|
*pdwSize,
|
|
SIZEOF_IFTABLE(dwNumIf),
|
|
SIZEOF_IFTABLE(dwNumIf + OVERFLOW_COUNT));
|
|
|
|
*pdwSize = SIZEOF_IFTABLE(dwNumIf + OVERFLOW_COUNT);
|
|
|
|
TraceLeave("GetIfTable");
|
|
|
|
return ERROR_INSUFFICIENT_BUFFER;
|
|
}
|
|
|
|
#ifndef CHICAGO
|
|
if(IsRouterRunning())
|
|
{
|
|
mqQuery.dwVarId = IF_TABLE;
|
|
|
|
dwResult = MprAdminMIBEntryGet(g_hMIBServer,
|
|
PID_IP,
|
|
IPRTRMGR_PID,
|
|
(PVOID)&mqQuery,
|
|
sizeof(MIB_OPAQUE_QUERY),
|
|
(PVOID)&pInfo,
|
|
&dwOutEntrySize);
|
|
|
|
if(dwResult isnot NO_ERROR)
|
|
{
|
|
Trace1(ERR,"GetIfTable: MprAdminMIBEntryGet failed with error %x",
|
|
dwResult);
|
|
|
|
TraceLeave("GetIfTable");
|
|
|
|
return dwResult;
|
|
}
|
|
|
|
CAST_MIB_INFO(pInfo, PMIB_IFTABLE, pTable);
|
|
|
|
if(pTable->dwNumEntries is 0)
|
|
{
|
|
Trace0(ERR,"GetIfTable: MprAdminMIBEntryGet returned 0 interfaces");
|
|
|
|
MprAdminMIBBufferFree((PVOID)pInfo);
|
|
|
|
TraceLeave("GetIfTable");
|
|
|
|
return ERROR_NO_DATA;
|
|
}
|
|
|
|
if(*pdwSize < SIZEOF_IFTABLE(pTable->dwNumEntries))
|
|
{
|
|
Trace3(ERR,"GetIfTable: After MIBQuery. In size %d. Required %d. With overflow %d",
|
|
*pdwSize,
|
|
SIZEOF_IFTABLE(pTable->dwNumEntries),
|
|
SIZEOF_IFTABLE(pTable->dwNumEntries + OVERFLOW_COUNT));
|
|
|
|
*pdwSize = SIZEOF_IFTABLE(pTable->dwNumEntries + OVERFLOW_COUNT);
|
|
|
|
TraceLeave("GetIfTable");
|
|
|
|
return ERROR_INSUFFICIENT_BUFFER;
|
|
}
|
|
|
|
*pdwSize = SIZEOF_IFTABLE(pTable->dwNumEntries);
|
|
|
|
CopyMemory((PVOID)(pIfTable),
|
|
(PVOID)pTable,
|
|
SIZEOF_IFTABLE(pTable->dwNumEntries));
|
|
|
|
MprAdminMIBBufferFree((PVOID)pInfo);
|
|
}
|
|
else
|
|
{
|
|
|
|
#endif
|
|
EnterCriticalSection(&g_ifLock);
|
|
|
|
|
|
if (dwNumIf != g_dwNumIf)
|
|
{
|
|
bForceUpdate = TRUE;
|
|
}
|
|
|
|
|
|
g_dwNumIf = dwNumIf;
|
|
|
|
LeaveCriticalSection(&g_ifLock);
|
|
|
|
dwResult = GetIfTableFromStack(pIfTable,
|
|
*pdwSize,
|
|
bOrder,
|
|
bForceUpdate);
|
|
|
|
if(dwResult isnot NO_ERROR)
|
|
{
|
|
Trace1(ERR,"GetIfTable: GetIfTableFromStack failed with error %d",
|
|
dwResult);
|
|
}
|
|
|
|
#ifndef CHICAGO
|
|
}
|
|
#endif
|
|
|
|
// if bOrder is 0 sort on adapter order
|
|
if( (bOrder == 0) && (dwResult == NO_ERROR) && (pIfTable) ) {
|
|
EnterCriticalSection(&g_ifLock);
|
|
if (g_adapterOrderMap = GetAdapterOrderMap()) {
|
|
qsort(pIfTable->table,
|
|
pIfTable->dwNumEntries,
|
|
sizeof(MIB_IFROW),
|
|
CompareIfRow2);
|
|
LocalFree(g_adapterOrderMap);
|
|
}
|
|
LeaveCriticalSection(&g_ifLock);
|
|
}
|
|
|
|
TraceLeave("GetIfTable");
|
|
|
|
return dwResult;
|
|
}
|
|
|
|
|
|
DWORD
|
|
WINAPI
|
|
GetIpAddrTable(
|
|
OUT PMIB_IPADDRTABLE pIpAddrTable,
|
|
IN OUT PULONG pdwSize,
|
|
IN BOOL bOrder
|
|
)
|
|
{
|
|
DWORD dwResult, dwOutEntrySize;
|
|
MIB_IPSTATS miStats;
|
|
|
|
PMIB_IPADDRTABLE pTable;
|
|
MIB_OPAQUE_QUERY mqQuery;
|
|
PMIB_OPAQUE_INFO pInfo;
|
|
|
|
TraceEnter("GetIpAddrTable");
|
|
|
|
CheckTcpipState();
|
|
|
|
if(!g_bIpConfigured)
|
|
{
|
|
Trace0(ERR, "GetIpAddrTable: No IP Stack on machine\n");
|
|
|
|
TraceLeave("GetIpAddrTable");
|
|
|
|
return ERROR_NOT_SUPPORTED;
|
|
}
|
|
|
|
if(pdwSize is NULL)
|
|
{
|
|
Trace0(ERR,"GetIpAddrTable: pdwSize is NULL");
|
|
|
|
TraceLeave("GetIpAddrTable");
|
|
|
|
return ERROR_INVALID_PARAMETER;
|
|
}
|
|
|
|
if (IsBadWritePtr(pdwSize, sizeof(ULONG))) {
|
|
return ERROR_INVALID_PARAMETER;
|
|
}
|
|
|
|
if (IsBadWritePtr(pIpAddrTable, *pdwSize)) {
|
|
return ERROR_INVALID_PARAMETER;
|
|
}
|
|
|
|
dwResult = GetIpStatsFromStack(&miStats);
|
|
|
|
if(dwResult isnot NO_ERROR)
|
|
{
|
|
Trace1(ERR,"GetIpAddrTable: GetIpStatistics returned error %d",
|
|
dwResult);
|
|
|
|
TraceLeave("GetIpAddrTable");
|
|
|
|
return dwResult;
|
|
}
|
|
|
|
if(miStats.dwNumAddr is 0)
|
|
{
|
|
Trace0(ERR,"GetIpAddrTable: No entries");
|
|
|
|
TraceLeave("GetIpAddrTable");
|
|
|
|
return ERROR_NO_DATA;
|
|
}
|
|
|
|
if( (*pdwSize < SIZEOF_IPADDRTABLE(miStats.dwNumAddr)) || (pIpAddrTable is NULL) )
|
|
{
|
|
Trace3(TRACE,"GetIpAddrTable: In size %d. Required %d. With overflow %d",
|
|
*pdwSize,
|
|
SIZEOF_IPADDRTABLE(miStats.dwNumAddr),
|
|
SIZEOF_IPADDRTABLE(miStats.dwNumAddr + OVERFLOW_COUNT));
|
|
|
|
*pdwSize = SIZEOF_IPADDRTABLE(miStats.dwNumAddr + OVERFLOW_COUNT);
|
|
|
|
TraceLeave("GetIpAddrTable");
|
|
|
|
return ERROR_INSUFFICIENT_BUFFER;
|
|
}
|
|
|
|
//
|
|
// Retrieve the IP address table directly from TCP/IP. Note that we do not
|
|
// determine first whether RRAS is running, since the IP address table
|
|
// held by TCP/IP is always complete, and always contains interface indices
|
|
// consistent with those held by RRAS.
|
|
//
|
|
|
|
dwResult = GetIpAddrTableFromStack(pIpAddrTable,
|
|
*pdwSize,
|
|
bOrder);
|
|
|
|
if(dwResult isnot NO_ERROR)
|
|
{
|
|
Trace1(ERR,"GetIpAddrTable: GetIpAddrTableFromStack failed with error %d",
|
|
dwResult);
|
|
}
|
|
|
|
// if bOrder is 0 sort on adapter order
|
|
if( (bOrder == 0) && (dwResult == NO_ERROR) && (pIpAddrTable) ) {
|
|
EnterCriticalSection(&g_ifLock);
|
|
if (g_adapterOrderMap = GetAdapterOrderMap()) {
|
|
qsort(pIpAddrTable->table,
|
|
pIpAddrTable->dwNumEntries,
|
|
sizeof(MIB_IPADDRROW),
|
|
CompareIpAddrRow2);
|
|
LocalFree(g_adapterOrderMap);
|
|
}
|
|
LeaveCriticalSection(&g_ifLock);
|
|
}
|
|
|
|
TraceLeave("GetIpAddrTable");
|
|
|
|
return dwResult;
|
|
}
|
|
|
|
|
|
DWORD
|
|
WINAPI
|
|
GetIpNetTable(
|
|
OUT PMIB_IPNETTABLE pIpNetTable,
|
|
IN OUT PULONG pdwSize,
|
|
IN BOOL bOrder
|
|
)
|
|
{
|
|
DWORD dwResult, dwOutEntrySize, dwArpCount;
|
|
|
|
PMIB_IPNETTABLE pTable;
|
|
MIB_OPAQUE_QUERY mqQuery;
|
|
PMIB_OPAQUE_INFO pInfo;
|
|
|
|
TraceEnter("GetIpNetTable");
|
|
|
|
CheckTcpipState();
|
|
|
|
if(!g_bIpConfigured)
|
|
{
|
|
Trace0(ERR, "GetIpNetTable: No IP Stack on machine\n");
|
|
|
|
TraceLeave("GetIpNetTable");
|
|
|
|
return ERROR_NOT_SUPPORTED;
|
|
}
|
|
|
|
if(pdwSize is NULL)
|
|
{
|
|
Trace0(ERR,"GetIpNetTable: pdwSize is NULL");
|
|
|
|
TraceLeave("GetIpNetTable");
|
|
|
|
return ERROR_INVALID_PARAMETER;
|
|
}
|
|
|
|
if (IsBadWritePtr(pdwSize, sizeof(ULONG))) {
|
|
return ERROR_INVALID_PARAMETER;
|
|
}
|
|
|
|
if (IsBadWritePtr(pIpNetTable, *pdwSize)) {
|
|
return ERROR_INVALID_PARAMETER;
|
|
}
|
|
|
|
dwArpCount = 0;
|
|
|
|
EnterCriticalSection(&g_ipNetLock);
|
|
|
|
dwResult = GetArpEntryCount(&dwArpCount);
|
|
|
|
LeaveCriticalSection(&g_ipNetLock);
|
|
|
|
if(dwResult isnot NO_ERROR)
|
|
{
|
|
Trace1(ERR,"GetIpNetTable: GetIpStatistics returned error %d",
|
|
dwResult);
|
|
|
|
TraceLeave("GetIpNetTable");
|
|
|
|
return dwResult;
|
|
}
|
|
|
|
if(dwArpCount is 0)
|
|
{
|
|
Trace0(ERR,"GetIpNetTable: No entries");
|
|
|
|
TraceLeave("GetIpNetTable");
|
|
|
|
return ERROR_NO_DATA;
|
|
}
|
|
|
|
if( (*pdwSize < SIZEOF_IPNETTABLE(dwArpCount)) || (pIpNetTable is NULL) )
|
|
{
|
|
Trace3(TRACE,"GetIpNetTable: In size %d. Required %d. With overflow %d",
|
|
*pdwSize,
|
|
SIZEOF_IPNETTABLE(dwArpCount),
|
|
SIZEOF_IPNETTABLE(dwArpCount + OVERFLOW_COUNT));
|
|
|
|
*pdwSize = SIZEOF_IPNETTABLE(dwArpCount + OVERFLOW_COUNT);
|
|
|
|
TraceLeave("GetIpNetTable");
|
|
|
|
return ERROR_INSUFFICIENT_BUFFER;
|
|
}
|
|
|
|
#ifndef CHICAGO
|
|
if(IsRouterRunning())
|
|
{
|
|
mqQuery.dwVarId = IP_NETTABLE;
|
|
|
|
dwResult = MprAdminMIBEntryGet(g_hMIBServer,
|
|
PID_IP,
|
|
IPRTRMGR_PID,
|
|
(PVOID)&mqQuery,
|
|
sizeof(MIB_OPAQUE_QUERY),
|
|
(PVOID)&pInfo,
|
|
&dwOutEntrySize);
|
|
|
|
if(dwResult isnot NO_ERROR)
|
|
{
|
|
Trace1(ERR,"GetIpNetTable: MprAdminMIBEntryGet failed with error %x",
|
|
dwResult);
|
|
|
|
TraceLeave("GetIpNetTable");
|
|
|
|
return dwResult;
|
|
}
|
|
|
|
CAST_MIB_INFO(pInfo, PMIB_IPNETTABLE, pTable);
|
|
|
|
if(pTable->dwNumEntries is 0)
|
|
{
|
|
Trace0(ERR,"GetIpNetTable: MprAdminMIBEntryGet returned 0 interfaces");
|
|
|
|
MprAdminMIBBufferFree((PVOID)pInfo);
|
|
|
|
TraceLeave("GetIpNetTable");
|
|
|
|
return ERROR_NO_DATA;
|
|
}
|
|
|
|
if(*pdwSize < SIZEOF_IPNETTABLE(pTable->dwNumEntries))
|
|
{
|
|
Trace3(ERR,"GetIpNetTable: After MIBQuery. In size %d. Required %d. With overflow %d",
|
|
*pdwSize,
|
|
SIZEOF_IPNETTABLE(pTable->dwNumEntries),
|
|
SIZEOF_IPNETTABLE(pTable->dwNumEntries + OVERFLOW_COUNT));
|
|
|
|
*pdwSize = SIZEOF_IPNETTABLE(pTable->dwNumEntries + OVERFLOW_COUNT);
|
|
|
|
TraceLeave("GetIpNetTable");
|
|
|
|
return ERROR_INSUFFICIENT_BUFFER;
|
|
}
|
|
|
|
*pdwSize = SIZEOF_IPNETTABLE(pTable->dwNumEntries);
|
|
|
|
CopyMemory((PVOID)(pIpNetTable),
|
|
(PVOID)pTable,
|
|
SIZEOF_IPNETTABLE(pTable->dwNumEntries));
|
|
|
|
MprAdminMIBBufferFree((PVOID)pInfo);
|
|
}
|
|
else
|
|
{
|
|
#endif
|
|
dwResult = GetIpNetTableFromStack(pIpNetTable,
|
|
*pdwSize,
|
|
bOrder,
|
|
FALSE);
|
|
|
|
|
|
if(dwResult isnot NO_ERROR)
|
|
{
|
|
Trace1(ERR,"GetIpNetTable: GetIpNetTableFromStack failed with error %d",
|
|
dwResult);
|
|
}
|
|
#ifndef CHICAGO
|
|
}
|
|
#endif
|
|
|
|
TraceLeave("GetIpNetTable");
|
|
|
|
return dwResult;
|
|
}
|
|
|
|
|
|
DWORD
|
|
WINAPI
|
|
GetIpForwardTable(
|
|
OUT PMIB_IPFORWARDTABLE pIpForwardTable,
|
|
IN OUT PULONG pdwSize,
|
|
IN BOOL bOrder
|
|
)
|
|
{
|
|
DWORD dwResult, dwOutEntrySize;
|
|
MIB_IPSTATS miStats;
|
|
|
|
PMIB_IPFORWARDTABLE pTable;
|
|
MIB_OPAQUE_QUERY mqQuery;
|
|
PMIB_OPAQUE_INFO pInfo;
|
|
|
|
|
|
TraceEnter("GetIpForwardTable");
|
|
|
|
CheckTcpipState();
|
|
|
|
if(!g_bIpConfigured)
|
|
{
|
|
Trace0(ERR, "GetIpForwardTable: No IP Stack on machine\n");
|
|
|
|
TraceLeave("GetIpForwardTable");
|
|
|
|
return ERROR_NOT_SUPPORTED;
|
|
}
|
|
|
|
if(pdwSize is NULL)
|
|
{
|
|
Trace0(ERR,"GetIpForwardTable: pdwSize is NULL");
|
|
|
|
TraceLeave("GetIpForwardTable");
|
|
|
|
return ERROR_INVALID_PARAMETER;
|
|
}
|
|
|
|
if (IsBadWritePtr(pdwSize, sizeof(ULONG))) {
|
|
return ERROR_INVALID_PARAMETER;
|
|
}
|
|
|
|
if (IsBadWritePtr(pIpForwardTable, *pdwSize)) {
|
|
return ERROR_INVALID_PARAMETER;
|
|
}
|
|
|
|
dwResult = GetIpStatistics(&miStats);
|
|
|
|
if(dwResult isnot NO_ERROR)
|
|
{
|
|
Trace1(ERR,"GetIpForwardTable: GetIpStatistics returned error %d",
|
|
dwResult);
|
|
|
|
TraceLeave("GetIpForwardTable");
|
|
|
|
return dwResult;
|
|
}
|
|
|
|
if(miStats.dwNumRoutes is 0)
|
|
{
|
|
Trace0(ERR,"GetIpForwardTable: No entries");
|
|
|
|
TraceLeave("GetIpForwardTable");
|
|
|
|
return ERROR_NO_DATA;
|
|
}
|
|
|
|
if( (*pdwSize < SIZEOF_IPFORWARDTABLE(miStats.dwNumRoutes)) || (pIpForwardTable is NULL) )
|
|
{
|
|
Trace3(TRACE,"GetIpForwardTable: In size %d. Required %d. With overflow %d",
|
|
*pdwSize,
|
|
SIZEOF_IPFORWARDTABLE(miStats.dwNumRoutes),
|
|
SIZEOF_IPFORWARDTABLE(miStats.dwNumRoutes + ROUTE_OVERFLOW_COUNT));
|
|
|
|
*pdwSize = SIZEOF_IPFORWARDTABLE(miStats.dwNumRoutes + ROUTE_OVERFLOW_COUNT);
|
|
|
|
TraceLeave("GetIpForwardTable");
|
|
|
|
return ERROR_INSUFFICIENT_BUFFER;
|
|
}
|
|
|
|
#ifndef CHICAGO
|
|
if(IsRouterRunning())
|
|
{
|
|
mqQuery.dwVarId = IP_FORWARDTABLE;
|
|
|
|
dwResult = MprAdminMIBEntryGet(g_hMIBServer,
|
|
PID_IP,
|
|
IPRTRMGR_PID,
|
|
(PVOID)&mqQuery,
|
|
sizeof(MIB_OPAQUE_QUERY),
|
|
(PVOID)&pInfo,
|
|
&dwOutEntrySize);
|
|
|
|
if(dwResult isnot NO_ERROR)
|
|
{
|
|
Trace1(ERR,"GetIpForwardTable: MprAdminMIBEntryGet failed with error %x",
|
|
dwResult);
|
|
|
|
TraceLeave("GetIpForwardTable");
|
|
|
|
return dwResult;
|
|
}
|
|
|
|
CAST_MIB_INFO(pInfo, PMIB_IPFORWARDTABLE, pTable);
|
|
|
|
if(pTable->dwNumEntries is 0)
|
|
{
|
|
Trace0(ERR,"GetIpForwardTable: MprAdminMIBEntryGet returned 0 interfaces");
|
|
|
|
MprAdminMIBBufferFree((PVOID)pInfo);
|
|
|
|
TraceLeave("GetIpForwardTable");
|
|
|
|
return ERROR_NO_DATA;
|
|
}
|
|
|
|
if(*pdwSize < SIZEOF_IPFORWARDTABLE(pTable->dwNumEntries))
|
|
{
|
|
Trace3(ERR,"GetIpForwardTable: After MIBQuery. In size %d. Required %d. With overflow %d",
|
|
*pdwSize,
|
|
SIZEOF_IPFORWARDTABLE(pTable->dwNumEntries),
|
|
SIZEOF_IPFORWARDTABLE(pTable->dwNumEntries + ROUTE_OVERFLOW_COUNT));
|
|
|
|
*pdwSize = SIZEOF_IPFORWARDTABLE(pTable->dwNumEntries + ROUTE_OVERFLOW_COUNT);
|
|
|
|
TraceLeave("GetIpForwardTable");
|
|
|
|
return ERROR_INSUFFICIENT_BUFFER;
|
|
}
|
|
|
|
*pdwSize = SIZEOF_IPFORWARDTABLE(pTable->dwNumEntries);
|
|
|
|
CopyMemory((PVOID)(pIpForwardTable),
|
|
(PVOID)pTable,
|
|
SIZEOF_IPFORWARDTABLE(pTable->dwNumEntries));
|
|
|
|
MprAdminMIBBufferFree((PVOID)pInfo);
|
|
}
|
|
else
|
|
{
|
|
#endif
|
|
dwResult = GetIpForwardTableFromStack(pIpForwardTable,
|
|
*pdwSize,
|
|
bOrder);
|
|
|
|
|
|
if(dwResult isnot NO_ERROR)
|
|
{
|
|
Trace1(ERR,"GetIpForwardTable: GetIpForwardTableFromStack failed with error %d",
|
|
dwResult);
|
|
}
|
|
|
|
#ifndef CHICAGO
|
|
}
|
|
#endif
|
|
|
|
TraceLeave("GetIpForwardTable");
|
|
|
|
return dwResult;
|
|
}
|
|
|
|
|
|
DWORD
|
|
WINAPI
|
|
GetTcpTable(
|
|
OUT PMIB_TCPTABLE pTcpTable,
|
|
IN OUT PDWORD pdwSize,
|
|
IN BOOL bOrder
|
|
)
|
|
{
|
|
DWORD dwResult, dwOutEntrySize;
|
|
|
|
PMIB_TCPTABLE pTable;
|
|
MIB_TCPSTATS mtStats;
|
|
MIB_OPAQUE_QUERY mqQuery;
|
|
PMIB_OPAQUE_INFO pInfo;
|
|
|
|
TraceEnter("GetTcpTable");
|
|
|
|
CheckTcpipState();
|
|
|
|
if(!g_bIpConfigured)
|
|
{
|
|
Trace0(ERR, "GetTcpTable: No IP Stack on machine\n");
|
|
|
|
TraceLeave("GetTcpTable");
|
|
|
|
return ERROR_NOT_SUPPORTED;
|
|
}
|
|
|
|
if(pdwSize is NULL)
|
|
{
|
|
Trace0(ERR,"GetTcpTable: pdwSize is NULL");
|
|
|
|
TraceLeave("GetTcpTable");
|
|
|
|
return ERROR_INVALID_PARAMETER;
|
|
}
|
|
|
|
if (IsBadWritePtr(pdwSize, sizeof(ULONG))) {
|
|
return ERROR_INVALID_PARAMETER;
|
|
}
|
|
|
|
if (IsBadWritePtr(pTcpTable, *pdwSize)) {
|
|
return ERROR_INVALID_PARAMETER;
|
|
}
|
|
|
|
dwResult = GetTcpStatistics(&mtStats);
|
|
|
|
if(dwResult isnot NO_ERROR)
|
|
{
|
|
Trace1(ERR,"GetTcpTable: GetTcpStatistics returned error %d",
|
|
dwResult);
|
|
|
|
TraceLeave("GetTcpTable");
|
|
|
|
return dwResult;
|
|
}
|
|
|
|
if(mtStats.dwNumConns is 0)
|
|
{
|
|
Trace0(ERR,"GetTcpTable: No entries");
|
|
|
|
TraceLeave("GetTcpTable");
|
|
|
|
return ERROR_NO_DATA;
|
|
}
|
|
|
|
if( (*pdwSize < SIZEOF_TCPTABLE(mtStats.dwNumConns)) || (pTcpTable is NULL) )
|
|
{
|
|
Trace3(TRACE,"GetTcpTable: In size %d. Required %d. With overflow %d",
|
|
*pdwSize,
|
|
SIZEOF_TCPTABLE(mtStats.dwNumConns),
|
|
SIZEOF_TCPTABLE(mtStats.dwNumConns + OVERFLOW_COUNT));
|
|
|
|
*pdwSize = SIZEOF_TCPTABLE(mtStats.dwNumConns + OVERFLOW_COUNT);
|
|
|
|
TraceLeave("GetTcpTable");
|
|
|
|
return ERROR_INSUFFICIENT_BUFFER;
|
|
}
|
|
|
|
#ifndef CHICAGO
|
|
if(IsRouterRunning())
|
|
{
|
|
mqQuery.dwVarId = TCP_TABLE;
|
|
|
|
dwResult = MprAdminMIBEntryGet(g_hMIBServer,
|
|
PID_IP,
|
|
IPRTRMGR_PID,
|
|
(PVOID)&mqQuery,
|
|
sizeof(MIB_OPAQUE_QUERY),
|
|
(PVOID)&pInfo,
|
|
&dwOutEntrySize);
|
|
|
|
if(dwResult isnot NO_ERROR)
|
|
{
|
|
Trace1(ERR,"GetTcpTable: MprAdminMIBEntryGet failed with error %x",
|
|
dwResult);
|
|
|
|
TraceLeave("GetTcpTable");
|
|
|
|
return dwResult;
|
|
}
|
|
|
|
CAST_MIB_INFO(pInfo, PMIB_TCPTABLE, pTable);
|
|
|
|
if(pTable->dwNumEntries is 0)
|
|
{
|
|
Trace0(ERR,"GetTcpTable: MprAdminMIBEntryGet returned 0 interfaces");
|
|
|
|
MprAdminMIBBufferFree((PVOID)pInfo);
|
|
|
|
TraceLeave("GetTcpTable");
|
|
|
|
return ERROR_NO_DATA;
|
|
}
|
|
|
|
if(*pdwSize < SIZEOF_TCPTABLE(pTable->dwNumEntries))
|
|
{
|
|
Trace3(ERR,"GetTcpTable: After MIBQuery. In size %d. Required %d. With overflow %d",
|
|
*pdwSize,
|
|
SIZEOF_TCPTABLE(pTable->dwNumEntries),
|
|
SIZEOF_TCPTABLE(pTable->dwNumEntries + OVERFLOW_COUNT));
|
|
|
|
*pdwSize = SIZEOF_TCPTABLE(pTable->dwNumEntries + OVERFLOW_COUNT);
|
|
|
|
TraceLeave("GetTcpTable");
|
|
|
|
return ERROR_INSUFFICIENT_BUFFER;
|
|
}
|
|
|
|
*pdwSize = SIZEOF_TCPTABLE(pTable->dwNumEntries);
|
|
|
|
CopyMemory((PVOID)(pTcpTable),
|
|
(PVOID)pTable,
|
|
SIZEOF_TCPTABLE(pTable->dwNumEntries));
|
|
|
|
MprAdminMIBBufferFree((PVOID)pInfo);
|
|
}
|
|
else
|
|
{
|
|
#endif
|
|
dwResult = GetTcpTableFromStack(pTcpTable,
|
|
*pdwSize,
|
|
bOrder);
|
|
|
|
|
|
if(dwResult isnot NO_ERROR)
|
|
{
|
|
Trace1(ERR,"GetTcpTable: GetTcpTableFromStack failed with error %d",
|
|
dwResult);
|
|
}
|
|
#ifndef CHICAGO
|
|
}
|
|
#endif
|
|
|
|
TraceLeave("GetTcpTable");
|
|
|
|
return dwResult;
|
|
}
|
|
|
|
DWORD
|
|
WINAPI
|
|
GetUdpTable(
|
|
OUT PMIB_UDPTABLE pUdpTable,
|
|
IN OUT PDWORD pdwSize,
|
|
IN BOOL bOrder
|
|
)
|
|
{
|
|
DWORD dwResult, dwOutEntrySize;
|
|
|
|
PMIB_UDPTABLE pTable;
|
|
MIB_UDPSTATS muStats;
|
|
MIB_OPAQUE_QUERY mqQuery;
|
|
PMIB_OPAQUE_INFO pInfo;
|
|
|
|
TraceEnter("GetUdpTable");
|
|
|
|
CheckTcpipState();
|
|
|
|
if(!g_bIpConfigured)
|
|
{
|
|
Trace0(ERR, "GetUdpTable: No IP Stack on machine\n");
|
|
|
|
TraceLeave("GetUdpTable");
|
|
|
|
return ERROR_NOT_SUPPORTED;
|
|
}
|
|
|
|
if(pdwSize is NULL)
|
|
{
|
|
Trace0(ERR,"GetUdpTable: pdwSize is NULL");
|
|
|
|
TraceLeave("GetUdpTable");
|
|
|
|
return ERROR_INVALID_PARAMETER;
|
|
}
|
|
|
|
if (IsBadWritePtr(pdwSize, sizeof(ULONG))) {
|
|
return ERROR_INVALID_PARAMETER;
|
|
}
|
|
|
|
if (IsBadWritePtr(pUdpTable, *pdwSize)) {
|
|
return ERROR_INVALID_PARAMETER;
|
|
}
|
|
|
|
dwResult = GetUdpStatistics(&muStats);
|
|
|
|
if(dwResult isnot NO_ERROR)
|
|
{
|
|
Trace1(ERR,"GetUdpTable: GetUdpStatistics returned error %d",
|
|
dwResult);
|
|
|
|
TraceLeave("GetUdpTable");
|
|
|
|
return dwResult;
|
|
}
|
|
|
|
if(muStats.dwNumAddrs is 0)
|
|
{
|
|
Trace0(ERR,"GetUdpTable: No entries");
|
|
|
|
TraceLeave("GetUdpTable");
|
|
|
|
return ERROR_NO_DATA;
|
|
}
|
|
|
|
if( (*pdwSize < SIZEOF_UDPTABLE(muStats.dwNumAddrs)) || (pUdpTable is NULL) )
|
|
{
|
|
Trace3(TRACE,"GetUdpTable: In size %d. Required %d. With overflow %d",
|
|
*pdwSize,
|
|
SIZEOF_UDPTABLE(muStats.dwNumAddrs),
|
|
SIZEOF_UDPTABLE(muStats.dwNumAddrs + OVERFLOW_COUNT));
|
|
|
|
*pdwSize = SIZEOF_UDPTABLE(muStats.dwNumAddrs + OVERFLOW_COUNT);
|
|
|
|
TraceLeave("GetUdpTable");
|
|
|
|
return ERROR_INSUFFICIENT_BUFFER;
|
|
}
|
|
|
|
#ifndef CHICAGO
|
|
if(IsRouterRunning())
|
|
{
|
|
mqQuery.dwVarId = UDP_TABLE;
|
|
|
|
dwResult = MprAdminMIBEntryGet(g_hMIBServer,
|
|
PID_IP,
|
|
IPRTRMGR_PID,
|
|
(PVOID)&mqQuery,
|
|
sizeof(MIB_OPAQUE_QUERY),
|
|
(PVOID)&pInfo,
|
|
&dwOutEntrySize);
|
|
|
|
if(dwResult isnot NO_ERROR)
|
|
{
|
|
Trace1(ERR,"GetUdpTable: MprAdminMIBEntryGet failed with error %x",
|
|
dwResult);
|
|
|
|
TraceLeave("GetUdpTable");
|
|
|
|
return dwResult;
|
|
}
|
|
|
|
CAST_MIB_INFO(pInfo, PMIB_UDPTABLE, pTable);
|
|
|
|
if(pTable->dwNumEntries is 0)
|
|
{
|
|
Trace0(ERR,"GetUdpTable: MprAdminMIBEntryGet returned 0 interfaces");
|
|
|
|
MprAdminMIBBufferFree((PVOID)pInfo);
|
|
|
|
TraceLeave("GetUdpTable");
|
|
|
|
return ERROR_NO_DATA;
|
|
}
|
|
|
|
if(*pdwSize < SIZEOF_UDPTABLE(pTable->dwNumEntries))
|
|
{
|
|
Trace3(ERR,"GetUdpTable: After MIBQuery. In size %d. Required %d. With overflow %d",
|
|
*pdwSize,
|
|
SIZEOF_UDPTABLE(pTable->dwNumEntries),
|
|
SIZEOF_UDPTABLE(pTable->dwNumEntries + OVERFLOW_COUNT));
|
|
|
|
*pdwSize = SIZEOF_UDPTABLE(pTable->dwNumEntries + OVERFLOW_COUNT);
|
|
|
|
TraceLeave("GetUdpTable");
|
|
|
|
return ERROR_INSUFFICIENT_BUFFER;
|
|
}
|
|
|
|
*pdwSize = SIZEOF_UDPTABLE(pTable->dwNumEntries);
|
|
|
|
CopyMemory((PVOID)(pUdpTable),
|
|
(PVOID)pTable,
|
|
SIZEOF_UDPTABLE(pTable->dwNumEntries));
|
|
|
|
MprAdminMIBBufferFree((PVOID)pInfo);
|
|
}
|
|
else
|
|
{
|
|
#endif
|
|
dwResult = GetUdpTableFromStack(pUdpTable,
|
|
*pdwSize,
|
|
bOrder);
|
|
|
|
|
|
if(dwResult isnot NO_ERROR)
|
|
{
|
|
Trace1(ERR,"GetUdpTable: GetUdpTableFromStack failed with error %d",
|
|
dwResult);
|
|
}
|
|
#ifndef CHICAGO
|
|
}
|
|
#endif
|
|
|
|
TraceLeave("GetUdpTable");
|
|
|
|
return dwResult;
|
|
}
|
|
|
|
|
|
DWORD
|
|
WINAPI
|
|
GetIpStatisticsEx(
|
|
OUT PMIB_IPSTATS pStats,
|
|
IN DWORD dwFamily
|
|
)
|
|
{
|
|
DWORD dwResult, dwOutEntrySize;
|
|
|
|
MIB_OPAQUE_QUERY mqQuery;
|
|
PMIB_OPAQUE_INFO pInfo;
|
|
PMIB_IPSTATS pIpStats;
|
|
|
|
TraceEnter("GetIpStatisticsEx");
|
|
|
|
if (pStats == NULL)
|
|
{
|
|
return ERROR_INVALID_PARAMETER;
|
|
}
|
|
if ((dwFamily != AF_INET) && (dwFamily != AF_INET6))
|
|
{
|
|
return ERROR_INVALID_PARAMETER;
|
|
}
|
|
|
|
if (IsBadWritePtr(pStats, sizeof(MIB_IPSTATS))) {
|
|
return ERROR_INVALID_PARAMETER;
|
|
}
|
|
|
|
CheckTcpipState();
|
|
|
|
if (((dwFamily == AF_INET) && !g_bIpConfigured) ||
|
|
((dwFamily == AF_INET6) && !g_bIp6Configured))
|
|
{
|
|
Trace0(ERR, "GetIpStatistics: No IP Stack on machine\n");
|
|
|
|
TraceLeave("GetIpStatistics");
|
|
|
|
return ERROR_NOT_SUPPORTED;
|
|
}
|
|
|
|
#ifndef CHICAGO
|
|
if((dwFamily == AF_INET) && IsRouterRunning())
|
|
{
|
|
mqQuery.dwVarId = IP_STATS;
|
|
|
|
dwResult = MprAdminMIBEntryGet(g_hMIBServer,
|
|
PID_IP,
|
|
IPRTRMGR_PID,
|
|
(PVOID)&mqQuery,
|
|
sizeof(MIB_OPAQUE_QUERY),
|
|
(PVOID)&pInfo,
|
|
&dwOutEntrySize);
|
|
|
|
if(dwResult isnot NO_ERROR)
|
|
{
|
|
Trace1(ERR,"MprAdminMIBEntryGet failed with error %x",
|
|
dwResult);
|
|
TraceLeave("GetIpStats");
|
|
|
|
return dwResult;
|
|
}
|
|
|
|
CAST_MIB_INFO(pInfo, PMIB_IPSTATS, pIpStats);
|
|
|
|
*pStats = *pIpStats;
|
|
|
|
MprAdminMIBBufferFree((PVOID)pInfo);
|
|
}
|
|
else
|
|
{
|
|
#endif
|
|
dwResult = GetIpStatsFromStackEx(pStats, dwFamily);
|
|
|
|
if(dwResult isnot NO_ERROR)
|
|
{
|
|
Trace1(ERR,"GetIpStatsFromStackEx failed with error %x",
|
|
dwResult);
|
|
}
|
|
#ifndef CHICAGO
|
|
}
|
|
#endif
|
|
|
|
TraceLeave("GetIpStatisticsEx");
|
|
|
|
return dwResult;
|
|
}
|
|
|
|
DWORD
|
|
WINAPI
|
|
GetIpStatistics(
|
|
OUT PMIB_IPSTATS pStats
|
|
)
|
|
{
|
|
return GetIpStatisticsEx(pStats, AF_INET);
|
|
}
|
|
|
|
DWORD
|
|
WINAPI
|
|
GetIcmpStatistics(
|
|
OUT PMIB_ICMP pStats
|
|
)
|
|
{
|
|
DWORD dwResult, dwOutEntrySize;
|
|
|
|
MIB_OPAQUE_QUERY mqQuery;
|
|
PMIB_OPAQUE_INFO pInfo;
|
|
PMIB_ICMP pIcmp;
|
|
|
|
CheckTcpipState();
|
|
|
|
if(!g_bIpConfigured)
|
|
{
|
|
Trace0(ERR, "GetIcmpStatistics: No IP Stack on machine\n");
|
|
|
|
TraceLeave("GetIcmpStatistics");
|
|
|
|
return ERROR_NOT_SUPPORTED;
|
|
}
|
|
|
|
|
|
if (pStats == NULL)
|
|
{
|
|
return ERROR_INVALID_PARAMETER;
|
|
}
|
|
|
|
if (IsBadWritePtr(pStats, sizeof(MIB_ICMP))) {
|
|
return ERROR_INVALID_PARAMETER;
|
|
}
|
|
|
|
#ifndef CHICAGO
|
|
if(IsRouterRunning())
|
|
{
|
|
mqQuery.dwVarId = ICMP_STATS;
|
|
|
|
dwResult = MprAdminMIBEntryGet(g_hMIBServer,
|
|
PID_IP,
|
|
IPRTRMGR_PID,
|
|
(PVOID)&mqQuery,
|
|
sizeof(MIB_OPAQUE_QUERY),
|
|
(PVOID)&pInfo,
|
|
&dwOutEntrySize);
|
|
|
|
if(dwResult isnot NO_ERROR)
|
|
{
|
|
Trace1(ERR,"MprAdminMIBEntryGet failed with error %x",
|
|
dwResult);
|
|
TraceLeave("GetIcmpStats");
|
|
|
|
return dwResult;
|
|
}
|
|
|
|
CAST_MIB_INFO(pInfo, PMIB_ICMP, pIcmp);
|
|
|
|
*pStats = *pIcmp;
|
|
|
|
MprAdminMIBBufferFree((PVOID)pInfo);
|
|
}
|
|
else
|
|
{
|
|
#endif
|
|
|
|
dwResult = GetIcmpStatsFromStack(pStats);
|
|
|
|
if(dwResult isnot NO_ERROR)
|
|
{
|
|
Trace1(ERR,"GetIpStatsFromStack failed with error %x",
|
|
dwResult);
|
|
}
|
|
#ifndef CHICAGO
|
|
}
|
|
#endif
|
|
|
|
TraceLeave("GetIcmpStats");
|
|
|
|
return NO_ERROR;
|
|
}
|
|
|
|
VOID
|
|
MakeIcmpStatsEx(
|
|
OUT PMIBICMPSTATS_EX pNewStats,
|
|
IN PMIBICMPSTATS pOldStats
|
|
)
|
|
{
|
|
pNewStats->dwMsgs = pOldStats->dwMsgs;
|
|
pNewStats->dwErrors = pOldStats->dwErrors;
|
|
ZeroMemory(pNewStats->rgdwTypeCount, sizeof(pNewStats->rgdwTypeCount));
|
|
pNewStats->rgdwTypeCount[ICMP4_DST_UNREACH] = pOldStats->dwDestUnreachs;
|
|
pNewStats->rgdwTypeCount[ICMP4_TIME_EXCEEDED] = pOldStats->dwTimeExcds;
|
|
pNewStats->rgdwTypeCount[ICMP4_PARAM_PROB] = pOldStats->dwParmProbs;
|
|
pNewStats->rgdwTypeCount[ICMP4_SOURCE_QUENCH] = pOldStats->dwSrcQuenchs;
|
|
pNewStats->rgdwTypeCount[ICMP4_REDIRECT] = pOldStats->dwRedirects;
|
|
pNewStats->rgdwTypeCount[ICMP4_ECHO_REQUEST] = pOldStats->dwEchos;
|
|
pNewStats->rgdwTypeCount[ICMP4_ECHO_REPLY] = pOldStats->dwEchoReps;
|
|
pNewStats->rgdwTypeCount[ICMP4_TIMESTAMP_REQUEST] = pOldStats->dwTimestamps;
|
|
pNewStats->rgdwTypeCount[ICMP4_TIMESTAMP_REPLY] = pOldStats->dwTimestampReps;
|
|
pNewStats->rgdwTypeCount[ICMP4_MASK_REQUEST] = pOldStats->dwAddrMasks;
|
|
pNewStats->rgdwTypeCount[ICMP4_MASK_REPLY] = pOldStats->dwAddrMaskReps;
|
|
}
|
|
|
|
DWORD
|
|
WINAPI
|
|
GetIcmpStatisticsEx(
|
|
OUT PMIB_ICMP_EX pStats,
|
|
IN DWORD dwFamily
|
|
)
|
|
{
|
|
DWORD dwResult, dwOutEntrySize;
|
|
|
|
MIB_OPAQUE_QUERY mqQuery;
|
|
PMIB_OPAQUE_INFO pInfo;
|
|
PVOID pIcmp;
|
|
|
|
TraceEnter("GetIcmpStatisticsEx");
|
|
|
|
if (pStats == NULL)
|
|
{
|
|
return ERROR_INVALID_PARAMETER;
|
|
}
|
|
|
|
if ((dwFamily != AF_INET) && (dwFamily != AF_INET6))
|
|
{
|
|
return ERROR_INVALID_PARAMETER;
|
|
}
|
|
|
|
if (IsBadWritePtr(pStats, sizeof(MIB_ICMP_EX))) {
|
|
return ERROR_INVALID_PARAMETER;
|
|
}
|
|
|
|
CheckTcpipState();
|
|
|
|
if (((dwFamily == AF_INET) && !g_bIpConfigured) ||
|
|
((dwFamily == AF_INET6) && !g_bIp6Configured))
|
|
{
|
|
Trace0(ERR, "GetIcmpStatisticsEx: No IP Stack on machine\n");
|
|
|
|
TraceLeave("GetIcmpStatisticsEx");
|
|
|
|
return ERROR_NOT_SUPPORTED;
|
|
}
|
|
|
|
if (dwFamily == AF_INET)
|
|
{
|
|
//
|
|
// The IPv4 stack doesn't yet support MIB_ICMP_EX, so we'll
|
|
// get the MIB_ICMP structure and convert it.
|
|
//
|
|
MIB_ICMP OldStats;
|
|
|
|
dwResult = GetIcmpStatistics(&OldStats);
|
|
if(dwResult == NO_ERROR)
|
|
{
|
|
MakeIcmpStatsEx(&pStats->icmpInStats,
|
|
&OldStats.stats.icmpInStats);
|
|
MakeIcmpStatsEx(&pStats->icmpOutStats,
|
|
&OldStats.stats.icmpOutStats);
|
|
}
|
|
}
|
|
else
|
|
{
|
|
dwResult = GetIcmpStatsFromStackEx(pStats, dwFamily);
|
|
|
|
if(dwResult isnot NO_ERROR)
|
|
{
|
|
Trace1(ERR,"GetIpStatsFromStackEx failed with error %x",
|
|
dwResult);
|
|
}
|
|
}
|
|
|
|
TraceLeave("GetIcmpStatisticsEx");
|
|
|
|
return dwResult;
|
|
}
|
|
|
|
DWORD
|
|
WINAPI
|
|
GetTcpStatisticsEx(
|
|
OUT PMIB_TCPSTATS pStats,
|
|
IN DWORD dwFamily
|
|
)
|
|
{
|
|
DWORD dwResult, dwOutEntrySize;
|
|
|
|
MIB_OPAQUE_QUERY mqQuery;
|
|
PMIB_OPAQUE_INFO pInfo;
|
|
PMIB_TCPSTATS pTcpStats;
|
|
|
|
if ((dwFamily != AF_INET) && (dwFamily != AF_INET6))
|
|
{
|
|
return ERROR_INVALID_PARAMETER;
|
|
}
|
|
|
|
CheckTcpipState();
|
|
|
|
if (((dwFamily == AF_INET) && !g_bIpConfigured) ||
|
|
((dwFamily == AF_INET6) && !g_bIp6Configured))
|
|
{
|
|
Trace0(ERR, "GetTcpStatistics: No IP Stack on machine\n");
|
|
|
|
TraceLeave("GetTcpStatistics");
|
|
|
|
return ERROR_NOT_SUPPORTED;
|
|
}
|
|
|
|
if(pStats == NULL)
|
|
{
|
|
return ERROR_INVALID_PARAMETER;
|
|
}
|
|
|
|
if (IsBadWritePtr(pStats, sizeof(MIB_TCPSTATS))) {
|
|
return ERROR_INVALID_PARAMETER;
|
|
}
|
|
|
|
#ifndef CHICAGO
|
|
if((dwFamily == AF_INET) && IsRouterRunning())
|
|
{
|
|
mqQuery.dwVarId = TCP_STATS;
|
|
|
|
dwResult = MprAdminMIBEntryGet(g_hMIBServer,
|
|
PID_IP,
|
|
IPRTRMGR_PID,
|
|
(PVOID)&mqQuery,
|
|
sizeof(MIB_OPAQUE_QUERY),
|
|
(PVOID)&pInfo,
|
|
&dwOutEntrySize);
|
|
|
|
if(dwResult isnot NO_ERROR)
|
|
{
|
|
Trace1(ERR,"MprAdminMIBEntryGet failed with error %x",
|
|
dwResult);
|
|
TraceLeave("GetTcpStats");
|
|
|
|
return dwResult;
|
|
}
|
|
|
|
CAST_MIB_INFO(pInfo, PMIB_TCPSTATS, pTcpStats);
|
|
|
|
*pStats = *pTcpStats;
|
|
|
|
MprAdminMIBBufferFree((PVOID)pInfo);
|
|
}
|
|
else
|
|
{
|
|
#endif
|
|
dwResult = GetTcpStatsFromStackEx(pStats, dwFamily);
|
|
|
|
if(dwResult isnot NO_ERROR)
|
|
{
|
|
Trace1(ERR,"GetTcpStatsFromStackEx failed with error %x",
|
|
dwResult);
|
|
}
|
|
#ifndef CHICAGO
|
|
}
|
|
#endif
|
|
|
|
TraceLeave("GetTcpStats");
|
|
|
|
return dwResult;
|
|
}
|
|
|
|
DWORD
|
|
WINAPI
|
|
GetTcpStatistics(
|
|
OUT PMIB_TCPSTATS pStats
|
|
)
|
|
{
|
|
return GetTcpStatisticsEx(pStats, AF_INET);
|
|
}
|
|
|
|
DWORD
|
|
WINAPI
|
|
GetUdpStatisticsEx(
|
|
OUT PMIB_UDPSTATS pStats,
|
|
IN DWORD dwFamily
|
|
)
|
|
{
|
|
DWORD dwResult,dwOutEntrySize;
|
|
|
|
PMIB_OPAQUE_INFO pInfo;
|
|
PMIB_UDPSTATS pUdpStats;
|
|
MIB_OPAQUE_QUERY mqQuery;
|
|
|
|
if ((dwFamily != AF_INET) && (dwFamily != AF_INET6))
|
|
{
|
|
return ERROR_INVALID_PARAMETER;
|
|
}
|
|
|
|
CheckTcpipState();
|
|
|
|
if (((dwFamily == AF_INET) && !g_bIpConfigured) ||
|
|
((dwFamily == AF_INET6) && !g_bIp6Configured))
|
|
{
|
|
Trace0(ERR, "GetUdpStatistics: No IP Stack on machine\n");
|
|
|
|
TraceLeave("GetUdpStatistics");
|
|
|
|
return ERROR_NOT_SUPPORTED;
|
|
}
|
|
|
|
|
|
if(pStats == NULL)
|
|
{
|
|
return ERROR_INVALID_PARAMETER;
|
|
}
|
|
|
|
if (IsBadWritePtr(pStats, sizeof(MIB_UDPSTATS))) {
|
|
return ERROR_INVALID_PARAMETER;
|
|
}
|
|
|
|
#ifndef CHICAGO
|
|
if((dwFamily == AF_INET) && IsRouterRunning())
|
|
{
|
|
mqQuery.dwVarId = UDP_STATS;
|
|
|
|
dwResult = MprAdminMIBEntryGet(g_hMIBServer,
|
|
PID_IP,
|
|
IPRTRMGR_PID,
|
|
(PVOID)&mqQuery,
|
|
sizeof(MIB_OPAQUE_QUERY),
|
|
(PVOID)&pInfo,
|
|
&dwOutEntrySize);
|
|
|
|
if(dwResult isnot NO_ERROR)
|
|
{
|
|
Trace1(ERR,"MprAdminMIBEntryGet failed with error %x",
|
|
dwResult);
|
|
TraceLeave("GetUdpStats");
|
|
|
|
return dwResult;
|
|
}
|
|
|
|
CAST_MIB_INFO(pInfo, PMIB_UDPSTATS, pUdpStats);
|
|
|
|
*pStats = *pUdpStats;
|
|
|
|
MprAdminMIBBufferFree((PVOID)pInfo);
|
|
}
|
|
else
|
|
{
|
|
#endif
|
|
dwResult = GetUdpStatsFromStackEx(pStats, dwFamily);
|
|
|
|
if(dwResult isnot NO_ERROR)
|
|
{
|
|
Trace1(ERR,"GetUdpStatsFromStack failed with error %x",
|
|
dwResult);
|
|
}
|
|
#ifndef CHICAGO
|
|
}
|
|
#endif
|
|
|
|
TraceLeave("GetUdpStats");
|
|
|
|
return dwResult;
|
|
}
|
|
|
|
DWORD
|
|
WINAPI
|
|
GetUdpStatistics(
|
|
OUT PMIB_UDPSTATS pStats
|
|
)
|
|
{
|
|
return GetUdpStatisticsEx(pStats, AF_INET);
|
|
}
|
|
|
|
|
|
DWORD
|
|
GetIfEntry(
|
|
IN OUT PMIB_IFROW pIfEntry
|
|
)
|
|
{
|
|
if (!pIfEntry ||
|
|
IsBadWritePtr(pIfEntry, sizeof(MIB_IFROW)))
|
|
{
|
|
return ERROR_INVALID_PARAMETER;
|
|
}
|
|
|
|
CheckTcpipState();
|
|
|
|
if(!g_bIpConfigured)
|
|
{
|
|
return ERROR_NOT_SUPPORTED;
|
|
}
|
|
|
|
return GetIfEntryFromStack(pIfEntry,
|
|
pIfEntry->dwIndex,
|
|
TRUE);
|
|
}
|
|
|
|
DWORD
|
|
WINAPI
|
|
SetIfEntry(
|
|
IN PMIB_IFROW pIfRow
|
|
)
|
|
{
|
|
DWORD dwResult;
|
|
DEFINE_MIB_BUFFER(pInfo,MIB_IFROW, pSetRow);
|
|
|
|
TraceEnter("SetIfEntry");
|
|
|
|
if(pIfRow == NULL)
|
|
{
|
|
return ERROR_INVALID_PARAMETER;
|
|
}
|
|
|
|
if (IsBadReadPtr(pIfRow, sizeof(MIB_IFROW))) {
|
|
return ERROR_INVALID_PARAMETER;
|
|
}
|
|
|
|
CheckTcpipState();
|
|
|
|
if(!g_bIpConfigured)
|
|
{
|
|
Trace0(ERR, "SetIfEntry: No IP Stack on machine\n");
|
|
|
|
TraceLeave("SetIfEntry");
|
|
|
|
return ERROR_NOT_SUPPORTED;
|
|
}
|
|
|
|
if (!pInfo) {
|
|
Trace0(ERR, "SetIfEntry: If Entry NULL\n");
|
|
|
|
TraceLeave("SetIfEntry");
|
|
|
|
return ERROR_INVALID_DATA;
|
|
|
|
}
|
|
|
|
pInfo->dwId = IF_ROW;
|
|
*pSetRow = *pIfRow;
|
|
|
|
dwResult = InternalSetIfEntry(pInfo);
|
|
|
|
if(dwResult isnot NO_ERROR)
|
|
{
|
|
Trace1(ERR,
|
|
"SetIfEntry: InternalSetIfEntry returned %d",
|
|
dwResult);
|
|
}
|
|
|
|
TraceLeave("SetIfEntry");
|
|
|
|
return dwResult;
|
|
}
|
|
|
|
|
|
DWORD
|
|
WINAPI
|
|
CreateIpForwardEntry(
|
|
IN PMIB_IPFORWARDROW pRoute
|
|
)
|
|
{
|
|
DWORD dwResult;
|
|
DEFINE_MIB_BUFFER(pCreateInfo,MIB_IPFORWARDROW,pCreateRow);
|
|
|
|
TraceEnter("CreateIpForwardEntry");
|
|
|
|
CheckTcpipState();
|
|
|
|
if(!g_bIpConfigured)
|
|
{
|
|
Trace0(ERR, "CreateIpForwardEntry: No IP Stack on machine\n");
|
|
|
|
TraceLeave("CreateIpForwardEntry");
|
|
|
|
return ERROR_NOT_SUPPORTED;
|
|
}
|
|
|
|
if(pRoute == NULL)
|
|
{
|
|
return(ERROR_INVALID_PARAMETER);
|
|
}
|
|
|
|
if (IsBadReadPtr(pRoute, sizeof(MIB_IPFORWARDROW))) {
|
|
return ERROR_INVALID_PARAMETER;
|
|
}
|
|
|
|
pCreateInfo->dwId = IP_FORWARDROW;
|
|
*pCreateRow = *pRoute;
|
|
|
|
dwResult = InternalCreateIpForwardEntry(pCreateInfo);
|
|
|
|
if(dwResult isnot NO_ERROR)
|
|
{
|
|
Trace1(ERR,
|
|
"CreateIpForwardEntry: InternalCreateIpForwardEntry returned %d",
|
|
dwResult);
|
|
}
|
|
if (dwResult == STATUS_INVALID_PARAMETER) {
|
|
return(ERROR_INVALID_PARAMETER);
|
|
}
|
|
|
|
TraceLeave("CreateIpForwardEntry");
|
|
|
|
return dwResult;
|
|
}
|
|
|
|
|
|
DWORD
|
|
WINAPI
|
|
SetIpForwardEntry(
|
|
IN PMIB_IPFORWARDROW pRoute
|
|
)
|
|
{
|
|
DWORD dwResult;
|
|
DEFINE_MIB_BUFFER(pSetInfo,MIB_IPFORWARDROW,pSetRow);
|
|
|
|
TraceEnter("SetIpForwardEntry");
|
|
|
|
CheckTcpipState();
|
|
|
|
if(!g_bIpConfigured)
|
|
{
|
|
Trace0(ERR, "SetIpForwardEntry: No IP Stack on machine\n");
|
|
|
|
TraceLeave("SetIpForwardEntry");
|
|
|
|
return ERROR_NOT_SUPPORTED;
|
|
}
|
|
|
|
|
|
if(pRoute == NULL)
|
|
{
|
|
return(ERROR_INVALID_PARAMETER);
|
|
}
|
|
|
|
if (IsBadReadPtr(pRoute, sizeof(MIB_IPFORWARDROW))) {
|
|
return ERROR_INVALID_PARAMETER;
|
|
}
|
|
|
|
pSetInfo->dwId = IP_FORWARDROW;
|
|
*pSetRow = *pRoute;
|
|
|
|
dwResult = InternalSetIpForwardEntry(pSetInfo);
|
|
|
|
if(dwResult isnot NO_ERROR)
|
|
{
|
|
Trace1(ERR,
|
|
"SetIpForwardEntry: InternalSetIpForwardEntry returned %d",
|
|
dwResult);
|
|
}
|
|
|
|
if (dwResult == STATUS_INVALID_PARAMETER) {
|
|
|
|
return(ERROR_INVALID_PARAMETER);
|
|
}
|
|
|
|
|
|
TraceLeave("SetIpForwardEntry");
|
|
|
|
return dwResult;
|
|
}
|
|
|
|
|
|
DWORD
|
|
WINAPI
|
|
DeleteIpForwardEntry(
|
|
IN PMIB_IPFORWARDROW pRoute
|
|
)
|
|
{
|
|
DWORD dwResult;
|
|
DEFINE_MIB_BUFFER(pDeleteInfo,MIB_IPFORWARDROW,pDeleteRow);
|
|
|
|
|
|
TraceEnter("DeleteIpForwardEntry");
|
|
|
|
CheckTcpipState();
|
|
|
|
if(!g_bIpConfigured)
|
|
{
|
|
Trace0(ERR, "DeleteIpForwardEntry: No IP Stack on machine\n");
|
|
|
|
TraceLeave("DeleteIpForwardEntry");
|
|
|
|
return ERROR_NOT_SUPPORTED;
|
|
}
|
|
|
|
|
|
if(pRoute == NULL)
|
|
{
|
|
return(ERROR_INVALID_PARAMETER);
|
|
}
|
|
|
|
if (IsBadReadPtr(pRoute, sizeof(MIB_IPFORWARDROW))) {
|
|
return ERROR_INVALID_PARAMETER;
|
|
}
|
|
|
|
pDeleteInfo->dwId = IP_FORWARDROW;
|
|
*pDeleteRow = *pRoute;
|
|
|
|
dwResult = InternalDeleteIpForwardEntry(pDeleteInfo);
|
|
|
|
if(dwResult isnot NO_ERROR)
|
|
{
|
|
Trace1(ERR,
|
|
"DeleteIpForwardEntry: InternalDeleteIpForwardEntry returned %d",
|
|
dwResult);
|
|
}
|
|
if (dwResult == STATUS_INVALID_PARAMETER) {
|
|
return(ERROR_NOT_FOUND);
|
|
}
|
|
|
|
|
|
|
|
TraceLeave("DeleteIpForwardEntry");
|
|
|
|
return dwResult;
|
|
}
|
|
|
|
DWORD
|
|
WINAPI
|
|
SetIpTTL(
|
|
UINT nTTL
|
|
)
|
|
{
|
|
MIB_IPSTATS Stats;
|
|
DWORD dwResult;
|
|
|
|
TraceEnter("SetIpTTL");
|
|
|
|
CheckTcpipState();
|
|
|
|
if(!g_bIpConfigured)
|
|
{
|
|
Trace0(ERR, "SetIpTTL: No IP Stack on machine\n");
|
|
|
|
TraceLeave("SetIpTTL");
|
|
|
|
return ERROR_NOT_SUPPORTED;
|
|
}
|
|
|
|
dwResult = GetIpStatistics( &Stats );
|
|
|
|
if(dwResult isnot NO_ERROR)
|
|
{
|
|
Trace1(ERR,"SetIpTll: GetIpStatistics failed with error %x",
|
|
dwResult);
|
|
|
|
TraceLeave("SetIpTTL");
|
|
|
|
return dwResult;
|
|
}
|
|
|
|
Stats.dwForwarding = MIB_USE_CURRENT_FORWARDING;
|
|
Stats.dwDefaultTTL = nTTL;
|
|
|
|
dwResult = SetIpStatistics( &Stats );
|
|
|
|
if(dwResult isnot NO_ERROR)
|
|
{
|
|
Trace1(ERR,"SetIpTll: GetIpStatistics failed with error %x",
|
|
dwResult);
|
|
|
|
}
|
|
|
|
TraceLeave("SetIpTTL");
|
|
return dwResult;
|
|
}
|
|
|
|
|
|
DWORD
|
|
WINAPI
|
|
SetIpStatistics(
|
|
IN PMIB_IPSTATS pIpStats
|
|
)
|
|
{
|
|
DWORD dwResult;
|
|
DEFINE_MIB_BUFFER(pSetInfo,MIB_IPSTATS,pSetStats);
|
|
|
|
TraceEnter("SetIpStatistics");
|
|
|
|
CheckTcpipState();
|
|
|
|
if(!g_bIpConfigured)
|
|
{
|
|
Trace0(ERR, "SetIpStatistics: No IP Stack on machine\n");
|
|
|
|
TraceLeave("SetIpStatistics");
|
|
|
|
return ERROR_NOT_SUPPORTED;
|
|
}
|
|
|
|
if(pIpStats == NULL)
|
|
{
|
|
return(ERROR_INVALID_PARAMETER);
|
|
}
|
|
|
|
if (IsBadReadPtr(pIpStats, sizeof(MIB_IPSTATS))) {
|
|
return ERROR_INVALID_PARAMETER;
|
|
}
|
|
|
|
pSetInfo->dwId = IP_STATS;
|
|
*pSetStats = *pIpStats;
|
|
|
|
dwResult = InternalSetIpStats(pSetInfo);
|
|
|
|
if(dwResult isnot NO_ERROR)
|
|
{
|
|
Trace1(ERR,
|
|
"SetIpStatistics: InternalSetIpStats returned %d",
|
|
dwResult);
|
|
}
|
|
|
|
TraceLeave("SetIpStatistics");
|
|
|
|
return dwResult;
|
|
}
|
|
|
|
|
|
DWORD
|
|
WINAPI
|
|
CreateIpNetEntry(
|
|
IN PMIB_IPNETROW pArpEntry
|
|
)
|
|
{
|
|
DWORD dwResult;
|
|
DEFINE_MIB_BUFFER(pCreateInfo,MIB_IPNETROW,pCreateRow);
|
|
|
|
TraceEnter("CreateIpNetEntry");
|
|
|
|
CheckTcpipState();
|
|
|
|
if(!g_bIpConfigured)
|
|
{
|
|
Trace0(ERR, "CreateIpNetEntry: No IP Stack on machine\n");
|
|
|
|
TraceLeave("CreateIpNetEntry");
|
|
|
|
return ERROR_NOT_SUPPORTED;
|
|
}
|
|
|
|
if(!pArpEntry)
|
|
{
|
|
return ERROR_INVALID_PARAMETER;
|
|
}
|
|
|
|
pCreateInfo->dwId = IP_NETROW;
|
|
*pCreateRow = *pArpEntry;
|
|
|
|
if((pArpEntry->dwPhysAddrLen is 0) or
|
|
(pArpEntry->dwPhysAddrLen > MAXLEN_PHYSADDR))
|
|
{
|
|
return ERROR_INVALID_PARAMETER;
|
|
}
|
|
|
|
if(((pArpEntry->dwAddr & 0x000000FF) is 0x0000007F) or
|
|
((DWORD)(pArpEntry->dwAddr & 0x000000FF) >= (DWORD) 0x000000E0))
|
|
{
|
|
return ERROR_INVALID_PARAMETER;
|
|
}
|
|
|
|
dwResult = InternalCreateIpNetEntry(pCreateInfo);
|
|
|
|
if(dwResult isnot NO_ERROR)
|
|
{
|
|
Trace1(ERR,
|
|
"CreateIpNetEntry: InternalCreateIpNetEntry returned %d",
|
|
dwResult);
|
|
}
|
|
|
|
TraceLeave("CreateIpNetEntry");
|
|
|
|
return dwResult;
|
|
}
|
|
|
|
|
|
DWORD
|
|
WINAPI
|
|
SetIpNetEntry(
|
|
IN PMIB_IPNETROW pArpEntry
|
|
)
|
|
{
|
|
DWORD dwResult;
|
|
DEFINE_MIB_BUFFER(pSetInfo,MIB_IPNETROW,pSetRow);
|
|
|
|
TraceEnter("SetIpNetEntry");
|
|
|
|
CheckTcpipState();
|
|
|
|
if(!g_bIpConfigured)
|
|
{
|
|
Trace0(ERR, "SetIpNetEntry: No IP Stack on machine\n");
|
|
|
|
TraceLeave("SetIpNetEntry");
|
|
|
|
return ERROR_NOT_SUPPORTED;
|
|
}
|
|
|
|
if (!pArpEntry)
|
|
{
|
|
return ERROR_INVALID_PARAMETER;
|
|
}
|
|
|
|
if (IsBadReadPtr(pArpEntry, sizeof(MIB_IPNETROW))) {
|
|
return ERROR_INVALID_PARAMETER;
|
|
}
|
|
|
|
pSetInfo->dwId = IP_NETROW;
|
|
*pSetRow = *pArpEntry;
|
|
|
|
dwResult = InternalSetIpNetEntry(pSetInfo);
|
|
|
|
if(dwResult isnot NO_ERROR)
|
|
{
|
|
Trace1(ERR,
|
|
"SetIpNetEntry: InternalSetIpNetEntry returned %d",
|
|
dwResult);
|
|
}
|
|
|
|
TraceLeave("SetIpNetEntry");
|
|
|
|
return dwResult;
|
|
}
|
|
|
|
|
|
DWORD
|
|
WINAPI
|
|
DeleteIpNetEntry(
|
|
IN PMIB_IPNETROW pArpEntry
|
|
)
|
|
{
|
|
DWORD dwResult;
|
|
DEFINE_MIB_BUFFER(pDeleteInfo,MIB_IPNETROW,pDeleteRow);
|
|
|
|
TraceEnter("DeleteIpNetEntry");
|
|
|
|
CheckTcpipState();
|
|
|
|
if(!g_bIpConfigured)
|
|
{
|
|
Trace0(ERR, "DeleteIpNetEntry: No IP Stack on machine\n");
|
|
|
|
TraceLeave("DeleteIpNetEntry");
|
|
|
|
return ERROR_NOT_SUPPORTED;
|
|
}
|
|
|
|
if(pArpEntry == NULL)
|
|
{
|
|
return(ERROR_INVALID_PARAMETER);
|
|
}
|
|
|
|
if (IsBadReadPtr(pArpEntry, sizeof(MIB_IPNETROW))) {
|
|
return ERROR_INVALID_PARAMETER;
|
|
}
|
|
|
|
pDeleteInfo->dwId = IP_NETROW;
|
|
*pDeleteRow = *pArpEntry;
|
|
|
|
dwResult = InternalDeleteIpNetEntry(pDeleteInfo);
|
|
|
|
if(dwResult isnot NO_ERROR)
|
|
{
|
|
Trace1(ERR,
|
|
"DeleteIpNetEntry: InternalDeleteIpNetEntry returned %d",
|
|
dwResult);
|
|
}
|
|
|
|
TraceLeave("DeleteIpNetEntry");
|
|
|
|
|
|
return dwResult;
|
|
}
|
|
|
|
DWORD
|
|
WINAPI
|
|
FlushIpNetTable(
|
|
IN DWORD dwIfIndex
|
|
)
|
|
{
|
|
DWORD dwResult;
|
|
DEFINE_MIB_BUFFER(pDeleteInfo,MIB_IPNETROW,pDeleteRow);
|
|
|
|
TraceEnter("FlushIpNetTable");
|
|
|
|
CheckTcpipState();
|
|
|
|
if(!g_bIpConfigured)
|
|
{
|
|
Trace0(ERR, "FlushIpNetTable: No IP Stack on machine\n");
|
|
|
|
TraceLeave("FlushIpNetTable");
|
|
|
|
return ERROR_NOT_SUPPORTED;
|
|
}
|
|
|
|
if(dwIfIndex == 0)
|
|
{
|
|
return(ERROR_INVALID_PARAMETER);
|
|
}
|
|
|
|
#ifndef CHICAGO
|
|
|
|
if(IsRouterRunning())
|
|
{
|
|
MIB_OPAQUE_QUERY Query;
|
|
|
|
Query.dwVarId = IP_NETTABLE;
|
|
|
|
Query.rgdwVarIndex[0] = dwIfIndex;
|
|
|
|
dwResult = MprAdminMIBEntryDelete(g_hMIBServer,
|
|
PID_IP,
|
|
IPRTRMGR_PID,
|
|
&Query,
|
|
sizeof(Query));
|
|
|
|
if(dwResult isnot NO_ERROR)
|
|
{
|
|
Trace1(ERR,"MprAdminMIBEntryDelete failed with error %x",
|
|
dwResult);
|
|
|
|
TraceLeave("FlushIpNetTable");
|
|
|
|
return dwResult;
|
|
}
|
|
}
|
|
else
|
|
{
|
|
#endif
|
|
dwResult = FlushIpNetTableFromStack(dwIfIndex);
|
|
|
|
if(dwResult isnot NO_ERROR)
|
|
{
|
|
Trace1(ERR,"FlushIpNetTableFromStack failed with error %d",
|
|
dwResult);
|
|
|
|
TraceLeave("FlushIpNetTable");
|
|
|
|
return dwResult;
|
|
}
|
|
|
|
#ifndef CHICAGO
|
|
}
|
|
#endif
|
|
|
|
TraceLeave("FlushIpNetTable");
|
|
|
|
return dwResult;
|
|
}
|
|
|
|
|
|
DWORD
|
|
WINAPI
|
|
SetTcpEntry(
|
|
IN PMIB_TCPROW pTcpRow
|
|
)
|
|
{
|
|
DWORD dwResult;
|
|
DEFINE_MIB_BUFFER(pSetInfo,MIB_TCPROW,pSetRow);
|
|
|
|
TraceEnter("SetTcpEntry");
|
|
|
|
if(!pTcpRow)
|
|
{
|
|
return ERROR_INVALID_PARAMETER;
|
|
}
|
|
|
|
CheckTcpipState();
|
|
|
|
if(!g_bIpConfigured)
|
|
{
|
|
Trace0(ERR, "SetTcpEntry: No IP Stack on machine\n");
|
|
|
|
TraceLeave("SetTcpEntry");
|
|
|
|
return ERROR_NOT_SUPPORTED;
|
|
}
|
|
|
|
if (IsBadReadPtr(pTcpRow, sizeof(MIB_TCPROW))) {
|
|
return ERROR_INVALID_PARAMETER;
|
|
}
|
|
|
|
pSetInfo->dwId = TCP_ROW;
|
|
*pSetRow = *pTcpRow;
|
|
|
|
dwResult = InternalSetTcpEntry(pSetInfo);
|
|
|
|
if(dwResult isnot NO_ERROR)
|
|
{
|
|
Trace1(ERR,
|
|
"SetTcpEntry: InternalSetTcpEntry returned %d",
|
|
dwResult);
|
|
}
|
|
|
|
TraceLeave("SetTcpEntry");
|
|
|
|
return dwResult;
|
|
}
|
|
|
|
DWORD
|
|
WINAPI
|
|
GetBestInterface(
|
|
IN IPAddr dwDestAddr,
|
|
OUT PDWORD pdwBestIfIndex
|
|
)
|
|
{
|
|
DWORD dwResult, dwOutEntrySize;
|
|
MIB_OPAQUE_QUERY mqQuery;
|
|
PMIB_OPAQUE_INFO pInfo;
|
|
PMIB_BEST_IF pBestIf;
|
|
|
|
TraceEnter("GetBestInterface");
|
|
|
|
if(pdwBestIfIndex is NULL)
|
|
{
|
|
return ERROR_INVALID_PARAMETER;
|
|
}
|
|
|
|
if (IsBadWritePtr(pdwBestIfIndex, sizeof(DWORD))) {
|
|
return ERROR_INVALID_PARAMETER;
|
|
}
|
|
|
|
CheckTcpipState();
|
|
|
|
if(!g_bIpConfigured)
|
|
{
|
|
Trace0(ERR, "GetBestInterface: No IP Stack on machine\n");
|
|
|
|
TraceLeave("GetBestInterface");
|
|
|
|
return ERROR_NOT_SUPPORTED;
|
|
}
|
|
|
|
#ifndef CHICAGO
|
|
if(IsRouterRunning())
|
|
{
|
|
mqQuery.dwVarId = BEST_IF;
|
|
mqQuery.rgdwVarIndex[0] = dwDestAddr;
|
|
|
|
dwResult = MprAdminMIBEntryGet(g_hMIBServer,
|
|
PID_IP,
|
|
IPRTRMGR_PID,
|
|
(PVOID)&mqQuery,
|
|
sizeof(MIB_OPAQUE_QUERY),
|
|
(PVOID)&pInfo,
|
|
&dwOutEntrySize);
|
|
|
|
if(dwResult isnot NO_ERROR)
|
|
{
|
|
Trace1(ERR,"GetIfTable: MprAdminMIBEntryGet failed with error %x",
|
|
dwResult);
|
|
|
|
TraceLeave("GetIfTable");
|
|
|
|
return dwResult;
|
|
}
|
|
|
|
CAST_MIB_INFO(pInfo, PMIB_BEST_IF, pBestIf);
|
|
|
|
if(dwDestAddr is pBestIf->dwDestAddr)
|
|
{
|
|
*pdwBestIfIndex = pBestIf->dwIfIndex;
|
|
}
|
|
else
|
|
{
|
|
dwResult = ERROR_CAN_NOT_COMPLETE;
|
|
}
|
|
|
|
MprAdminMIBBufferFree((PVOID)pInfo);
|
|
}
|
|
else
|
|
{
|
|
#endif
|
|
dwResult = GetBestInterfaceFromStack(dwDestAddr,
|
|
pdwBestIfIndex);
|
|
|
|
if(dwResult is STATUS_SUCCESS)
|
|
{
|
|
dwResult = NO_ERROR;
|
|
}
|
|
else
|
|
{
|
|
dwResult = ERROR_CAN_NOT_COMPLETE;
|
|
}
|
|
#ifndef CHICAGO
|
|
}
|
|
#endif
|
|
|
|
return dwResult;
|
|
}
|
|
|
|
DWORD
|
|
WINAPI
|
|
GetBestInterfaceEx(
|
|
IN LPSOCKADDR pSockAddr,
|
|
OUT PDWORD pdwBestIfIndex
|
|
)
|
|
{
|
|
DWORD dwResult;
|
|
LPSOCKADDR_IN6 pSin6;
|
|
IPAddr dwDestAddr;
|
|
|
|
if (IsBadReadPtr(pSockAddr, sizeof(SOCKADDR))) {
|
|
return ERROR_INVALID_PARAMETER;
|
|
}
|
|
|
|
if (pSockAddr->sa_family == AF_INET) {
|
|
return GetBestInterface(((LPSOCKADDR_IN)pSockAddr)->sin_addr.s_addr, pdwBestIfIndex);
|
|
}
|
|
if (pSockAddr->sa_family != AF_INET6) {
|
|
return ERROR_INVALID_PARAMETER;
|
|
}
|
|
|
|
if (IsBadReadPtr(pSockAddr, sizeof(SOCKADDR_IN6))) {
|
|
return ERROR_INVALID_PARAMETER;
|
|
}
|
|
pSin6 = (LPSOCKADDR_IN6)pSockAddr;
|
|
|
|
if (IN6_IS_ADDR_V4MAPPED(&pSin6->sin6_addr)) {
|
|
CopyMemory(&dwDestAddr,
|
|
&pSin6->sin6_addr.s6_words[6],
|
|
sizeof(dwDestAddr));
|
|
|
|
return GetBestInterface(dwDestAddr, pdwBestIfIndex);
|
|
}
|
|
|
|
if (pdwBestIfIndex is NULL) {
|
|
return ERROR_INVALID_PARAMETER;
|
|
}
|
|
|
|
if (IsBadWritePtr(pdwBestIfIndex, sizeof(DWORD))) {
|
|
return ERROR_INVALID_PARAMETER;
|
|
}
|
|
|
|
CheckTcpipState();
|
|
|
|
if (!g_bIp6Configured) {
|
|
Trace0(ERR, "GetBestInterface: No IPv6 Stack on machine\n");
|
|
return ERROR_NOT_SUPPORTED;
|
|
}
|
|
|
|
dwResult = GetBestInterfaceFromIpv6Stack(pSin6, pdwBestIfIndex);
|
|
|
|
return dwResult;
|
|
}
|
|
|
|
DWORD
|
|
WINAPI
|
|
GetBestRoute(
|
|
IN DWORD dwDestAddr,
|
|
IN DWORD dwSourceAddr, OPTIONAL
|
|
OUT PMIB_IPFORWARDROW pBestRoute
|
|
)
|
|
{
|
|
DWORD dwResult, dwOutEntrySize, dwQuerySize;
|
|
|
|
TraceEnter("GetBestRoute");
|
|
|
|
CheckTcpipState();
|
|
|
|
if(!g_bIpConfigured)
|
|
{
|
|
Trace0(ERR, "GetBestInterface: No IP Stack on machine\n");
|
|
|
|
TraceLeave("GetBestInterface");
|
|
|
|
return ERROR_NOT_SUPPORTED;
|
|
}
|
|
|
|
if(pBestRoute is NULL)
|
|
{
|
|
return ERROR_INVALID_PARAMETER;
|
|
}
|
|
|
|
if (IsBadWritePtr(pBestRoute, sizeof(MIB_IPFORWARDROW))) {
|
|
return ERROR_INVALID_PARAMETER;
|
|
}
|
|
|
|
dwResult = GetBestRouteFromStack(dwDestAddr,
|
|
dwSourceAddr,
|
|
pBestRoute);
|
|
|
|
if(dwResult is STATUS_SUCCESS)
|
|
{
|
|
dwResult = NO_ERROR;
|
|
}
|
|
else
|
|
{
|
|
dwResult = ERROR_CAN_NOT_COMPLETE;
|
|
}
|
|
|
|
return dwResult;
|
|
}
|
|
|
|
DWORD
|
|
WINAPI
|
|
CreateProxyArpEntry(
|
|
IN DWORD dwAddress,
|
|
IN DWORD dwMask,
|
|
IN DWORD dwIfIndex
|
|
)
|
|
{
|
|
DWORD dwResult, dwClassMask;
|
|
DEFINE_MIB_BUFFER(pSetInfo,MIB_PROXYARP,pParpRow);
|
|
|
|
TraceEnter("CreateProxyArpEntry");
|
|
|
|
#ifdef CHICAGO
|
|
|
|
TraceLeave("CreateProxyArpEntry");
|
|
|
|
return ERROR_NOT_SUPPORTED;
|
|
|
|
#else
|
|
|
|
CheckTcpipState();
|
|
|
|
if(!g_bIpConfigured)
|
|
{
|
|
Trace0(ERR, "CreateProxyArpEntry: No IP Stack on machine\n");
|
|
|
|
TraceLeave("CreateProxyArpEntry");
|
|
|
|
return ERROR_NOT_SUPPORTED;
|
|
}
|
|
|
|
dwClassMask = GetClassMask(dwAddress);
|
|
|
|
//
|
|
// Address & Mask should == Address
|
|
// Address should not be in the loopback range
|
|
// Address should not be all 0's
|
|
// Address should not be < ClassD
|
|
// Address should not be the all subnets broadcast
|
|
//
|
|
|
|
if(((dwAddress & 0x000000FF) is 0x0000007F) or
|
|
(dwAddress is 0x00000000) or
|
|
((DWORD)(dwAddress & 0x000000FF) >= (DWORD) 0x000000E0) or
|
|
((dwAddress & dwMask) isnot dwAddress) or
|
|
(dwAddress is (dwAddress | ~dwClassMask)))
|
|
{
|
|
TraceLeave("CreateProxyArpEntry");
|
|
|
|
return ERROR_INVALID_PARAMETER;
|
|
}
|
|
|
|
if(IsRouterRunning())
|
|
{
|
|
pSetInfo->dwId = PROXY_ARP;
|
|
|
|
pParpRow->dwAddress = dwAddress;
|
|
pParpRow->dwMask = dwMask;
|
|
pParpRow->dwIfIndex = dwIfIndex;
|
|
|
|
dwResult = MprAdminMIBEntrySet(g_hMIBServer,
|
|
PID_IP,
|
|
IPRTRMGR_PID,
|
|
(PVOID)pSetInfo,
|
|
MIB_INFO_SIZE(MIB_PROXYARP));
|
|
|
|
if(dwResult isnot NO_ERROR)
|
|
{
|
|
Trace1(ERR,
|
|
"MprAdminMIBEntrySet failed with error %x",
|
|
dwResult);
|
|
|
|
TraceLeave("CreateProxyArpEntry");
|
|
|
|
return dwResult;
|
|
}
|
|
}
|
|
else
|
|
{
|
|
dwResult = SetProxyArpEntryToStack(dwAddress,
|
|
dwMask,
|
|
dwIfIndex,
|
|
TRUE,
|
|
FALSE);
|
|
|
|
if(dwResult isnot NO_ERROR)
|
|
{
|
|
Trace1(ERR,
|
|
"SetProxyArpEntryToStack failed with error %d",
|
|
dwResult);
|
|
|
|
TraceLeave("CreateProxyArpEntry");
|
|
|
|
return dwResult;
|
|
}
|
|
|
|
}
|
|
|
|
TraceLeave("CreateProxyArpEntry");
|
|
|
|
return NO_ERROR;
|
|
|
|
#endif
|
|
|
|
}
|
|
|
|
DWORD
|
|
WINAPI
|
|
DeleteProxyArpEntry(
|
|
IN DWORD dwAddress,
|
|
IN DWORD dwMask,
|
|
IN DWORD dwIfIndex
|
|
)
|
|
{
|
|
DWORD dwResult, dwClassMask;
|
|
PMIB_OPAQUE_QUERY pmqQuery;
|
|
|
|
#define QUERY_SIZE sizeof(MIB_OPAQUE_QUERY) + 2 * sizeof(DWORD)
|
|
|
|
BYTE rgbyBuffer[QUERY_SIZE];
|
|
|
|
#undef QUERY_SIZE
|
|
|
|
TraceEnter("DeleteProxyArpEntry");
|
|
|
|
#ifdef CHICAGO
|
|
|
|
TraceLeave("DeleteProxyArpEntry");
|
|
|
|
return ERROR_NOT_SUPPORTED;
|
|
|
|
#else
|
|
|
|
CheckTcpipState();
|
|
|
|
if(!g_bIpConfigured)
|
|
{
|
|
Trace0(ERR,
|
|
"DeleteProxyArpEntry: No IP Stack on machine\n");
|
|
|
|
TraceLeave("DeleteProxyArpEntry");
|
|
|
|
return ERROR_NOT_SUPPORTED;
|
|
}
|
|
|
|
dwClassMask = GetClassMask(dwAddress);
|
|
|
|
if(((dwAddress & 0x000000FF) is 0x0000007F) or
|
|
(dwAddress is 0x00000000) or
|
|
((DWORD)(dwAddress & 0x000000FF) >= (DWORD) 0x000000E0) or
|
|
((dwAddress & dwMask) isnot dwAddress) or
|
|
(dwAddress is (dwAddress | ~dwClassMask)))
|
|
{
|
|
TraceLeave("DeleteProxyArpEntry");
|
|
|
|
return ERROR_INVALID_PARAMETER;
|
|
}
|
|
|
|
|
|
if(IsRouterRunning())
|
|
{
|
|
pmqQuery = (PMIB_OPAQUE_QUERY)rgbyBuffer;
|
|
|
|
pmqQuery->dwVarId = PROXY_ARP;
|
|
pmqQuery->rgdwVarIndex[0] = dwAddress;
|
|
pmqQuery->rgdwVarIndex[1] = dwMask;
|
|
pmqQuery->rgdwVarIndex[2] = dwIfIndex;
|
|
|
|
dwResult = MprAdminMIBEntryDelete(g_hMIBServer,
|
|
PID_IP,
|
|
IPRTRMGR_PID,
|
|
(PVOID)pmqQuery,
|
|
sizeof(rgbyBuffer));
|
|
|
|
if(dwResult isnot NO_ERROR)
|
|
{
|
|
Trace1(ERR,
|
|
"MprAdminMIBEntryDelete failed with error %x",
|
|
dwResult);
|
|
|
|
TraceLeave("DeleteProxyArpEntry");
|
|
|
|
return dwResult;
|
|
}
|
|
}
|
|
else
|
|
{
|
|
dwResult = SetProxyArpEntryToStack(dwAddress,
|
|
dwMask,
|
|
dwIfIndex,
|
|
FALSE,
|
|
FALSE);
|
|
|
|
if(dwResult isnot NO_ERROR)
|
|
{
|
|
Trace1(ERR,
|
|
"SetProxyArpEntryToStack failed with error %x",
|
|
dwResult);
|
|
|
|
TraceLeave("DeleteProxyArpEntry");
|
|
|
|
return dwResult;
|
|
}
|
|
|
|
}
|
|
|
|
TraceLeave("DeleteProxyArpEntry");
|
|
|
|
return NO_ERROR;
|
|
|
|
#endif
|
|
}
|
|
|
|
DWORD
|
|
WINAPI
|
|
GetFriendlyIfIndex(
|
|
DWORD IfIndex
|
|
)
|
|
{
|
|
return (0x00FFFFFF & IfIndex);
|
|
}
|
|
|
|
PWCHAR
|
|
NhGetInterfaceTypeString(
|
|
IN DWORD dwIfType
|
|
)
|
|
{
|
|
PWCHAR pwszOut;
|
|
|
|
|
|
if((dwIfType < MIN_IF_TYPE) or
|
|
(dwIfType > MAX_IF_TYPE))
|
|
{
|
|
return NULL;
|
|
}
|
|
|
|
pwszOut = HeapAlloc(g_hPrivateHeap,
|
|
0,
|
|
MAX_IF_TYPE_LENGTH * sizeof(WCHAR));
|
|
|
|
if(pwszOut is NULL)
|
|
{
|
|
return NULL;
|
|
}
|
|
|
|
if(!LoadStringW(g_hModule,
|
|
dwIfType,
|
|
pwszOut,
|
|
MAX_IF_TYPE_LENGTH))
|
|
{
|
|
HeapFree(g_hPrivateHeap,
|
|
0,
|
|
pwszOut);
|
|
|
|
return NULL;
|
|
}
|
|
|
|
return pwszOut;
|
|
}
|
|
|
|
VOID
|
|
NhFreeString(
|
|
IN PWCHAR pwszString
|
|
)
|
|
{
|
|
HeapFree(g_hPrivateHeap,
|
|
0,
|
|
pwszString);
|
|
}
|
|
|
|
|
|
VOID
|
|
CheckTcpipState()
|
|
{
|
|
// Check whether tcpip was configured
|
|
// if not, check whether tcpip is configured now
|
|
|
|
EnterCriticalSection(&g_stateLock);
|
|
|
|
if (!g_bIpConfigured) {
|
|
if(OpenTCPDriver(AF_INET) == NO_ERROR) {
|
|
g_bIpConfigured = TRUE;
|
|
if(UpdateAdapterToIFInstanceMapping() != NO_ERROR) {
|
|
g_bIpConfigured = FALSE;
|
|
CloseTCPDriver();
|
|
} else {
|
|
if(UpdateAdapterToATInstanceMapping() != NO_ERROR) {
|
|
g_bIpConfigured = FALSE;
|
|
CloseTCPDriver();
|
|
} else {
|
|
g_bIpConfigured = TRUE;
|
|
}
|
|
}
|
|
} else {
|
|
g_bIpConfigured = FALSE;
|
|
}
|
|
|
|
if (g_bIpConfigured) {
|
|
if (IpcfgdllInit(NULL, DLL_PROCESS_ATTACH, NULL) == FALSE) {
|
|
g_bIpConfigured = FALSE;
|
|
CloseTCPDriver();
|
|
}
|
|
}
|
|
}
|
|
|
|
if (!g_bIp6Configured) {
|
|
if(OpenTCPDriver(AF_INET6) == NO_ERROR) {
|
|
g_bIp6Configured = TRUE;
|
|
} else {
|
|
g_bIp6Configured = FALSE;
|
|
}
|
|
}
|
|
|
|
LeaveCriticalSection(&g_stateLock);
|
|
}
|