⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 mgmtapi.c

📁 windows的snmp api源码
💻 C
📖 第 1 页 / 共 5 页
字号:
            // 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 + -