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

📄 wsnmp_no.c

📁 windows的snmp api源码
💻 C
📖 第 1 页 / 共 3 页
字号:
endPtr = pdu->VBL_addr;
// setup the new head of the list
pdu->VBL_addr = VbTicks;
VbTicks->next_var = VbTrap;
VbTrap->next_var = endPtr;
// position endPtr on the last varbind from the list
if (endPtr != NULL)
{
    // set it on the last varbind from the original V1 trap
    while (endPtr->next_var != NULL)
        endPtr = endPtr->next_var;
}
else
{
    // set it on VbTrap if no varbinds were passed in the V1 trap
    endPtr = VbTrap;
}
// append VbAddress if any and set endPtr on the new ending
if (VbAddress != NULL)
{
    endPtr->next_var = VbAddress;
    endPtr = VbAddress;
}
// append VbEnterprise
endPtr->next_var = VbEnterprise;
VbEnterprise->next_var = NULL;
//
// make it say it's an SNMPv2 Trap PDU
pdu->type = SNMP_PDU_TRAP;
// Assign a RequestID (not in SNMPv1 Trap PDUs (no need to lock)
pdu->appReqId = ++(TaskData.nLastReqId);
return (TRUE);
//
ERROROUT:
// Free only those resources created in this function
// FreeVarBind is a noop on NULLs, so no need to check first
FreeVarBind (VbEnterprise);
FreeVarBind (VbAddress);
FreeVarBind (VbTrap);
FreeVarBind (VbTicks);
return (FALSE);
} // end_MapV1TrapV2

BOOL DispatchTrap (LPSAS host, smiLPOCTETS community, LPPDUS pdu)
{
#define MAXSLOTS 10 // maximum active trap receivers
DWORD nCmp;
DWORD nFound = 0;
DWORD nTrap = 0;
DWORD nTraps[MAXSLOTS];
DWORD nMsg = 0;
LPSNMPMSG pMsg;
LPTRAPNOTICE pTrap;

EnterCriticalSection (&cs_TRAP);
for (nTrap = 0; nTrap < TrapDescr.Allocated; nTrap++)
   {
   pTrap = snmpGetTableEntry(&TrapDescr, nTrap);
   if (!pTrap->Session) continue;  // Active trap registration and
   if (pTrap->notification.len)    // all Traps?
      {                            // Nope, specific test

	  SNMPAPI_STATUS lError;
      // Next line is critical...do not remove...BN 3/8/96
      pTrap->notification.ptr = &(pTrap->notificationValue[0]);
      // 2nd param below assumes well-formed trap/inform...BN 1/21/97
      lError = SnmpOidCompare (&(pTrap->notification),
         &pdu->VBL_addr->next_var->value.value.oid,
         pTrap->notification.len, &nCmp);
      if (lError != SNMPAPI_SUCCESS || nCmp) continue;  // not equal...
      }
   if (pTrap->agentEntity)         // Specific agent?
      {
      int nResult;
      LPENTITY pEntity = snmpGetTableEntry(&EntsDescr, HandleToUlong(pTrap->agentEntity) - 1);
      if (host->ipx.sa_family == AF_IPX)
         nResult = memcmp (&host->ipx.sa_netnum,
                   &(pEntity->addr.ipx.sa_netnum), AF_IPX_ADDR_SIZE);
      else // AF_IPX
         nResult = memcmp (&host->inet.sin_addr,
                   &(pEntity->addr.inet.sin_addr), AF_INET_ADDR_SIZE);
      if (nResult)
         continue;                           // not equal...
      }
   if (pTrap->Context)             // Specific context?
      {
      LPCTXT pCtxt = snmpGetTableEntry(&CntxDescr, HandleToUlong(pTrap->Context) - 1);
      if (community->len != pCtxt->commLen)
         continue;                           // not equal...lengths
      if (memcmp (community->ptr, pCtxt->commStr,
                  (size_t)community->len))
         continue;                           // not equal...values
      }
   nTraps[nFound] = nTrap;                   // Got a match!
   nFound++; // Count the number found and check it against maximums
   if ((nFound == (MAXSLOTS)) || (nFound == TrapDescr.Used))
      break;
   } // end_for
LeaveCriticalSection (&cs_TRAP);
if (nFound == 0)  // Nothing to do
   return (SNMPAPI_FAILURE);
//
nCmp = nFound;    // Save count for later user
EnterCriticalSection (&cs_MSG);
while (nFound)
   {
   DWORD lError;

   lError = snmpAllocTableEntry(&MsgDescr, &nMsg);
   if (lError != SNMPAPI_SUCCESS)
   {
       LeaveCriticalSection(&cs_MSG);
       return lError;
   }
   pMsg = snmpGetTableEntry(&MsgDescr, nMsg);

   --nFound;
   nTrap = nTraps[nFound];
   nTraps[nFound] = nMsg;   // Need for later use
   pTrap = snmpGetTableEntry(&TrapDescr, nTrap);

   pMsg->Session = pTrap->Session;
   pMsg->Status = NP_RCVD;
   pMsg->Type = pdu->type;
   // 960522 - BN...
   // Need to increment the eventual "dstEntity" if
   // one was specified on the SnmpRegister() filter (unusual).
   // Deliberate assignment...
   if (pMsg->ourEntity = pTrap->ourEntity)
      {
      LPENTITY pEntity = snmpGetTableEntry(&EntsDescr, HandleToUlong(pTrap->ourEntity)-1);
      pEntity->refCount++;
      }

   // end_960522 - BN
   pMsg->dllReqId = pMsg->appReqId = pdu->appReqId;
   pMsg->Ticks = pMsg->Tries = 0;
   CopyMemory (&(pMsg->Host), host, sizeof(SAS));
   if (!(BuildMessage (1, community, pdu, pdu->appReqId,
         &(pMsg->Addr), &(pMsg->Size))))
      {
      snmpFreeTableEntry(&MsgDescr, nMsg);
      LeaveCriticalSection (&cs_MSG);
      return (SNMPAPI_PDU_INVALID);
      }
   } // end_while (nFound)
LeaveCriticalSection (&cs_MSG);
//
// The next while loop actually sends the one or more trap messages
// to the application(s)...
// This is due to the fact that we "clone" the incoming trap msg
// if there are multiple registrations for it.  BobN 2/20/95
while (nCmp) // Saved message count
   { // Now actually send the message(s)
   LPSESSION pSession;

   nMsg = nTraps[--nCmp];
   pMsg = snmpGetTableEntry(&MsgDescr, nMsg);
   pSession = snmpGetTableEntry(&SessDescr, HandleToUlong(pMsg->Session) - 1);
   if (pSession->fCallBack)
      { // callback session notification mode
      EnterCriticalSection (&cs_SESSION);
      if (pSession->thrHandle)
         {
         if (pSession->thrCount != 0xFFFFFFFF)
            pSession->thrCount++;
         SetEvent (pSession->thrEvent);
         }
      else
         FreeMsg (nMsg);
      LeaveCriticalSection (&cs_SESSION);
      }
   else
      { // window/message session notification mode
      if (IsWindow(pSession->hWnd))
         {
         pMsg->Status = NP_READY;
         PostMessage (pSession->hWnd,
                      pSession->wMsg, 0, 0L);
         }
      else
         FreeMsg (nMsg);
      }
   } // end_while (nCmp)
return (SNMPAPI_SUCCESS);
} // end_DispatchTrap

LPPDUS MapV2TrapV1 (HSNMP_PDU hPdu)
{
// Convert SNMPv2 trap to SNMPv1 trap, for sending only
HSNMP_VBL hNewVbl = NULL;
LPPDUS oldPdu = NULL;
LPPDUS newPdu = NULL;
smiUINT32 lCount;
smiUINT32 lCmp;
smiUINT32 i;
smiLPBYTE tmpPtr = NULL;
smiOID sName;
smiVALUE sValue;
//
if (hPdu == NULL)
   return (NULL);
oldPdu = snmpGetTableEntry(&PDUsDescr, HandleToUlong(hPdu)-1);
if (oldPdu->type != SNMP_PDU_TRAP)
   return (NULL);
SnmpGetPduData (hPdu, NULL, NULL, NULL, NULL, &hNewVbl);
if (hNewVbl == NULL)
   return (NULL);
newPdu = GlobalAlloc (GPTR, sizeof(PDUS));
if (newPdu == NULL)
   goto ERR_OUT;
// From RFC 2089
// 3.3  Processing an outgoing SNMPv2 TRAP
//
// If SNMPv2 compliant instrumentation presents an SNMPv2 trap to the
// SNMP engine and such a trap passes all regular checking and then is
// to be sent to an SNMPv1 destination, then the following steps must be
// followed to convert such a trap to an SNMPv1 trap.  This is basically
// the reverse of the SNMPv1 to SNMPv2 mapping as described in RFC1908
// [3].
newPdu->type = SNMP_PDU_V1TRAP;
newPdu->v1Trap = GlobalAlloc (GPTR, sizeof(V1TRAP));
if (newPdu->v1Trap == NULL)
   goto ERR_OUT;
//
//   1.  If any of the varBinds in the varBindList has an SNMPv2 syntax
//       of Counter64, then such varBinds are implicitly considered to
//       be not in view, and so they are removed from the varBindList to
//       be sent with the SNMPv1 trap.
//
// We will do that step later, but check the VB count for now:
lCount = SnmpCountVbl (hNewVbl);
// Need at least 2 for sysUptime and snmpTrapOID!
if (lCount < 2)
   goto ERR_OUT;
//
//   2.  The 3 special varBinds in the varBindList of an SNMPv2 trap
//       (sysUpTime.0 (TimeTicks), snmpTrapOID.0 (OBJECT IDENTIFIER) and
//       optionally snmpTrapEnterprise.0 (OBJECT IDENTIFIER)) are
//       removed from the varBindList to be sent with the SNMPv1 trap.
//       These 2 (or 3) varBinds are used to decide how to set other
//       fields in the SNMPv1 trap PDU as follows:
//
//       a.  The value of sysUpTime.0 is copied into the timestamp field
//           of the SNMPv1 trap.
//
SnmpGetVb (hNewVbl, 1, &sName, &sValue);
SnmpOidCompare (&sysUpTimeName, &sName, 0, &lCmp);
SnmpFreeDescriptor (SNMP_SYNTAX_OID, (smiLPOPAQUE)&sName);
   if (lCmp != 0)
      goto ERR_OUT;
newPdu->v1Trap->time_ticks = sValue.value.uNumber;
SnmpDeleteVb (hNewVbl, 1);
lCount--;
//
//       b.  If the snmpTrapOID.0 value is one of the standard traps
//           the specific-trap field is set to zero and the generic
//           trap field is set according to this mapping:
//
//              value of snmpTrapOID.0                generic-trap
//              ===============================       ============
//              1.3.6.1.6.3.1.1.5.1 (coldStart)                  0
//              1.3.6.1.6.3.1.1.5.2 (warmStart)                  1
//              1.3.6.1.6.3.1.1.5.3 (linkDown)                   2
//              1.3.6.1.6.3.1.1.5.4 (linkUp)                     3
//              1.3.6.1.6.3.1.1.5.5 (authenticationFailure)      4
//              1.3.6.1.6.3.1.1.5.6 (egpNeighborLoss)            5
//
SnmpGetVb (hNewVbl, 1, &sName, &sValue);
SnmpOidCompare (&snmpTrapOidName, &sName, 0, &lCmp);
SnmpFreeDescriptor (SNMP_SYNTAX_OID, (smiLPOPAQUE)&sName);
   if (lCmp != 0)
      goto ERR_OUT;
SnmpOidCompare (&snmpTrapsName, &sValue.value.oid, 9, &lCmp);
if (!lCmp)
   {
   newPdu->v1Trap->generic_trap = sValue.value.oid.ptr[9] - 1;
   newPdu->v1Trap->specific_trap = 0;
//           The enterprise field is set to the value of
//           snmpTrapEnterprise.0 if this varBind is present, otherwise
//           it is set to the value snmpTraps as defined in RFC1907 [4].
   i = snmpTrapsName.len - 1;
   tmpPtr = (smiLPBYTE)snmpTrapsValue;
   }
//
//       c.  If the snmpTrapOID.0 value is not one of the standard
//           traps, then the generic-trap field is set to 6 and the
//           specific-trap field is set to the last subid of the
//           snmpTrapOID.0 value.
else
   {
   newPdu->v1Trap->generic_trap = 6;
   i = sValue.value.oid.len;
   newPdu->v1Trap->specific_trap = sValue.value.oid.ptr[i-1];
   tmpPtr = (smiLPBYTE)sValue.value.oid.ptr;
//
//           o   If the next to last subid of snmpTrapOID.0 is zero,
//               then the enterprise field is set to snmpTrapOID.0 value
//               and the last 2 subids are truncated from that value.
   if (sValue.value.oid.ptr[i-2] == 0)
      i -= 2;
//           o   If the next to last subid of snmpTrapOID.0 is not zero,
//               then the enterprise field is set to snmpTrapOID.0 value
//               and the last 1 subid is truncated from that value.
   else
      i -= 1;
//           In any event, the snmpTrapEnterprise.0 varBind (if present)
//           is ignored in this case.
   }
//
newPdu->v1Trap->enterprise.len = i;
i *= sizeof(smiUINT32);
// This allocation might have to be freed later,
// if generic trap and SnmpTrapEnterprise.0 is present in the varbindlist.
newPdu->v1Trap->enterprise.ptr = GlobalAlloc (GPTR, i);
if (newPdu->v1Trap->enterprise.ptr == NULL)
   {
   SnmpFreeDescriptor (SNMP_SYNTAX_OID, (smiLPOPAQUE)&sValue.value.oid);
   goto ERR_OUT;
   }
CopyMemory (newPdu->v1Trap->enterprise.ptr, tmpPtr, i);
SnmpFreeDescriptor (SNMP_SYNTAX_OID, (smiLPOPAQUE)&sValue.value.oid);
SnmpDeleteVb (hNewVbl, 1);
lCount--;
//
i = 1;
while (i <= lCount)
   {
   SnmpGetVb (hNewVbl, i, &sName, &sValue);
   if (sValue.syntax == SNMP_SYNTAX_CNTR64)
      {
      SnmpDeleteVb (hNewVbl, i);
      lCount--;
      goto LOOP;
      }
   SnmpOidCompare (&snmpTrapEntName, &sName, 0, &lCmp);
   if (lCmp == 0)
      {
      if (newPdu->v1Trap->specific_trap == 0)
         {
         if  (newPdu->v1Trap->enterprise.ptr)
            GlobalFree (newPdu->v1Trap->enterprise.ptr);
         lCmp = sValue.value.oid.len * sizeof(smiUINT32);
         newPdu->v1Trap->enterprise.ptr = GlobalAlloc (GPTR, lCmp);
         if (newPdu->v1Trap->enterprise.ptr == NULL)
            goto ERR_OUT;
         newPdu->v1Trap->enterprise.len = sValue.value.oid.len;
         CopyMemory (newPdu->v1Trap->enterprise.ptr,
                     sValue.value.oid.ptr, lCmp);
         }
      SnmpDeleteVb (hNewVbl, i);
      lCount--;
      goto LOOP;
      }
   i++;
LOOP:
   SnmpFreeDescriptor (SNMP_SYNTAX_OID, (smiLPOPAQUE)&sName);
   SnmpFreeDescriptor (sValue.syntax, (smiLPOPAQUE)&sValue.value.oid);
   }
if (lCount > 0)
   {
   LPVBLS pVbl = snmpGetTableEntry(&VBLsDescr, HandleToUlong(hNewVbl)-1);
   // Retain existing varbindlist remainder
   newPdu->VBL_addr = pVbl->vbList;
   // Flag it as gone for subsequent call to SnmpFreeVbl
   pVbl->vbList = NULL;
   }
SnmpFreeVbl (hNewVbl);
//
//   3.  The agent-addr field is set with the appropriate address of the
//       the sending SNMP entity, which is the IP address of the sending
//       entity of the trap goes out over UDP; otherwise the agent-addr
//       field is set to address 0.0.0.0.
newPdu->v1Trap->agent_addr.len = sizeof(DWORD);
newPdu->v1Trap->agent_addr.ptr = GlobalAlloc (GPTR, sizeof(DWORD));
if (newPdu->v1Trap->agent_addr.ptr == NULL)
   goto ERR_OUT;
if (TaskData.localAddress == 0)
   { // Get the local machine address (for outgoing v1 traps)
   char szLclHost [MAX_HOSTNAME];
   LPHOSTENT lpstHostent;
   if (gethostname (szLclHost, MAX_HOSTNAME) != SOCKET_ERROR)
      {
      lpstHostent = gethostbyname ((LPSTR)szLclHost);
      if (lpstHostent)
         TaskData.localAddress = *((LPDWORD)(lpstHostent->h_addr));
      }
   }
*(LPDWORD)newPdu->v1Trap->agent_addr.ptr = TaskData.localAddress;
// end_RFC2089
return (newPdu);
//
ERR_OUT:
SnmpFreeVbl (hNewVbl);
if (newPdu)
   {
   FreeVarBindList (newPdu->VBL_addr); // Checks for NULL
   FreeV1Trap (newPdu->v1Trap);        // Checks for NULL
   GlobalFree (newPdu);
   }
return (NULL);
} // end_MapV2TrapV1

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -