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