📄 mgmtapi.c
字号:
// point to snmpAddress varbind structure (maybe)
pVarBind = &pTLE->VarBindList.list[pTLE->VarBindList.len - 2];
// verify variable is snmpAddress
if ((pVarBind->value.asnType == SNMP_SYNTAX_IPADDR) &&
!SnmpUtilOidNCmp(&pVarBind->name,
&snmpAddress,
snmpAddress.idLength)) {
// transfer agent address oid to list entry
pTLE->AgentAddress = pVarBind->value.asnValue.address;
// store agent address for later
pAgentAddress = &pTLE->AgentAddress;
// modify type to avoid deallocation
pVarBind->value.asnType = ASN_NULL;
} else {
SNMPDBG((
SNMP_LOG_TRACE,
"MGMTAPI: Could not find snmpAddress.\n"
));
}
}
// point to snmpTrapOID varbind structure
pVarBind = &pTLE->VarBindList.list[SNMPTRAPOIDINDEX];
// verify variable is snmpTrapOID
if ((pVarBind->value.asnType == ASN_OBJECTIDENTIFIER) &&
!SnmpUtilOidNCmp(&pVarBind->name,
&snmpTrapOID,
snmpTrapOID.idLength)) {
// retrieve pointer to oid
pOID = &pVarBind->value.asnValue.object;
// check for generic trap
if (!SnmpUtilOidNCmp(pOID,
&snmpTraps,
snmpTraps.idLength)) {
// validate size is one greater than root
if (pOID->idLength == (snmpTraps.idLength + 1)) {
// retrieve trap id
// --ft:10/01/98 (bug #231344): WINSNMP gives up the V2 syntax => pOID->ids[snmpTraps.idLength] = [1..6]
// --ft:10/01/98 (bug #231344): as MGMTAPI turns back to V1, we need to decrement this value.
pTLE->nGenericTrap = (pOID->ids[snmpTraps.idLength])-1;
// re-initialize
pTLE->nSpecificTrap = 0;
} else {
SNMPDBG((
SNMP_LOG_ERROR,
"MGMTAPI: Invalid snmpTrapOID.\n"
));
goto cleanup; // bail...
}
// check for specific trap
} else if ((pEnterpriseOID != NULL) &&
!SnmpUtilOidNCmp(pOID,
pEnterpriseOID,
pEnterpriseOID->idLength)) {
// validate size is two greater than root
if (pOID->idLength == (pEnterpriseOID->idLength + 2)) {
// validate separator sub-identifier
WSNMP_ASSERT(pOID->ids[pEnterpriseOID->idLength] == 0);
// retrieve trap id
pTLE->nSpecificTrap = pOID->ids[pEnterpriseOID->idLength + 1];
// re-initialize
pTLE->nGenericTrap = SNMP_GENERICTRAP_ENTERSPECIFIC;
} else {
SNMPDBG((
SNMP_LOG_ERROR,
"MGMTAPI: Invalid snmpTrapOID.\n"
));
goto cleanup; // bail...
}
} else {
SNMPDBG((
SNMP_LOG_ERROR,
"MGMTAPI: Could not identify snmpTrapOID.\n"
));
goto cleanup; // bail...
}
} else {
SNMPDBG((
SNMP_LOG_ERROR,
"MGMTAPI: Could not find snmpTrapOID.\n"
));
goto cleanup; // bail...
}
// check for enterprise oid
if (pEnterpriseOID != NULL) {
// release snmpTrapEnterprise varbind structure
SnmpUtilVarBindFree(&pTLE->VarBindList.list[pTLE->VarBindList.len - 1]);
// decrement the list length as the last varbind was freed
pTLE->VarBindList.len--;
}
// check for agent address
if (pAgentAddress != NULL) {
// release snmpAgentAddress varbind structure
SnmpUtilVarBindFree(&pTLE->VarBindList.list[pTLE->VarBindList.len - 1]);
// decrement the list length as the last varbind was again freed
pTLE->VarBindList.len--;
}
// release sysUpTime varbind structure
SnmpUtilVarBindFree(&pTLE->VarBindList.list[SYSUPTIMEINDEX]);
// release snmpTrapOID varbind structure
SnmpUtilVarBindFree(&pTLE->VarBindList.list[SNMPTRAPOIDINDEX]);
// subtract released varbinds
pTLE->VarBindList.len -= MINVARBINDLEN;
// check if all varbinds freed
if (pTLE->VarBindList.len == 0) {
// release memory for list
SnmpUtilMemFree(pTLE->VarBindList.list);
// re-initialize
pTLE->VarBindList.list = NULL;
} else {
// shift varbind list up two spaces
memmove((LPBYTE)(pTLE->VarBindList.list),
(LPBYTE)(pTLE->VarBindList.list + MINVARBINDLEN),
(pTLE->VarBindList.len * sizeof(SnmpVarBind))
);
}
} else {
SNMPDBG((
SNMP_LOG_ERROR,
"MGMTAPI: Too few subidentifiers.\n"
));
}
// success
return TRUE;
cleanup:
// failure
return FALSE;
}
BOOL
FreeTle(
PTRAP_LIST_ENTRY pTLE
)
/*++
Routine Description:
Release memory used for trap entry.
Arguments:
pTLE - pointer to trap list entry.
Return Values:
Returns true if successful.
--*/
{
// validate pointer
WSNMP_ASSERT(pTLE != NULL);
// release memory for enterprise oid
SnmpUtilOidFree(&pTLE->EnterpriseOID);
// release memory for community string
SnmpUtilMemFree(pTLE->Community.stream);
// release memory used in varbind list
SnmpUtilVarBindListFree(&pTLE->VarBindList);
// release list entry
SnmpUtilMemFree(pTLE);
return TRUE;
}
BOOL
AllocateTle(
PSNMP_MGR_SESSION pSMS,
PTRAP_LIST_ENTRY * ppTLE,
HSNMP_ENTITY hAgentEntity,
HSNMP_CONTEXT hViewContext
)
/*++
Routine Description:
Allocate memory for trap entry.
Arguments:
pSMS - pointer to MGMTAPI session structure.
ppTLE - pointer to pointer to trap list entry.
hAgentEntity - handle to agent sending trap.
hViewContext - handle to view context of trap.
Return Values:
Returns true if successful.
--*/
{
BOOL fOk = FALSE;
PTRAP_LIST_ENTRY pTLE;
SNMPAPI_STATUS status;
smiOCTETS CommunityStr;
CHAR SourceStrAddr[MAXENTITYSTRLEN+1];
struct sockaddr SourceSockAddr;
// validate pointers
WSNMP_ASSERT(pSMS != NULL);
WSNMP_ASSERT(ppTLE != NULL);
// allocate memory from list entry
pTLE = SnmpUtilMemAlloc(sizeof(TRAP_LIST_ENTRY));
// validate pointer
if (pTLE == NULL) {
SNMPDBG((
SNMP_LOG_ERROR,
"MGMTAPI: Could not allocate trap entry.\n"
));
return FALSE; // bail...
}
// initialize
*ppTLE = NULL;
// copy varbinds to trap list entry
if (!CopyVbl(pSMS, &pTLE->VarBindList)) {
goto cleanup; // bail...
}
// parse trap-related varbinds
if (!ParseVbl(pSMS, pTLE)) {
goto cleanup; // bail...
}
// check if source address is specified
if (hAgentEntity != (HSNMP_ENTITY)NULL) {
// convert addr to string
status = SnmpEntityToStr(
hAgentEntity,
sizeof(SourceStrAddr),
SourceStrAddr
);
// validate error code
if (WSNMP_SUCCEEDED(status)) {
DWORD AddrLen = 0;
LPBYTE AddrPtr = NULL;
// convert string to socket address structure
SnmpSvcAddrToSocket(SourceStrAddr, &SourceSockAddr);
// validate address family
if (SourceSockAddr.sa_family == AF_INET) {
// assign ip values
AddrLen = IPADDRLEN;
AddrPtr = (LPBYTE)&(((struct sockaddr_in *)
(&SourceSockAddr))->sin_addr);
} else if (SourceSockAddr.sa_family == AF_IPX) {
// assign ipx values
AddrLen = IPXADDRLEN;
AddrPtr = (LPBYTE)&(((struct sockaddr_ipx *)
(&SourceSockAddr))->sa_netnum);
} else {
SNMPDBG((
SNMP_LOG_ERROR,
"MGMTAPI: Ignoring invalid address.\n"
));
goto cleanup; // bail...
}
// allocate address to return (if specified)
pTLE->SourceAddress.stream = SnmpUtilMemAlloc(AddrLen);
// validate pointer
if (pTLE->SourceAddress.stream != NULL) {
// initialize length values
pTLE->SourceAddress.length = AddrLen;
pTLE->SourceAddress.dynamic = TRUE;
// transfer agent address information
memcpy(pTLE->SourceAddress.stream, AddrPtr, AddrLen);
}
} else {
SNMPDBG((
SNMP_LOG_ERROR,
"MGMTAPI: SnmpEntityToStr returned %d.\n",
SnmpGetLastError((HSNMP_SESSION)NULL)
));
goto cleanup; // bail...
}
}
// check if community specified
if (hViewContext != (HSNMP_CONTEXT)NULL) {
// convert agent entity to string
status = SnmpContextToStr(hViewContext, &CommunityStr);
// validate error code
if (WSNMP_SUCCEEDED(status)) {
// copy octet string
CopyOctets(&pTLE->Community, &CommunityStr);
// release memory for string
SnmpFreeDescriptor(SNMP_SYNTAX_OCTETS, &CommunityStr);
// ignore terminating character
if ((pTLE->Community.length != 0) &&
(pTLE->Community.stream != NULL) &&
(pTLE->Community.stream[pTLE->Community.length] == 0)) {
// decrement count
pTLE->Community.length--;
}
} else {
SNMPDBG((
SNMP_LOG_ERROR,
"MGMTAPI: SnmpContextToStr returned %d.\n",
SnmpGetLastError((HSNMP_SESSION)NULL)
));
goto cleanup; // bail...
}
}
// transfer
*ppTLE = pTLE;
// success
return TRUE;
cleanup:
// release
FreeTle(pTLE);
// failure
return FALSE;
}
BOOL
NotificationCallback(
PSNMP_MGR_SESSION pSMS
)
/*++
Routine Description:
Callback for processing notification messages.
Arguments:
pSMS - pointer to mgmtapi session structure.
Return Values:
Returns true if processing finished.
--*/
{
BOOL fDone = TRUE;
SNMPAPI_STATUS status;
HSNMP_ENTITY hAgentEntity = (HSNMP_ENTITY)NULL;
HSNMP_ENTITY hManagerEntity = (HSNMP_ENTITY)NULL;
HSNMP_CONTEXT hViewContext = (HSNMP_CONTEXT)NULL;
smiINT32 nPduType;
smiINT32 nRequestId;
// validate pointer
WSNMP_ASSERT(pSMS != NULL);
// retrieve message
status = SnmpRecvMsg(
pSMS->hSnmpSession,
&hAgentEntity,
&hManagerEntity,
&hViewContext,
&pSMS->hPdu
);
// validate return code
if (WSNMP_SUCCEEDED(status)) {
// retrieve pdu data
status = SnmpGetPduData(
pSMS->hPdu,
&nPduType,
&nRequestId,
&pSMS->nErrorStatus,
&pSMS->nErrorIndex,
&pSMS->hVbl
);
// validate return code
if (WSNMP_SUCCEEDED(status)) {
// process reponse to request
if (nPduType == SNMP_PDU_RESPONSE) {
// validate context information
if ((pSMS->nRequestId == nRequestId) &&
(pSMS->hViewContext == hViewContext) &&
(pSMS->hAgentEntity == hAgentEntity) &&
(pSMS->hManagerEntity == hManagerEntity)) {
// validate returned error status
if (pSMS->nErrorStatus == SNMP_ERROR_NOERROR) {
SnmpVarBindList VarBindList;
// copy variable binding list
if (CopyVbl(pSMS, &VarBindList)) {
// release existing varbind list
SnmpUtilVarBindListFree(pSMS->pVarBindList);
// manually copy new varbind list
*pSMS->pVarBindList = VarBindList;
} else {
// modify last error status
pSMS->nLastError = SNMPAPI_ALLOC_ERROR;
}
}
} else {
SNMPDBG((
SNMP_LOG_TRACE,
"MGMTAPI: Ignoring invalid context.\n"
));
// continue
fDone = FALSE;
}
} else if (nPduType == SNMP_PDU_TRAP) {
PTRAP_LIST_ENTRY pTLE;
// allocate trap list entry (transfers varbinds etc.)
if (AllocateTle(pSMS, &pTLE, hAgentEntity, hViewContext)) {
// obtain exclusive access
EnterCriticalSection(&g_GlobalLock);
// insert new trap into the incoming queue
InsertTailList(&g_IncomingTraps, &pTLE->Link);
// alert user
SetEvent(g_hTrapEvent);
// release exclusive access
LeaveCriticalSection(&g_GlobalLock);
}
} else {
SNMPDBG((
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -