xref: /aosp_15_r20/external/libpcap/rpcapd/win32-svc.c (revision 8b26181f966a6af5cf6981a6f474313de533bb28)
1*8b26181fSAndroid Build Coastguard Worker /*
2*8b26181fSAndroid Build Coastguard Worker  * Copyright (c) 2002 - 2003
3*8b26181fSAndroid Build Coastguard Worker  * NetGroup, Politecnico di Torino (Italy)
4*8b26181fSAndroid Build Coastguard Worker  * All rights reserved.
5*8b26181fSAndroid Build Coastguard Worker  *
6*8b26181fSAndroid Build Coastguard Worker  * Redistribution and use in source and binary forms, with or without
7*8b26181fSAndroid Build Coastguard Worker  * modification, are permitted provided that the following conditions
8*8b26181fSAndroid Build Coastguard Worker  * are met:
9*8b26181fSAndroid Build Coastguard Worker  *
10*8b26181fSAndroid Build Coastguard Worker  * 1. Redistributions of source code must retain the above copyright
11*8b26181fSAndroid Build Coastguard Worker  * notice, this list of conditions and the following disclaimer.
12*8b26181fSAndroid Build Coastguard Worker  * 2. Redistributions in binary form must reproduce the above copyright
13*8b26181fSAndroid Build Coastguard Worker  * notice, this list of conditions and the following disclaimer in the
14*8b26181fSAndroid Build Coastguard Worker  * documentation and/or other materials provided with the distribution.
15*8b26181fSAndroid Build Coastguard Worker  * 3. Neither the name of the Politecnico di Torino nor the names of its
16*8b26181fSAndroid Build Coastguard Worker  * contributors may be used to endorse or promote products derived from
17*8b26181fSAndroid Build Coastguard Worker  * this software without specific prior written permission.
18*8b26181fSAndroid Build Coastguard Worker  *
19*8b26181fSAndroid Build Coastguard Worker  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
20*8b26181fSAndroid Build Coastguard Worker  * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
21*8b26181fSAndroid Build Coastguard Worker  * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
22*8b26181fSAndroid Build Coastguard Worker  * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
23*8b26181fSAndroid Build Coastguard Worker  * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
24*8b26181fSAndroid Build Coastguard Worker  * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
25*8b26181fSAndroid Build Coastguard Worker  * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
26*8b26181fSAndroid Build Coastguard Worker  * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
27*8b26181fSAndroid Build Coastguard Worker  * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
28*8b26181fSAndroid Build Coastguard Worker  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
29*8b26181fSAndroid Build Coastguard Worker  * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
30*8b26181fSAndroid Build Coastguard Worker  *
31*8b26181fSAndroid Build Coastguard Worker  */
32*8b26181fSAndroid Build Coastguard Worker 
33*8b26181fSAndroid Build Coastguard Worker 
34*8b26181fSAndroid Build Coastguard Worker #include "rpcapd.h"
35*8b26181fSAndroid Build Coastguard Worker #include <pcap.h>		// for PCAP_ERRBUF_SIZE
36*8b26181fSAndroid Build Coastguard Worker #include "fmtutils.h"
37*8b26181fSAndroid Build Coastguard Worker #include "portability.h"
38*8b26181fSAndroid Build Coastguard Worker #include "fileconf.h"
39*8b26181fSAndroid Build Coastguard Worker #include "log.h"
40*8b26181fSAndroid Build Coastguard Worker 
41*8b26181fSAndroid Build Coastguard Worker #include "win32-svc.h"	// for Win32 service stuff
42*8b26181fSAndroid Build Coastguard Worker 
43*8b26181fSAndroid Build Coastguard Worker static SERVICE_STATUS_HANDLE service_status_handle;
44*8b26181fSAndroid Build Coastguard Worker static SERVICE_STATUS service_status;
45*8b26181fSAndroid Build Coastguard Worker 
46*8b26181fSAndroid Build Coastguard Worker static void WINAPI svc_main(DWORD argc, char **argv);
47*8b26181fSAndroid Build Coastguard Worker static void WINAPI svc_control_handler(DWORD Opcode);
48*8b26181fSAndroid Build Coastguard Worker static void update_svc_status(DWORD state, DWORD progress_indicator);
49*8b26181fSAndroid Build Coastguard Worker 
svc_start(void)50*8b26181fSAndroid Build Coastguard Worker BOOL svc_start(void)
51*8b26181fSAndroid Build Coastguard Worker {
52*8b26181fSAndroid Build Coastguard Worker 	BOOL rc;
53*8b26181fSAndroid Build Coastguard Worker 	SERVICE_TABLE_ENTRY ste[] =
54*8b26181fSAndroid Build Coastguard Worker 	{
55*8b26181fSAndroid Build Coastguard Worker 		{ PROGRAM_NAME, svc_main },
56*8b26181fSAndroid Build Coastguard Worker 		{ NULL, NULL }
57*8b26181fSAndroid Build Coastguard Worker 	};
58*8b26181fSAndroid Build Coastguard Worker 	char string[PCAP_ERRBUF_SIZE];
59*8b26181fSAndroid Build Coastguard Worker 
60*8b26181fSAndroid Build Coastguard Worker 	// This call is blocking. A new thread is created which will launch
61*8b26181fSAndroid Build Coastguard Worker 	// the svc_main() function
62*8b26181fSAndroid Build Coastguard Worker 	if ((rc = StartServiceCtrlDispatcher(ste)) == 0) {
63*8b26181fSAndroid Build Coastguard Worker 		pcap_fmt_errmsg_for_win32_err(string, sizeof (string),
64*8b26181fSAndroid Build Coastguard Worker 		    GetLastError(), "StartServiceCtrlDispatcher() failed");
65*8b26181fSAndroid Build Coastguard Worker 		rpcapd_log(LOGPRIO_ERROR, "%s", string);
66*8b26181fSAndroid Build Coastguard Worker 	}
67*8b26181fSAndroid Build Coastguard Worker 
68*8b26181fSAndroid Build Coastguard Worker 	return rc; // FALSE if this is not started as a service
69*8b26181fSAndroid Build Coastguard Worker }
70*8b26181fSAndroid Build Coastguard Worker 
71*8b26181fSAndroid Build Coastguard Worker static void WINAPI
svc_control_handler(DWORD Opcode)72*8b26181fSAndroid Build Coastguard Worker svc_control_handler(DWORD Opcode)
73*8b26181fSAndroid Build Coastguard Worker {
74*8b26181fSAndroid Build Coastguard Worker 	switch(Opcode)
75*8b26181fSAndroid Build Coastguard Worker 	{
76*8b26181fSAndroid Build Coastguard Worker 		case SERVICE_CONTROL_STOP:
77*8b26181fSAndroid Build Coastguard Worker 			//
78*8b26181fSAndroid Build Coastguard Worker 			// XXX - is this sufficient to clean up the service?
79*8b26181fSAndroid Build Coastguard Worker 			// To be really honest, only the main socket and
80*8b26181fSAndroid Build Coastguard Worker 			// such these stuffs are cleared; however the threads
81*8b26181fSAndroid Build Coastguard Worker 			// that are running are not stopped.
82*8b26181fSAndroid Build Coastguard Worker 			// This can be seen by placing a breakpoint at the
83*8b26181fSAndroid Build Coastguard Worker 			// end of svc_main(), in which you will see that is
84*8b26181fSAndroid Build Coastguard Worker 			// never reached. However, as soon as you set the
85*8b26181fSAndroid Build Coastguard Worker 			// service status to "stopped",	the
86*8b26181fSAndroid Build Coastguard Worker 			// StartServiceCtrlDispatcher() returns and the main
87*8b26181fSAndroid Build Coastguard Worker 			// thread ends. Then, Win32 has a good automatic
88*8b26181fSAndroid Build Coastguard Worker 			// cleanup, so that all the threads which are still
89*8b26181fSAndroid Build Coastguard Worker 			// running are stopped when the main thread ends.
90*8b26181fSAndroid Build Coastguard Worker 			//
91*8b26181fSAndroid Build Coastguard Worker 			send_shutdown_notification();
92*8b26181fSAndroid Build Coastguard Worker 
93*8b26181fSAndroid Build Coastguard Worker 			update_svc_status(SERVICE_STOP_PENDING, 0);
94*8b26181fSAndroid Build Coastguard Worker 			break;
95*8b26181fSAndroid Build Coastguard Worker 
96*8b26181fSAndroid Build Coastguard Worker 		/*
97*8b26181fSAndroid Build Coastguard Worker 			Pause and Continue have an usual meaning and they are used just to be able
98*8b26181fSAndroid Build Coastguard Worker 			to change the running parameters at run-time. In other words, they act
99*8b26181fSAndroid Build Coastguard Worker 			like the SIGHUP signal on UNIX. All the running threads continue to run and
100*8b26181fSAndroid Build Coastguard Worker 			they are not paused at all.
101*8b26181fSAndroid Build Coastguard Worker 			Particularly,
102*8b26181fSAndroid Build Coastguard Worker 			- PAUSE does nothing
103*8b26181fSAndroid Build Coastguard Worker 			- CONTINUE re-reads the configuration file and creates the new threads that
104*8b26181fSAndroid Build Coastguard Worker 			can be needed according to the new configuration.
105*8b26181fSAndroid Build Coastguard Worker 		*/
106*8b26181fSAndroid Build Coastguard Worker 		case SERVICE_CONTROL_PAUSE:
107*8b26181fSAndroid Build Coastguard Worker 			update_svc_status(SERVICE_PAUSED, 0);
108*8b26181fSAndroid Build Coastguard Worker 			break;
109*8b26181fSAndroid Build Coastguard Worker 
110*8b26181fSAndroid Build Coastguard Worker 		case SERVICE_CONTROL_CONTINUE:
111*8b26181fSAndroid Build Coastguard Worker 			update_svc_status(SERVICE_RUNNING, 0);
112*8b26181fSAndroid Build Coastguard Worker 			//
113*8b26181fSAndroid Build Coastguard Worker 			// Tell the main loop to re-read the configuration.
114*8b26181fSAndroid Build Coastguard Worker 			//
115*8b26181fSAndroid Build Coastguard Worker 			send_reread_configuration_notification();
116*8b26181fSAndroid Build Coastguard Worker 			break;
117*8b26181fSAndroid Build Coastguard Worker 
118*8b26181fSAndroid Build Coastguard Worker 		case SERVICE_CONTROL_INTERROGATE:
119*8b26181fSAndroid Build Coastguard Worker 			// Fall through to send current status.
120*8b26181fSAndroid Build Coastguard Worker 			//	WARNING: not implemented
121*8b26181fSAndroid Build Coastguard Worker 			update_svc_status(SERVICE_RUNNING, 0);
122*8b26181fSAndroid Build Coastguard Worker 			MessageBox(NULL, "Not implemented", "warning", MB_OK);
123*8b26181fSAndroid Build Coastguard Worker 			break;
124*8b26181fSAndroid Build Coastguard Worker 
125*8b26181fSAndroid Build Coastguard Worker 		case SERVICE_CONTROL_PARAMCHANGE:
126*8b26181fSAndroid Build Coastguard Worker 			//
127*8b26181fSAndroid Build Coastguard Worker 			// Tell the main loop to re-read the configuration.
128*8b26181fSAndroid Build Coastguard Worker 			//
129*8b26181fSAndroid Build Coastguard Worker 			send_reread_configuration_notification();
130*8b26181fSAndroid Build Coastguard Worker 			break;
131*8b26181fSAndroid Build Coastguard Worker 	}
132*8b26181fSAndroid Build Coastguard Worker 
133*8b26181fSAndroid Build Coastguard Worker 	// Send current status.
134*8b26181fSAndroid Build Coastguard Worker 	return;
135*8b26181fSAndroid Build Coastguard Worker }
136*8b26181fSAndroid Build Coastguard Worker 
137*8b26181fSAndroid Build Coastguard Worker static void WINAPI
svc_main(DWORD argc,char ** argv)138*8b26181fSAndroid Build Coastguard Worker svc_main(DWORD argc, char **argv)
139*8b26181fSAndroid Build Coastguard Worker {
140*8b26181fSAndroid Build Coastguard Worker 	service_status_handle = RegisterServiceCtrlHandler(PROGRAM_NAME, svc_control_handler);
141*8b26181fSAndroid Build Coastguard Worker 
142*8b26181fSAndroid Build Coastguard Worker 	if (!service_status_handle)
143*8b26181fSAndroid Build Coastguard Worker 		return;
144*8b26181fSAndroid Build Coastguard Worker 
145*8b26181fSAndroid Build Coastguard Worker 	service_status.dwServiceType = SERVICE_WIN32_OWN_PROCESS | SERVICE_INTERACTIVE_PROCESS;
146*8b26181fSAndroid Build Coastguard Worker 	service_status.dwControlsAccepted = SERVICE_ACCEPT_STOP | SERVICE_ACCEPT_PAUSE_CONTINUE | SERVICE_ACCEPT_PARAMCHANGE;
147*8b26181fSAndroid Build Coastguard Worker 	// | SERVICE_ACCEPT_SHUTDOWN ;
148*8b26181fSAndroid Build Coastguard Worker 	update_svc_status(SERVICE_RUNNING, 0);
149*8b26181fSAndroid Build Coastguard Worker 
150*8b26181fSAndroid Build Coastguard Worker 	//
151*8b26181fSAndroid Build Coastguard Worker 	// Service requests until we're told to stop.
152*8b26181fSAndroid Build Coastguard Worker 	//
153*8b26181fSAndroid Build Coastguard Worker 	main_startup();
154*8b26181fSAndroid Build Coastguard Worker 
155*8b26181fSAndroid Build Coastguard Worker 	//
156*8b26181fSAndroid Build Coastguard Worker 	// It returned, so we were told to stop.
157*8b26181fSAndroid Build Coastguard Worker 	//
158*8b26181fSAndroid Build Coastguard Worker 	update_svc_status(SERVICE_STOPPED, 0);
159*8b26181fSAndroid Build Coastguard Worker }
160*8b26181fSAndroid Build Coastguard Worker 
161*8b26181fSAndroid Build Coastguard Worker static void
update_svc_status(DWORD state,DWORD progress_indicator)162*8b26181fSAndroid Build Coastguard Worker update_svc_status(DWORD state, DWORD progress_indicator)
163*8b26181fSAndroid Build Coastguard Worker {
164*8b26181fSAndroid Build Coastguard Worker 	service_status.dwWin32ExitCode = NO_ERROR;
165*8b26181fSAndroid Build Coastguard Worker 	service_status.dwCurrentState = state;
166*8b26181fSAndroid Build Coastguard Worker 	service_status.dwCheckPoint = progress_indicator;
167*8b26181fSAndroid Build Coastguard Worker 	service_status.dwWaitHint = 0;
168*8b26181fSAndroid Build Coastguard Worker 	SetServiceStatus(service_status_handle, &service_status);
169*8b26181fSAndroid Build Coastguard Worker }
170*8b26181fSAndroid Build Coastguard Worker 
171*8b26181fSAndroid Build Coastguard Worker /*
172*8b26181fSAndroid Build Coastguard Worker sc create rpcapd DisplayName= "Remote Packet Capture Protocol v.0 (experimental)" binpath= "C:\cvsroot\winpcap\wpcap\PRJ\Debug\rpcapd -d -f rpcapd.ini"
173*8b26181fSAndroid Build Coastguard Worker sc description rpcapd "Allows to capture traffic on this host from a remote machine."
174*8b26181fSAndroid Build Coastguard Worker */
175