00001 /* 00002 * Copyright (c) 2002 - 2003 00003 * NetGroup, Politecnico di Torino (Italy) 00004 * All rights reserved. 00005 * 00006 * Redistribution and use in source and binary forms, with or without 00007 * modification, are permitted provided that the following conditions 00008 * are met: 00009 * 00010 * 1. Redistributions of source code must retain the above copyright 00011 * notice, this list of conditions and the following disclaimer. 00012 * 2. Redistributions in binary form must reproduce the above copyright 00013 * notice, this list of conditions and the following disclaimer in the 00014 * documentation and/or other materials provided with the distribution. 00015 * 3. Neither the name of the Politecnico di Torino nor the names of its 00016 * contributors may be used to endorse or promote products derived from 00017 * this software without specific prior written permission. 00018 * 00019 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 00020 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 00021 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 00022 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 00023 * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 00024 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 00025 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 00026 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 00027 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 00028 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 00029 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 00030 * 00031 */ 00032 00033 00034 #include "rpcapd.h" 00035 #include <signal.h> 00036 #define _WINSOCKAPI_ 00037 #include "windows.h" 00038 #include <pcap.h> // for PCAP_ERRBUF_SIZE 00039 #include "sockutils.h" // for SOCK_ASSERT 00040 #include "fileconf.h" 00041 00042 00043 SERVICE_STATUS_HANDLE service_status_handle; 00044 SERVICE_STATUS service_status; 00045 00046 00047 void svc_geterr(char *str); 00048 void WINAPI svc_main(DWORD argc, char **argv); 00049 00050 00051 00052 int svc_start(void) 00053 { 00054 int rc; 00055 SERVICE_TABLE_ENTRY ste[] = 00056 { 00057 { PROGRAM_NAME, svc_main }, 00058 { NULL, NULL } 00059 }; 00060 00061 // This call is blocking. A new thread is created which will launch 00062 // the svc_main() function 00063 if ( (rc = StartServiceCtrlDispatcher(ste)) == 0) 00064 svc_geterr("StartServiceCtrlDispatcher()"); 00065 00066 return rc; // FALSE if this is not started as a service 00067 } 00068 00069 00070 void svc_geterr(char *str) 00071 { 00072 char message[PCAP_ERRBUF_SIZE]; 00073 char string[PCAP_ERRBUF_SIZE]; 00074 int val; 00075 00076 val= GetLastError(); 00077 FormatMessage(FORMAT_MESSAGE_FROM_SYSTEM | FORMAT_MESSAGE_IGNORE_INSERTS | 00078 FORMAT_MESSAGE_MAX_WIDTH_MASK, 00079 NULL, val, MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), 00080 (LPSTR) string, PCAP_ERRBUF_SIZE, NULL); 00081 00082 snprintf(message, PCAP_ERRBUF_SIZE, "%s failed with error %d: %s", str, val, string); 00083 00084 SOCK_ASSERT(message, 1); 00085 } 00086 00087 00088 00089 void WINAPI svc_control_handler(DWORD Opcode) 00090 { 00091 service_status.dwWin32ExitCode= 0; 00092 service_status.dwCheckPoint= 0; 00093 service_status.dwWaitHint= 0; 00094 00095 switch(Opcode) 00096 { 00097 case SERVICE_CONTROL_STOP: 00098 service_status.dwCurrentState= SERVICE_STOPPED; 00099 00100 /* 00101 Uses ABORT to clean up the service. To be really honest, only the main socket and 00102 such these stuffs are cleared; however the thread which are running are not stopped. 00103 This can be seen by placing a breakpoint at the end of svc_main(), in which you will 00104 see that is never reached. However, as soon as you set the service status to "stopped", 00105 the StartServiceCtrlDispatcher() returns and the main thread ends. Then, Win32 has a good 00106 authomatic cleanup, so that all the threads which are still running are stopped 00107 when the main thread ends. 00108 */ 00109 raise(SIGABRT); 00110 00111 SetServiceStatus(service_status_handle, &service_status); 00112 break; 00113 00114 /* 00115 Pause and Continue have an usual meaning and they are used just to be able 00116 to change the running parameters at run-time. In other words, they act 00117 like the SIGHUP signal on UNIX. All the running threads continue to run and 00118 they are not paused at all. 00119 Particularly, 00120 - PAUSE does nothing 00121 - CONTINUE re-reads the configuration file and creates the new threads that 00122 can be needed according to the new configuration. 00123 */ 00124 case SERVICE_CONTROL_PAUSE: 00125 service_status.dwCurrentState= SERVICE_PAUSED; 00126 SetServiceStatus(service_status_handle, &service_status); 00127 break; 00128 00129 case SERVICE_CONTROL_CONTINUE: 00130 service_status.dwCurrentState= SERVICE_RUNNING; 00131 SetServiceStatus(service_status_handle, &service_status); 00132 fileconf_read(0); 00133 break; 00134 00135 case SERVICE_CONTROL_INTERROGATE: 00136 // Fall through to send current status. 00137 // WARNING: not implemented 00138 SetServiceStatus(service_status_handle, &service_status); 00139 MessageBox(NULL, "Not implemented", "warning", MB_OK); 00140 break; 00141 } 00142 00143 // Send current status. 00144 return; 00145 } 00146 00147 00148 00149 void WINAPI svc_main(DWORD argc, char **argv) 00150 { 00151 service_status_handle = RegisterServiceCtrlHandler(PROGRAM_NAME, svc_control_handler); 00152 00153 if (!service_status_handle) 00154 return; 00155 00156 service_status.dwServiceType= SERVICE_WIN32_OWN_PROCESS | SERVICE_INTERACTIVE_PROCESS; 00157 service_status.dwCurrentState= SERVICE_RUNNING; 00158 service_status.dwControlsAccepted= SERVICE_ACCEPT_STOP | SERVICE_ACCEPT_PAUSE_CONTINUE; 00159 // | SERVICE_ACCEPT_SHUTDOWN ; 00160 service_status.dwWin32ExitCode= 0; 00161 service_status.dwServiceSpecificExitCode= 0; 00162 service_status.dwCheckPoint= 0; 00163 service_status.dwWaitHint= 0; 00164 00165 SetServiceStatus(service_status_handle, &service_status); 00166 00167 main_startup(); 00168 } 00169 00170 /* 00171 sc create rpcapd DisplayName= "Remote Packet Capture Protocol v.0 (experimental)" binpath= "C:\cvsroot\winpcap\wpcap\PRJ\Debug\rpcapd -d -f rpcapd.ini" 00172 sc description rpcapd "Allows to capture traffic on this host from a remote machine." 00173 */
documentation. Copyright (c) 2002-2003 Politecnico di Torino. All rights reserved.