📄 snmptrap.c
字号:
status.dwCheckPoint = 0;
status.dwWaitHint = 0;
if (!SetServiceStatus(hService, &status))
exit(1);
} // end_svcMainFunction()
//--------------------------- PUBLIC PROCEDURES -----------------------------
int __cdecl main ()
{
BOOL fOk;
OSVERSIONINFO osInfo;
SERVICE_TABLE_ENTRY svcStartTable[2] =
{
{(LPTSTR)svcName, svcMainFunction},
{NULL, NULL}
};
osInfo.dwOSVersionInfoSize = sizeof(OSVERSIONINFO);
fOk = GetVersionEx (&osInfo);
if (fOk && (osInfo.dwPlatformId == VER_PLATFORM_WIN32_NT))
{ // create event to synchronize trap server shutdown
hExitEvent = CreateEvent (NULL, TRUE, FALSE, NULL);
// this call will not return until service stopped
fOk = StartServiceCtrlDispatcher (svcStartTable);
CloseHandle (hExitEvent);
}
return fOk;
} // end_main()
//
DWORD WINAPI svrTrapThread (LPVOID threadParam)
// This thread takes a SOCKET parameter, loops on select()
// for data in-coming over that socket, writing it back
// out to clients over all pipes currently on the list of
// trap notification pipes.shared by this thread and the
// pipe thread
{
PSNMP_TRAP pRecvTrap = NULL;
struct fd_set readfds;
SOCKET fd = (SOCKET)threadParam;
int len;
//
while (TRUE)
{
ULONG ulTrapSize = 0;
DWORD dwError = 0;
// construct readfds which gets destroyed by select()
FD_ZERO(&readfds);
FD_SET(fd, &readfds);
if (select (0, &readfds, NULL, NULL, NULL) == SOCKET_ERROR)
break; // terminate thread
if (!(FD_ISSET(fd, &readfds)))
continue;
if (ioctlsocket(
fd, // socket to query
FIONREAD, // query for the size of the incoming datagram
&ulTrapSize // unsigned long to store the size of the datagram
) != 0)
continue; // continue if we could not determine the size of the
// incoming datagram
if (pRecvTrap == NULL ||
pRecvTrap->TrapBufSz < ulTrapSize)
{
if (pRecvTrap != NULL)
{
GlobalFree(pRecvTrap);
pRecvTrap = NULL;
}
pRecvTrap = (PSNMP_TRAP)GlobalAlloc(GPTR, sizeof(SNMP_TRAP) - sizeof(pRecvTrap->TrapBufSz) + ulTrapSize);
if (pRecvTrap == NULL) // if there is so few memory that we can't allocate a bit ..
break; // bail out and stop the SNMPTRAP service (bug? - other option => 100% CPU which is worst)
}
pRecvTrap->TrapBufSz = ulTrapSize;
pRecvTrap->AddrLen = sizeof(pRecvTrap->Addr);
len = recvfrom (
fd,
pRecvTrap->TrapBuf,
pRecvTrap->TrapBufSz,
0,
&(pRecvTrap->Addr),
&(pRecvTrap->AddrLen));
if (len == SOCKET_ERROR)
continue;
EnterCriticalSection (&cs_PIPELIST);
// add header to length
len += sizeof(SNMP_TRAP) - sizeof(pRecvTrap->TrapBuf);
if (!ll_empt(pSvrPipeListHead))
{
DWORD written;
ll_node *item = pSvrPipeListHead;
while (item = ll_next(item, pSvrPipeListHead))
{
if (!WriteFile(
((svrPipeListEntry *)item)->hPipe,
(LPBYTE)pRecvTrap,
len,
&written,
NULL)
)
{
DWORD dwError = GetLastError();
// OPENISSUE - what errors could result from pipe break
if (dwError != ERROR_NO_DATA)
{
; // Placeholder for error handling
}
if (!DisconnectNamedPipe(((svrPipeListEntry *)item)->hPipe))
{
; // Placeholder for error handling
}
else if (!CloseHandle(((svrPipeListEntry *)item)->hPipe))
{
; // Placeholder for error handling
}
ll_rmv(item);
GlobalFree(item); // check for errors?
item = pSvrPipeListHead;
} // end_if !WriteFile
else if (written != (DWORD)len)
{
; // Placeholder for error handling
}
} // end_while item = ll_next
} // end_if !ll_empt
LeaveCriticalSection (&cs_PIPELIST);
} // end while TRUE
if (pRecvTrap != NULL)
GlobalFree(pRecvTrap);
return 0;
} // end svrTrapThread()
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_READ | GENERIC_WRITE,
pSidAdmins ) ||
!AddAccessAllowedAce ( pAcl,
ACL_REVISION,
(GENERIC_READ | (FILE_GENERIC_WRITE & ~FILE_CREATE_PIPE_INSTANCE)),
pSidUsers ))
{
GlobalFree(pAcl);
pAcl = NULL;
}
}
FreeSid(pSidAdmins);
FreeSid(pSidUsers);
return pAcl;
}
void FreeGenericACL( PACL pAcl)
{
if (pAcl != NULL)
GlobalFree(pAcl);
}
DWORD WINAPI svrPipeThread (LPVOID threadParam)
{
// This thread creates a named pipe instance and
// blocks waiting for a client connection. When
// client connects, the pipe handle is added to the
// list of trap notification pipes.
// It then waits for another connection.
DWORD nInBufLen = sizeof(SNMP_TRAP);
DWORD nOutBufLen = sizeof(SNMP_TRAP) * MAX_OUT_BUFS;
SECURITY_ATTRIBUTES S_Attrib;
SECURITY_DESCRIPTOR S_Desc;
PACL pAcl;
// construct security decsriptor
InitializeSecurityDescriptor (&S_Desc, SECURITY_DESCRIPTOR_REVISION);
if ((pAcl = AllocGenericACL()) == NULL ||
!SetSecurityDescriptorDacl (&S_Desc, TRUE, pAcl, FALSE))
{
FreeGenericACL(pAcl);
return (0);
}
S_Attrib.nLength = sizeof(SECURITY_ATTRIBUTES);
S_Attrib.lpSecurityDescriptor = &S_Desc;
S_Attrib.bInheritHandle = TRUE;
//
while (TRUE)
{
HANDLE hPipe;
svrPipeListEntry *item;
hPipe = CreateNamedPipe (SNMPMGRTRAPPIPE,
PIPE_ACCESS_DUPLEX,
(PIPE_WAIT | PIPE_READMODE_MESSAGE | PIPE_TYPE_MESSAGE),
PIPE_UNLIMITED_INSTANCES,
nOutBufLen, nInBufLen, 0, &S_Attrib);
if (hPipe == INVALID_HANDLE_VALUE)
{
break;
}
else if (!ConnectNamedPipe(hPipe, NULL) &&
(GetLastError() != ERROR_PIPE_CONNECTED))
{
break;
}
else if (!(item = (svrPipeListEntry *)
GlobalAlloc (GPTR, sizeof(svrPipeListEntry))))
{
break;;
}
else
{
item->hPipe = hPipe;
EnterCriticalSection (&cs_PIPELIST);
ll_adde(item, pSvrPipeListHead);
LeaveCriticalSection (&cs_PIPELIST);
} // end_else
} // end_while TRUE
FreeGenericACL(pAcl);
return(0);
} // end_svrPipeThread()
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -