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

📄 wsnmp_cf.c

📁 windows的snmp api源码
💻 C
📖 第 1 页 / 共 3 页
字号:
   }

// 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 + -