📄 win32_service.c
字号:
* with its work. If an error has occurred in initialization, SnortServiceStart * reports SERVICE_STOPPED with the SetServiceStatus function and returns. * * Because this sample service does not complete any real tasks, SnortServiceStart * simply returns control to the caller. However, your service should use this * thread to complete whatever tasks it was designed to do. If a service does not * need a thread to do its work (such as a service that only processes RPC * requests), its ServiceMain function should return control to the caller. It is * important for the function to return, rather than call the ExitThread * function, because returning allows for cleanup of the memory allocated for the * arguments. * * To output debugging information, SnortServiceStart calls SvcDebugOut. The source * code for SvcDebugOut is given in Writing a Service Program's main Function. *******************************************************************************/void logmsg(char* msg){ FILE *pFile; if( (pFile=fopen("c:\\snortlog.txt", "a")) != NULL ) { if( msg != NULL ) { fprintf(pFile, msg); } else { fprintf(pFile, "Message String is NULL\n"); } fclose(pFile); pFile = NULL; }}void logadapternames( char* interfacenames, char* errorbuf ){ char AdaptersName[8192]; int i; memset(AdaptersName, 0x00, sizeof(AdaptersName)); for( i=0; i<sizeof(AdaptersName); i+=2 ) { AdaptersName[i/2] = interfacenames[i]; } for( i=0; i<sizeof(AdaptersName)-1; i++ ) { if( AdaptersName[i] == 0x00 && AdaptersName[i+1] != 0x00 ) { AdaptersName[i] = '\n'; } } logmsg("Errorbuf:"); logmsg(errorbuf); logmsg("\nAdaptersName:"); logmsg(AdaptersName); logmsg("\n");}void WINAPI SnortServiceStart (DWORD argc, LPTSTR *argv) { int i; int iArgCounter; char** argvDynamic = NULL; char errorbuf[PCAP_ERRBUF_SIZE]; char *interfacenames = NULL; DWORD dwStatus; DWORD dwSpecificError; g_SnortServiceStatus.dwServiceType = SERVICE_WIN32; g_SnortServiceStatus.dwCurrentState = SERVICE_START_PENDING; g_SnortServiceStatus.dwControlsAccepted = SERVICE_ACCEPT_STOP | SERVICE_ACCEPT_PAUSE_CONTINUE; g_SnortServiceStatus.dwWin32ExitCode = 0; g_SnortServiceStatus.dwServiceSpecificExitCode = 0; g_SnortServiceStatus.dwCheckPoint = 0; g_SnortServiceStatus.dwWaitHint = 0; g_SnortServiceStatusHandle = RegisterServiceCtrlHandler(g_lpszServiceName, SnortServiceCtrlHandler); if (g_SnortServiceStatusHandle == (SERVICE_STATUS_HANDLE)0) { TCHAR szMsg[1000]; SvcFormatMessage(szMsg, sizeof(szMsg)); SvcDebugOut(" [SNORT_SERVICE] RegisterServiceCtrlHandler failed %d\n", GetLastError()); FatalError (" [SNORT_SERVICE] RegisterServiceCtrlHandler failed %d\n%s\n", GetLastError(), szMsg); return; } /* Initialization code goes here. */ dwStatus = SnortServiceInitialization(argc, argv, &dwSpecificError); /* Handle error condition */ if (dwStatus != NO_ERROR) { g_SnortServiceStatus.dwCurrentState = SERVICE_STOPPED; g_SnortServiceStatus.dwCheckPoint = 0; g_SnortServiceStatus.dwWaitHint = 0; g_SnortServiceStatus.dwWin32ExitCode = dwStatus; g_SnortServiceStatus.dwServiceSpecificExitCode = dwSpecificError; SetServiceStatus (g_SnortServiceStatusHandle, &g_SnortServiceStatus); return; } /* Initialization complete - report running status. */ g_SnortServiceStatus.dwCurrentState = SERVICE_RUNNING; g_SnortServiceStatus.dwCheckPoint = 0; g_SnortServiceStatus.dwWaitHint = 0; if (!SetServiceStatus (g_SnortServiceStatusHandle, &g_SnortServiceStatus)) { TCHAR szMsg[1000]; SvcFormatMessage(szMsg, sizeof(szMsg)); dwStatus = GetLastError(); SvcDebugOut(" [SNORT_SERVICE] SetServiceStatus error %ld\n",dwStatus); FatalError (" [SNORT_SERVICE] SetServiceStatus error %ld\n%s\n",dwStatus,szMsg); } /* There seems to be a bug in Winpcap, such that snort works fine * when it is started from the command line, and the service works * fine if a user has run "snort -W" already. However the service * fails to start (on some machines only) if snort hasn't been * run manually first. So here we simulate a user having run * "snort -W", then let it go on its merry way. */ memset( errorbuf, '\0', sizeof(errorbuf) ); interfacenames = pcap_lookupdev(errorbuf); logadapternames( interfacenames, errorbuf ); /* This is where the service does its work. */ ReadServiceCommandLineParams( &iArgCounter, &argvDynamic ); SnortMain( iArgCounter+1, argvDynamic ); /* Cleanup now */ for( i=0; i<=iArgCounter; i++ ) { free( argvDynamic[i] ); argvDynamic[i] = NULL; } free( argvDynamic ); argvDynamic = NULL; SvcDebugOut(" [SNORT_SERVICE] Returning the Main Thread \n",0); return; } /* Stub initialization function. */DWORD SnortServiceInitialization(DWORD argc, LPTSTR *argv, DWORD *pdwSpecificError) { argv; argc; pdwSpecificError; return(0); } /******************************************************************************* * (This documentation was taken from Microsoft's own doc's on how to create * a Win32 Service.) * * Writing a Control Handler Function * ----------------------------------------------------------------------------- * * The SnortServiceCtrlHandler function in the following example is the Handler * function. When this function is called by the dispatcher thread, it handles * the control code passed in the Opcode parameter and then calls the * SetServiceStatus function to update the service's status. Every time a * Handler function receives a control code, it is appropriate to return status * with a call to SetServiceStatus regardless of whether the service acts on * the control. * * When the pause control is received, SnortServiceCtrlHandler simply sets the * dwCurrentState field in the SERVICE_STATUS structure to SERVICE_PAUSED. * Likewise, when the continue control is received, the state is set to * SERVICE_RUNNING. Therefore, SnortServiceCtrlHandler is not a good example of * how to handle the pause and continue controls. Because SnortServiceCtrlHandler * is a template for a Handler function, code for the pause and continue * controls is included for completeness. A service that supports either the * pause or continue control should handle these controls in a way that makes * sense. Many services support neither the pause or continue control. If the * service indicates that it does not support pause or continue with the * dwControlsAccepted parameter, then the SCM will not send pause or continue * controls to the service's Handler function. * * To output debugging information, SnortServiceCtrlHandler calls SvcDebugOut. The * source code for SvcDebugOut is listed in Writing a Service Program's main * Function. Also, note that the g_SnortServiceStatus variable is a global variable * and should be initialized as demonstrated in Writing a ServiceMain function. *******************************************************************************/VOID WINAPI SnortServiceCtrlHandler (DWORD dwOpcode) { DWORD dwStatus; switch(dwOpcode) { case SERVICE_CONTROL_PAUSE: /* Do whatever it takes to pause here. */ pv.pause_service_flag = 1; g_SnortServiceStatus.dwCurrentState = SERVICE_PAUSED; break; case SERVICE_CONTROL_CONTINUE: /* Do whatever it takes to continue here. */ pv.pause_service_flag = 0; g_SnortServiceStatus.dwCurrentState = SERVICE_RUNNING; break; case SERVICE_CONTROL_STOP: /* Do whatever it takes to stop here. */ pv.terminate_service_flag = 1; Sleep( READ_TIMEOUT * 2 ); /* wait for 2x the timeout, just to ensure that things * the service has processed any last packets */ g_SnortServiceStatus.dwWin32ExitCode = 0; g_SnortServiceStatus.dwCurrentState = SERVICE_STOPPED; g_SnortServiceStatus.dwCheckPoint = 0; g_SnortServiceStatus.dwWaitHint = 0; if (!SetServiceStatus (g_SnortServiceStatusHandle, &g_SnortServiceStatus)) { dwStatus = GetLastError(); SvcDebugOut(" [SNORT_SERVICE] SetServiceStatus error %ld\n",dwStatus); } SvcDebugOut(" [SNORT_SERVICE] Leaving SnortService \n",0); return; case SERVICE_CONTROL_INTERROGATE: /* Fall through to send current status. */ break; default: SvcDebugOut(" [SNORT_SERVICE] Unrecognized opcode %ld\n", dwOpcode); } /* Send current status. */ if (!SetServiceStatus (g_SnortServiceStatusHandle, &g_SnortServiceStatus)) { dwStatus = GetLastError(); SvcDebugOut(" [SNORT_SERVICE] SetServiceStatus error %ld\n",dwStatus); } return; } /******************************************************************************* * (This documentation was taken from Microsoft's own doc's on how to create * a Win32 Service.) * * Installing a Service * ----------------------------------------------------------------------------- * * A service configuration program uses the CreateService function to install a * service in a SCM database. The application-defined schSCManager handle must * have SC_MANAGER_CREATE_SERVICE access to the SCManager object. The following * example shows how to install a service. *******************************************************************************/VOID InstallSnortService(int argc, char* argv[]) { SC_HANDLE schSCManager, schService; char buffer[_MAX_PATH+1]; LPCTSTR lpszBinaryPathName = NULL; HKEY hkSnort = NULL; long lRegRC = 0; int iArgCounter; DWORD dwWriteCounter = 0;#ifdef SET_SERVICE_DESCRIPTION SERVICE_DESCRIPTION sdBuf;#endif printf("\n\n"); printf(" [SNORT_SERVICE] Attempting to install the Snort service.\n"); /********** * Build up a string which stores the full path to the Snort executable. * This takes into account the current working directory, along with a * relative path to the Snort executable. **********/ memset( buffer, 0, sizeof(buffer) ); if( _getcwd( buffer, _MAX_PATH ) == NULL ) { TCHAR szMsg[1000]; SvcFormatMessage(szMsg, sizeof(szMsg)); FatalError(" [SNORT_SERVICE] Unable to determine current working directory. %s", szMsg); } if( buffer[strlen(buffer)-1] != '\\' ) { strcat(buffer, "\\"); } strcat(buffer, argv[0]); strcat(buffer, " "); strcat(buffer, SERVICE_CMDLINE_PARAM); lpszBinaryPathName = buffer; printf("\n"); printf(" [SNORT_SERVICE] The full path to the Snort binary appears to be:\n"); printf(" %s\n", lpszBinaryPathName); /********** * Create the registry entries for Snort command line parameters **********/ lRegRC = RegCreateKeyEx( HKEY_LOCAL_MACHINE, /* handle to open key */ g_lpszRegistryKey, /* subkey name */ 0, /* reserved (must be zero) */ NULL, /* class string */ REG_OPTION_NON_VOLATILE, /* special options */ KEY_ALL_ACCESS, /* desired security access */ NULL, /* inheritance */ &hkSnort, /* key handle */ NULL /* disposition value buffer */ ); if( lRegRC != ERROR_SUCCESS ) { TCHAR szMsg[1000]; SvcFormatMessage(szMsg, sizeof(szMsg)); FatalError(" [SNORT_SERVICE] Unable to create Snort registry entry. %s", szMsg); } for( iArgCounter=1; iArgCounter<argc; iArgCounter++ ) { /* ignore the Service command line parameters (/SERVICE, /INSTALL, /UNINSTALL) * and store all others in the registry */ if( ( _stricmp(argv[iArgCounter],SERVICE_CMDLINE_PARAM) == 0 ) || ( _stricmp(argv[iArgCounter],SERVICE_INSTALL_CMDLINE_PARAM) == 0 ) || ( _stricmp(argv[iArgCounter],SERVICE_UNINSTALL_CMDLINE_PARAM) == 0 ) ) { /* ignore it, because it isn't a real Snort command-line parameter */ } else if( strlen(argv[iArgCounter]) > MAX_REGISTRY_DATA_LENGTH ) { FatalError(" [SNORT_SERVICE] A single command line parameter cannot exceed %d characters.", MAX_REGISTRY_DATA_LENGTH); }
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -