windows-nt/Source/XPSP1/NT/sdktools/rasdiag/rsniffsvc/rsniff.cpp
2020-09-26 16:20:57 +08:00

1206 lines
32 KiB
C++

#include <conio.h>
#include <stdio.h>
#include <stdlib.h>
#include <windows.h>
#include <lmcons.h>
#include <userenv.h>
#include <ras.h>
#include <raserror.h>
#include <process.h>
#include <netmon.h>
#include <ncdefine.h>
#include <ncmem.h>
#include <diag.h>
#include <winsock.h>
#include <devguid.h>
#include "rsniffclnt.h"
#include "rasdiag.h"
SERVICE_STATUS_HANDLE g_hSs=NULL;
SOCKET g_sock;
HANDLE g_hTerminateEvent=NULL;
#define RSNIFF_SERVICE_NAME TEXT("RSNIFF")
#define RSNIFF_DISPLAY_NAME TEXT("RAS REMOTE SNIFF AGENT")
#define INSTALL_PATH TEXT("C:\\RSNIFF")
BOOL
WriteLogEntry(HANDLE hFile, DWORD dwCallID, WCHAR *szClientName, WCHAR *pszTextMsg);
BOOL
CreateNewService(void);
BOOL
UninstallService(void);
void
RSniffServiceMain(DWORD argc, LPTSTR *argv);
void
BeSniffServer(SOCKET s,PRASDIAGCAPTURE pInterfaces, DWORD dwInterfaces);
DWORD
WINAPI
RSniffSvcHandler(DWORD dwControl,DWORD dwEventType,LPVOID lpEventData,LPVOID lpContext);
BOOL
SetupListen(SOCKET *ps);
BOOL
Init(PRASDIAGCAPTURE *ppInterfaces, DWORD *pdwInterfaces, SOCKET *ps);
BOOL
Init(PRASDIAGCAPTURE *ppInterfaces, DWORD *pdwInterfaces, SOCKET *ps)
{
PRASDIAGCAPTURE pInterfaces=NULL;
DWORD dwInterfaces=0;
HRESULT hr;
SOCKET s;
*ppInterfaces = NULL;
*pdwInterfaces = 0;
hr = CoInitialize(NULL);
if(!SUCCEEDED(hr)) {
return FALSE;
}
// Create a termination event
if((g_hTerminateEvent = CreateEvent(NULL, TRUE, FALSE, NULL))
== NULL) return FALSE;
if(InitWinsock() == FALSE) {
wprintf(L"could not init winsock\n");
return FALSE;
}
if(IdentifyInterfaces(&pInterfaces, &dwInterfaces) == FALSE) {
wprintf(L"Could not ID interfaces\n");
return FALSE;
}
if(SetupListen(&s) == FALSE) {
wprintf(L"Could not listen!\n");
return FALSE;
}
*ps = s;
*ppInterfaces = pInterfaces;
*pdwInterfaces = dwInterfaces;
return TRUE;
}
int
__cdecl
wmain(int argc, TCHAR **argv)
{
SERVICE_TABLE_ENTRY ste[] = {
RSNIFF_SERVICE_NAME, RSniffServiceMain,
NULL, NULL
};
if (argc>1) {
if(lstrcmpi(argv[1], L"-i") == 0) {
wprintf(L"Installing RSNIFF. Result = %s\n", CreateNewService() ? L"Done" : L"Failed!!");
return 0;
}
if(lstrcmpi(argv[1], L"-u") == 0) {
wprintf(L"Uninstalling RSNIFF. Result = %s\n", UninstallService() ? L"Done" : L"Failed!!");
return 0;
}
if(lstrcmpi(argv[1], L"-?") == 0 || lstrcmpi(argv[1], L"/?") == 0) {
wprintf(L"\n"
L"------------------------------------------------\n"
L"RSNIFF - RAS REMOTE SNIFFING AGENT SERVICE (%d.%d)\n"
L"------------------------------------------------\n"
L"-i Install RSNIFF service\n"
L"-u Uninstall RSNIFF service\n"
L"-? This menu\n"
L"/? This menu\n"
L"------------------------------------------------\n", RASDIAG_MAJOR_VERSION, RASDIAG_MINOR_VERSION
);
return 0;
}
return 0;
}
if(StartServiceCtrlDispatcher(ste) == FALSE)
{
return 0;
}
return 1;
}
DWORD
WINAPI
RSniffSvcHandler(DWORD dwControl,DWORD dwEventType,LPVOID lpEventData,LPVOID lpContext)
{
SERVICE_STATUS ss;
switch(dwControl)
{
case SERVICE_CONTROL_STOP:
ss.dwServiceType = SERVICE_WIN32;
ss.dwCurrentState = SERVICE_STOP_PENDING;
ss.dwControlsAccepted = SERVICE_CONTROL_INTERROGATE;
ss.dwWin32ExitCode = 0;
ss.dwServiceSpecificExitCode = 0;
ss.dwCheckPoint = 1;
ss.dwWaitHint = 60*1000;
SetServiceStatus(g_hSs, &ss);
//
// set event that causes service to exit
//
SetEvent(g_hTerminateEvent);
closesocket(g_sock);
return NO_ERROR;
break;
}
return ERROR_CALL_NOT_IMPLEMENTED;
}
void
RSniffServiceMain(DWORD argc, LPTSTR *argv)
{
SERVICE_STATUS_HANDLE hSs;
SERVICE_STATUS ss;
PRASDIAGCAPTURE pInterfaces=NULL;
DWORD dwInterfaces=0;
SOCKET s;
ZeroMemory(&ss, sizeof(SERVICE_STATUS));
if((g_hSs=hSs=RegisterServiceCtrlHandlerEx(RSNIFF_SERVICE_NAME, RSniffSvcHandler,0))
== 0) return;
ss.dwServiceType = SERVICE_WIN32;
ss.dwCurrentState = SERVICE_START_PENDING;
ss.dwControlsAccepted = SERVICE_ACCEPT_STOP;
ss.dwWin32ExitCode = 0;
ss.dwServiceSpecificExitCode = 0;
ss.dwCheckPoint = 0;
ss.dwWaitHint = 0;
if(Init(&pInterfaces, &dwInterfaces, &s)==TRUE) {
ss.dwCurrentState = SERVICE_RUNNING;
SetServiceStatus (hSs, &ss);
//
// Report start event to eventlog
//
//MyReportEvent(BEACONMSG_STARTED, EVENTLOG_INFORMATION_TYPE, NULL, 0);
//
// Execute the service - run until term event is signalled
//
BeSniffServer(s,pInterfaces,dwInterfaces);
//
// Unload winsock
//
WSACleanup();
//
// Report halt to event log
//
//MyReportEvent(BEACONMSG_STOPPED, EVENTLOG_INFORMATION_TYPE, NULL, 0);
} else {
//
// Report the init failure
//
//MyReportEvent(BEACONMSG_STOPPED, EVENTLOG_INFORMATION_TYPE, NULL, 0);
}
ss.dwServiceType = SERVICE_WIN32;
ss.dwCurrentState = SERVICE_STOPPED;
ss.dwControlsAccepted = 0;
ss.dwWin32ExitCode = 0;
ss.dwServiceSpecificExitCode = 0;
ss.dwCheckPoint = 0;
ss.dwWaitHint = 0;
//
// Tell service controller that service is halted.
//
SetServiceStatus(g_hSs, &ss);
//DBGPRINTF(D, TEXT("Beacon service is halting\n"));
return;
}
BOOL
SetupListen(SOCKET *ps)
{
SOCKADDR_IN ServSockAddr = { AF_INET };
SOCKET s;
ServSockAddr.sin_port = htons(TCP_SERV_PORT);
ServSockAddr.sin_addr.s_addr = INADDR_ANY;
ServSockAddr.sin_family = AF_INET;
wprintf(L"Create listen socket...\n");
if((g_sock=s=socket(AF_INET, SOCK_STREAM, 0)) == INVALID_SOCKET)
{
wprintf(L"Create listen socket failed! (%d)", WSAGetLastError());
return FALSE;
}
//
// Bind an address to the socket
//
wprintf(L"Bind listen socket...\n");
if (bind(s, (const struct sockaddr *) &ServSockAddr,
sizeof(SOCKADDR_IN)) == SOCKET_ERROR)
{
wprintf(L"Bind failed...\n");
//
// Close the socket
//
closesocket(s);
return FALSE;
}
//
// Attempt to listen
//
wprintf(L"Listen...\n");
if(listen(s, 1) == SOCKET_ERROR)
{
wprintf(L"Could not listen...\n");
//
// Close the socket
//
closesocket(s);
return FALSE;
}
*ps = s;
return TRUE;
}
void
BeSniffServer(SOCKET s,PRASDIAGCAPTURE pInt, DWORD dwIntCount)
{
HANDLE hLog;
WCHAR szLogFileName[MAX_PATH+1];
SYSTEMTIME st;
DWORD dwCallerID=0;
GetLocalTime(&st);
wsprintf(szLogFileName, L"%s\\%04d%02d%02d%02d%02d-RSNIFFLOG.TXT",
INSTALL_PATH,
st.wYear,
st.wMonth,
st.wDay,
st.wHour,
st.wMinute,
st.wSecond);
hLog = CreateFile(szLogFileName,
GENERIC_READ|GENERIC_WRITE,
FILE_SHARE_READ,
NULL,
CREATE_ALWAYS,
0,NULL);
if(hLog == INVALID_HANDLE_VALUE)
hLog = NULL;
WriteLogEntry(hLog, 0, L"RSNIFFSVC", L"Service Started");
while(1)
{
REMOTECAPTURE rc;
REMOTECAPTURE_V5 rc_v5;
SOCKADDR_IN PeerSockAddr;
SOCKET NewSock=0;
BYTE x;
int iSize = sizeof(SOCKADDR_IN);
DWORD i,dwStatus;
SYSTEMTIME st;
WCHAR wcRootDir[MAX_PATH+1];
// should always be signalled except when we're going to quit.
if(WaitForSingleObject(g_hTerminateEvent, 0) != WAIT_TIMEOUT) {
CloseHandle(hLog);
return;
}
wprintf(L"Waiting for connection\n");
if((NewSock = accept(s, (struct sockaddr *) &PeerSockAddr,
&iSize)) == INVALID_SOCKET)
{
wprintf(L"accept() failed\n");
continue;
}
// Increment the caller count
dwCallerID++;
GetLocalTime(&st);
// Receive least common denominator...
if(RecvBuffer(NewSock, (LPBYTE)&rc_v5, sizeof(REMOTECAPTURE_V5)) == FALSE)
{
wprintf(L"Recv invalid REMOTECAPTURE (rc.dwVer=%d)\n", rc.dwVer);
closesocket(NewSock);
continue;
}
// Convert v5 -> v7 structure
if(rc_v5.dwVer == sizeof(REMOTECAPTURE_V5))
{
REMOTECAPTURE rc_new;
PREMOTECAPTURE_V5 pRc5=(PREMOTECAPTURE_V5)&rc_v5;
ZeroMemory(&rc_new, sizeof(REMOTECAPTURE));
rc_new.dwVer = sizeof(REMOTECAPTURE);
mbstowcs(rc_new.szMachine, pRc5->szMachine, lstrlenA(pRc5->szMachine)+1);
WriteLogEntry(hLog, dwCallerID, rc_new.szMachine, L"Version 5 client");
// All pre v7 clients will want to do sniff.
rc_new.dwOpt1 = RSNIFF_OPT1_DOSNIFF;
memcpy(&rc,&rc_new,sizeof(REMOTECAPTURE));
} else // Convert v6 -> v7 structure
if(rc_v5.dwVer == sizeof(REMOTECAPTURE_V6)) {
REMOTECAPTURE rc_new;
PREMOTECAPTURE_V5 pRc5=(PREMOTECAPTURE_V5)&rc_v5;
// copy portion of struct received.
memcpy(&rc_new, pRc5, sizeof(REMOTECAPTURE_V5));
WriteLogEntry(hLog, dwCallerID, rc_new.szMachine, L"Version 6 client");
// Receive the remaining part of the v6 structure...
if(RecvBuffer(NewSock, (LPBYTE)&rc_new + sizeof(REMOTECAPTURE_V5), (sizeof(REMOTECAPTURE_V6) - sizeof(REMOTECAPTURE_V5))) == FALSE)
{
WriteLogEntry(hLog, dwCallerID, rc_new.szMachine, L"Recv err!");
wprintf(L"Recv invalid REMOTECAPTURE (rc.dwVer=%d)\n", rc.dwVer);
closesocket(NewSock);
continue;
}
// Covert structure (since copied from V6, just change version number
rc_new.dwVer = sizeof(REMOTECAPTURE);
// All pre v7 clients will want to do sniff.
rc_new.dwOpt1 = RSNIFF_OPT1_DOSNIFF;
// copy structure
memcpy(&rc,&rc_new,sizeof(REMOTECAPTURE));
} else if(rc_v5.dwVer == sizeof(REMOTECAPTURE)) {
REMOTECAPTURE rc_new;
PREMOTECAPTURE_V5 pRc5=(PREMOTECAPTURE_V5)&rc_v5;
// copy portion of struct received.
memcpy(&rc_new, pRc5, sizeof(REMOTECAPTURE_V5));
WriteLogEntry(hLog, dwCallerID, rc_new.szMachine, L"Version 7 client");
// Receive the remaining part of the v6 structure...
if(RecvBuffer(NewSock, (LPBYTE)&rc_new + sizeof(REMOTECAPTURE_V5), (sizeof(REMOTECAPTURE) - sizeof(REMOTECAPTURE_V5))) == FALSE)
{
WriteLogEntry(hLog, dwCallerID, rc_new.szMachine, L"Recv err!");
wprintf(L"Recv invalid REMOTECAPTURE (rc.dwVer=%d)\n", rc.dwVer);
closesocket(NewSock);
continue;
}
// valid v7 structure - read remaining bytes; no conversion necessary
// copy structure
memcpy(&rc,&rc_new,sizeof(REMOTECAPTURE));
} else {
// no idea what this is...
WriteLogEntry(hLog, dwCallerID, L"UNKNOWN CLIENT!", NULL);
wprintf(L"Recv invalid REMOTECAPTURE version (rc.dwVer=%d)\n", rc.dwVer);
closesocket(NewSock);
continue;
}
wsprintf(wcRootDir, L"%s\\%04d%02d%02d%02d%02d%02d-%s-SID_%03d",
INSTALL_PATH,
st.wYear,
st.wMonth,
st.wDay,
st.wHour,
st.wMinute,
st.wSecond,
rc.szMachine,
dwCallerID);
CreateDirectory(wcRootDir,NULL);
if(rc.dwOpt1 & RSNIFF_OPT1_DOSNIFF)
{
WriteLogEntry(hLog, dwCallerID, rc.szMachine, L"Request for local network sniff");
wprintf(L"Sniffing traffic for caller: %s\n", rc.szMachine);
// start sniffing
for(i=0;i<dwIntCount;i++)
{
// Initialize this interface...
if(InitIDelaydC(pInt[i].hBlob, &pInt[i].pIDelaydC) == TRUE)
{
if(pInt[i].pIDelaydC)
{
CHAR szCaptureFile[MAX_PATH+1];
dwStatus = pInt[i].pIDelaydC->Start(szCaptureFile);
if(dwStatus != NMERR_SUCCESS)
{
wprintf(L"pIDelaydC->Start() FAILED! Start rtn %x\n", dwStatus);
pInt[i].pIDelaydC->Disconnect();
} else {
// convert mbs to wide
mbstowcs(pInt[i].szCaptureFileName, szCaptureFile, lstrlenA(szCaptureFile)+1);
}
}
} else {
wprintf(L"InitIDelaydC() failed\n");
}
}
}
// Get pre-connect routing table info
if(rc.dwOpt1 & RSNIFF_OPT1_GETSRVROUTINGINFO)
{
WCHAR szRoutingInfo[MAX_PATH+1];
WriteLogEntry(hLog, dwCallerID, rc.szMachine, L"Request for local routing table");
wsprintf(szRoutingInfo, L"route print > %s\\ROUTINGINFO.TXT", wcRootDir);
_wsystem(szRoutingInfo);
wsprintf(szRoutingInfo, L"ipconfig >> %s\\ROUTINGINFO.TXT", wcRootDir);
_wsystem(szRoutingInfo);
}
// wait until remote closes socket
RecvBuffer(NewSock, (LPBYTE)&x, 1);
closesocket(NewSock);
// Get the routing table info
if(rc.dwOpt1 & RSNIFF_OPT1_GETSRVROUTINGINFO)
{
WCHAR szRoutingInfo[MAX_PATH+1];
wsprintf(szRoutingInfo, L"route print >> %s\\ROUTINGINFO.TXT", wcRootDir);
_wsystem(szRoutingInfo);
wsprintf(szRoutingInfo, L"ipconfig >> %s\\ROUTINGINFO.TXT", wcRootDir);
_wsystem(szRoutingInfo);
}
if(rc.dwOpt1 & RSNIFF_OPT1_DOSNIFF)
{
wprintf(L"Sniffing complete\n");
// Stop sniffing...
for(i=0;i<dwIntCount;i++)
{
dwStatus = pInt[i].pIDelaydC->Stop(&pInt[i].stats);
if(dwStatus != NMERR_SUCCESS)
{
wprintf(L"pIDelaydC->Stop() rtn %x\n", dwStatus);
pInt[i].pIDelaydC->Disconnect();
}
if(pInt[i].stats.TotalBytesCaptured)
{
WCHAR szNewFileName[MAX_PATH+1];
WCHAR *pChar=NULL;
WCHAR *pFn=NULL;
pFn = pInt[i].szCaptureFileName + lstrlenW(pInt[i].szCaptureFileName) + 1;
// Get the filename
while(*pFn != '\\' && pFn!=pInt[i].szCaptureFileName) pFn--;
pFn++;
wprintf(L"%d LAN bytes captured (%s)\n", pInt[i].stats.TotalBytesCaptured, pInt[i].szCaptureFileName);
wsprintf(szNewFileName,L"%s\\%s__%s_SID_%d.CAP", wcRootDir, pFn, rc.szMachine, dwCallerID);
if((pChar=wcsstr(szNewFileName, L"."))
!= NULL) {
*pChar='_';
}
wprintf(L"Saving %s\n", szNewFileName);
MoveFile(pInt[i].szCaptureFileName, szNewFileName);
} else {
wprintf(L"%d bytes captured (%s)\n", pInt[i].stats.TotalBytesCaptured, pInt[i].szCaptureFileName);
}
// Disconnect
if(pInt[i].pIDelaydC)
{
pInt[i].pIDelaydC->Disconnect();
}
}
WriteLogEntry(hLog, dwCallerID, rc.szMachine, L"Client processing complete.");
wprintf(L"Sniffing complete\n");
}
}
}
void
Listen(PRASDIAGCAPTURE pInt, DWORD dwIntCount)
{
SOCKADDR_IN ServSockAddr = { AF_INET };
SOCKET s;
ServSockAddr.sin_port = htons(TCP_SERV_PORT);
ServSockAddr.sin_addr.s_addr = INADDR_ANY;
ServSockAddr.sin_family = AF_INET;
wprintf(L"Create listen socket...\n");
if((s=socket(AF_INET, SOCK_STREAM, 0)) == INVALID_SOCKET)
{
wprintf(L"Create listen socket failed! (%d)", WSAGetLastError());
}
//
// Bind an address to the socket
//
wprintf(L"Bind listen socket...\n");
if (bind(s, (const struct sockaddr *) &ServSockAddr,
sizeof(SOCKADDR_IN)) == SOCKET_ERROR)
{
wprintf(L"Bind failed...\n");
//
// Close the socket
//
closesocket(s);
return;
}
//
// Attempt to listen
//
wprintf(L"Listen...\n");
if(listen(s, 1) == SOCKET_ERROR)
{
wprintf(L"Could not listen...\n");
//
// Close the socket
//
closesocket(s);
return;
}
while(1)
{
REMOTECAPTURE rc;
SOCKADDR_IN PeerSockAddr;
SOCKET NewSock=0;
BYTE x;
int iSize = sizeof(SOCKADDR_IN);
DWORD i,dwStatus;
wprintf(L"Waiting for connection\n");
if((NewSock = accept(s, (struct sockaddr *) &PeerSockAddr,
&iSize)) == INVALID_SOCKET)
{
wprintf(L"accept() failed\n");
continue;
}
if(RecvBuffer(NewSock, (LPBYTE)&rc, sizeof(REMOTECAPTURE)) == FALSE)
{
wprintf(L"Recv invalid REMOTECAPTURE (rc.dwVer=%d)\n", rc.dwVer);
closesocket(NewSock);
continue;
}
wprintf(L"Sniffing traffic for caller: %s\n", rc.szMachine);
// start sniffing
for(i=0;i<dwIntCount;i++)
{
// Initialize this interface...
if(InitIDelaydC(pInt[i].hBlob, &pInt[i].pIDelaydC) == TRUE)
{
if(pInt[i].pIDelaydC)
{
CHAR szCaptureName[MAX_PATH+1];
dwStatus = pInt[i].pIDelaydC->Start(szCaptureName);
if(dwStatus != NMERR_SUCCESS)
{
wprintf(L"pIDelaydC->Start() FAILED! Start rtn %x\n", dwStatus);
pInt[i].pIDelaydC->Disconnect();
} else {
mbstowcs(pInt[i].szCaptureFileName, szCaptureName, lstrlenA(szCaptureName)+1);
}
}
} else {
wprintf(L"InitIDelaydC() failed\n");
}
}
// wait until remote closes socket
RecvBuffer(NewSock, (LPBYTE)&x, 1);
closesocket(NewSock);
wprintf(L"Sniffing complete\n");
// Stop sniffing...
for(i=0;i<dwIntCount;i++)
{
dwStatus = pInt[i].pIDelaydC->Stop(&pInt[i].stats);
if(dwStatus != NMERR_SUCCESS)
{
wprintf(L"pIDelaydC->Stop() rtn %x\n", dwStatus);
pInt[i].pIDelaydC->Disconnect();
}
if(pInt[i].stats.TotalBytesCaptured)
{
WCHAR szNewFileName[MAX_PATH+1];
WCHAR *pChar=NULL;
wprintf(L"%d LAN bytes captured (%s)\n", pInt[i].stats.TotalBytesCaptured, pInt[i].szCaptureFileName);
wsprintf(szNewFileName, L"%s__%s.CAP", pInt[i].szCaptureFileName, rc.szMachine);
if((pChar=wcsstr(szNewFileName, L"."))
!= NULL) {
*pChar='_';
}
wprintf(L"Saving %s\n", szNewFileName);
MoveFile(pInt[i].szCaptureFileName, szNewFileName);
} else {
wprintf(L"%d bytes captured (%s)\n", pInt[i].stats.TotalBytesCaptured, pInt[i].szCaptureFileName);
}
// Disconnect
if(pInt[i].pIDelaydC)
{
pInt[i].pIDelaydC->Disconnect();
}
}
wprintf(L"Sniffing complete\n");
}
}
BOOL
IdentifyInterfaces(PRASDIAGCAPTURE *hLAN, DWORD *pdwLanCount)
{
DWORD dwStatus;
HBLOB hBlob;
BLOB_TABLE *pTable=NULL;
DWORD i;
BOOL bRas=FALSE;
DWORD dwLanCount=0;
PRASDIAGCAPTURE hLanAr=NULL;
*hLAN = NULL;
*pdwLanCount = 0;
if((hLanAr = (PRASDIAGCAPTURE)LocalAlloc(LMEM_ZEROINIT, sizeof(RASDIAGCAPTURE) * MAX_LAN_CAPTURE_COUNT))
== NULL) return FALSE;
wprintf(L"Identifying Network Interfaces\n");
// Create blob for blob table
dwStatus = CreateBlob(&hBlob);
if(dwStatus != NMERR_SUCCESS) {
wprintf(L"Blob not created!\n");
return FALSE;
}
// Get the blob table
dwStatus = GetNPPBlobTable(hBlob, &pTable);
if(dwStatus != NMERR_SUCCESS) {
wprintf(L"GetNPPBlobTable failed (%d)!\n",dwStatus);
DestroyBlob(hBlob);
return FALSE;
}
wprintf(L"Interface Count: %d\n",pTable->dwNumBlobs);
for(i=0;i<pTable->dwNumBlobs && (dwLanCount < MAX_LAN_CAPTURE_COUNT);i++)
{
NETWORKINFO ni;
dwStatus = GetNetworkInfoFromBlob(pTable->hBlobs[i], &ni);
if(dwStatus == NMERR_SUCCESS)
{
wprintf(L"----------------------------------------\n");
wprintf(L"%d. LinkSpeed: %d (%d)\n", i,ni.LinkSpeed, ni.MacType );
if(NMERR_SUCCESS != GetBoolFromBlob( pTable->hBlobs[i],
OWNER_NPP,
CATEGORY_LOCATION, //CATEGORY_NETWORKINFO,
TAG_RAS,
&bRas))
{
DestroyBlob(hBlob);
return FALSE;
}
if(bRas)
{
wprintf(L"Interface %d: %s\n", i, TAG_RAS);
hLanAr[dwLanCount].hBlob=pTable->hBlobs[i];
hLanAr[dwLanCount++].bWan=TRUE;
} else {
const char *pString=NULL;
if(GetStringFromBlob(pTable->hBlobs[i],
OWNER_NPP,
CATEGORY_LOCATION,
TAG_MACADDRESS,
&pString)
== NMERR_SUCCESS)
{
//wprintf(L"Interface %d: %s (MAC: %s)\n", i, "LAN", pString);
} else {
//wprintf(L"Interface %d: %s (UNKNOWN)\n", i, "LAN");
}
// use this interface only if the mac type
// is one of the following:
if(ni.MacType == MAC_TYPE_ETHERNET ||
ni.MacType == MAC_TYPE_TOKENRING ||
ni.MacType == MAC_TYPE_ATM)
if(pString)
{
if((hLanAr[dwLanCount].pszMacAddr = (WCHAR*)LocalAlloc(LMEM_ZEROINIT, sizeof(WCHAR) * (lstrlenA(pString) + 1)))
!= NULL)
mbstowcs(hLanAr[dwLanCount].pszMacAddr, pString, lstrlenA(pString));
}
hLanAr[dwLanCount++].hBlob = pTable->hBlobs[i];
}
} else {
wprintf(L"GetNetworkInfoFromBlob rtn %d\n", dwStatus);
DestroyBlob(hBlob);
return FALSE;
}
}
wprintf(L"----------------------------------------\n");
DestroyBlob(hBlob);
if(dwLanCount)
{
*pdwLanCount = dwLanCount;
*hLAN = hLanAr;
}
return TRUE;
}
BOOL
InitWinsock(void)
{
WSADATA WSAData;
WORD WSAVerReq = MAKEWORD(2,0);
if (WSAStartup(WSAVerReq, &WSAData)) {
return FALSE;
} else
return TRUE;
}
PSOCKCB
TcpConnectRoutine(LPSTR pAddr)
{
SOCKADDR_IN DstAddrIP = { AF_INET };
HOSTENT *pHost;
ULONG uAddr;
PSOCKCB pSock;
BOOL bResult;
ULONG ulHostAddr=0;
//
// Resolve name
//
if ((ulHostAddr = inet_addr(pAddr)) == -1L)
{
return NULL;
}
uAddr = ntohl(ulHostAddr);
wprintf(L"Connecting to remote server sniffing agent (ADDR: %d.%d.%d.%d)\n",
((struct in_addr *) &uAddr)->S_un.S_un_b.s_b4,
((struct in_addr *) &uAddr)->S_un.S_un_b.s_b3,
((struct in_addr *) &uAddr)->S_un.S_un_b.s_b2,
((struct in_addr *) &uAddr)->S_un.S_un_b.s_b1);
DstAddrIP.sin_port = htons(TCP_SERV_PORT);
DstAddrIP.sin_addr.s_addr = htonl(uAddr);
//
// Create socket
//
pSock = CreateSocket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
if(pSock == NULL)
return NULL;
//
// Connect the socket
//
if(ConnectSock(pSock, (struct sockaddr *)&DstAddrIP, sizeof(SOCKADDR_IN))
!= TRUE)
{
wprintf(L"Could not connect to remote server sniffing agent!\n");
closesocket(pSock->s);
LocalFree(pSock);
return NULL;
}
return pSock;
}
BOOL
ConnectSock(PSOCKCB pSock, SOCKADDR* pDstAddr, int size)
{
int err;
//
// Connect the socket
//
err = connect(pSock->s, pDstAddr, size);
if(err==SOCKET_ERROR)
{
return FALSE;
}
return TRUE;
}
PSOCKCB
CreateSocket(int Af, int Type, int Proto)
{
PSOCKCB pSock;
if((pSock = (PSOCKCB)LocalAlloc(LMEM_ZEROINIT, sizeof(SOCKCB)))
== NULL)
return NULL;
//
// Create a socket
//
if((pSock->s = socket(Af, Type, Proto))
== INVALID_SOCKET)
{
LocalFree(pSock);
return NULL;
}
return pSock;
}
BOOL
SendStartSniffPacket(PSOCKCB pSock)
{
REMOTECAPTURE rc;
DWORD dwSize = MAX_COMPUTERNAME_LENGTH+1;
ZeroMemory(&rc, sizeof(REMOTECAPTURE));
rc.dwVer = sizeof(REMOTECAPTURE);
GetComputerName(rc.szMachine, &dwSize);
return SendBuffer(pSock->s, (LPBYTE)&rc, sizeof(REMOTECAPTURE));
}
BOOL
SendBuffer(SOCKET s, LPBYTE pBuffer, ULONG uSize)
{
ULONG err,uSent, uBytesSent=0;
while(uBytesSent != uSize)
{
uSent = send(s, (const char *)(pBuffer+uBytesSent), uSize-uBytesSent, 0);
switch(uSent)
{
case SOCKET_ERROR:
err = WSAGetLastError();
return FALSE;
break;
case 0:
return FALSE;
default:
uBytesSent+=uSent;
break;
}
}
return TRUE;
}
BOOL
RecvBuffer(SOCKET s, LPBYTE pBuffer, ULONG uSize)
{
ULONG err=0,uRecv=0, uBytesRecv=0;
while(uBytesRecv != uSize)
{
wprintf(L"Recv...\n");
uRecv = recv(s, (char *)pBuffer+uBytesRecv, uSize-uBytesRecv, 0);
switch(uRecv)
{
case SOCKET_ERROR:
err=WSAGetLastError();
wprintf(L"err=%d\n",err);
return FALSE;
break;
case 0:
wprintf(L"Socket gracefully closed by peer\n");
return FALSE;
default:
uBytesRecv += uRecv;
wprintf(L"rtn %d bytes recv\n", uBytesRecv);
break;
}
}
wprintf(L"RecvBuffer complete\n");
return TRUE;
}
BOOL
InitIDelaydC(HBLOB hBlob, IDelaydC **ppIDelaydC)
{
DWORD dwStatus;
const char *sterrLSID;
IDelaydC *pIDelaydC=NULL;
wprintf(L"hBlob: %p\n", hBlob);
if(NMERR_SUCCESS != GetStringFromBlob(hBlob,OWNER_NPP,CATEGORY_LOCATION,TAG_CLASSID,&sterrLSID))
{
wprintf(L"GetStringFromBlob failed\n");
return FALSE;
}
wprintf(L"ClassID: %s\n",sterrLSID);
dwStatus = CreateNPPInterface(hBlob,IID_IDelaydC,(void**)&pIDelaydC);
if(dwStatus != NMERR_SUCCESS)
{
wprintf(L"CreateNPPInterface rtn %x (%p)\n", dwStatus, pIDelaydC);
return FALSE;
}
dwStatus = pIDelaydC->Connect(hBlob,NULL,NULL,NULL);
if(dwStatus != NMERR_SUCCESS)
{
wprintf(L"Connect rtn %x\n", dwStatus);
return FALSE;
}
*ppIDelaydC = pIDelaydC;
return TRUE;
}
BOOL
CreateNewService(void)
{
SC_HANDLE schService, schSCManager;
WCHAR szPath[MAX_PATH+1];
LPCTSTR lpszBinaryPathName = szPath;
wsprintf(szPath, L"%s\\RSNIFF.EXE", INSTALL_PATH);
if((schSCManager= OpenSCManager(NULL,NULL,SC_MANAGER_CREATE_SERVICE))
== NULL) return FALSE;
if((schService = CreateService(
schSCManager, // SCManager database
RSNIFF_SERVICE_NAME, // name of service
RSNIFF_DISPLAY_NAME, // service name to display
SERVICE_ALL_ACCESS, // desired access
SERVICE_WIN32_OWN_PROCESS | SERVICE_INTERACTIVE_PROCESS, // service type
SERVICE_AUTO_START, // start type
SERVICE_ERROR_NORMAL, // error control type
lpszBinaryPathName, // service's binary
NULL, // no load ordering group
NULL, // no tag identifier
NULL, // no dependencies
NULL, // LocalSystem account
NULL)) // no password
== NULL)
{
WCHAR szErrTxt[MAX_PATH+1];
wsprintf(szErrTxt, L"Could not install Beacon service. Err=%d", GetLastError());
wprintf(L"%s\n", szErrTxt);
CloseServiceHandle(schSCManager);
return FALSE;
}
CloseServiceHandle(schService);
CloseServiceHandle(schSCManager);
return TRUE;
}
BOOL
UninstallService(void)
{
SC_HANDLE schService, schSCManager;
if((schSCManager=OpenSCManager(NULL,NULL,SC_MANAGER_CREATE_SERVICE))
== NULL) return FALSE;
if((schService = OpenService(schSCManager,RSNIFF_SERVICE_NAME, SERVICE_ALL_ACCESS))
== NULL) {
WCHAR szErrTxt[MAX_PATH+1];
wsprintf(szErrTxt, L"Could not uninstall Beacon service. Err=%d", GetLastError());
wprintf(L"%s\n", szErrTxt);
CloseServiceHandle(schSCManager);
return FALSE;
}
DeleteService(schService);
CloseServiceHandle(schService);
CloseServiceHandle(schSCManager);
return TRUE;
}
BOOL
WriteLogEntry(HANDLE hFile, DWORD dwCallID, WCHAR *szClientName, WCHAR *pszTextMsg)
{
WCHAR *pBuff;
SYSTEMTIME st;
DWORD dwBytesWritten;
if(hFile == NULL) return FALSE;
if(pszTextMsg)
pBuff = new WCHAR[(MAX_COMPUTERNAME_LENGTH + lstrlenW(pszTextMsg) + 1 + 100)];
else
pBuff = new WCHAR[(MAX_COMPUTERNAME_LENGTH + 1 + 100)]; // no text msg
// got buffer?
if(pBuff == NULL) return FALSE;
GetLocalTime(&st);
wsprintf(pBuff, L"%04d%02d%02d%02d%02d%02d %05d %-15.15s %s\r\n",
st.wYear,
st.wMonth,
st.wDay,
st.wHour,
st.wMinute,
st.wSecond,
dwCallID,
szClientName,
pszTextMsg ? pszTextMsg : L"");
return WriteFile(hFile, pBuff, lstrlenW(pBuff) * sizeof(WCHAR), &dwBytesWritten, NULL);
}