📄 wsnmp_cf.c
字号:
}
// Save valid session for later error returns
lSession = hSession;
if (hSrc) // Allowed to be NULL
{
nSrc = HandleToUlong(hSrc) - 1;
if (!snmpValidTableEntry(&EntsDescr, nSrc))
{
lError = SNMPAPI_ENTITY_INVALID;
goto ERROR_OUT;
}
pEntSrc = snmpGetTableEntry(&EntsDescr, nSrc);
}
nDst = HandleToUlong(hDst) - 1;
if (!snmpValidTableEntry(&EntsDescr, nDst))
{
lError = SNMPAPI_ENTITY_INVALID;
goto ERROR_OUT;
}
pEntDst = snmpGetTableEntry(&EntsDescr, nDst);
nCtx = HandleToUlong(hCtx) - 1;
if (!snmpValidTableEntry(&CntxDescr, nCtx))
{
lError = SNMPAPI_CONTEXT_INVALID;
goto ERROR_OUT;
}
pCtxt = snmpGetTableEntry(&CntxDescr, nCtx);
nPdu = HandleToUlong(hPdu) - 1;
if (!snmpValidTableEntry(&PDUsDescr, nPdu))
{
lError = SNMPAPI_PDU_INVALID;
goto ERROR_OUT;
}
pPdu = snmpGetTableEntry(&PDUsDescr, nPdu);
if (!snmpValidTableEntry(&VBLsDescr, HandleToUlong(pPdu->VBL)-1))
{
lError = SNMPAPI_VBL_INVALID;
goto ERROR_OUT;
}
//--------------
tFamily = pEntDst->addr.inet.sin_family;
// enter the critical section for the TaskData structure to insure
// the atomicity of the Test&Set operation of the TaskData.[ip|ipx]Thread
EnterCriticalSection (&cs_TASK);
pThread = (tFamily==AF_IPX) ? &TaskData.ipxThread : &TaskData.ipThread;
pSock = (tFamily==AF_IPX) ? &TaskData.ipxSock : &TaskData.ipSock;
if (*pThread) // ASSERT(*pSock != INVALID_SOCKET)
{
LeaveCriticalSection(&cs_TASK);
goto CHANNEL_OPEN;
}
*pSock = socket (tFamily, SOCK_DGRAM, (tFamily==AF_IPX)?NSPROTO_IPX:0);
if (*pSock == INVALID_SOCKET)
{
LeaveCriticalSection(&cs_TASK);
lError = SNMPAPI_TL_NOT_SUPPORTED;
goto ERROR_OUT;
}
// try to set the socket for broadcasts. No matter the result
// a possible error will be caught later
fBroadcast = TRUE;
setsockopt (*pSock,
SOL_SOCKET,
SO_BROADCAST,
(CHAR *) &fBroadcast,
sizeof ( BOOL )
);
// Kludge for Win95 WinSock/IPX bug...have to "bind"
ZeroMemory (&tAddr, sizeof(SOCKADDR));
tAddr.sa_family = (USHORT)tFamily;
bind (*pSock, &tAddr, (tFamily==AF_IPX)?sizeof(SOCKADDR_IPX):sizeof(SOCKADDR_IN));
// Start "listener" and timer threads
#ifdef SOLARIS
thr_create (NULL, 0, thrManager, (LPVOID)tSock, THR_FLAGS, pThread);
#else
*pThread = (HANDLE)_beginthreadex (NULL, 0, thrManager, (LPVOID)pSock, 0, &thrId);
#endif // SOLARIS
if (*pThread == NULL)
{
LeaveCriticalSection (&cs_TASK);
closesocket (*pSock);
*pSock = INVALID_SOCKET;
lError = SNMPAPI_TL_RESOURCE_ERROR;
goto ERROR_OUT;
}
LeaveCriticalSection (&cs_TASK);
//---------------
CHANNEL_OPEN:
pduType = pPdu->type;
sendPdu = pPdu;
if (pEntDst->version == 1)
{ // Test for special v2 msg -> v1 dst operations
if (pduType == SNMP_PDU_TRAP)
{ // RFC 2089 v2 to v1 trap conversion
sendPdu = MapV2TrapV1 (hPdu);
if (sendPdu == NULL)
{
lError = SNMPAPI_OTHER_ERROR;
goto ERROR_OUT;
}
pduType = SNMP_PDU_V1TRAP;
}
else if (pduType == SNMP_PDU_INFORM)
{
lError = SNMPAPI_OPERATION_INVALID;
goto ERROR_OUT;
}
}
// Space check
EnterCriticalSection (&cs_MSG);
lError = snmpAllocTableEntry(&MsgDescr, &nMsg);
if (lError != SNMPAPI_SUCCESS)
goto ERROR_PRECHECK;
pMsg = snmpGetTableEntry(&MsgDescr, nMsg);
// Now Build it
if (pduType == SNMP_PDU_RESPONSE || pduType == SNMP_PDU_TRAP)
dllReqId = pPdu->appReqId;
else
dllReqId = ++(TaskData.nLastReqId);
tmpContext.len = pCtxt->commLen;
tmpContext.ptr = pCtxt->commStr;
// Save BuildMessage status for later check
fMsg = BuildMessage (pEntDst->version-1, &tmpContext, sendPdu,
dllReqId, &(pMsg->Addr), &(pMsg->Size));
// If v2 to v1 trap conversion was required, then cleanup...
if (pduType == SNMP_PDU_V1TRAP)
{
FreeVarBindList (sendPdu->VBL_addr); // Checks for NULL
FreeV1Trap (sendPdu->v1Trap); // Checks for NULL
GlobalFree (sendPdu);
}
// If BuildMessage failed, that's all folks!
if (!fMsg)
{
snmpFreeTableEntry(&MsgDescr, nMsg);
lError = SNMPAPI_PDU_INVALID;
goto ERROR_PRECHECK;
}
pMsg->Session = hSession;
pMsg->Status = NP_SEND; // "send"
pMsg->Type = pduType;
pMsg->nRetransmitMode = TaskData.nRetransmitMode;
pMsg->dllReqId = dllReqId;
pMsg->appReqId = pPdu->appReqId;
pMsg->agentEntity = hDst;
pMsg->ourEntity = hSrc;
pMsg->Context = hCtx;
LeaveCriticalSection (&cs_MSG);
// Update reference counts for entities and contexts,
EnterCriticalSection (&cs_ENTITY);
if (hSrc)
pEntSrc->refCount++;
pEntDst->refCount++;
LeaveCriticalSection (&cs_ENTITY);
EnterCriticalSection (&cs_CONTEXT);
pCtxt->refCount++;
LeaveCriticalSection (&cs_CONTEXT);
// Prepare addressing info for traps
EnterCriticalSection (&cs_MSG);
CopyMemory (&(pMsg->Host), &pEntDst->addr, sizeof(SAS));
if (pduType == SNMP_PDU_V1TRAP ||
pduType == SNMP_PDU_TRAP ||
pduType == SNMP_PDU_INFORM)
{
if (tFamily == AF_IPX)
{
if (pMsg->Host.ipx.sa_socket == ntohs (IPX_SNMP_PORT))
pMsg->Host.ipx.sa_socket = htons (IPX_TRAP_PORT);
}
else // Assume AF_INET
{
if (pMsg->Host.inet.sin_port == ntohs (IP_SNMP_PORT))
pMsg->Host.inet.sin_port = htons(IP_TRAP_PORT);
}
}
// Send the packet
thrId = sendto (*pSock, pMsg->Addr, pMsg->Size,
0, (LPSOCKADDR)&(pMsg->Host), sizeof(SAS));
if (thrId == SOCKET_ERROR)
{
FreeMsg (nMsg);
lError = SNMPAPI_TL_OTHER;
goto ERROR_PRECHECK;
}
// Need to check for SOCKET_ERROR!
if (pduType == SNMP_PDU_TRAP ||
pduType == SNMP_PDU_V1TRAP ||
pduType == SNMP_PDU_RESPONSE)
{
FreeMsg (nMsg);
}
else
{
pMsg->Status = NP_SENT;
// Time entity's timeout value is stored as centiseconds in 32 bits
pMsg->Wait = pEntDst->nPolicyTimeout;
// Converting to milliseconds for timer operations could overflow
if (pMsg->Wait <= MAXCENTISECONDS) // So check first...if ok
pMsg->Wait *= 10; // Convert to milliseconds
else // eles...
pMsg->Wait = MAXMILLISECONDS; // Set to max milliseconds
pMsg->Tries = pEntDst->nPolicyRetry;
pMsg->Ticks = GetTickCount();
}
ERROR_PRECHECK:
LeaveCriticalSection (&cs_MSG);
if (lError == SNMPAPI_SUCCESS)
return (SNMPAPI_SUCCESS);
ERROR_OUT:
return (SaveError (lSession, lError));
} // end_SnmpSendMsg
// SnmpRecvMsg
SNMPAPI_STATUS SNMPAPI_CALL
SnmpRecvMsg (IN HSNMP_SESSION hSession,
OUT LPHSNMP_ENTITY srcEntity,
OUT LPHSNMP_ENTITY dstEntity,
OUT LPHSNMP_CONTEXT context,
OUT LPHSNMP_PDU pdu)
{
DWORD nMsg;
DWORD nPdu;
int pduType;
smiLPOCTETS community;
smiUINT32 version;
smiUINT32 nMode;
SNMPAPI_STATUS lError = SNMPAPI_SUCCESS;
HSNMP_SESSION lSession = 0;
DWORD nSes = HandleToUlong(hSession) - 1;
LPPDUS pPdu;
LPENTITY pEntity;
LPSNMPMSG pMsg;
if (TaskData.hTask == 0)
{
lError = SNMPAPI_NOT_INITIALIZED;
goto ERROR_OUT;
}
if (!snmpValidTableEntry(&SessDescr, nSes))
{
lError = SNMPAPI_SESSION_INVALID;
goto ERROR_OUT;
}
// Valid session...save for possible error return
lSession = hSession;
EnterCriticalSection (&cs_MSG);
// Find a message for the calling session
for (nMsg = 0; nMsg < MsgDescr.Allocated; nMsg++)
{
pMsg = snmpGetTableEntry(&MsgDescr, nMsg);
if (pMsg->Session == hSession &&
pMsg->Status == NP_READY)
break;
}
if (nMsg == MsgDescr.Allocated)
{
lError = SNMPAPI_NOOP;
goto ERROR_PRECHECK1;
}
if (!pMsg->Addr)
{
lError = SNMPAPI_MESSAGE_INVALID;
goto ERROR_PRECHECK1;
}
ERROR_PRECHECK1:
LeaveCriticalSection (&cs_MSG);
if (lError != SNMPAPI_SUCCESS)
goto ERROR_OUT;
// Allocate a slot in PDU table
EnterCriticalSection (&cs_PDU);
lError = snmpAllocTableEntry(&PDUsDescr, &nPdu);
if (lError != SNMPAPI_SUCCESS)
goto ERROR_PRECHECK2;
pPdu = snmpGetTableEntry(&PDUsDescr, nPdu);
nMode = ParseMessage (pMsg->Addr, pMsg->Size,
&version, &community, pPdu);
if (nMode != 0) // non-zero = error code
{
snmpFreeTableEntry(&PDUsDescr, nPdu);
FreeMsg (nMsg);
lError = SNMPAPI_PDU_INVALID;
goto ERROR_PRECHECK2;
}
pPdu->Session = hSession;
pPdu->appReqId = pMsg->appReqId;
ERROR_PRECHECK2:
LeaveCriticalSection (&cs_PDU);
if (lError != SNMPAPI_SUCCESS)
goto ERROR_OUT;
pduType = pPdu->type;
EnterCriticalSection (&cs_ENTITY);
if (dstEntity)
{ // Deliberate assignment...
if (*dstEntity = pMsg->ourEntity)
{
pEntity = snmpGetTableEntry(&EntsDescr, HandleToUlong(pMsg->ourEntity)-1);
pEntity->refCount++;
}
}
if (srcEntity)
{
if (pduType == SNMP_PDU_TRAP ||
pduType == SNMP_PDU_INFORM ||
pduType != SNMP_PDU_RESPONSE)
{
int afType = pMsg->Host.ipx.sa_family;
char afHost[24];
EnterCriticalSection (&cs_XMODE);
SnmpGetTranslateMode (&nMode);
SnmpSetTranslateMode (SNMPAPI_UNTRANSLATED_V1);
if (afType == AF_IPX)
SnmpIpxAddressToStr (pMsg->Host.ipx.sa_netnum,
pMsg->Host.ipx.sa_nodenum,
afHost);
else // AF_INET
lstrcpy (afHost, inet_ntoa (pMsg->Host.inet.sin_addr));
pMsg->agentEntity = SnmpStrToEntity (hSession, afHost);
pEntity = snmpGetTableEntry(&EntsDescr, HandleToUlong(pMsg->agentEntity)-1);
if (afType == AF_IPX)
pEntity->addr.ipx.sa_socket = pMsg->Host.ipx.sa_socket;
else // AF_INET
pEntity->addr.inet.sin_port = pMsg->Host.inet.sin_port;
SnmpSetTranslateMode (nMode);
LeaveCriticalSection (&cs_XMODE);
}
// Deliberate assignment...
if (*srcEntity = pMsg->agentEntity)
{
pEntity = snmpGetTableEntry(&EntsDescr, HandleToUlong(pMsg->agentEntity)-1);
pEntity->refCount++;
}
}
LeaveCriticalSection (&cs_ENTITY);
EnterCriticalSection (&cs_CONTEXT);
if (context)
{
if (pduType == SNMP_PDU_TRAP ||
pduType == SNMP_PDU_INFORM ||
pduType != SNMP_PDU_RESPONSE)
{
EnterCriticalSection (&cs_XMODE);
SnmpGetTranslateMode (&nMode);
SnmpSetTranslateMode (SNMPAPI_UNTRANSLATED_V1);
pMsg->Context = SnmpStrToContext (hSession, community);
SnmpSetTranslateMode (nMode);
LeaveCriticalSection (&cs_XMODE);
}
// Deliberate assignment...
if (*context = pMsg->Context)
((LPCTXT)snmpGetTableEntry(&CntxDescr, HandleToUlong(pMsg->Context)-1))->refCount++;
}
LeaveCriticalSection (&cs_CONTEXT);
FreeOctetString (community);
if (pdu)
*pdu = (HSNMP_PDU)(nPdu+1);
else
SnmpFreePdu ((HSNMP_PDU)(nPdu+1));
// Mark SendRecv slot as free
FreeMsg (nMsg);
return (SNMPAPI_SUCCESS);
ERROR_OUT:
return (SaveError (lSession, lError));
} // end_SnmpRecvMsg
// Allocates a generic ACL to be used for the security descriptor of the SNMPTRAP service
PACL AllocGenericACL()
{
PACL pAcl;
PSID pSidAdmins, pSidUsers;
SID_IDENTIFIER_AUTHORITY Authority = SECURITY_NT_AUTHORITY;
DWORD dwAclLength;
pSidAdmins = pSidUsers = NULL;
if ( !AllocateAndInitializeSid( &Authority,
2,
SECURITY_BUILTIN_DOMAIN_RID,
DOMAIN_ALIAS_RID_ADMINS,
0, 0, 0, 0, 0, 0,
&pSidAdmins ) ||
!AllocateAndInitializeSid( &Authority,
2,
SECURITY_BUILTIN_DOMAIN_RID,
DOMAIN_ALIAS_RID_USERS,
0, 0, 0, 0, 0, 0,
&pSidUsers ))
{
return NULL;
}
dwAclLength = sizeof(ACL) +
sizeof(ACCESS_ALLOWED_ACE) -
sizeof(ULONG) +
GetLengthSid(pSidAdmins) +
sizeof(ACCESS_ALLOWED_ACE) -
sizeof(ULONG) +
GetLengthSid(pSidUsers);
pAcl = GlobalAlloc (GPTR, dwAclLength);
if (pAcl != NULL)
{
if (!InitializeAcl( pAcl, dwAclLength, ACL_REVISION) ||
!AddAccessAllowedAce ( pAcl,
ACL_REVISION,
GENERIC_ALL,
pSidAdmins ) ||
!AddAccessAllowedAce ( pAcl,
ACL_REVISION,
GENERIC_READ | GENERIC_EXECUTE,
pSidUsers ))
{
GlobalFree(pAcl);
pAcl = NULL;
}
}
FreeSid(pSidAdmins);
FreeSid(pSidUsers);
return pAcl;
}
// frees a generic ACL
void FreeGenericACL( PACL pAcl)
{
if (pAcl != NULL)
GlobalFree(pAcl);
}
// SnmpRegister
SNMPAPI_STATUS SNMPAPI_CALL
SnmpRegister (IN HSNMP_SESSION hSession,
IN HSNMP_ENTITY hSrc,
IN HSNMP_ENTITY hDst,
IN HSNMP_CONTEXT hCtx,
IN smiLPCOID notification,
IN smiUINT32 status)
{
DWORD nNotice, nFound;
smiINT32 nCmp;
SNMPAPI_STATUS lError = SNMPAPI_SUCCESS;
HSNMP_SESSION lSession = 0;
DWORD nSes = HandleToUlong(hSession) - 1;
DWORD nSrc;
DWORD nDst;
DWORD nCtx;
LPENTITY pEntSrc, pEntDst;
LPCTXT pCtxt;
LPTRAPNOTICE pTrap;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -