windows-nt/Source/XPSP1/NT/net/tcpip/apis/iphlpapi/dll/extapi.c

2700 lines
60 KiB
C
Raw Permalink Normal View History

2020-09-26 03:20:57 -05:00
/*++
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);
}