📄 wsnmp_no.c
字号:
bFree = FALSE; // Retain the message slot
}
else
{
LPSESSION pSession;
pSession = snmpGetTableEntry(&SessDescr, HandleToUlong(pMsg->Session) - 1);
if (pSession->fCallBack)
{ // callback session notification mode
EnterCriticalSection (&cs_SESSION);
if (pSession->thrHandle)
{
bFree = FALSE; // thrNotify will free it
pMsg->Status = NP_EXPIRED;
if (pSession->thrCount != 0xFFFFFFFF)
pSession->thrCount++;
SetEvent (pSession->thrEvent);
}
LeaveCriticalSection (&cs_SESSION);
}
else
{ // windows/message session notification mode
if (IsWindow(pSession->hWnd))
{
PostMessage (pSession->hWnd,
pSession->wMsg,
SNMPAPI_TL_TIMEOUT,
pMsg->appReqId);
}
}
} // end_else (no retry left)
} // end_if (retransmitMode)
if (bFree) FreeMsg (nMsg);
} // end_for
LeaveCriticalSection (&cs_MSG);
} // end_while
DONE:
return (0);
} // end_thrTimer
#ifndef SOLARIS
// Client side trap processing for Win32
THR_TYPE WINAPI thrTrap (LPVOID lpTask)
{
#define TRAPBUFSIZE 4096
typedef struct
{
SOCKADDR Addr;
int AddrLen;
UINT TrapBufSz;
char TrapBuf[TRAPBUFSIZE];
} SNMP_TRAP, *PSNMP_TRAP;
SNMP_TRAP recvTrap;
DWORD iBytes;
smiLPBYTE rMsgPtr;
//
// Approach differs for NT (SNMPTRAP) vs '95
//
if (TaskData.sEnv.dwPlatformId == VER_PLATFORM_WIN32_NT)
{
// IMPORTANT NOTE FOR NT:
// This code must be consistent with the SNMPTRAP code
// wrt TRAPBUFSIZE, SNMPTRAPPIPE, and the SNMP_TRAP struct
while (TRUE)
{
if (ReadFile (
TaskData.trapPipe,
(LPBYTE)&recvTrap,
sizeof(SNMP_TRAP) - sizeof(recvTrap.TrapBuf),
&iBytes,
NULL) ||
GetLastError() != ERROR_MORE_DATA)
break;
// Find the message buffer address...
rMsgPtr = GlobalAlloc (GPTR, 2*recvTrap.TrapBufSz);
if (rMsgPtr == NULL ||
!ReadFile(
TaskData.trapPipe,
(LPBYTE)rMsgPtr,
2*recvTrap.TrapBufSz,
&iBytes,
NULL)) // No space error or wrong data on pipe...drop the message...
{
GetLastError();
continue;
}
// get the datagram and the address of the host that sent it
MsgNotify (NP_TRAP, rMsgPtr, iBytes, 0, (LPSAS)&recvTrap.Addr);
} // end while()
goto DONE;
} // end_NT_thrTrap
//
// Handle Win95 traps
//
else if (TaskData.sEnv.dwPlatformId == VER_PLATFORM_WIN32_WINDOWS)
{
#define BASE_PORT 26025
#define MAX_PORTS 10
SOCKADDR_IN trapAddr;
int trapPort;
int nSock;
fd_set readFDS;
int i, j;
DWORD iHeader = sizeof(SOCKADDR) + sizeof(int);
TaskData.trapWnd = FindWindow (NP_WSX95, NP_WSX95);
if (TaskData.trapWnd == NULL)
{
STARTUPINFO su;
PROCESS_INFORMATION pi;
ZeroMemory (&su, sizeof(STARTUPINFO));
su.cb = sizeof(STARTUPINFO);
if (CreateProcess (NULL, NP_WSX95_EXE, NULL, NULL, FALSE,
0, NULL, NULL, &su, &pi))
{
WaitForInputIdle (pi.hProcess, TRAPSERVERTIMEOUT);
TaskData.trapWnd = FindWindow (NP_WSX95, NP_WSX95);
}
if (TaskData.trapWnd == NULL)
return (0); // ERROR: Cannot connect to NP_WSX95
}
// create UDP socket to receive traps from NP_WSX95
TaskData.trapSock = socket (AF_INET, SOCK_DGRAM, 0);
if (TaskData.trapSock == INVALID_SOCKET)
return (0); // ERROR: Cannot create socket
ZeroMemory (&trapAddr, sizeof(trapAddr));
trapAddr.sin_family = AF_INET;
trapAddr.sin_addr.s_addr = inet_addr (LOOPBACK_ADDR);
trapPort = BASE_PORT;
for (i = 0; i < MAX_PORTS; i++)
{
trapPort++;
trapAddr.sin_port = htons ((WORD)trapPort);
j = bind (TaskData.trapSock, (LPSOCKADDR)&trapAddr, sizeof(trapAddr));
if (j == 0)
break; // 0 = bind success
}
if (j == SOCKET_ERROR)
{
closesocket (TaskData.trapSock);
TaskData.trapSock = INVALID_SOCKET;
goto DONE; // ERROR: Cannot bind a port
}
// Notify NP_WSX95 to forward traps
PostMessage (TaskData.trapWnd, WSNMP_TRAPS_ON, (DWORD_PTR)TaskData.hTask, trapPort);
//
while (TRUE)
{
FD_ZERO (&readFDS);
FD_SET (TaskData.trapSock, &readFDS);
nSock = select (0, &readFDS, NULL, NULL, NULL);
if (nSock == SOCKET_ERROR)
goto DONE;
// Thread is listening on only one socket, so
// FD_ISSET can be safely assumed here
// get the datagram and the address of the host that sent it
iBytes = recv (TaskData.trapSock, (LPBYTE)&recvTrap, sizeof(SNMP_TRAP), 0);
if (iBytes != SOCKET_ERROR && iBytes > iHeader)
{
iBytes -= iHeader;
// Find the message buffer address...
rMsgPtr = GlobalAlloc (GPTR, iBytes);
if (rMsgPtr == NULL) // No space error!
continue;
CopyMemory (rMsgPtr, &recvTrap.TrapBuf, iBytes);
MsgNotify (NP_TRAP, rMsgPtr, iBytes, 0, (LPSAS)&recvTrap.Addr);
} // end_if
} // end_while
} // end_95_thrTrap
DONE:
return (0);
} // end_Win32_thrTrap
#endif // ! SOLARIS
#ifdef SOLARIS
THR_TYPE WINAPI thrTrap (LPVOID lpTask)
// This thread sets up a trap listen socket,
// receives traps from the socket,
// then notifies the DLL for processing.
{
SOCKADDR localAddress;
SOCKADDR_IN localAddress_in;
SOCKADDR_IPX localAddress_ipx;
struct servent *serv;
struct fd_set readfds;
int fdSockMax = 0;
int fLen = 0;
int nSock;
SOCKET fd;
SOCKET fdSock[2];
BOOL fSuccess = FALSE;
SAS host;
smiLPBYTE rMsgPtr;
DWORD iBytes;
int i;
//
fd = socket (AF_INET, SOCK_DGRAM, 0);
if (fd != INVALID_SOCKET)
{
ZeroMemory (&localAddress_in, sizeof(localAddress_in));
localAddress_in.sin_family = AF_INET;
if ((serv = getservbyname ("snmp-trap", "udp")) == NULL)
localAddress_in.sin_port = htons (IP_TRAP_PORT);
else
localAddress_in.sin_port = (short)serv->s_port;
localAddress_in.sin_addr.s_addr = htonl (INADDR_ANY);
CopyMemory (&localAddress, &localAddress_in, sizeof(localAddress_in));
if (bind (fd, &localAddress, sizeof(localAddress)) != SOCKET_ERROR)
{
fLen = fd;
fdSock[fdSockMax++] = fd;
fSuccess = TRUE;
}
}
fd = socket (AF_IPX, SOCK_DGRAM, NSPROTO_IPX);
if (fd != INVALID_SOCKET)
{
ZeroMemory (&localAddress_ipx, sizeof(localAddress_ipx));
localAddress_ipx.sa_family = AF_IPX;
localAddress_ipx.sa_socket = htons (IPX_TRAP_PORT);
CopyMemory (&localAddress, &localAddress_ipx, sizeof(localAddress_ipx));
if (bind (fd, &localAddress, sizeof(localAddress)) != SOCKET_ERROR)
{
if (fd > fLen) fLen = fd;
fdSock[fdSockMax++] = fd;
fSuccess = TRUE;
}
}
if (!fSuccess)
return (0); // can't open either socket
fLen++; // increment select counter
while (TRUE)
{
FD_ZERO(&readfds);
// construct readfds which gets destroyed by select()
for (i=0; i < fdSockMax; i++)
FD_SET(fdSock[i], &readfds);
// Must preserve value of fLen across loops
nSock = select (fLen, &readfds, NULL, NULL, NULL);
if (nSock == SOCKET_ERROR)
goto DONE;
for (i=0; i<fdSockMax; i++)
{
if (FD_ISSET(fdSock[i], &readfds))
{
ioctlsocket (fdSock[i], FIONREAD, &iBytes);
rMsgPtr = GlobalAlloc (GPTR, iBytes);
if (rMsgPtr == NULL)
{
recvfrom (fdSock[i], (LPSTR)&nSock, 1, 0, NULL, NULL);
continue;
}
nSock = sizeof(SAS);
iBytes = recvfrom (fdSock[i], rMsgPtr, iBytes, 0, (LPSOCKADDR)&host, &nSock);
if (iBytes != SOCKET_ERROR)
MsgNotify (NP_TRAP, rMsgPtr, iBytes, 0, &host);
} // end_if FD_ISSET
} // end_for
} // end while TRUE
DONE:
return (NULL);
} // end_thrTrap (SOLARIS)
#endif // SOLARIS
THR_TYPE WINAPI thrAgent (LPVOID newAgent)
{
DWORD iBytes;
int iLen;
fd_set readFDS;
SAS host;
smiLPBYTE rMsgPtr;
DWORD nAgent = (DWORD)((DWORD_PTR)newAgent);
SOCKET sAgent = ((LPAGENT)snmpGetTableEntry(&AgentDescr, nAgent))->Socket;
// fLen logic needed for Solaris; ignored in Win32
int fLen = (int)sAgent + 1;
while (TRUE)
{
FD_ZERO (&readFDS);
FD_SET (sAgent, &readFDS);
// Must preserve value of fLen acroos loops
iLen = select (fLen, &readFDS, NULL, NULL, NULL);
if (iLen == SOCKET_ERROR)
goto DONE;
// Only one socket per thread, therefore
// we can safely assume FD_ISSET here
iLen = ioctlsocket (sAgent, FIONREAD, &iBytes);
if (iLen == SOCKET_ERROR)
goto DONE;
if (iBytes == 0)
continue;
// Find the message buffer address...
rMsgPtr = GlobalAlloc (GPTR, iBytes);
if (rMsgPtr == NULL)
{ // No space error...throw away the message...
recvfrom (sAgent, (LPSTR)&iLen, 1, 0, NULL, NULL);
// ...and call it quits.
continue;
}
iLen = sizeof(SAS);
// get the datagram and the address of the host that sent it
iBytes = recvfrom (sAgent, rMsgPtr, iBytes, 0, (LPSOCKADDR)&host, &iLen);
if (iBytes != SOCKET_ERROR)
MsgNotify (NP_REQUEST, rMsgPtr, iBytes, nAgent, &host);
} // end_while
DONE:
return (0);
} // end_thrAgent
BOOL MapV1TrapV2 (LPPDUS pdu)
{
LPVARBIND VbTicks = NULL;
LPVARBIND VbTrap = NULL;
LPVARBIND VbAddress = NULL;
LPVARBIND VbEnterprise = NULL;
LPVARBIND endPtr;
smiLPUINT32 ptrTrap;
smiUINT32 lenTrap;
if (!pdu)
return (FALSE);
// Adjust "generic" for v2 values
pdu->v1Trap->generic_trap++; // as oid in v2 is v1 # +1
if (pdu->v1Trap->generic_trap == 7) // specific?
pdu->v1Trap->generic_trap = 0; // v2
// rfc1908:(2) If a Trap-PDU is received, then it is mapped into a
// SNMPv2-Trap-PDU. This is done by prepending onto the variable-bindings
// field two new bindings: sysUpTime.0 [12], which takes its value from the
// timestamp field of the Trap-PDU; and.......
if (!(VbTicks = (LPVARBIND)GlobalAlloc (GPTR, sizeof(VARBIND))))
return (FALSE);
if (SnmpOidCopy (&sysUpTimeName, &VbTicks->name) == SNMPAPI_FAILURE)
goto ERROROUT;
VbTicks->value.syntax = SNMP_SYNTAX_TIMETICKS;
VbTicks->value.value.uNumber = pdu->v1Trap->time_ticks;
// ..... snmpTrapOID.0 [13], which is calculated thusly: if the value of
// generic-trap field is `enterpriseSpecific', then the value used is the
// concatenation of the enterprise field from the Trap-PDU with two additional
// sub-identifiers, `0', and the value of the specific-trap field; otherwise,
// the value of the corresponding trap defined in [13] is used. (For example,
// if the value of the generic-trap field is `coldStart', then the coldStart
// trap [13] is used.)
if (!(VbTrap = (LPVARBIND)GlobalAlloc (GPTR, sizeof(VARBIND))))
goto ERROROUT;
if (SnmpOidCopy (&snmpTrapOidName, &VbTrap->name) == SNMPAPI_FAILURE)
goto ERROROUT;
VbTrap->value.syntax = SNMP_SYNTAX_OID;
if (snmpTrapsValue[9] = pdu->v1Trap->generic_trap) // Deliberate assignment
{ // SNMP_TRAP_GENERIC
lenTrap = sizeof(snmpTrapsValue);
VbTrap->value.value.oid.len = lenTrap / sizeof(smiUINT32);
ptrTrap = snmpTrapsValue;
}
else
{ // SNMP_TRAP_ENTERPRISE
lenTrap = pdu->v1Trap->enterprise.len * sizeof(smiUINT32);
VbTrap->value.value.oid.len = pdu->v1Trap->enterprise.len + 2;
ptrTrap = pdu->v1Trap->enterprise.ptr;
}
if (!(VbTrap->value.value.oid.ptr = (smiLPUINT32)GlobalAlloc
(GPTR, VbTrap->value.value.oid.len * sizeof(smiUINT32))))
goto ERROROUT;
CopyMemory (VbTrap->value.value.oid.ptr, ptrTrap, lenTrap);
if (!pdu->v1Trap->generic_trap)
{ // SNMP_TRAP_ENTERPRISE
VbTrap->value.value.oid.ptr[pdu->v1Trap->enterprise.len+1] =
pdu->v1Trap->specific_trap;
}
// Special code to retain v1Trap AgentAddress info in an experimental object
// This is *not* part of the WinSNMP v2.0 standard at this time (6/25/98)
if (TaskData.conveyAddress != SNMPAPI_ON)
goto DO_ENTERPRISE;
if (!(VbAddress = (LPVARBIND)GlobalAlloc (GPTR, sizeof(VARBIND))))
goto ERROROUT;
if (SnmpOidCopy (&snmpTrapAddrName, &VbAddress->name) == SNMPAPI_FAILURE)
goto ERROROUT;
VbAddress->value.syntax = SNMP_SYNTAX_IPADDR;
// *Re-use* this OID parsed in WSNMP_BN code
VbAddress->value.value.string.len = pdu->v1Trap->agent_addr.len;
VbAddress->value.value.string.ptr = pdu->v1Trap->agent_addr.ptr;
pdu->v1Trap->agent_addr.len = 0; // Setting .ptr to NULL required
pdu->v1Trap->agent_addr.ptr = NULL; // for later call to FreeV1Trap()
DO_ENTERPRISE:
// Then,......one new binding is appended onto the variable-bindings field:
// snmpTrapEnterpriseOID.0 [13], which takes its value from the enterprise field
// of the Trap-PDU.
//
// WINSNMP specs in SnmpRecvMsg specifies this append for both the generic and
// specific traps and not only for specific as RFC 1452 does.
if (!(VbEnterprise = (LPVARBIND)GlobalAlloc (GPTR, sizeof(VARBIND))))
goto ERROROUT;
if (SnmpOidCopy (&snmpTrapEntName, &VbEnterprise->name) == SNMPAPI_FAILURE)
goto ERROROUT;
VbEnterprise->value.syntax = SNMP_SYNTAX_OID;
// *Re-use* this OID parsed in WSNMP_BN code
VbEnterprise->value.value.oid.len = pdu->v1Trap->enterprise.len;
VbEnterprise->value.value.oid.ptr = pdu->v1Trap->enterprise.ptr;
pdu->v1Trap->enterprise.len = 0; // Setting .ptr to NULL required
pdu->v1Trap->enterprise.ptr = NULL; // for later call to FreeV1Trap()
//We have all the variables set, just need to link them together
//backup the head of the original vbs
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -