📄 wsnmp_cf.c
字号:
if (TaskData.hTask == 0)
{
lError = SNMPAPI_NOT_INITIALIZED;
goto ERROR_OUT;
}
if (status != SNMPAPI_OFF) status = SNMPAPI_ON;
if (status == SNMPAPI_ON)
{
if (!snmpValidTableEntry(&SessDescr, nSes))
{
lError = SNMPAPI_SESSION_INVALID;
goto ERROR_OUT;
}
else // Got a valid session...save for possible error return
lSession = hSession;
}
if (hSrc)
{
nSrc = HandleToUlong(hSrc) - 1;
if (!snmpValidTableEntry(&EntsDescr, nSrc))
{
lError = SNMPAPI_ENTITY_INVALID;
goto ERROR_OUT;
}
pEntSrc = snmpGetTableEntry(&EntsDescr, nSrc);
}
if (hDst)
{
nDst = HandleToUlong(hDst) - 1;
if (!snmpValidTableEntry(&EntsDescr, nDst))
{
lError = SNMPAPI_ENTITY_INVALID;
goto ERROR_OUT;
}
pEntDst = snmpGetTableEntry(&EntsDescr, nDst);
}
if (hCtx)
{
nCtx = HandleToUlong(hCtx) - 1;
if (!snmpValidTableEntry(&CntxDescr, nCtx))
{
lError = SNMPAPI_CONTEXT_INVALID;
goto ERROR_OUT;
}
pCtxt = snmpGetTableEntry(&CntxDescr, nCtx);
}
if (notification)
{
if ((!notification->len) || notification->len > MAXOBJIDSIZE)
{
lError = SNMPAPI_SIZE_INVALID;
goto ERROR_OUT;
}
if (!notification->ptr)
{
lError = SNMPAPI_OID_INVALID;
goto ERROR_OUT;
}
}
EnterCriticalSection (&cs_TRAP);
for (nNotice = 0, nFound = 0; nNotice < TrapDescr.Allocated,
nFound < TrapDescr.Used; nNotice++)
{ // First, count now many we've tested
pTrap = snmpGetTableEntry(&TrapDescr, nNotice);
if (pTrap->Session) nFound++;
// then search for a parameter matches
if ((pTrap->Session == hSession) &&
(pTrap->ourEntity == hSrc) &&
(pTrap->agentEntity == hDst) &&
(pTrap->Context == hCtx))
{ // Ok, we found one
if (!notification)
// if the notification parameter is null, then we
// want to either turn on or turn off all notifications
// from this match...so clear any entries already in
// the table and we'll add this wildcard entry if the
// operation is SNMPAPI_ON at the end.
{
FreeRegister (nNotice);
continue;
}
else // notification specified
{
if (!pTrap->notification.len)
{
// Redundant request (already wildcarded)
// Skip it and return!
goto ERROR_PRECHECK;
}
else // pTrap->notification
{
// compare OIDs
SnmpOidCompare (notification, &(pTrap->notification),
0, &nCmp);
if (nCmp) // no match
continue; // ...try the next one
else // !nCcmp
{ // got a match...
// if SNMPAPI_ON, redundant request...skip it and return
// if SNMPAPI_OFF, free the entry first
if (status != SNMPAPI_ON)
FreeRegister (nNotice); // SNMPAPI_OFF
goto ERROR_PRECHECK;
} // end_else_!nCmp
} // end_else_TrapTable[nNotice].notificatin
} // end_else_notification_specified
} // end_if_we_found_one
} // end_for
if (status == SNMPAPI_OFF)
{ // Found nothing to turn off...that's ok.
goto ERROR_PRECHECK;
}
//
#ifndef SOLARIS
// Special check for NT...is SNMPTRAP service running?
if (TaskData.trapThread == NULL &&
TaskData.sEnv.dwPlatformId == VER_PLATFORM_WIN32_NT)
{
DWORD dwReturn = SNMPAPI_TL_NOT_INITIALIZED;
DWORD pMode = PIPE_WAIT | PIPE_READMODE_MESSAGE;
LPCTSTR svcName = "SNMPTRAP";
LPCTSTR svcDesc = "SNMP Trap Service";
LPCTSTR svcPath = "%SystemRoot%\\system32\\snmptrap.exe";
SC_HANDLE scmHandle = NULL;
SC_HANDLE svcHandle = NULL;
SERVICE_STATUS svcStatus;
BOOL fStatus;
// Minimal SCM connection, for case when SNMPTRAP is running
scmHandle = OpenSCManager (NULL, NULL, SC_MANAGER_CONNECT);
if (scmHandle == NULL)
goto DONE_SC;
svcHandle = OpenService (scmHandle, svcName, SERVICE_QUERY_STATUS);
if (svcHandle == NULL)
{
if (GetLastError() != ERROR_SERVICE_DOES_NOT_EXIST)
goto DONE_SC;
else
{ // Must attempt to create service
PACL pAcl;
SECURITY_DESCRIPTOR S_Desc;
// Need new scmHandle with admin priv
CloseServiceHandle (scmHandle);
scmHandle = OpenSCManager (NULL, NULL, SC_MANAGER_CREATE_SERVICE);
if (scmHandle == NULL)
goto DONE_SC; // Could not open SCM with admin priv
svcHandle = CreateService (scmHandle, svcName, svcDesc,
WRITE_DAC|SERVICE_QUERY_STATUS,
SERVICE_WIN32_OWN_PROCESS,
SERVICE_DEMAND_START,
SERVICE_ERROR_NORMAL,
svcPath,
NULL, NULL,
"TCPIP\0EventLog\0\0",
NULL, NULL);
if (svcHandle == NULL)
goto DONE_SC; // Could not create service
InitializeSecurityDescriptor (&S_Desc, SECURITY_DESCRIPTOR_REVISION);
if ((pAcl = AllocGenericACL()) == NULL ||
!SetSecurityDescriptorDacl (&S_Desc, TRUE, pAcl, FALSE))
{
FreeGenericACL(pAcl);
goto DONE_SC;
}
SetServiceObjectSecurity (svcHandle, DACL_SECURITY_INFORMATION, &S_Desc);
FreeGenericACL(pAcl);
}
}
fStatus = QueryServiceStatus (svcHandle, &svcStatus);
while (fStatus)
{
switch (svcStatus.dwCurrentState)
{
case SERVICE_RUNNING:
dwReturn = SNMPAPI_SUCCESS;
goto DONE_SC;
case SERVICE_STOPPED:
// Start SNMPTRAP service if necessary
CloseServiceHandle (svcHandle);
svcHandle = OpenService (scmHandle, svcName, SERVICE_START|SERVICE_QUERY_STATUS);
if (svcHandle == NULL)
goto DONE_SC; // Could not start service
svcStatus.dwCurrentState = SERVICE_START_PENDING;
fStatus = StartService (svcHandle, 0, NULL);
break;
case SERVICE_STOP_PENDING:
case SERVICE_START_PENDING:
Sleep (MAX_PENDING_WAIT);
fStatus = QueryServiceStatus (svcHandle, &svcStatus);
break;
case SERVICE_PAUSED:
case SERVICE_PAUSE_PENDING:
case SERVICE_CONTINUE_PENDING:
default:
fStatus = FALSE; // Nothing to do about these
break;
}
}
DONE_SC:
if (scmHandle)
CloseServiceHandle (scmHandle);
if (svcHandle)
CloseServiceHandle (svcHandle);
if (dwReturn != SNMPAPI_SUCCESS)
{
ERROR_PRECHECK1:
lError = dwReturn;
goto ERROR_PRECHECK;
}
// Setup for pipe-oriented operations
dwReturn = SNMPAPI_TL_RESOURCE_ERROR;
// block on instance of server pipe becoming available
if (!WaitNamedPipe (SNMPTRAPPIPE, TRAPSERVERTIMEOUT))
goto ERROR_PRECHECK1;
TaskData.trapPipe =
CreateFile (SNMPTRAPPIPE, GENERIC_READ|GENERIC_WRITE,
FILE_SHARE_READ|FILE_SHARE_WRITE, NULL,
OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL);
if (TaskData.trapPipe == INVALID_HANDLE_VALUE)
goto ERROR_PRECHECK1;
if (!SetNamedPipeHandleState (TaskData.trapPipe, &pMode, NULL, NULL))
{
CloseHandle (TaskData.trapPipe);
TaskData.trapPipe = INVALID_HANDLE_VALUE;
goto ERROR_PRECHECK1;
}
} // end_NT check for SNMPTRAP service
#endif // !SOLARIS
//If we got this far, add it
lError = snmpAllocTableEntry(&TrapDescr, &nNotice);
if (lError != SNMPAPI_SUCCESS)
goto ERROR_PRECHECK;
pTrap = snmpGetTableEntry(&TrapDescr, nNotice);
// add it
pTrap->Session = hSession;
// Deliberate assignments in next three if statements
if (pTrap->ourEntity = hSrc)
//EntityTable[nSrc-1].refCount++; -- was this a bug??? nSrc is already 0 based
pEntSrc->refCount++;
if (pTrap->agentEntity = hDst)
//EntityTable[nDst-1].refCount++; -- was this a bug??? nDst is already 0 based
pEntDst->refCount++;
if (pTrap->Context = hCtx)
//ContextTable[nCtx-1].refCount++; -- was this a bug?? nCtx is already 0 based
pCtxt->refCount++;
if (notification)
{ // Reproduce the OID
pTrap->notification.ptr = NULL;
// Deliberate assignment in next statement
if (pTrap->notification.len = notification->len)
{
if (pTrap->notification.len > MAXTRAPIDS)
pTrap->notification.len = MAXTRAPIDS;
if (notification->ptr)
{
// Deliberate assignment in next statement
pTrap->notification.ptr = &(pTrap->notificationValue[0]);
CopyMemory (pTrap->notification.ptr, notification->ptr,
pTrap->notification.len * sizeof(smiUINT32));
}
}
}
if (TaskData.trapThread == NULL)
{
// Leave # lines at margin (for Solaris cc compiler)
#ifdef SOLARIS
thr_create (NULL, 0, thrTrap, NULL, THR_FLAGS, &TaskData.trapThread);
#else // Win32
DWORD thrId;
TaskData.trapThread = (HANDLE)_beginthreadex (NULL, 0, thrTrap, NULL, 0, &thrId);
#endif
}
ERROR_PRECHECK:
LeaveCriticalSection (&cs_TRAP);
if (lError == SNMPAPI_SUCCESS)
return (SNMPAPI_SUCCESS);
ERROR_OUT:
return (SaveError (lSession, lError));
} // end_SnmpRegister
void FreeMsg (DWORD nMsg)
{
LPSNMPMSG pMsg;
EnterCriticalSection (&cs_MSG);
// Decrement reference counts
pMsg = snmpGetTableEntry(&MsgDescr, nMsg);
SnmpFreeEntity (pMsg->agentEntity);
SnmpFreeEntity (pMsg->ourEntity);
SnmpFreeContext (pMsg->Context);
if (pMsg->Addr)
GlobalFree (pMsg->Addr);
snmpFreeTableEntry(&MsgDescr, nMsg);
LeaveCriticalSection (&cs_MSG);
return;
} // end_FreeMsg
SNMPAPI_STATUS SNMPAPI_CALL
SnmpListen (IN HSNMP_ENTITY hEntity,
IN smiUINT32 status)
{
smiUINT32 nAgent = 0;
DWORD thrId;
DWORD nEntity = HandleToUlong(hEntity) - 1;
SNMPAPI_STATUS lError = SNMPAPI_SUCCESS;
HSNMP_SESSION lSession = 0;
LPENTITY pEntity;
LPAGENT pAgent;
if (TaskData.hTask == 0)
{
lError = SNMPAPI_NOT_INITIALIZED;
goto ERROR_OUT;
}
if (!snmpValidTableEntry(&EntsDescr, nEntity))
{
lError = SNMPAPI_ENTITY_INVALID;
goto ERROR_OUT;
}
pEntity = snmpGetTableEntry(&EntsDescr, nEntity);
lSession = pEntity->Session;
if (status != SNMPAPI_ON && status != SNMPAPI_OFF)
{
lError = SNMPAPI_MODE_INVALID;
goto ERROR_OUT;
}
EnterCriticalSection (&cs_ENTITY);
EnterCriticalSection (&cs_AGENT);
if (status)
{ // status == SNMPAPI_ON
int nProto = IPPROTO_UDP;
int nSize = sizeof(SOCKADDR_IN);
int nFamily = pEntity->addr.inet.sin_family;
if (pEntity->Agent)
{ // Entity already running as agent
lError = SNMPAPI_NOOP;
goto ERROR_PRECHECK;
}
// Allocate a slot in AGENT table
lError = snmpAllocTableEntry(&AgentDescr, &nAgent);
if (lError != SNMPAPI_SUCCESS)
goto ERROR_PRECHECK;
pAgent = snmpGetTableEntry(&AgentDescr, nAgent);
// Agent table entry allocated...setup for agent thread
if (nFamily == AF_IPX)
{
nProto = NSPROTO_IPX;
nSize = sizeof(SOCKADDR_IPX);
}
pAgent->Socket = socket (nFamily, SOCK_DGRAM, nProto);
if (pAgent->Socket == INVALID_SOCKET)
{
snmpFreeTableEntry(&AgentDescr, nAgent);
lError = SNMPAPI_TL_RESOURCE_ERROR;
goto ERROR_PRECHECK;
}
if (bind (pAgent->Socket,
(LPSOCKADDR)&pEntity->addr, nSize)
== SOCKET_ERROR)
{
snmpFreeTableEntry(&AgentDescr, nAgent);
closesocket (pAgent->Socket);
lError = SNMPAPI_TL_OTHER;
goto ERROR_PRECHECK;
}
// Make Entity and Agent point to each other
pEntity->Agent = nAgent + 1;
pAgent->Entity = hEntity;
pAgent->Session = lSession;
// Create agent thread...needs error checking
#ifdef SOLARIS // Leave at left margin for Solaris compiler
thr_create (NULL, 0, thrAgent, (LPVOID)nAgent, THR_FLAGS, &(pAgent->Thread));
#else // Win32
pAgent->Thread = (HANDLE)_beginthreadex (NULL, 0, thrAgent, (LPVOID)nAgent, 0, &thrId);
#endif // SOLARIS
} // end_if status == SNMPAPI_ON
else
{ // status == SNMPAPI_OFF
if (!pEntity->Agent)
{ // Entity not running as agent
lError = SNMPAPI_NOOP;
goto ERROR_PRECHECK;
}
// Entity is running as agent
nAgent = pEntity->Agent - 1;
pAgent = snmpGetTableEntry(&AgentDescr, nAgent);
closesocket (pAgent->Socket);
WaitForSingleObject (pAgent->Thread, INFINITE);
CloseHandle (pAgent->Thread);
snmpFreeTableEntry(&AgentDescr, nAgent);
// Must terminate entity's agent status
pEntity->Agent = 0;
// Must terminate entity if nothing else was using it
if (pEntity->refCount == 0)
SnmpFreeEntity (hEntity);
} // end_else status == SNMPAPI_OFF
ERROR_PRECHECK:
LeaveCriticalSection (&cs_AGENT);
LeaveCriticalSection (&cs_ENTITY);
ERROR_OUT:
if (lError == SNMPAPI_SUCCESS)
return (SNMPAPI_SUCCESS);
else
return (SaveError (lSession, lError));
} // end_SnmpListen()
SNMPAPI_STATUS SNMPAPI_CALL
SnmpCancelMsg (HSNMP_SESSION hSession, smiINT32 nReqID)
{
DWORD nMsg = 0;
DWORD nFound = 0;
SNMPAPI_STATUS lError = SNMPAPI_SUCCESS;
HSNMP_SESSION lSession = 0;
LPSNMPMSG pMsg;
if (TaskData.hTask == 0)
{
lError = SNMPAPI_NOT_INITIALIZED;
goto ERROR_OUT;
}
if (!snmpValidTableEntry(&SessDescr, HandleToUlong(hSession)-1))
{
lError = SNMPAPI_SESSION_INVALID;
goto ERROR_OUT;
}
lSession = hSession;
EnterCriticalSection (&cs_MSG);
while (nFound < MsgDescr.Used && nMsg < MsgDescr.Allocated)
{
pMsg = snmpGetTableEntry(&MsgDescr, nMsg);
// Deliberate assignement in next conditional
if (pMsg->Session)
{
nFound++;
if (pMsg->Session == hSession)
{
if (pMsg->Status == NP_SENT &&
pMsg->appReqId == (smiUINT32)nReqID)
{
FreeMsg (nMsg);
goto ERROR_PRECHECK;
}
}
}
nMsg++;
}
// Falied to find a MSG that matched the request
lError = SNMPAPI_PDU_INVALID;
ERROR_PRECHECK:
LeaveCriticalSection (&cs_MSG);
if (lError == SNMPAPI_SUCCESS)
return (SNMPAPI_SUCCESS);
// else...failure case
ERROR_OUT:
return (SaveError (lSession, lError));
} // end_SnmpCancelMsg
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -