windows-nt/Source/XPSP1/NT/net/tcpip/snmp/locate.c
2020-09-26 16:20:57 +08:00

716 lines
18 KiB
C

/*++
Copyright (c) 1995 Microsoft Corporation
Module Name:
Abstract:
File contains the following functions
LocateIfRow
LocateIpAddrRow
LocateIpForwardRow
LocateIpNetRow
LocateUdpRow
LocateUdp6Row
LocateTcpRow
LocateTcp6Row
The LocateXXXRow Functions are passed a variable sized array of indices, a count of
the number of indices passed and the type of query for which the location is being
done (GET_FIRST, NEXT or GET/SET/CREATE/DELETE - there are only three type of
behaviours of the locators). They fill in the index of the corresponding row and return
ERROR_NO_DATA, ERROR_INVALID_INDEX, NO_ERROR or ERROR_NO_MORE_ITEMS
The general search algorithm is this;
If the table is empty, return ERROR_NO_DATA
else
If the query is a GET_FIRST
Return the first row
else
Build the index as follows:
Set the Index to all 0s
From the number of indices passed figure out how much of the index you can build
keeping the rest 0. If the query is a GET, SET, CREATE_ENTRY or DELETE_ENTRY
then the complete index must be given. This check is, however, supposed to be done
at the agent.
If the full index has not been given, the index is deemed to be modified (Again
this can only happen in the NEXT case).
After this a search is done. We try for an exact match with the index. For all
queries other than NEXT there is no problem. For NEXT there are two cases:
If the complete index was given and and you get an exact match, then you
return the next entry. If you dont get an exact match you return the next
higher entry
If an incomplete index was given and you modified it by padding 0s, and if
an exact match is found, then you return the matching entry (Of course if an
exact match is not found you again return the next higher entry)
Revision History:
Amritansh Raghav 6/8/95 Created
--*/
#include "allinc.h"
PMIB_IFROW
LocateIfRow(
DWORD dwQueryType,
AsnAny *paaIfIndex
)
{
DWORD i;
DWORD dwIndex;
//
// If there is no index the type is ASN_NULL. This causes the macro to return the
// default value (0 in this case)
//
dwIndex = GetAsnInteger(paaIfIndex, 0);
TraceEnter("LocateIfRow");
if (g_Cache.pRpcIfTable->dwNumEntries is 0)
{
TraceLeave("LocateIfRow");
return NULL;
}
if (dwQueryType is GET_FIRST)
{
TraceLeave("LocateIfRow");
return &(g_Cache.pRpcIfTable->table[0]);
}
for (i = 0; i < g_Cache.pRpcIfTable->dwNumEntries; i++)
{
if ((g_Cache.pRpcIfTable->table[i].dwIndex is dwIndex) and dwQueryType is GET_EXACT)
{
TraceLeave("LocateIfRow");
return &(g_Cache.pRpcIfTable->table[i]);
}
if (g_Cache.pRpcIfTable->table[i].dwIndex > dwIndex)
{
if (dwQueryType is GET_NEXT)
{
TraceLeave("LocateIfRow");
return &(g_Cache.pRpcIfTable->table[i]);
}
else
{
TraceLeave("LocateIfRow");
return NULL;
}
}
}
TraceLeave("LocateIfRow");
return NULL;
}
PMIB_IPADDRROW
LocateIpAddrRow(
DWORD dwQueryType,
AsnAny *paaIpAddr
)
{
LONG lCompare;
DWORD i, dwAddr;
BOOL bNext, bModified;
TraceEnter("LocateIpAddrRow");
if (g_Cache.pRpcIpAddrTable->dwNumEntries is 0)
{
TraceLeave("LocateIpAddrRow");
return NULL;
}
if (dwQueryType is GET_FIRST)
{
TraceLeave("LocateIpAddrRow");
return &(g_Cache.pRpcIpAddrTable->table[0]);
}
dwAddr = GetAsnIPAddress(paaIpAddr, 0x00000000);
bModified = FALSE;
if (IsAsnIPAddressTypeNull(paaIpAddr))
{
bModified = TRUE;
}
bNext = (dwQueryType is GET_NEXT) and (bModified is FALSE);
for (i = 0; i < g_Cache.pRpcIpAddrTable->dwNumEntries; i++)
{
if ((InetCmp(dwAddr, g_Cache.pRpcIpAddrTable->table[i].dwAddr, lCompare) is 0) and !bNext)
{
TraceLeave("LocateIpAddrRow");
return &(g_Cache.pRpcIpAddrTable->table[i]);
}
if (lCompare < 0)
{
if (dwQueryType is GET_NEXT)
{
TraceLeave("LocateIpAddrRow");
return &(g_Cache.pRpcIpAddrTable->table[i]);
}
else
{
TraceLeave("LocateIpAddrRow");
return NULL;
}
}
}
TraceLeave("LocateIpAddrRow");
return NULL;
}
PMIB_IPFORWARDROW
LocateIpRouteRow(
DWORD dwQueryType,
AsnAny *paaIpDest
)
{
DWORD dwDest;
LONG lCompare;
DWORD i;
BOOL bNext, bModified;
TraceEnter("LocateIpRouteRow");
if (g_Cache.pRpcIpForwardTable->dwNumEntries is 0)
{
TraceLeave("LocateIpRouteRow");
return NULL;
}
if (dwQueryType is GET_FIRST)
{
TraceLeave("LocateIpRouteRow");
return &(g_Cache.pRpcIpForwardTable->table[0]);
}
dwDest = GetAsnIPAddress(paaIpDest, 0x00000000);
bModified = FALSE;
if (IsAsnIPAddressTypeNull(paaIpDest))
{
bModified = TRUE;
}
bNext = (dwQueryType is GET_NEXT) and (bModified is FALSE);
for (i = 0; i < g_Cache.pRpcIpForwardTable->dwNumEntries; i++)
{
if ((InetCmp(dwDest, g_Cache.pRpcIpForwardTable->table[i].dwForwardDest, lCompare) is 0) and !bNext)
{
TraceLeave("LocateIpRouteRow");
return &(g_Cache.pRpcIpForwardTable->table[i]);
}
if (lCompare < 0)
{
if (dwQueryType is GET_NEXT)
{
TraceLeave("LocateIpRouteRow");
return &(g_Cache.pRpcIpForwardTable->table[i]);
}
else
{
TraceLeave("LocateIpRouteRow");
return NULL;
}
}
}
TraceLeave("LocateIpRouteRow");
return NULL;
}
PMIB_IPFORWARDROW
LocateIpForwardRow(
DWORD dwQueryType,
AsnAny *paaDest,
AsnAny *paaProto,
AsnAny *paaPolicy,
AsnAny *paaNextHop
)
{
DWORD dwIpForwardIndex[4];
LONG lCompare;
DWORD i;
BOOL bNext, bModified;
TraceEnter("LocateIpForwardRow");
if (g_Cache.pRpcIpForwardTable->dwNumEntries is 0)
{
TraceLeave("LocateIpForwardRow");
return NULL;
}
if (dwQueryType is GET_FIRST)
{
TraceLeave("LocateIpForwardRow");
return &(g_Cache.pRpcIpForwardTable->table[0]);
}
dwIpForwardIndex[0] = GetAsnIPAddress(paaDest, 0x00000000);
dwIpForwardIndex[1] = GetAsnInteger(paaProto, 0);
dwIpForwardIndex[2] = GetAsnInteger(paaPolicy, 0);
dwIpForwardIndex[3] = GetAsnIPAddress(paaNextHop, 0x00000000);
bModified = FALSE;
if (IsAsnIPAddressTypeNull(paaDest) or
IsAsnTypeNull(paaProto) or
IsAsnTypeNull(paaPolicy) or
IsAsnIPAddressTypeNull(paaNextHop))
{
bModified = TRUE;
}
bNext = (dwQueryType is GET_NEXT) and (bModified is FALSE);
for (i = 0; i < g_Cache.pRpcIpForwardTable->dwNumEntries; i++)
{
lCompare = IpForwardCmp(dwIpForwardIndex[0],
dwIpForwardIndex[1],
dwIpForwardIndex[2],
dwIpForwardIndex[3],
g_Cache.pRpcIpForwardTable->table[i].dwForwardDest,
g_Cache.pRpcIpForwardTable->table[i].dwForwardProto,
g_Cache.pRpcIpForwardTable->table[i].dwForwardPolicy,
g_Cache.pRpcIpForwardTable->table[i].dwForwardNextHop);
if ((lCompare is 0) and !bNext)
{
TraceLeave("LocateIpForwardRow");
return &(g_Cache.pRpcIpForwardTable->table[i]);
}
if (lCompare < 0)
{
if (dwQueryType is GET_NEXT)
{
TraceLeave("LocateIpForwardRow");
return &(g_Cache.pRpcIpForwardTable->table[i]);
}
else
{
TraceLeave("LocateIpForwardRow");
return NULL;
}
}
}
TraceLeave("LocateIpForwardRow");
return NULL;
}
PMIB_IPNETROW
LocateIpNetRow(
DWORD dwQueryType,
AsnAny *paaIndex,
AsnAny *paaAddr
)
{
DWORD i;
LONG lCompare;
DWORD dwIpNetIfIndex, dwIpNetIpAddr;
BOOL bNext, bModified;
TraceEnter("LocateIfNetRow");
if (g_Cache.pRpcIpNetTable->dwNumEntries is 0)
{
TraceLeave("LocateIpNetRow");
return NULL;
}
if (dwQueryType is GET_FIRST)
{
TraceLeave("LocateIpNetRow");
return &(g_Cache.pRpcIpNetTable->table[0]);
}
bModified = FALSE;
dwIpNetIfIndex = GetAsnInteger(paaIndex, 0);
dwIpNetIpAddr = GetAsnIPAddress(paaAddr, 0x00000000);
if (IsAsnTypeNull(paaIndex) or
IsAsnIPAddressTypeNull(paaAddr))
{
bModified = TRUE;
}
bNext = (dwQueryType is GET_NEXT) and (bModified is FALSE);
for (i = 0; i < g_Cache.pRpcIpNetTable->dwNumEntries; i++)
{
lCompare = IpNetCmp(dwIpNetIfIndex,
dwIpNetIpAddr,
g_Cache.pRpcIpNetTable->table[i].dwIndex,
g_Cache.pRpcIpNetTable->table[i].dwAddr);
if ((lCompare is 0) and !bNext)
{
TraceLeave("LocateIpNetRow");
return &(g_Cache.pRpcIpNetTable->table[i]);
}
if (lCompare < 0)
{
if (dwQueryType is GET_NEXT)
{
TraceLeave("LocateIpNetRow");
return &(g_Cache.pRpcIpNetTable->table[i]);
}
else
{
TraceLeave("LocateIpNetRow");
return NULL;
}
}
}
TraceLeave("LocateIpNetRow");
return NULL;
}
PMIB_UDPROW
LocateUdpRow(
DWORD dwQueryType,
AsnAny *paaLocalAddr,
AsnAny *paaLocalPort
)
{
DWORD i;
LONG lCompare;
DWORD dwIndex[2];
BOOL bNext, bModified;
TraceEnter("LocateUdpRow");
if (g_Cache.pRpcUdpTable->dwNumEntries is 0)
{
TraceLeave("LocateUdpRow");
return NULL;
}
if (dwQueryType is GET_FIRST)
{
TraceLeave("LocateUdpRow");
return &(g_Cache.pRpcUdpTable->table[0]);
}
#define LOCAL_ADDR 0
#define LOCAL_PORT 1
dwIndex[LOCAL_ADDR] = GetAsnIPAddress(paaLocalAddr, 0x00000000);
dwIndex[LOCAL_PORT] = GetAsnInteger(paaLocalPort, 0);
bModified = FALSE;
if (IsAsnIPAddressTypeNull(paaLocalAddr) or
IsAsnTypeNull(paaLocalPort))
{
bModified = TRUE;
}
bNext = (dwQueryType is GET_NEXT) and (bModified is FALSE);
for (i = 0; i < g_Cache.pRpcUdpTable->dwNumEntries; i++)
{
lCompare = UdpCmp(dwIndex[LOCAL_ADDR],
dwIndex[LOCAL_PORT],
g_Cache.pRpcUdpTable->table[i].dwLocalAddr,
g_Cache.pRpcUdpTable->table[i].dwLocalPort);
if ((lCompare is 0) and !bNext)
{
TraceLeave("LocateUdpRow");
return &(g_Cache.pRpcUdpTable->table[i]);
}
if (lCompare < 0)
{
if (dwQueryType is GET_NEXT)
{
TraceLeave("LocateUdpRow");
return &(g_Cache.pRpcUdpTable->table[i]);
}
else
{
TraceLeave("LocateUdpRow");
return NULL;
}
}
}
TraceLeave("LocateUdpRow");
return NULL;
}
PUDP6ListenerEntry
LocateUdp6Row(
DWORD dwQueryType,
AsnAny *paaLocalAddr,
AsnAny *paaLocalPort
)
{
DWORD i;
LONG lCompare;
DWORD dwLocalPort;
BOOL bNext, bModified;
// address plus scope id
BYTE rgbyLocalAddrEx[20];
TraceEnter("LocateUdp6Row");
if (g_Cache.pRpcUdp6ListenerTable->dwNumEntries is 0)
{
TraceLeave("LocateUdp6Row");
return NULL;
}
if (dwQueryType is GET_FIRST)
{
TraceLeave("LocateUdp6Row");
return &(g_Cache.pRpcUdp6ListenerTable->table[0]);
}
// zero out scope id in case the octet string doesn't include it
ZeroMemory(rgbyLocalAddrEx, sizeof(rgbyLocalAddrEx));
GetAsnOctetString(rgbyLocalAddrEx, paaLocalAddr);
dwLocalPort = GetAsnInteger(paaLocalPort, 0);
bModified = FALSE;
if (IsAsnIPAddressTypeNull(paaLocalAddr) or
IsAsnTypeNull(paaLocalPort))
{
bModified = TRUE;
}
bNext = (dwQueryType is GET_NEXT) and (bModified is FALSE);
for (i = 0; i < g_Cache.pRpcUdp6ListenerTable->dwNumEntries; i++)
{
lCompare = Udp6Cmp(rgbyLocalAddrEx,
dwLocalPort,
g_Cache.pRpcUdp6ListenerTable->table[i].ule_localaddr.s6_bytes,
g_Cache.pRpcUdp6ListenerTable->table[i].ule_localport);
if ((lCompare is 0) and !bNext)
{
TraceLeave("LocateUdp6Row");
return &(g_Cache.pRpcUdp6ListenerTable->table[i]);
}
if (lCompare < 0)
{
if (dwQueryType is GET_NEXT)
{
TraceLeave("LocateUdp6Row");
return &(g_Cache.pRpcUdp6ListenerTable->table[i]);
}
else
{
TraceLeave("LocateUdp6Row");
return NULL;
}
}
}
TraceLeave("LocateUdp6Row");
return NULL;
}
PMIB_TCPROW
LocateTcpRow(
DWORD dwQueryType,
AsnAny *paaLocalAddr,
AsnAny *paaLocalPort,
AsnAny *paaRemoteAddr,
AsnAny *paaRemotePort
)
{
LONG lCompare;
DWORD dwIndex[4];
BOOL bNext, bModified;
DWORD startIndex, stopIndex, i;
TraceEnter("LocateTcpRow");
if (g_Cache.pRpcTcpTable->dwNumEntries is 0)
{
TraceLeave("LocateTcpRow");
return NULL;
}
if (dwQueryType is GET_FIRST)
{
TraceLeave("LocateTcpRow");
return &(g_Cache.pRpcTcpTable->table[0]);
}
#define REM_ADDR 2
#define REM_PORT 3
dwIndex[LOCAL_ADDR] = GetAsnIPAddress(paaLocalAddr, 0x00000000);
dwIndex[LOCAL_PORT] = GetAsnInteger(paaLocalPort, 0);
dwIndex[REM_ADDR] = GetAsnIPAddress(paaRemoteAddr, 0x00000000);
dwIndex[REM_PORT] = GetAsnInteger(paaRemotePort, 0);
bModified = FALSE;
if (IsAsnIPAddressTypeNull(paaLocalAddr) or
IsAsnTypeNull(paaLocalPort) or
IsAsnIPAddressTypeNull(paaRemoteAddr) or
IsAsnTypeNull(paaRemotePort))
{
bModified = TRUE;
}
bNext = (dwQueryType is GET_NEXT) and (bModified is FALSE);
for (i = 0; i < g_Cache.pRpcTcpTable->dwNumEntries; i++)
{
lCompare = TcpCmp(dwIndex[LOCAL_ADDR],
dwIndex[LOCAL_PORT],
dwIndex[REM_ADDR],
dwIndex[REM_PORT],
g_Cache.pRpcTcpTable->table[i].dwLocalAddr,
g_Cache.pRpcTcpTable->table[i].dwLocalPort,
g_Cache.pRpcTcpTable->table[i].dwRemoteAddr,
g_Cache.pRpcTcpTable->table[i].dwRemotePort);
if ((lCompare is 0) and !bNext)
{
TraceLeave("LocateTcpRow");
return &(g_Cache.pRpcTcpTable->table[i]);
}
if (lCompare < 0)
{
if (dwQueryType is GET_NEXT)
{
TraceLeave("LocateTcpRow");
return &(g_Cache.pRpcTcpTable->table[i]);
}
else
{
TraceLeave("LocateTcpRow");
return NULL;
}
}
}
TraceLeave("LocateTcpRow");
return NULL;
}
PTCP6ConnTableEntry
LocateTcp6Row(
DWORD dwQueryType,
AsnAny *paaLocalAddr,
AsnAny *paaLocalPort,
AsnAny *paaRemoteAddr,
AsnAny *paaRemotePort
)
{
LONG lCompare;
DWORD dwLocalPort, dwRemotePort;
BOOL bNext, bModified;
DWORD startIndex, stopIndex, i;
// address plus scope id
BYTE rgbyLocalAddrEx[20];
BYTE rgbyRemoteAddrEx[20];
TraceEnter("LocateTcp6Row");
if (g_Cache.pRpcTcp6Table->dwNumEntries is 0)
{
TraceLeave("LocateTcp6Row");
return NULL;
}
if (dwQueryType is GET_FIRST)
{
TraceLeave("LocateTcp6Row");
return &(g_Cache.pRpcTcp6Table->table[0]);
}
// zero out scope id in case the octet string doesn't include it
ZeroMemory(rgbyLocalAddrEx, sizeof(rgbyLocalAddrEx));
ZeroMemory(rgbyRemoteAddrEx, sizeof(rgbyRemoteAddrEx));
GetAsnOctetString(rgbyLocalAddrEx, paaLocalAddr);
dwLocalPort = GetAsnInteger(paaLocalPort, 0);
GetAsnOctetString(rgbyRemoteAddrEx, paaRemoteAddr);
dwRemotePort = GetAsnInteger(paaRemotePort, 0);
bModified = FALSE;
if (IsAsnOctetStringTypeNull(paaLocalAddr) or
IsAsnTypeNull(paaLocalPort) or
IsAsnOctetStringTypeNull(paaRemoteAddr) or
IsAsnTypeNull(paaRemotePort))
{
bModified = TRUE;
}
bNext = (dwQueryType is GET_NEXT) and (bModified is FALSE);
for (i = 0; i < g_Cache.pRpcTcp6Table->dwNumEntries; i++)
{
lCompare = Tcp6Cmp(rgbyLocalAddrEx,
dwLocalPort,
rgbyRemoteAddrEx,
dwRemotePort,
g_Cache.pRpcTcp6Table->table[i].tct_localaddr.s6_bytes,
g_Cache.pRpcTcp6Table->table[i].tct_localport,
g_Cache.pRpcTcp6Table->table[i].tct_remoteaddr.s6_bytes,
g_Cache.pRpcTcp6Table->table[i].tct_remoteport);
if ((lCompare is 0) and !bNext)
{
TraceLeave("LocateTcp6Row");
return &(g_Cache.pRpcTcp6Table->table[i]);
}
if (lCompare < 0)
{
if (dwQueryType is GET_NEXT)
{
TraceLeave("LocateTcp6Row");
return &(g_Cache.pRpcTcp6Table->table[i]);
}
else
{
TraceLeave("LocateTcp6Row");
return NULL;
}
}
}
TraceLeave("LocateTcp6Row");
return NULL;
}