• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 #ifdef HAVE_CONFIG_H
33 #include <config.h>
34 #endif
35 
36 #include "ftmacros.h"
37 #include "varattrs.h"
38 
39 #include <errno.h>		// for the errno variable
40 #include <stdlib.h>		// for malloc(), free(), ...
41 #include <string.h>		// for strlen(), ...
42 
43 #ifdef _WIN32
44   #include <process.h>		// for threads
45 #else
46   #include <unistd.h>
47   #include <pthread.h>
48   #include <sys/time.h>
49   #include <sys/types.h>	// for select() and such
50   #include <pwd.h>		// for password management
51 #endif
52 
53 #ifdef HAVE_GETSPNAM
54 #include <shadow.h>		// for password management
55 #endif
56 
57 #include <pcap.h>		// for libpcap/WinPcap calls
58 
59 #include "fmtutils.h"
60 #include "sockutils.h"		// for socket calls
61 #include "portability.h"
62 #include "rpcap-protocol.h"
63 #include "daemon.h"
64 #include "log.h"
65 
66 #define RPCAP_TIMEOUT_INIT 90		/* Initial timeout for RPCAP connections (default: 90 sec) */
67 #define RPCAP_TIMEOUT_RUNTIME 180	/* Run-time timeout for RPCAP connections (default: 3 min) */
68 #define RPCAP_SUSPEND_WRONGAUTH 1	/* If the authentication is wrong, stops 1 sec before accepting a new auth message */
69 
70 // Parameters for the service loop.
71 struct daemon_slpars
72 {
73 	SOCKET sockctrl_in;	//!< SOCKET ID of the input side of the control connection
74 	SOCKET sockctrl_out;	//!< SOCKET ID of the output side of the control connection
75 	uint8 protocol_version;	//!< negotiated protocol version
76 	int isactive;		//!< Not null if the daemon has to run in active mode
77 	int nullAuthAllowed;	//!< '1' if we permit NULL authentication, '0' otherwise
78 };
79 
80 /*
81  * Data for a session managed by a thread.
82  */
83 struct session {
84 	SOCKET sockctrl_out;
85 	SOCKET sockdata;
86 	uint8 protocol_version;
87 	pcap_t *fp;
88 	unsigned int TotCapt;
89 };
90 
91 //
92 // Structure to refer to a thread.
93 // It includes both a Boolean indicating whether we *have* a thread,
94 // and a platform-dependent (UN*X vs. Windows) identifier for the
95 // thread; on Windows, we could use an invalid handle to indicate
96 // that we don't have a thread, but there *is* no portable "no thread"
97 // value for a pthread_t on UN*X.
98 //
99 struct thread_handle {
100 	int	have_thread;
101 #ifdef _WIN32
102 	HANDLE thread;
103 #else
104 	pthread_t thread;
105 #endif
106 };
107 
108 // Locally defined functions
109 static int daemon_msg_err(SOCKET sockctrl_in, uint32 plen);
110 static int daemon_msg_auth_req(struct daemon_slpars *pars, uint32 plen);
111 static int daemon_AuthUserPwd(char *username, char *password, char *errbuf);
112 
113 static int daemon_msg_findallif_req(struct daemon_slpars *pars, uint32 plen);
114 
115 static int daemon_msg_open_req(struct daemon_slpars *pars, uint32 plen, char *source, size_t sourcelen);
116 static int daemon_msg_startcap_req(struct daemon_slpars *pars, uint32 plen, struct thread_handle *threaddata, char *source, struct session **sessionp, struct rpcap_sampling *samp_param);
117 static int daemon_msg_endcap_req(struct daemon_slpars *pars, struct session *session, struct thread_handle *threaddata);
118 
119 static int daemon_msg_updatefilter_req(struct daemon_slpars *pars, struct session *session, uint32 plen);
120 static int daemon_unpackapplyfilter(SOCKET sockctrl_in, struct session *session, uint32 *plenp, char *errbuf);
121 
122 static int daemon_msg_stats_req(struct daemon_slpars *pars, struct session *session, uint32 plen, struct pcap_stat *stats, unsigned int svrcapt);
123 
124 static int daemon_msg_setsampling_req(struct daemon_slpars *pars, uint32 plen, struct rpcap_sampling *samp_param);
125 
126 static void daemon_seraddr(struct sockaddr_storage *sockaddrin, struct rpcap_sockaddr *sockaddrout);
127 #ifdef _WIN32
128 static unsigned __stdcall daemon_thrdatamain(void *ptr);
129 #else
130 static void *daemon_thrdatamain(void *ptr);
131 #endif
132 
133 static int rpcapd_recv_msg_header(SOCKET sock, struct rpcap_header *headerp);
134 static int rpcapd_recv(SOCKET sock, char *buffer, size_t toread, uint32 *plen, char *errmsgbuf);
135 static int rpcapd_discard(SOCKET sock, uint32 len);
136 
137 int
daemon_serviceloop(SOCKET sockctrl_in,SOCKET sockctrl_out,int isactive,int nullAuthAllowed)138 daemon_serviceloop(SOCKET sockctrl_in, SOCKET sockctrl_out, int isactive, int nullAuthAllowed)
139 {
140 	struct daemon_slpars pars;		// service loop parameters
141 	char errbuf[PCAP_ERRBUF_SIZE + 1];	// keeps the error string, prior to be printed
142 	char errmsgbuf[PCAP_ERRBUF_SIZE + 1];	// buffer for errors to send to the client
143 	int nrecv;
144 	struct rpcap_header header;		// RPCAP message general header
145 	uint32 plen;				// payload length from header
146 	int authenticated = 0;			// 1 if the client has successfully authenticated
147 	char source[PCAP_BUF_SIZE+1];		// keeps the string that contains the interface to open
148 	int got_source = 0;			// 1 if we've gotten the source from an open request
149 	struct session *session = NULL;		// struct session main variable
150 	const char *msg_type_string;		// string for message type
151 	int client_told_us_to_close = 0;	// 1 if the client told us to close the capture
152 
153 	struct thread_handle threaddata;	// 'read from daemon and send to client' thread
154 
155 	// needed to save the values of the statistics
156 	struct pcap_stat stats;
157 	unsigned int svrcapt;
158 
159 	struct rpcap_sampling samp_param;	// in case sampling has been requested
160 
161 	// Structures needed for the select() call
162 	fd_set rfds;				// set of socket descriptors we have to check
163 	struct timeval tv;			// maximum time the select() can block waiting for data
164 	int retval;				// select() return value
165 
166 	// Set parameters structure
167 	pars.sockctrl_in = sockctrl_in;
168 	pars.sockctrl_out = sockctrl_out;
169 	pars.protocol_version = 0;		// not yet known
170 	pars.isactive = isactive;		// active mode
171 	pars.nullAuthAllowed = nullAuthAllowed;
172 
173 	// We don't have a thread yet.
174 	threaddata.have_thread = 0;
175 	//
176 	// We *shouldn't* have to initialize the thread indicator
177 	// itself, because the compiler *should* realize that we
178 	// only use this if have_thread isn't 0, but we *do* have
179 	// to do it, because not all compilers *do* realize that.
180 	//
181 	// There is no "invalid thread handle" value for a UN*X
182 	// pthread_t, so we just zero it out.
183 	//
184 #ifdef _WIN32
185 	threaddata.thread = INVALID_HANDLE_VALUE;
186 #else
187 	memset(&threaddata.thread, 0, sizeof(threaddata.thread));
188 #endif
189 
190 	*errbuf = 0;	// Initialize errbuf
191 
192 	//
193 	// The client must first authenticate; loop until they send us a
194 	// message with a version we support and credentials we accept,
195 	// they send us a close message indicating that they're giving up,
196 	// or we get a network error or other fatal error.
197 	//
198 	while (!authenticated)
199 	{
200 		//
201 		// If we're in active mode, we have to check for the
202 		// initial timeout.
203 		//
204 		// XXX - do this on *every* trip through the loop?
205 		//
206 		if (!pars.isactive)
207 		{
208 			FD_ZERO(&rfds);
209 			// We do not have to block here
210 			tv.tv_sec = RPCAP_TIMEOUT_INIT;
211 			tv.tv_usec = 0;
212 
213 			FD_SET(pars.sockctrl_in, &rfds);
214 
215 			retval = select(pars.sockctrl_in + 1, &rfds, NULL, NULL, &tv);
216 			if (retval == -1)
217 			{
218 				sock_geterror("select failed: ", errmsgbuf, PCAP_ERRBUF_SIZE);
219 				if (rpcap_senderror(pars.sockctrl_out, 0, PCAP_ERR_NETW, errmsgbuf, errbuf) == -1)
220 					rpcapd_log(LOGPRIO_ERROR, "Send to client failed: %s", errbuf);
221 				goto end;
222 			}
223 
224 			// The timeout has expired
225 			// So, this was a fake connection. Drop it down
226 			if (retval == 0)
227 			{
228 				if (rpcap_senderror(pars.sockctrl_out, 0, PCAP_ERR_INITTIMEOUT, "The RPCAP initial timeout has expired", errbuf) == -1)
229 					rpcapd_log(LOGPRIO_ERROR, "Send to client failed: %s", errbuf);
230 				goto end;
231 			}
232 		}
233 
234 		//
235 		// Read the message header from the client.
236 		//
237 		nrecv = rpcapd_recv_msg_header(pars.sockctrl_in, &header);
238 		if (nrecv == -1)
239 		{
240 			// Fatal error.
241 			goto end;
242 		}
243 		if (nrecv == -2)
244 		{
245 			// Client closed the connection.
246 			goto end;
247 		}
248 
249 		plen = header.plen;
250 
251 		//
252 		// Did the client specify a version we can handle?
253 		//
254 		if (!RPCAP_VERSION_IS_SUPPORTED(header.ver))
255 		{
256 			//
257 			// Tell them it's not a valid protocol version.
258 			//
259 			uint8 reply_version;
260 
261 			//
262 			// If RPCAP_MIN_VERSION is 0, no version is too
263 			// old, as the oldest supported version is 0,
264 			// and there are no negative versions.
265 			//
266 #if RPCAP_MIN_VERSION != 0
267 			if (header.ver < RPCAP_MIN_VERSION)
268 			{
269 				//
270 				// Their maximum version is too old;
271 				// there *is* no version we can both
272 				// handle, and they might reject
273 				// an error with a version they don't
274 				// understand, so reply with the
275 				// version they sent.  That may
276 				// make them retry with that version,
277 				// but they'll give up on that
278 				// failure.
279 				//
280 				reply_version = header.ver;
281 			}
282 			else
283 #endif
284 			{
285 				//
286 				// Their maximum version is too new,
287 				// but they might be able to handle
288 				// *our* maximum version, so reply
289 				// with that version.
290 				//
291 				reply_version = RPCAP_MAX_VERSION;
292 			}
293 			if (rpcap_senderror(pars.sockctrl_out, reply_version,
294 			    PCAP_ERR_WRONGVER, "RPCAP version number mismatch",
295 			    errbuf) == -1)
296 			{
297 				// That failed; log a message and give up.
298 				rpcapd_log(LOGPRIO_ERROR, "Send to client failed: %s", errbuf);
299 				goto end;
300 			}
301 
302 			// Discard the rest of the message.
303 			if (rpcapd_discard(pars.sockctrl_in, plen) == -1)
304 			{
305 				// Network error.
306 				goto end;
307 			}
308 
309 			// Let them try again.
310 			continue;
311 		}
312 
313 		//
314 		// OK, we use the version the client specified.
315 		//
316 		pars.protocol_version = header.ver;
317 
318 		switch (header.type)
319 		{
320 			case RPCAP_MSG_AUTH_REQ:
321 				retval = daemon_msg_auth_req(&pars, plen);
322 				if (retval == -1)
323 				{
324 					// Fatal error; a message has
325 					// been logged, so just give up.
326 					goto end;
327 				}
328 				if (retval == -2)
329 				{
330 					// Non-fatal error; we sent back
331 					// an error message, so let them
332 					// try again.
333 					continue;
334 				}
335 
336 				// OK, we're authenticated; we sent back
337 				// a reply, so start serving requests.
338 				authenticated = 1;
339 				break;
340 
341 			case RPCAP_MSG_CLOSE:
342 				//
343 				// The client is giving up.
344 				// Discard the rest of the message, if
345 				// there is anything more.
346 				//
347 				(void)rpcapd_discard(pars.sockctrl_in, plen);
348 				// We're done with this client.
349 				goto end;
350 
351 			case RPCAP_MSG_ERROR:
352 				// Log this and close the connection?
353 				// XXX - is this what happens in active
354 				// mode, where *we* initiate the
355 				// connection, and the client gives us
356 				// an error message rather than a "let
357 				// me log in" message, indicating that
358 				// we're not allowed to connect to them?
359 				(void)daemon_msg_err(pars.sockctrl_in, plen);
360 				goto end;
361 
362 			case RPCAP_MSG_FINDALLIF_REQ:
363 			case RPCAP_MSG_OPEN_REQ:
364 			case RPCAP_MSG_STARTCAP_REQ:
365 			case RPCAP_MSG_UPDATEFILTER_REQ:
366 			case RPCAP_MSG_STATS_REQ:
367 			case RPCAP_MSG_ENDCAP_REQ:
368 			case RPCAP_MSG_SETSAMPLING_REQ:
369 				//
370 				// These requests can't be sent until
371 				// the client is authenticated.
372 				//
373 				msg_type_string = rpcap_msg_type_string(header.type);
374 				if (msg_type_string != NULL)
375 				{
376 					pcap_snprintf(errmsgbuf, PCAP_ERRBUF_SIZE, "%s request sent before authentication was completed", msg_type_string);
377 				}
378 				else
379 				{
380 					pcap_snprintf(errmsgbuf, PCAP_ERRBUF_SIZE, "Message of type %u sent before authentication was completed", header.type);
381 				}
382 				if (rpcap_senderror(pars.sockctrl_out,
383 				    pars.protocol_version, PCAP_ERR_WRONGMSG,
384 				    errmsgbuf, errbuf) == -1)
385 				{
386 					rpcapd_log(LOGPRIO_ERROR, "Send to client failed: %s", errbuf);
387 					goto end;
388 				}
389 				// Discard the rest of the message.
390 				if (rpcapd_discard(pars.sockctrl_in, plen) == -1)
391 				{
392 					// Network error.
393 					goto end;
394 				}
395 				break;
396 
397 			case RPCAP_MSG_PACKET:
398 			case RPCAP_MSG_FINDALLIF_REPLY:
399 			case RPCAP_MSG_OPEN_REPLY:
400 			case RPCAP_MSG_STARTCAP_REPLY:
401 			case RPCAP_MSG_UPDATEFILTER_REPLY:
402 			case RPCAP_MSG_AUTH_REPLY:
403 			case RPCAP_MSG_STATS_REPLY:
404 			case RPCAP_MSG_ENDCAP_REPLY:
405 			case RPCAP_MSG_SETSAMPLING_REPLY:
406 				//
407 				// These are server-to-client messages.
408 				//
409 				msg_type_string = rpcap_msg_type_string(header.type);
410 				if (msg_type_string != NULL)
411 				{
412 					pcap_snprintf(errmsgbuf, PCAP_ERRBUF_SIZE, "Server-to-client message %s received from client", msg_type_string);
413 				}
414 				else
415 				{
416 					pcap_snprintf(errmsgbuf, PCAP_ERRBUF_SIZE, "Server-to-client message of type %u received from client", header.type);
417 				}
418 				if (rpcap_senderror(pars.sockctrl_out,
419 				    pars.protocol_version, PCAP_ERR_WRONGMSG,
420 				    errmsgbuf, errbuf) == -1)
421 				{
422 					rpcapd_log(LOGPRIO_ERROR, "Send to client failed: %s", errbuf);
423 					goto end;
424 				}
425 				// Discard the rest of the message.
426 				if (rpcapd_discard(pars.sockctrl_in, plen) == -1)
427 				{
428 					// Fatal error.
429 					goto end;
430 				}
431 				break;
432 
433 			default:
434 				//
435 				// Unknown message type.
436 				//
437 				pcap_snprintf(errmsgbuf, PCAP_ERRBUF_SIZE, "Unknown message type %u", header.type);
438 				if (rpcap_senderror(pars.sockctrl_out,
439 				    pars.protocol_version, PCAP_ERR_WRONGMSG,
440 				    errmsgbuf, errbuf) == -1)
441 				{
442 					rpcapd_log(LOGPRIO_ERROR, "Send to client failed: %s", errbuf);
443 					goto end;
444 				}
445 				// Discard the rest of the message.
446 				if (rpcapd_discard(pars.sockctrl_in, plen) == -1)
447 				{
448 					// Fatal error.
449 					goto end;
450 				}
451 				break;
452 		}
453 	}
454 
455 	//
456 	// OK, the client has authenticated itself, and we can start
457 	// processing regular requests from it.
458 	//
459 
460 	//
461 	// We don't have any statistics yet.
462 	//
463 	stats.ps_ifdrop = 0;
464 	stats.ps_recv = 0;
465 	stats.ps_drop = 0;
466 	svrcapt = 0;
467 
468 	//
469 	// Service requests.
470 	//
471 	for (;;)
472 	{
473 		errbuf[0] = 0;	// clear errbuf
474 
475 		// Avoid zombies connections; check if the connection is opens but no commands are performed
476 		// from more than RPCAP_TIMEOUT_RUNTIME
477 		// Conditions:
478 		// - I have to be in normal mode (no active mode)
479 		// - if the device is open, I don't have to be in the middle of a capture (session->sockdata)
480 		// - if the device is closed, I have always to check if a new command arrives
481 		//
482 		// Be carefully: the capture can have been started, but an error occurred (so session != NULL, but
483 		//  sockdata is 0
484 		if ((!pars.isactive) &&  ((session == NULL) || ((session != NULL) && (session->sockdata == 0))))
485 		{
486 			// Check for the initial timeout
487 			FD_ZERO(&rfds);
488 			// We do not have to block here
489 			tv.tv_sec = RPCAP_TIMEOUT_RUNTIME;
490 			tv.tv_usec = 0;
491 
492 			FD_SET(pars.sockctrl_in, &rfds);
493 
494 			retval = select(pars.sockctrl_in + 1, &rfds, NULL, NULL, &tv);
495 			if (retval == -1)
496 			{
497 				sock_geterror("select failed: ", errmsgbuf, PCAP_ERRBUF_SIZE);
498 				if (rpcap_senderror(pars.sockctrl_out,
499 				    pars.protocol_version, PCAP_ERR_NETW,
500 				    errmsgbuf, errbuf) == -1)
501 					rpcapd_log(LOGPRIO_ERROR, "Send to client failed: %s", errbuf);
502 				goto end;
503 			}
504 
505 			// The timeout has expired
506 			// So, this was a fake connection. Drop it down
507 			if (retval == 0)
508 			{
509 				if (rpcap_senderror(pars.sockctrl_out,
510 				    pars.protocol_version,
511 				    PCAP_ERR_INITTIMEOUT,
512 				    "The RPCAP initial timeout has expired",
513 				    errbuf) == -1)
514 					rpcapd_log(LOGPRIO_ERROR, "Send to client failed: %s", errbuf);
515 				goto end;
516 			}
517 		}
518 
519 		//
520 		// Read the message header from the client.
521 		//
522 		nrecv = rpcapd_recv_msg_header(pars.sockctrl_in, &header);
523 		if (nrecv == -1)
524 		{
525 			// Fatal error.
526 			goto end;
527 		}
528 		if (nrecv == -2)
529 		{
530 			// Client closed the connection.
531 			goto end;
532 		}
533 
534 		plen = header.plen;
535 
536 		//
537 		// Did the client specify the version we negotiated?
538 		//
539 		// For now, there's only one version.
540 		//
541 		if (header.ver != pars.protocol_version)
542 		{
543 			//
544 			// Tell them it's not the negotiated version.
545 			// Send the error message with their version,
546 			// so they don't reject it as having the wrong
547 			// version.
548 			//
549 			if (rpcap_senderror(pars.sockctrl_out,
550 			    header.ver, PCAP_ERR_WRONGVER,
551 			    "RPCAP version in message isn't the negotiated version",
552 			    errbuf) == -1)
553 			{
554 				// That failed; log a message and give up.
555 				rpcapd_log(LOGPRIO_ERROR, "Send to client failed: %s", errbuf);
556 				goto end;
557 			}
558 
559 			// Discard the rest of the message.
560 			(void)rpcapd_discard(pars.sockctrl_in, plen);
561 			// Give up on them.
562 			goto end;
563 		}
564 
565 		switch (header.type)
566 		{
567 			case RPCAP_MSG_ERROR:		// The other endpoint reported an error
568 			{
569 				(void)daemon_msg_err(pars.sockctrl_in, plen);
570 				// Do nothing; just exit; the error code is already into the errbuf
571 				// XXX - actually exit....
572 				break;
573 			}
574 
575 			case RPCAP_MSG_FINDALLIF_REQ:
576 			{
577 				if (daemon_msg_findallif_req(&pars, plen) == -1)
578 				{
579 					// Fatal error; a message has
580 					// been logged, so just give up.
581 					goto end;
582 				}
583 				break;
584 			}
585 
586 			case RPCAP_MSG_OPEN_REQ:
587 			{
588 				//
589 				// Process the open request, and keep
590 				// the source from it, for use later
591 				// when the capture is started.
592 				//
593 				// XXX - we don't care if the client sends
594 				// us multiple open requests, the last
595 				// one wins.
596 				//
597 				retval = daemon_msg_open_req(&pars, plen, source, sizeof(source));
598 				if (retval == -1)
599 				{
600 					// Fatal error; a message has
601 					// been logged, so just give up.
602 					goto end;
603 				}
604 				got_source = 1;
605 				break;
606 			}
607 
608 			case RPCAP_MSG_STARTCAP_REQ:
609 			{
610 				if (!got_source)
611 				{
612 					// They never told us what device
613 					// to capture on!
614 					if (rpcap_senderror(pars.sockctrl_out,
615 					    pars.protocol_version,
616 					    PCAP_ERR_STARTCAPTURE,
617 					    "No capture device was specified",
618 					    errbuf) == -1)
619 					{
620 						// Fatal error; log an
621 						// error and  give up.
622 						rpcapd_log(LOGPRIO_ERROR, "Send to client failed: %s", errbuf);
623 						goto end;
624 					}
625 					if (rpcapd_discard(pars.sockctrl_in, plen) == -1)
626 					{
627 						goto end;
628 					}
629 					break;
630 				}
631 
632 				if (daemon_msg_startcap_req(&pars, plen, &threaddata, source, &session, &samp_param) == -1)
633 				{
634 					// Fatal error; a message has
635 					// been logged, so just give up.
636 					goto end;
637 				}
638 				break;
639 			}
640 
641 			case RPCAP_MSG_UPDATEFILTER_REQ:
642 			{
643 				if (session)
644 				{
645 					if (daemon_msg_updatefilter_req(&pars, session, plen) == -1)
646 					{
647 						// Fatal error; a message has
648 						// been logged, so just give up.
649 						goto end;
650 					}
651 				}
652 				else
653 				{
654 					if (rpcap_senderror(pars.sockctrl_out,
655 					    pars.protocol_version,
656 					    PCAP_ERR_UPDATEFILTER,
657 					    "Device not opened. Cannot update filter",
658 					    errbuf) == -1)
659 					{
660 						// That failed; log a message and give up.
661 						rpcapd_log(LOGPRIO_ERROR, "Send to client failed: %s", errbuf);
662 						goto end;
663 					}
664 				}
665 				break;
666 			}
667 
668 			case RPCAP_MSG_CLOSE:		// The other endpoint close the pcap session
669 			{
670 				//
671 				// Indicate to our caller that the client
672 				// closed the control connection.
673 				// This is used only in case of active mode.
674 				//
675 				client_told_us_to_close = 1;
676 				SOCK_DEBUG_MESSAGE("The other end system asked to close the connection.");
677 				goto end;
678 			}
679 
680 			case RPCAP_MSG_STATS_REQ:
681 			{
682 				if (daemon_msg_stats_req(&pars, session, plen, &stats, svrcapt) == -1)
683 				{
684 					// Fatal error; a message has
685 					// been logged, so just give up.
686 					goto end;
687 				}
688 				break;
689 			}
690 
691 			case RPCAP_MSG_ENDCAP_REQ:		// The other endpoint close the current capture session
692 			{
693 				if (session)
694 				{
695 					// Save statistics (we can need them in the future)
696 					if (pcap_stats(session->fp, &stats))
697 					{
698 						svrcapt = session->TotCapt;
699 					}
700 					else
701 					{
702 						stats.ps_ifdrop = 0;
703 						stats.ps_recv = 0;
704 						stats.ps_drop = 0;
705 						svrcapt = 0;
706 					}
707 
708 					if (daemon_msg_endcap_req(&pars, session, &threaddata) == -1)
709 					{
710 						free(session);
711 						session = NULL;
712 						// Fatal error; a message has
713 						// been logged, so just give up.
714 						goto end;
715 					}
716 					free(session);
717 					session = NULL;
718 				}
719 				else
720 				{
721 					rpcap_senderror(pars.sockctrl_out,
722 					    pars.protocol_version,
723 					    PCAP_ERR_ENDCAPTURE,
724 					    "Device not opened. Cannot close the capture",
725 					    errbuf);
726 				}
727 				break;
728 			}
729 
730 			case RPCAP_MSG_SETSAMPLING_REQ:
731 			{
732 				if (daemon_msg_setsampling_req(&pars, plen, &samp_param) == -1)
733 				{
734 					// Fatal error; a message has
735 					// been logged, so just give up.
736 					goto end;
737 				}
738 				break;
739 			}
740 
741 			case RPCAP_MSG_AUTH_REQ:
742 			{
743 				//
744 				// We're already authenticated; you don't
745 				// get to reauthenticate.
746 				//
747 				rpcapd_log(LOGPRIO_INFO, "The client sent an RPCAP_MSG_AUTH_REQ message after authentication was completed");
748 				if (rpcap_senderror(pars.sockctrl_out,
749 				    pars.protocol_version,
750 				    PCAP_ERR_WRONGMSG,
751 				    "RPCAP_MSG_AUTH_REQ request sent after authentication was completed",
752 				    errbuf) == -1)
753 				{
754 					rpcapd_log(LOGPRIO_ERROR, "Send to client failed: %s", errbuf);
755 					goto end;
756 				}
757 				// Discard the rest of the message.
758 				if (rpcapd_discard(pars.sockctrl_in, plen) == -1)
759 				{
760 					// Fatal error.
761 					goto end;
762 				}
763 				goto end;
764 
765 			case RPCAP_MSG_PACKET:
766 			case RPCAP_MSG_FINDALLIF_REPLY:
767 			case RPCAP_MSG_OPEN_REPLY:
768 			case RPCAP_MSG_STARTCAP_REPLY:
769 			case RPCAP_MSG_UPDATEFILTER_REPLY:
770 			case RPCAP_MSG_AUTH_REPLY:
771 			case RPCAP_MSG_STATS_REPLY:
772 			case RPCAP_MSG_ENDCAP_REPLY:
773 			case RPCAP_MSG_SETSAMPLING_REPLY:
774 				//
775 				// These are server-to-client messages.
776 				//
777 				msg_type_string = rpcap_msg_type_string(header.type);
778 				if (msg_type_string != NULL)
779 				{
780 					rpcapd_log(LOGPRIO_INFO, "The client sent a %s server-to-client message", msg_type_string);
781 					pcap_snprintf(errmsgbuf, PCAP_ERRBUF_SIZE, "Server-to-client message %s received from client", msg_type_string);
782 				}
783 				else
784 				{
785 					rpcapd_log(LOGPRIO_INFO, "The client sent a server-to-client message of type %u", header.type);
786 					pcap_snprintf(errmsgbuf, PCAP_ERRBUF_SIZE, "Server-to-client message of type %u received from client", header.type);
787 				}
788 				if (rpcap_senderror(pars.sockctrl_out,
789 				    pars.protocol_version, PCAP_ERR_WRONGMSG,
790 				    errmsgbuf, errbuf) == -1)
791 				{
792 					rpcapd_log(LOGPRIO_ERROR, "Send to client failed: %s", errbuf);
793 					goto end;
794 				}
795 				// Discard the rest of the message.
796 				if (rpcapd_discard(pars.sockctrl_in, plen) == -1)
797 				{
798 					// Fatal error.
799 					goto end;
800 				}
801 				goto end;
802 
803 			default:
804 				//
805 				// Unknown message type.
806 				//
807 				rpcapd_log(LOGPRIO_INFO, "The client sent a message of type %u", header.type);
808 				pcap_snprintf(errmsgbuf, PCAP_ERRBUF_SIZE, "Unknown message type %u", header.type);
809 				if (rpcap_senderror(pars.sockctrl_out,
810 				    pars.protocol_version, PCAP_ERR_WRONGMSG,
811 				    errbuf, errmsgbuf) == -1)
812 				{
813 					rpcapd_log(LOGPRIO_ERROR, "Send to client failed: %s", errbuf);
814 					goto end;
815 				}
816 				// Discard the rest of the message.
817 				if (rpcapd_discard(pars.sockctrl_in, plen) == -1)
818 				{
819 					// Fatal error.
820 					goto end;
821 				}
822 				goto end;
823 			}
824 		}
825 	}
826 
827 end:
828 	// The child thread is about to end
829 
830 	// perform pcap_t cleanup, in case it has not been done
831 	if (session)
832 	{
833 		if (threaddata.have_thread)
834 		{
835 #ifdef _WIN32
836 			//
837 			// Tell the data connection thread main capture
838 			// loop to break out of that loop.
839 			//
840 			pcap_breakloop(session->fp);
841 
842 			//
843 			// If it's currently blocked waiting for packets
844 			// to arrive, try to wake it up, so it can see
845 			// the "break out of the loop" indication.
846 			//
847 			SetEvent(pcap_getevent(session->fp));
848 
849 			//
850 			// Wait for the thread to exit, so we don't close
851 			// sockets out from under it.
852 			//
853 			// XXX - have a timeout, so we don't wait forever?
854 			//
855 			WaitForSingleObject(threaddata.thread, INFINITE);
856 
857 			//
858 			// Release the thread handle, as we're done with
859 			// it.
860 			//
861 			CloseHandle(threaddata.thread);
862 #else
863 			pthread_cancel(threaddata.thread);
864 #endif
865 			threaddata.have_thread = 0;
866 		}
867 		if (session->sockdata)
868 		{
869 			sock_close(session->sockdata, NULL, 0);
870 			session->sockdata = 0;
871 		}
872 		pcap_close(session->fp);
873 		free(session);
874 		session = NULL;
875 	}
876 
877 	// Print message and return
878 	SOCK_DEBUG_MESSAGE("I'm exiting from the child loop");
879 	SOCK_DEBUG_MESSAGE(errbuf);
880 
881 	return client_told_us_to_close;
882 }
883 
884 /*
885  * This handles the RPCAP_MSG_ERR message.
886  */
887 static int
daemon_msg_err(SOCKET sockctrl_in,uint32 plen)888 daemon_msg_err(SOCKET sockctrl_in, uint32 plen)
889 {
890 	char errbuf[PCAP_ERRBUF_SIZE];
891 	char remote_errbuf[PCAP_ERRBUF_SIZE];
892 
893 	if (plen >= PCAP_ERRBUF_SIZE)
894 	{
895 		/*
896 		 * Message is too long; just read as much of it as we
897 		 * can into the buffer provided, and discard the rest.
898 		 */
899 		if (sock_recv(sockctrl_in, remote_errbuf, PCAP_ERRBUF_SIZE - 1,
900 		    SOCK_RECEIVEALL_YES|SOCK_EOF_IS_ERROR, errbuf,
901 		    PCAP_ERRBUF_SIZE) == -1)
902 		{
903 			// Network error.
904 			rpcapd_log(LOGPRIO_ERROR, "Read from client failed: %s", errbuf);
905 			return -1;
906 		}
907 		if (rpcapd_discard(sockctrl_in, plen - (PCAP_ERRBUF_SIZE - 1)) == -1)
908 		{
909 			// Network error.
910 			return -1;
911 		}
912 
913 		/*
914 		 * Null-terminate it.
915 		 */
916 		remote_errbuf[PCAP_ERRBUF_SIZE - 1] = '\0';
917 	}
918 	else if (plen == 0)
919 	{
920 		/* Empty error string. */
921 		remote_errbuf[0] = '\0';
922 	}
923 	else
924 	{
925 		if (sock_recv(sockctrl_in, remote_errbuf, plen,
926 		    SOCK_RECEIVEALL_YES|SOCK_EOF_IS_ERROR, errbuf,
927 		    PCAP_ERRBUF_SIZE) == -1)
928 		{
929 			// Network error.
930 			rpcapd_log(LOGPRIO_ERROR, "Read from client failed: %s", errbuf);
931 			return -1;
932 		}
933 
934 		/*
935 		 * Null-terminate it.
936 		 */
937 		remote_errbuf[plen] = '\0';
938 	}
939 	// Log the message
940 	rpcapd_log(LOGPRIO_ERROR, "Error from client: %s", remote_errbuf);
941 	return 0;
942 }
943 
944 /*
945  * This handles the RPCAP_MSG_AUTH_REQ message.
946  * It checks if the authentication credentials supplied by the user are valid.
947  *
948  * This function is called if the daemon receives a RPCAP_MSG_AUTH_REQ
949  * message in its authentication loop.  It reads the body of the
950  * authentication message from the network and checks whether the
951  * credentials are valid.
952  *
953  * \param sockctrl: the socket for the control connection.
954  *
955  * \param nullAuthAllowed: '1' if the NULL authentication is allowed.
956  *
957  * \param errbuf: a user-allocated buffer in which the error message
958  * (if one) has to be written.  It must be at least PCAP_ERRBUF_SIZE
959  * bytes long.
960  *
961  * \return '0' if everything is fine, '-1' if an unrecoverable error occurred,
962  * or '-2' if the authentication failed.  For errors, an error message is
963  * returned in the 'errbuf' variable; this gives a message for the
964  * unrecoverable error or for the authentication failure.
965  */
966 static int
daemon_msg_auth_req(struct daemon_slpars * pars,uint32 plen)967 daemon_msg_auth_req(struct daemon_slpars *pars, uint32 plen)
968 {
969 	char errbuf[PCAP_ERRBUF_SIZE];		// buffer for network errors
970 	char errmsgbuf[PCAP_ERRBUF_SIZE];	// buffer for errors to send to the client
971 	struct rpcap_header header;		// RPCAP message general header
972 	int status;
973 	struct rpcap_auth auth;			// RPCAP authentication header
974 
975 	status = rpcapd_recv(pars->sockctrl_in, (char *) &auth, sizeof(struct rpcap_auth), &plen, errmsgbuf);
976 	if (status == -1)
977 	{
978 		return -1;
979 	}
980 	if (status == -2)
981 	{
982 		goto error;
983 	}
984 
985 	switch (ntohs(auth.type))
986 	{
987 		case RPCAP_RMTAUTH_NULL:
988 		{
989 			if (!pars->nullAuthAllowed)
990 			{
991 				// Send the client an error reply.
992 				pcap_snprintf(errmsgbuf, PCAP_ERRBUF_SIZE, "Authentication failed; NULL authentication not permitted.");
993 				goto error;
994 			}
995 			break;
996 		}
997 
998 		case RPCAP_RMTAUTH_PWD:
999 		{
1000 			char *username, *passwd;
1001 			uint32 usernamelen, passwdlen;
1002 
1003 			usernamelen = ntohs(auth.slen1);
1004 			username = (char *) malloc (usernamelen + 1);
1005 			if (username == NULL)
1006 			{
1007 				pcap_fmt_errmsg_for_errno(errmsgbuf,
1008 				    PCAP_ERRBUF_SIZE, errno, "malloc() failed");
1009 				goto error;
1010 			}
1011 			status = rpcapd_recv(pars->sockctrl_in, username, usernamelen, &plen, errmsgbuf);
1012 			if (status == -1)
1013 			{
1014 				free(username);
1015 				return -1;
1016 			}
1017 			if (status == -2)
1018 			{
1019 				free(username);
1020 				goto error;
1021 			}
1022 			username[usernamelen] = '\0';
1023 
1024 			passwdlen = ntohs(auth.slen2);
1025 			passwd = (char *) malloc (passwdlen + 1);
1026 			if (passwd == NULL)
1027 			{
1028 				pcap_fmt_errmsg_for_errno(errmsgbuf,
1029 				    PCAP_ERRBUF_SIZE, errno, "malloc() failed");
1030 				free(username);
1031 				goto error;
1032 			}
1033 			status = rpcapd_recv(pars->sockctrl_in, passwd, passwdlen, &plen, errmsgbuf);
1034 			if (status == -1)
1035 			{
1036 				free(username);
1037 				free(passwd);
1038 				return -1;
1039 			}
1040 			if (status == -2)
1041 			{
1042 				free(username);
1043 				free(passwd);
1044 				goto error;
1045 			}
1046 			passwd[passwdlen] = '\0';
1047 
1048 			if (daemon_AuthUserPwd(username, passwd, errmsgbuf))
1049 			{
1050 				//
1051 				// Authentication failed.  Let the client
1052 				// know.
1053 				//
1054 				free(username);
1055 				free(passwd);
1056 				if (rpcap_senderror(pars->sockctrl_out,
1057 				    pars->protocol_version,
1058 				    PCAP_ERR_AUTH, errmsgbuf, errbuf) == -1)
1059 				{
1060 					// That failed; log a message and give up.
1061 					rpcapd_log(LOGPRIO_ERROR, "Send to client failed: %s", errbuf);
1062 					return -1;
1063 				}
1064 
1065 				//
1066 				// Suspend for 1 second, so that they can't
1067 				// hammer us with repeated tries with an
1068 				// attack such as a dictionary attack.
1069 				//
1070 				// WARNING: this delay is inserted only
1071 				// at this point; if the client closes the
1072 				// connection and reconnects, the suspension
1073 				// time does not have any effect.
1074 				//
1075 				sleep_secs(RPCAP_SUSPEND_WRONGAUTH);
1076 				goto error_noreply;
1077 			}
1078 
1079 			free(username);
1080 			free(passwd);
1081 			break;
1082 			}
1083 
1084 		default:
1085 			pcap_snprintf(errmsgbuf, PCAP_ERRBUF_SIZE, "Authentication type not recognized.");
1086 			goto error;
1087 	}
1088 
1089 	// The authentication succeeded; let the client know.
1090 	rpcap_createhdr(&header, pars->protocol_version, RPCAP_MSG_AUTH_REPLY, 0, 0);
1091 
1092 	// Send the ok message back
1093 	if (sock_send(pars->sockctrl_out, (char *) &header, sizeof (struct rpcap_header), errbuf, PCAP_ERRBUF_SIZE) == -1)
1094 	{
1095 		// That failed; log a messsage and give up.
1096 		rpcapd_log(LOGPRIO_ERROR, "Send to client failed: %s", errbuf);
1097 		return -1;
1098 	}
1099 
1100 	// Check if all the data has been read; if not, discard the data in excess
1101 	if (rpcapd_discard(pars->sockctrl_in, plen) == -1)
1102 	{
1103 		return -1;
1104 	}
1105 
1106 	return 0;
1107 
1108 error:
1109 	if (rpcap_senderror(pars->sockctrl_out, pars->protocol_version,
1110 	    PCAP_ERR_AUTH, errmsgbuf, errbuf) == -1)
1111 	{
1112 		// That failed; log a message and give up.
1113 		rpcapd_log(LOGPRIO_ERROR, "Send to client failed: %s", errbuf);
1114 		return -1;
1115 	}
1116 
1117 error_noreply:
1118 	// Check if all the data has been read; if not, discard the data in excess
1119 	if (rpcapd_discard(pars->sockctrl_in, plen) == -1)
1120 	{
1121 		return -1;
1122 	}
1123 
1124 	return -2;
1125 }
1126 
1127 static int
daemon_AuthUserPwd(char * username,char * password,char * errbuf)1128 daemon_AuthUserPwd(char *username, char *password, char *errbuf)
1129 {
1130 #ifdef _WIN32
1131 	/*
1132 	 * Warning: the user which launches the process must have the
1133 	 * SE_TCB_NAME right.
1134 	 * This corresponds to have the "Act as part of the Operating System"
1135 	 * turned on (administrative tools, local security settings, local
1136 	 * policies, user right assignment)
1137 	 * However, it seems to me that if you run it as a service, this
1138 	 * right should be provided by default.
1139 	 */
1140 	HANDLE Token;
1141 	if (LogonUser(username, ".", password, LOGON32_LOGON_NETWORK, LOGON32_PROVIDER_DEFAULT, &Token) == 0)
1142 	{
1143 		int error;
1144 
1145 		error = GetLastError();
1146 		FormatMessageA(FORMAT_MESSAGE_FROM_SYSTEM, NULL, error, 0, errbuf,
1147 			PCAP_ERRBUF_SIZE, NULL);
1148 
1149 		return -1;
1150 	}
1151 
1152 	// This call should change the current thread to the selected user.
1153 	// I didn't test it.
1154 	if (ImpersonateLoggedOnUser(Token) == 0)
1155 	{
1156 		int error;
1157 
1158 		error = GetLastError();
1159 		FormatMessageA(FORMAT_MESSAGE_FROM_SYSTEM, NULL, error, 0, errbuf,
1160 			PCAP_ERRBUF_SIZE, NULL);
1161 
1162 		CloseHandle(Token);
1163 		return -1;
1164 	}
1165 
1166 	CloseHandle(Token);
1167 	return 0;
1168 
1169 #else
1170 	/*
1171 	 * See
1172 	 *
1173 	 *	http://www.unixpapa.com/incnote/passwd.html
1174 	 *
1175 	 * We use the Solaris/Linux shadow password authentication if
1176 	 * we have getspnam(), otherwise we just do traditional
1177 	 * authentication, which, on some platforms, might work, even
1178 	 * with shadow passwords, if we're running as root.  Traditional
1179 	 * authenticaion won't work if we're not running as root, as
1180 	 * I think these days all UN*Xes either won't return the password
1181 	 * at all with getpwnam() or will only do so if you're root.
1182 	 *
1183 	 * XXX - perhaps what we *should* be using is PAM, if we have
1184 	 * it.  That might hide all the details of username/password
1185 	 * authentication, whether it's done with a visible-to-root-
1186 	 * only password database or some other authentication mechanism,
1187 	 * behind its API.
1188 	 */
1189 	struct passwd *user;
1190 	char *user_password;
1191 #ifdef HAVE_GETSPNAM
1192 	struct spwd *usersp;
1193 #endif
1194 
1195 	// This call is needed to get the uid
1196 	if ((user = getpwnam(username)) == NULL)
1197 	{
1198 		pcap_snprintf(errbuf, PCAP_ERRBUF_SIZE, "Authentication failed: no such user");
1199 		return -1;
1200 	}
1201 
1202 #ifdef HAVE_GETSPNAM
1203 	// This call is needed to get the password; otherwise 'x' is returned
1204 	if ((usersp = getspnam(username)) == NULL)
1205 	{
1206 		pcap_snprintf(errbuf, PCAP_ERRBUF_SIZE, "Authentication failed: no such user");
1207 		return -1;
1208 	}
1209 	user_password = usersp->sp_pwdp;
1210 #else
1211 	/*
1212 	 * XXX - what about other platforms?
1213 	 * The unixpapa.com page claims this Just Works on *BSD if you're
1214 	 * running as root - it's from 2000, so it doesn't indicate whether
1215 	 * macOS (which didn't come out until 2001, under the name Mac OS
1216 	 * X) behaves like the *BSDs or not, and might also work on AIX.
1217 	 * HP-UX does something else.
1218 	 *
1219 	 * Again, hopefully PAM hides all that.
1220 	 */
1221 	user_password = user->pw_passwd;
1222 #endif
1223 
1224 	if (strcmp(user_password, (char *) crypt(password, user_password)) != 0)
1225 	{
1226 		pcap_snprintf(errbuf, PCAP_ERRBUF_SIZE, "Authentication failed: password incorrect");
1227 		return -1;
1228 	}
1229 
1230 	if (setuid(user->pw_uid))
1231 	{
1232 		pcap_fmt_errmsg_for_errno(errbuf, PCAP_ERRBUF_SIZE,
1233 		    errno, "setuid");
1234 		return -1;
1235 	}
1236 
1237 /*	if (setgid(user->pw_gid))
1238 	{
1239 		pcap_fmt_errmsg_for_errno(errbuf, PCAP_ERRBUF_SIZE,
1240 		    errno, "setgid");
1241 		return -1;
1242 	}
1243 */
1244 	return 0;
1245 
1246 #endif
1247 
1248 }
1249 
1250 static int
daemon_msg_findallif_req(struct daemon_slpars * pars,uint32 plen)1251 daemon_msg_findallif_req(struct daemon_slpars *pars, uint32 plen)
1252 {
1253 	char errbuf[PCAP_ERRBUF_SIZE];		// buffer for network errors
1254 	char errmsgbuf[PCAP_ERRBUF_SIZE];	// buffer for errors to send to the client
1255 	char sendbuf[RPCAP_NETBUF_SIZE];	// temporary buffer in which data to be sent is buffered
1256 	int sendbufidx = 0;			// index which keeps the number of bytes currently buffered
1257 	pcap_if_t *alldevs = NULL;		// pointer to the header of the interface chain
1258 	pcap_if_t *d;				// temp pointer needed to scan the interface chain
1259 	struct pcap_addr *address;		// pcap structure that keeps a network address of an interface
1260 	struct rpcap_findalldevs_if *findalldevs_if;// rpcap structure that packet all the data of an interface together
1261 	uint16 nif = 0;				// counts the number of interface listed
1262 
1263 	// Discard the rest of the message; there shouldn't be any payload.
1264 	if (rpcapd_discard(pars->sockctrl_in, plen) == -1)
1265 	{
1266 		// Network error.
1267 		return -1;
1268 	}
1269 
1270 	// Retrieve the device list
1271 	if (pcap_findalldevs(&alldevs, errmsgbuf) == -1)
1272 		goto error;
1273 
1274 	if (alldevs == NULL)
1275 	{
1276 		if (rpcap_senderror(pars->sockctrl_out, pars->protocol_version,
1277 			PCAP_ERR_NOREMOTEIF,
1278 			"No interfaces found! Make sure libpcap/WinPcap is properly installed"
1279 			" and you have the right to access to the remote device.",
1280 			errbuf) == -1)
1281 		{
1282 			rpcapd_log(LOGPRIO_ERROR, "Send to client failed: %s", errbuf);
1283 			return -1;
1284 		}
1285 		return 0;
1286 	}
1287 
1288 	// checks the number of interfaces and it computes the total length of the payload
1289 	for (d = alldevs; d != NULL; d = d->next)
1290 	{
1291 		nif++;
1292 
1293 		if (d->description)
1294 			plen+= strlen(d->description);
1295 		if (d->name)
1296 			plen+= strlen(d->name);
1297 
1298 		plen+= sizeof(struct rpcap_findalldevs_if);
1299 
1300 		for (address = d->addresses; address != NULL; address = address->next)
1301 		{
1302 			/*
1303 			 * Send only IPv4 and IPv6 addresses over the wire.
1304 			 */
1305 			switch (address->addr->sa_family)
1306 			{
1307 			case AF_INET:
1308 #ifdef AF_INET6
1309 			case AF_INET6:
1310 #endif
1311 				plen+= (sizeof(struct rpcap_sockaddr) * 4);
1312 				break;
1313 
1314 			default:
1315 				break;
1316 			}
1317 		}
1318 	}
1319 
1320 	// RPCAP findalldevs command
1321 	if (sock_bufferize(NULL, sizeof(struct rpcap_header), NULL,
1322 	    &sendbufidx, RPCAP_NETBUF_SIZE, SOCKBUF_CHECKONLY, errmsgbuf,
1323 	    PCAP_ERRBUF_SIZE) == -1)
1324 		goto error;
1325 
1326 	rpcap_createhdr((struct rpcap_header *) sendbuf, pars->protocol_version,
1327 	    RPCAP_MSG_FINDALLIF_REPLY, nif, plen);
1328 
1329 	// send the interface list
1330 	for (d = alldevs; d != NULL; d = d->next)
1331 	{
1332 		uint16 lname, ldescr;
1333 
1334 		findalldevs_if = (struct rpcap_findalldevs_if *) &sendbuf[sendbufidx];
1335 
1336 		if (sock_bufferize(NULL, sizeof(struct rpcap_findalldevs_if), NULL,
1337 		    &sendbufidx, RPCAP_NETBUF_SIZE, SOCKBUF_CHECKONLY, errmsgbuf, PCAP_ERRBUF_SIZE) == -1)
1338 			goto error;
1339 
1340 		memset(findalldevs_if, 0, sizeof(struct rpcap_findalldevs_if));
1341 
1342 		if (d->description) ldescr = (short) strlen(d->description);
1343 		else ldescr = 0;
1344 		if (d->name) lname = (short) strlen(d->name);
1345 		else lname = 0;
1346 
1347 		findalldevs_if->desclen = htons(ldescr);
1348 		findalldevs_if->namelen = htons(lname);
1349 		findalldevs_if->flags = htonl(d->flags);
1350 
1351 		for (address = d->addresses; address != NULL; address = address->next)
1352 		{
1353 			/*
1354 			 * Send only IPv4 and IPv6 addresses over the wire.
1355 			 */
1356 			switch (address->addr->sa_family)
1357 			{
1358 			case AF_INET:
1359 #ifdef AF_INET6
1360 			case AF_INET6:
1361 #endif
1362 				findalldevs_if->naddr++;
1363 				break;
1364 
1365 			default:
1366 				break;
1367 			}
1368 		}
1369 		findalldevs_if->naddr = htons(findalldevs_if->naddr);
1370 
1371 		if (sock_bufferize(d->name, lname, sendbuf, &sendbufidx,
1372 		    RPCAP_NETBUF_SIZE, SOCKBUF_BUFFERIZE, errmsgbuf,
1373 		    PCAP_ERRBUF_SIZE) == -1)
1374 			goto error;
1375 
1376 		if (sock_bufferize(d->description, ldescr, sendbuf, &sendbufidx,
1377 		    RPCAP_NETBUF_SIZE, SOCKBUF_BUFFERIZE, errmsgbuf,
1378 		    PCAP_ERRBUF_SIZE) == -1)
1379 			goto error;
1380 
1381 		// send all addresses
1382 		for (address = d->addresses; address != NULL; address = address->next)
1383 		{
1384 			struct rpcap_sockaddr *sockaddr;
1385 
1386 			/*
1387 			 * Send only IPv4 and IPv6 addresses over the wire.
1388 			 */
1389 			switch (address->addr->sa_family)
1390 			{
1391 			case AF_INET:
1392 #ifdef AF_INET6
1393 			case AF_INET6:
1394 #endif
1395 				sockaddr = (struct rpcap_sockaddr *) &sendbuf[sendbufidx];
1396 				if (sock_bufferize(NULL, sizeof(struct rpcap_sockaddr), NULL,
1397 				    &sendbufidx, RPCAP_NETBUF_SIZE, SOCKBUF_CHECKONLY, errmsgbuf, PCAP_ERRBUF_SIZE) == -1)
1398 					goto error;
1399 				daemon_seraddr((struct sockaddr_storage *) address->addr, sockaddr);
1400 
1401 				sockaddr = (struct rpcap_sockaddr *) &sendbuf[sendbufidx];
1402 				if (sock_bufferize(NULL, sizeof(struct rpcap_sockaddr), NULL,
1403 				    &sendbufidx, RPCAP_NETBUF_SIZE, SOCKBUF_CHECKONLY, errmsgbuf, PCAP_ERRBUF_SIZE) == -1)
1404 					goto error;
1405 				daemon_seraddr((struct sockaddr_storage *) address->netmask, sockaddr);
1406 
1407 				sockaddr = (struct rpcap_sockaddr *) &sendbuf[sendbufidx];
1408 				if (sock_bufferize(NULL, sizeof(struct rpcap_sockaddr), NULL,
1409 				    &sendbufidx, RPCAP_NETBUF_SIZE, SOCKBUF_CHECKONLY, errmsgbuf, PCAP_ERRBUF_SIZE) == -1)
1410 					goto error;
1411 				daemon_seraddr((struct sockaddr_storage *) address->broadaddr, sockaddr);
1412 
1413 				sockaddr = (struct rpcap_sockaddr *) &sendbuf[sendbufidx];
1414 				if (sock_bufferize(NULL, sizeof(struct rpcap_sockaddr), NULL,
1415 				    &sendbufidx, RPCAP_NETBUF_SIZE, SOCKBUF_CHECKONLY, errmsgbuf, PCAP_ERRBUF_SIZE) == -1)
1416 					goto error;
1417 				daemon_seraddr((struct sockaddr_storage *) address->dstaddr, sockaddr);
1418 				break;
1419 
1420 			default:
1421 				break;
1422 			}
1423 		}
1424 	}
1425 
1426 	// We no longer need the device list. Free it.
1427 	pcap_freealldevs(alldevs);
1428 
1429 	// Send a final command that says "now send it!"
1430 	if (sock_send(pars->sockctrl_out, sendbuf, sendbufidx, errbuf, PCAP_ERRBUF_SIZE) == -1)
1431 	{
1432 		rpcapd_log(LOGPRIO_ERROR, "Send to client failed: %s", errbuf);
1433 		return -1;
1434 	}
1435 
1436 	return 0;
1437 
1438 error:
1439 	if (alldevs)
1440 		pcap_freealldevs(alldevs);
1441 
1442 	if (rpcap_senderror(pars->sockctrl_out, pars->protocol_version,
1443 	    PCAP_ERR_FINDALLIF, errmsgbuf, errbuf) == -1)
1444 	{
1445 		rpcapd_log(LOGPRIO_ERROR, "Send to client failed: %s", errbuf);
1446 		return -1;
1447 	}
1448 	return 0;
1449 }
1450 
1451 /*
1452 	\param plen: the length of the current message (needed in order to be able
1453 	to discard excess data in the message, if present)
1454 */
1455 static int
daemon_msg_open_req(struct daemon_slpars * pars,uint32 plen,char * source,size_t sourcelen)1456 daemon_msg_open_req(struct daemon_slpars *pars, uint32 plen, char *source, size_t sourcelen)
1457 {
1458 	char errbuf[PCAP_ERRBUF_SIZE];		// buffer for network errors
1459 	char errmsgbuf[PCAP_ERRBUF_SIZE];	// buffer for errors to send to the client
1460 	pcap_t *fp;				// pcap_t main variable
1461 	int nread;
1462 	char sendbuf[RPCAP_NETBUF_SIZE];	// temporary buffer in which data to be sent is buffered
1463 	int sendbufidx = 0;			// index which keeps the number of bytes currently buffered
1464 	struct rpcap_openreply *openreply;	// open reply message
1465 
1466 	if (plen > sourcelen - 1)
1467 	{
1468 		pcap_snprintf(errmsgbuf, PCAP_ERRBUF_SIZE, "Source string too long");
1469 		goto error;
1470 	}
1471 
1472 	nread = sock_recv(pars->sockctrl_in, source, plen,
1473 	    SOCK_RECEIVEALL_YES|SOCK_EOF_IS_ERROR, errbuf, PCAP_ERRBUF_SIZE);
1474 	if (nread == -1)
1475 	{
1476 		rpcapd_log(LOGPRIO_ERROR, "Read from client failed: %s", errbuf);
1477 		return -1;
1478 	}
1479 	source[nread] = '\0';
1480 	plen -= nread;
1481 
1482 	// XXX - make sure it's *not* a URL; we don't support opening
1483 	// remote devices here.
1484 
1485 	// Open the selected device
1486 	// This is a fake open, since we do that only to get the needed parameters, then we close the device again
1487 	if ((fp = pcap_open_live(source,
1488 			1500 /* fake snaplen */,
1489 			0 /* no promis */,
1490 			1000 /* fake timeout */,
1491 			errmsgbuf)) == NULL)
1492 		goto error;
1493 
1494 	// Now, I can send a RPCAP open reply message
1495 	if (sock_bufferize(NULL, sizeof(struct rpcap_header), NULL, &sendbufidx,
1496 	    RPCAP_NETBUF_SIZE, SOCKBUF_CHECKONLY, errmsgbuf, PCAP_ERRBUF_SIZE) == -1)
1497 		goto error;
1498 
1499 	rpcap_createhdr((struct rpcap_header *) sendbuf, pars->protocol_version,
1500 	    RPCAP_MSG_OPEN_REPLY, 0, sizeof(struct rpcap_openreply));
1501 
1502 	openreply = (struct rpcap_openreply *) &sendbuf[sendbufidx];
1503 
1504 	if (sock_bufferize(NULL, sizeof(struct rpcap_openreply), NULL, &sendbufidx,
1505 	    RPCAP_NETBUF_SIZE, SOCKBUF_CHECKONLY, errmsgbuf, PCAP_ERRBUF_SIZE) == -1)
1506 		goto error;
1507 
1508 	memset(openreply, 0, sizeof(struct rpcap_openreply));
1509 	openreply->linktype = htonl(pcap_datalink(fp));
1510 	openreply->tzoff = 0; /* This is always 0 for live captures */
1511 
1512 	// We're done with the pcap_t.
1513 	pcap_close(fp);
1514 
1515 	// Send the reply.
1516 	if (sock_send(pars->sockctrl_out, sendbuf, sendbufidx, errbuf, PCAP_ERRBUF_SIZE) == -1)
1517 	{
1518 		rpcapd_log(LOGPRIO_ERROR, "Send to client failed: %s", errbuf);
1519 		return -1;
1520 	}
1521 	return 0;
1522 
1523 error:
1524 	if (rpcap_senderror(pars->sockctrl_out, pars->protocol_version,
1525 	    PCAP_ERR_OPEN, errmsgbuf, errbuf) == -1)
1526 	{
1527 		// That failed; log a message and give up.
1528 		rpcapd_log(LOGPRIO_ERROR, "Send to client failed: %s", errbuf);
1529 		return -1;
1530 	}
1531 
1532 	// Check if all the data has been read; if not, discard the data in excess
1533 	if (rpcapd_discard(pars->sockctrl_in, plen) == -1)
1534 	{
1535 		return -1;
1536 	}
1537 	return 0;
1538 }
1539 
1540 /*
1541 	\param plen: the length of the current message (needed in order to be able
1542 	to discard excess data in the message, if present)
1543 */
1544 static int
daemon_msg_startcap_req(struct daemon_slpars * pars,uint32 plen,struct thread_handle * threaddata,char * source,struct session ** sessionp,struct rpcap_sampling * samp_param _U_)1545 daemon_msg_startcap_req(struct daemon_slpars *pars, uint32 plen, struct thread_handle *threaddata, char *source, struct session **sessionp, struct rpcap_sampling *samp_param _U_)
1546 {
1547 	char errbuf[PCAP_ERRBUF_SIZE];		// buffer for network errors
1548 	char errmsgbuf[PCAP_ERRBUF_SIZE];	// buffer for errors to send to the client
1549 	char portdata[PCAP_BUF_SIZE];		// temp variable needed to derive the data port
1550 	char peerhost[PCAP_BUF_SIZE];		// temp variable needed to derive the host name of our peer
1551 	struct session *session = NULL;		// saves state of session
1552 	int status;
1553 	char sendbuf[RPCAP_NETBUF_SIZE];	// temporary buffer in which data to be sent is buffered
1554 	int sendbufidx = 0;			// index which keeps the number of bytes currently buffered
1555 
1556 	// socket-related variables
1557 	SOCKET sockdata = INVALID_SOCKET;	// socket descriptor of the data connection
1558 	struct addrinfo hints;			// temp, needed to open a socket connection
1559 	struct addrinfo *addrinfo;		// temp, needed to open a socket connection
1560 	struct sockaddr_storage saddr;		// temp, needed to retrieve the network data port chosen on the local machine
1561 	socklen_t saddrlen;			// temp, needed to retrieve the network data port chosen on the local machine
1562 	int ret;				// return value from functions
1563 
1564 #ifndef _WIN32
1565 	pthread_attr_t detachedAttribute;	// temp, needed to set the created thread as detached
1566 #endif
1567 
1568 	// RPCAP-related variables
1569 	struct rpcap_startcapreq startcapreq;		// start capture request message
1570 	struct rpcap_startcapreply *startcapreply;	// start capture reply message
1571 	int serveropen_dp;							// keeps who is going to open the data connection
1572 
1573 	addrinfo = NULL;
1574 
1575 	status = rpcapd_recv(pars->sockctrl_in, (char *) &startcapreq,
1576 	    sizeof(struct rpcap_startcapreq), &plen, errmsgbuf);
1577 	if (status == -1)
1578 	{
1579 		goto fatal_error;
1580 	}
1581 	if (status == -2)
1582 	{
1583 		goto error;
1584 	}
1585 
1586 	startcapreq.flags = ntohs(startcapreq.flags);
1587 
1588 	// Create a session structure
1589 	session = malloc(sizeof(struct session));
1590 	if (session == NULL)
1591 	{
1592 		pcap_snprintf(errmsgbuf, PCAP_ERRBUF_SIZE, "Can't allocate session structure");
1593 		goto error;
1594 	}
1595 
1596 	// Open the selected device
1597 	if ((session->fp = pcap_open_live(source,
1598 			ntohl(startcapreq.snaplen),
1599 			(startcapreq.flags & RPCAP_STARTCAPREQ_FLAG_PROMISC) ? 1 : 0 /* local device, other flags not needed */,
1600 			ntohl(startcapreq.read_timeout),
1601 			errmsgbuf)) == NULL)
1602 		goto error;
1603 
1604 #if 0
1605 	// Apply sampling parameters
1606 	fp->rmt_samp.method = samp_param->method;
1607 	fp->rmt_samp.value = samp_param->value;
1608 #endif
1609 
1610 	/*
1611 	We're in active mode if:
1612 	- we're using TCP, and the user wants us to be in active mode
1613 	- we're using UDP
1614 	*/
1615 	serveropen_dp = (startcapreq.flags & RPCAP_STARTCAPREQ_FLAG_SERVEROPEN) || (startcapreq.flags & RPCAP_STARTCAPREQ_FLAG_DGRAM) || pars->isactive;
1616 
1617 	/*
1618 	Gets the sockaddr structure referred to the other peer in the ctrl connection
1619 
1620 	We need that because:
1621 	- if we're in passive mode, we need to know the address family we want to use
1622 	(the same used for the ctrl socket)
1623 	- if we're in active mode, we need to know the network address of the other host
1624 	we want to connect to
1625 	*/
1626 	saddrlen = sizeof(struct sockaddr_storage);
1627 	if (getpeername(pars->sockctrl_in, (struct sockaddr *) &saddr, &saddrlen) == -1)
1628 	{
1629 		sock_geterror("getpeername(): ", errmsgbuf, PCAP_ERRBUF_SIZE);
1630 		goto error;
1631 	}
1632 
1633 	memset(&hints, 0, sizeof(struct addrinfo));
1634 	hints.ai_socktype = (startcapreq.flags & RPCAP_STARTCAPREQ_FLAG_DGRAM) ? SOCK_DGRAM : SOCK_STREAM;
1635 	hints.ai_family = saddr.ss_family;
1636 
1637 	// Now we have to create a new socket to send packets
1638 	if (serveropen_dp)		// Data connection is opened by the server toward the client
1639 	{
1640 		pcap_snprintf(portdata, sizeof portdata, "%d", ntohs(startcapreq.portdata));
1641 
1642 		// Get the name of the other peer (needed to connect to that specific network address)
1643 		if (getnameinfo((struct sockaddr *) &saddr, saddrlen, peerhost,
1644 				sizeof(peerhost), NULL, 0, NI_NUMERICHOST))
1645 		{
1646 			sock_geterror("getnameinfo(): ", errmsgbuf, PCAP_ERRBUF_SIZE);
1647 			goto error;
1648 		}
1649 
1650 		if (sock_initaddress(peerhost, portdata, &hints, &addrinfo, errmsgbuf, PCAP_ERRBUF_SIZE) == -1)
1651 			goto error;
1652 
1653 		if ((sockdata = sock_open(addrinfo, SOCKOPEN_CLIENT, 0, errmsgbuf, PCAP_ERRBUF_SIZE)) == INVALID_SOCKET)
1654 			goto error;
1655 	}
1656 	else		// Data connection is opened by the client toward the server
1657 	{
1658 		hints.ai_flags = AI_PASSIVE;
1659 
1660 		// Let's the server socket pick up a free network port for us
1661 		if (sock_initaddress(NULL, "0", &hints, &addrinfo, errmsgbuf, PCAP_ERRBUF_SIZE) == -1)
1662 			goto error;
1663 
1664 		if ((sockdata = sock_open(addrinfo, SOCKOPEN_SERVER, 1 /* max 1 connection in queue */, errmsgbuf, PCAP_ERRBUF_SIZE)) == INVALID_SOCKET)
1665 			goto error;
1666 
1667 		// get the complete sockaddr structure used in the data connection
1668 		saddrlen = sizeof(struct sockaddr_storage);
1669 		if (getsockname(sockdata, (struct sockaddr *) &saddr, &saddrlen) == -1)
1670 		{
1671 			sock_geterror("getsockname(): ", errmsgbuf, PCAP_ERRBUF_SIZE);
1672 			goto error;
1673 		}
1674 
1675 		// Get the local port the system picked up
1676 		if (getnameinfo((struct sockaddr *) &saddr, saddrlen, NULL,
1677 				0, portdata, sizeof(portdata), NI_NUMERICSERV))
1678 		{
1679 			sock_geterror("getnameinfo(): ", errmsgbuf, PCAP_ERRBUF_SIZE);
1680 			goto error;
1681 		}
1682 	}
1683 
1684 	// addrinfo is no longer used
1685 	freeaddrinfo(addrinfo);
1686 	addrinfo = NULL;
1687 
1688 	// Needed to send an error on the ctrl connection
1689 	session->sockctrl_out = pars->sockctrl_out;
1690 	session->protocol_version = pars->protocol_version;
1691 
1692 	// Now I can set the filter
1693 	ret = daemon_unpackapplyfilter(pars->sockctrl_in, session, &plen, errmsgbuf);
1694 	if (ret == -1)
1695 	{
1696 		// Fatal error.  A message has been logged; just give up.
1697 		goto fatal_error;
1698 	}
1699 	if (ret == -2)
1700 	{
1701 		// Non-fatal error.  Send an error message to the client.
1702 		goto error;
1703 	}
1704 
1705 	// Now, I can send a RPCAP start capture reply message
1706 	if (sock_bufferize(NULL, sizeof(struct rpcap_header), NULL, &sendbufidx,
1707 	    RPCAP_NETBUF_SIZE, SOCKBUF_CHECKONLY, errmsgbuf, PCAP_ERRBUF_SIZE) == -1)
1708 		goto error;
1709 
1710 	rpcap_createhdr((struct rpcap_header *) sendbuf, pars->protocol_version,
1711 	    RPCAP_MSG_STARTCAP_REPLY, 0, sizeof(struct rpcap_startcapreply));
1712 
1713 	startcapreply = (struct rpcap_startcapreply *) &sendbuf[sendbufidx];
1714 
1715 	if (sock_bufferize(NULL, sizeof(struct rpcap_startcapreply), NULL,
1716 	    &sendbufidx, RPCAP_NETBUF_SIZE, SOCKBUF_CHECKONLY, errmsgbuf, PCAP_ERRBUF_SIZE) == -1)
1717 		goto error;
1718 
1719 	memset(startcapreply, 0, sizeof(struct rpcap_startcapreply));
1720 	startcapreply->bufsize = htonl(pcap_bufsize(session->fp));
1721 
1722 	if (!serveropen_dp)
1723 	{
1724 		unsigned short port = (unsigned short)strtoul(portdata,NULL,10);
1725 		startcapreply->portdata = htons(port);
1726 	}
1727 
1728 	if (sock_send(pars->sockctrl_out, sendbuf, sendbufidx, errbuf, PCAP_ERRBUF_SIZE) == -1)
1729 	{
1730 		// That failed; log a message and give up.
1731 		rpcapd_log(LOGPRIO_ERROR, "Send to client failed: %s", errbuf);
1732 		goto fatal_error;
1733 	}
1734 
1735 	if (!serveropen_dp)
1736 	{
1737 		SOCKET socktemp;	// We need another socket, since we're going to accept() a connection
1738 
1739 		// Connection creation
1740 		saddrlen = sizeof(struct sockaddr_storage);
1741 
1742 		socktemp = accept(sockdata, (struct sockaddr *) &saddr, &saddrlen);
1743 
1744 		if (socktemp == INVALID_SOCKET)
1745 		{
1746 			sock_geterror("accept(): ", errbuf, PCAP_ERRBUF_SIZE);
1747 			rpcapd_log(LOGPRIO_ERROR, "Accept of data connection failed: %s",
1748 			    errbuf);
1749 			goto error;
1750 		}
1751 
1752 		// Now that I accepted the connection, the server socket is no longer needed
1753 		sock_close(sockdata, NULL, 0);
1754 		sockdata = socktemp;
1755 	}
1756 
1757 	session->sockdata = sockdata;
1758 
1759 	// Now we have to create a new thread to receive packets
1760 #ifdef _WIN32
1761 	threaddata->thread = (HANDLE)_beginthreadex(NULL, 0, daemon_thrdatamain,
1762 	    (void *) session, 0, NULL);
1763 	if (threaddata->thread == 0)
1764 	{
1765 		pcap_snprintf(errbuf, PCAP_ERRBUF_SIZE, "Error creating the data thread");
1766 		goto error;
1767 	}
1768 #else
1769 	/* GV we need this to create the thread as detached. */
1770 	/* GV otherwise, the thread handle is not destroyed  */
1771 	pthread_attr_init(&detachedAttribute);
1772 	pthread_attr_setdetachstate(&detachedAttribute, PTHREAD_CREATE_DETACHED);
1773 	ret = pthread_create(&threaddata->thread, &detachedAttribute,
1774 	    daemon_thrdatamain, (void *) session);
1775 	if (ret != 0)
1776 	{
1777 		pcap_fmt_errmsg_for_errno(errbuf, PCAP_ERRBUF_SIZE,
1778 		    ret, "Error creating the data thread");
1779 		pthread_attr_destroy(&detachedAttribute);
1780 		goto error;
1781 	}
1782 	pthread_attr_destroy(&detachedAttribute);
1783 #endif
1784 	threaddata->have_thread = 1;
1785 
1786 	// Check if all the data has been read; if not, discard the data in excess
1787 	if (rpcapd_discard(pars->sockctrl_in, plen) == -1)
1788 		goto fatal_error;
1789 
1790 	*sessionp = session;
1791 	return 0;
1792 
1793 error:
1794 	//
1795 	// Not a fatal error, so send the client an error message and
1796 	// keep serving client requests.
1797 	//
1798 	*sessionp = NULL;
1799 
1800 	if (addrinfo)
1801 		freeaddrinfo(addrinfo);
1802 
1803 	if (threaddata->have_thread)
1804 	{
1805 #ifdef _WIN32
1806 		if (session->fp)
1807 		{
1808 			pcap_breakloop(session->fp);
1809 			SetEvent(pcap_getevent(session->fp));
1810 		}
1811 		CloseHandle(threaddata->thread);
1812 #else
1813 		pthread_cancel(threaddata->thread);
1814 #endif
1815 		threaddata->have_thread = 0;
1816 	}
1817 
1818 	if (sockdata != INVALID_SOCKET)
1819 		sock_close(sockdata, NULL, 0);
1820 
1821 	if (session)
1822 	{
1823 		if (session->fp)
1824 			pcap_close(session->fp);
1825 		free(session);
1826 	}
1827 
1828 	if (rpcap_senderror(pars->sockctrl_out, pars->protocol_version,
1829 	    PCAP_ERR_STARTCAPTURE, errmsgbuf, errbuf) == -1)
1830 	{
1831 		// That failed; log a message and give up.
1832 		rpcapd_log(LOGPRIO_ERROR, "Send to client failed: %s", errbuf);
1833 		return -1;
1834 	}
1835 
1836 	// Check if all the data has been read; if not, discard the data in excess
1837 	if (rpcapd_discard(pars->sockctrl_in, plen) == -1)
1838 	{
1839 		// Network error.
1840 		return -1;
1841 	}
1842 
1843 	return 0;
1844 
1845 fatal_error:
1846 	//
1847 	// Fatal network error, so don't try to communicate with
1848 	// the client, just give up.
1849 	//
1850 	*sessionp = NULL;
1851 
1852 	if (threaddata->have_thread)
1853 	{
1854 #ifdef _WIN32
1855 		if (session && session->fp)
1856 		{
1857 			//
1858 			// Tell the data connection thread main capture
1859 			// loop to break out of that loop.
1860 			//
1861 			pcap_breakloop(session->fp);
1862 
1863 			//
1864 			// If it's currently blocked waiting for packets
1865 			// to arrive, try to wake it up, so it can see
1866 			// the "break out of the loop" indication.
1867 			//
1868 			SetEvent(pcap_getevent(session->fp));
1869 		}
1870 
1871 		//
1872 		// Wait for the thread to exit, so we don't close
1873 		// sockets out from under it.
1874 		//
1875 		// XXX - have a timeout, so we don't wait forever?
1876 		//
1877 		WaitForSingleObject(threaddata->thread, INFINITE);
1878 
1879 		//
1880 		// Release the thread handle, as we're done with
1881 		// it.
1882 		//
1883 		CloseHandle(threaddata->thread);
1884 #else
1885 		pthread_cancel(threaddata->thread);
1886 #endif
1887 		threaddata->have_thread = 0;
1888 	}
1889 
1890 	if (sockdata != INVALID_SOCKET)
1891 		sock_close(sockdata, NULL, 0);
1892 
1893 	if (session)
1894 	{
1895 		if (session->fp)
1896 			pcap_close(session->fp);
1897 		free(session);
1898 	}
1899 
1900 	return -1;
1901 }
1902 
1903 static int
daemon_msg_endcap_req(struct daemon_slpars * pars,struct session * session,struct thread_handle * threaddata)1904 daemon_msg_endcap_req(struct daemon_slpars *pars, struct session *session, struct thread_handle *threaddata)
1905 {
1906 	char errbuf[PCAP_ERRBUF_SIZE];		// buffer for network errors
1907 	struct rpcap_header header;
1908 
1909 	if (threaddata->have_thread)
1910 	{
1911 #ifdef _WIN32
1912 		//
1913 		// Tell the data connection thread main capture loop to
1914 		// break out of that loop.
1915 		//
1916 		pcap_breakloop(session->fp);
1917 
1918 		//
1919 		// If it's currently blocked waiting for packets to
1920 		// arrive, try to wake it up, so it can see the "break
1921 		// out of the loop" indication.
1922 		//
1923 		SetEvent(pcap_getevent(session->fp));
1924 
1925 		//
1926 		// Wait for the thread to exit, so we don't close
1927 		// sockets out from under it.
1928 		//
1929 		// XXX - have a timeout, so we don't wait forever?
1930 		//
1931 		WaitForSingleObject(threaddata->thread, INFINITE);
1932 
1933 		//
1934 		// Release the thread handle, as we're done with
1935 		// it.
1936 		//
1937 		CloseHandle(threaddata->thread);
1938 #else
1939 		pthread_cancel(threaddata->thread);
1940 #endif
1941 		threaddata->have_thread = 0;
1942 	}
1943 	if (session->sockdata)
1944 	{
1945 		sock_close(session->sockdata, NULL, 0);
1946 		session->sockdata = 0;
1947 	}
1948 
1949 	pcap_close(session->fp);
1950 
1951 	rpcap_createhdr(&header, pars->protocol_version,
1952 	    RPCAP_MSG_ENDCAP_REPLY, 0, 0);
1953 
1954 	if (sock_send(pars->sockctrl_out, (char *) &header, sizeof(struct rpcap_header), errbuf, PCAP_ERRBUF_SIZE) == -1)
1955 	{
1956 		// That failed; log a message and give up.
1957 		rpcapd_log(LOGPRIO_ERROR, "Send to client failed: %s", errbuf);
1958 		return -1;
1959 	}
1960 
1961 	return 0;
1962 }
1963 
1964 static int
daemon_unpackapplyfilter(SOCKET sockctrl_in,struct session * session,uint32 * plenp,char * errmsgbuf)1965 daemon_unpackapplyfilter(SOCKET sockctrl_in, struct session *session, uint32 *plenp, char *errmsgbuf)
1966 {
1967 	int status;
1968 	struct rpcap_filter filter;
1969 	struct rpcap_filterbpf_insn insn;
1970 	struct bpf_insn *bf_insn;
1971 	struct bpf_program bf_prog;
1972 	unsigned int i;
1973 
1974 	status = rpcapd_recv(sockctrl_in, (char *) &filter,
1975 	    sizeof(struct rpcap_filter), plenp, errmsgbuf);
1976 	if (status == -1)
1977 	{
1978 		return -1;
1979 	}
1980 	if (status == -2)
1981 	{
1982 		return -2;
1983 	}
1984 
1985 	bf_prog.bf_len = ntohl(filter.nitems);
1986 
1987 	if (ntohs(filter.filtertype) != RPCAP_UPDATEFILTER_BPF)
1988 	{
1989 		pcap_snprintf(errmsgbuf, PCAP_ERRBUF_SIZE, "Only BPF/NPF filters are currently supported");
1990 		return -2;
1991 	}
1992 
1993 	bf_insn = (struct bpf_insn *) malloc (sizeof(struct bpf_insn) * bf_prog.bf_len);
1994 	if (bf_insn == NULL)
1995 	{
1996 		pcap_fmt_errmsg_for_errno(errmsgbuf, PCAP_ERRBUF_SIZE,
1997 		    errno, "malloc() failed");
1998 		return -2;
1999 	}
2000 
2001 	bf_prog.bf_insns = bf_insn;
2002 
2003 	for (i = 0; i < bf_prog.bf_len; i++)
2004 	{
2005 		status = rpcapd_recv(sockctrl_in, (char *) &insn,
2006 		    sizeof(struct rpcap_filterbpf_insn), plenp, errmsgbuf);
2007 		if (status == -1)
2008 		{
2009 			return -1;
2010 		}
2011 		if (status == -2)
2012 		{
2013 			return -2;
2014 		}
2015 
2016 		bf_insn->code = ntohs(insn.code);
2017 		bf_insn->jf = insn.jf;
2018 		bf_insn->jt = insn.jt;
2019 		bf_insn->k = ntohl(insn.k);
2020 
2021 		bf_insn++;
2022 	}
2023 
2024 	if (bpf_validate(bf_prog.bf_insns, bf_prog.bf_len) == 0)
2025 	{
2026 		pcap_snprintf(errmsgbuf, PCAP_ERRBUF_SIZE, "The filter contains bogus instructions");
2027 		return -2;
2028 	}
2029 
2030 	if (pcap_setfilter(session->fp, &bf_prog))
2031 	{
2032 		pcap_snprintf(errmsgbuf, PCAP_ERRBUF_SIZE, "RPCAP error: %s", pcap_geterr(session->fp));
2033 		return -2;
2034 	}
2035 
2036 	return 0;
2037 }
2038 
2039 static int
daemon_msg_updatefilter_req(struct daemon_slpars * pars,struct session * session,uint32 plen)2040 daemon_msg_updatefilter_req(struct daemon_slpars *pars, struct session *session, uint32 plen)
2041 {
2042 	char errbuf[PCAP_ERRBUF_SIZE];
2043 	char errmsgbuf[PCAP_ERRBUF_SIZE];	// buffer for errors to send to the client
2044 	int ret;				// status of daemon_unpackapplyfilter()
2045 	struct rpcap_header header;		// keeps the answer to the updatefilter command
2046 
2047 	ret = daemon_unpackapplyfilter(pars->sockctrl_in, session, &plen, errmsgbuf);
2048 	if (ret == -1)
2049 	{
2050 		// Fatal error.  A message has been logged; just give up.
2051 		return -1;
2052 	}
2053 	if (ret == -2)
2054 	{
2055 		// Non-fatal error.  Send an error reply to the client.
2056 		goto error;
2057 	}
2058 
2059 	// Check if all the data has been read; if not, discard the data in excess
2060 	if (rpcapd_discard(pars->sockctrl_in, plen) == -1)
2061 	{
2062 		// Network error.
2063 		return -1;
2064 	}
2065 
2066 	// A response is needed, otherwise the other host does not know that everything went well
2067 	rpcap_createhdr(&header, pars->protocol_version,
2068 	    RPCAP_MSG_UPDATEFILTER_REPLY, 0, 0);
2069 
2070 	if (sock_send(pars->sockctrl_out, (char *) &header, sizeof (struct rpcap_header), pcap_geterr(session->fp), PCAP_ERRBUF_SIZE))
2071 	{
2072 		// That failed; log a messsage and give up.
2073 		rpcapd_log(LOGPRIO_ERROR, "Send to client failed: %s", errbuf);
2074 		return -1;
2075 	}
2076 
2077 	return 0;
2078 
2079 error:
2080 	if (rpcapd_discard(pars->sockctrl_in, plen) == -1)
2081 	{
2082 		return -1;
2083 	}
2084 	rpcap_senderror(pars->sockctrl_out, pars->protocol_version,
2085 	    PCAP_ERR_UPDATEFILTER, errmsgbuf, NULL);
2086 
2087 	return 0;
2088 }
2089 
2090 /*!
2091 	\brief Received the sampling parameters from remote host and it stores in the pcap_t structure.
2092 */
2093 static int
daemon_msg_setsampling_req(struct daemon_slpars * pars,uint32 plen,struct rpcap_sampling * samp_param)2094 daemon_msg_setsampling_req(struct daemon_slpars *pars, uint32 plen, struct rpcap_sampling *samp_param)
2095 {
2096 	char errbuf[PCAP_ERRBUF_SIZE];		// buffer for network errors
2097 	char errmsgbuf[PCAP_ERRBUF_SIZE];
2098 	struct rpcap_header header;
2099 	struct rpcap_sampling rpcap_samp;
2100 	int status;
2101 
2102 	status = rpcapd_recv(pars->sockctrl_in, (char *) &rpcap_samp, sizeof(struct rpcap_sampling), &plen, errmsgbuf);
2103 	if (status == -1)
2104 	{
2105 		return -1;
2106 	}
2107 	if (status == -2)
2108 	{
2109 		goto error;
2110 	}
2111 
2112 	// Save these settings in the pcap_t
2113 	samp_param->method = rpcap_samp.method;
2114 	samp_param->value = ntohl(rpcap_samp.value);
2115 
2116 	// A response is needed, otherwise the other host does not know that everything went well
2117 	rpcap_createhdr(&header, pars->protocol_version,
2118 	    RPCAP_MSG_SETSAMPLING_REPLY, 0, 0);
2119 
2120 	if (sock_send(pars->sockctrl_out, (char *) &header, sizeof (struct rpcap_header), errbuf, PCAP_ERRBUF_SIZE) == -1)
2121 	{
2122 		// That failed; log a messsage and give up.
2123 		rpcapd_log(LOGPRIO_ERROR, "Send to client failed: %s", errbuf);
2124 		return -1;
2125 	}
2126 
2127 	if (rpcapd_discard(pars->sockctrl_in, plen) == -1)
2128 	{
2129 		return -1;
2130 	}
2131 
2132 	return 0;
2133 
2134 error:
2135 	if (rpcap_senderror(pars->sockctrl_out, pars->protocol_version,
2136 	    PCAP_ERR_AUTH, errmsgbuf, errbuf) == -1)
2137 	{
2138 		// That failed; log a message and give up.
2139 		rpcapd_log(LOGPRIO_ERROR, "Send to client failed: %s", errbuf);
2140 		return -1;
2141 	}
2142 
2143 	// Check if all the data has been read; if not, discard the data in excess
2144 	if (rpcapd_discard(pars->sockctrl_in, plen) == -1)
2145 	{
2146 		return -1;
2147 	}
2148 
2149 	return 0;
2150 }
2151 
2152 static int
daemon_msg_stats_req(struct daemon_slpars * pars,struct session * session,uint32 plen,struct pcap_stat * stats,unsigned int svrcapt)2153 daemon_msg_stats_req(struct daemon_slpars *pars, struct session *session, uint32 plen, struct pcap_stat *stats, unsigned int svrcapt)
2154 {
2155 	char errbuf[PCAP_ERRBUF_SIZE];		// buffer for network errors
2156 	char errmsgbuf[PCAP_ERRBUF_SIZE];	// buffer for errors to send to the client
2157 	char sendbuf[RPCAP_NETBUF_SIZE];	// temporary buffer in which data to be sent is buffered
2158 	int sendbufidx = 0;			// index which keeps the number of bytes currently buffered
2159 	struct rpcap_stats *netstats;		// statistics sent on the network
2160 
2161 	// Checks that the header does not contain other data; if so, discard it
2162 	if (rpcapd_discard(pars->sockctrl_in, plen) == -1)
2163 	{
2164 		// Network error.
2165 		return -1;
2166 	}
2167 
2168 	if (sock_bufferize(NULL, sizeof(struct rpcap_header), NULL,
2169 	    &sendbufidx, RPCAP_NETBUF_SIZE, SOCKBUF_CHECKONLY, errmsgbuf, PCAP_ERRBUF_SIZE) == -1)
2170 		goto error;
2171 
2172 	rpcap_createhdr((struct rpcap_header *) sendbuf, pars->protocol_version,
2173 	    RPCAP_MSG_STATS_REPLY, 0, (uint16) sizeof(struct rpcap_stats));
2174 
2175 	netstats = (struct rpcap_stats *) &sendbuf[sendbufidx];
2176 
2177 	if (sock_bufferize(NULL, sizeof(struct rpcap_stats), NULL,
2178 	    &sendbufidx, RPCAP_NETBUF_SIZE, SOCKBUF_CHECKONLY, errmsgbuf, PCAP_ERRBUF_SIZE) == -1)
2179 		goto error;
2180 
2181 	if (session && session->fp)
2182 	{
2183 		if (pcap_stats(session->fp, stats) == -1)
2184 		{
2185 			pcap_snprintf(errmsgbuf, PCAP_ERRBUF_SIZE, "%s", pcap_geterr(session->fp));
2186 			goto error;
2187 		}
2188 
2189 		netstats->ifdrop = htonl(stats->ps_ifdrop);
2190 		netstats->ifrecv = htonl(stats->ps_recv);
2191 		netstats->krnldrop = htonl(stats->ps_drop);
2192 		netstats->svrcapt = htonl(session->TotCapt);
2193 	}
2194 	else
2195 	{
2196 		// We have to keep compatibility with old applications,
2197 		// which ask for statistics also when the capture has
2198 		// already stopped.
2199 		netstats->ifdrop = htonl(stats->ps_ifdrop);
2200 		netstats->ifrecv = htonl(stats->ps_recv);
2201 		netstats->krnldrop = htonl(stats->ps_drop);
2202 		netstats->svrcapt = htonl(svrcapt);
2203 	}
2204 
2205 	// Send the packet
2206 	if (sock_send(pars->sockctrl_out, sendbuf, sendbufidx, errbuf, PCAP_ERRBUF_SIZE) == -1)
2207 	{
2208 		rpcapd_log(LOGPRIO_ERROR, "Send to client failed: %s", errbuf);
2209 		return -1;
2210 	}
2211 
2212 	return 0;
2213 
2214 error:
2215 	rpcap_senderror(pars->sockctrl_out, pars->protocol_version,
2216 	    PCAP_ERR_GETSTATS, errmsgbuf, NULL);
2217 	return 0;
2218 }
2219 
2220 #ifdef _WIN32
2221 static unsigned __stdcall
2222 #else
2223 static void *
2224 #endif
daemon_thrdatamain(void * ptr)2225 daemon_thrdatamain(void *ptr)
2226 {
2227 	char errbuf[PCAP_ERRBUF_SIZE + 1];	// error buffer
2228 	struct session *session;		// pointer to the struct session for this session
2229 	int retval;							// general variable used to keep the return value of other functions
2230 	struct rpcap_pkthdr *net_pkt_header;// header of the packet
2231 	struct pcap_pkthdr *pkt_header;		// pointer to the buffer that contains the header of the current packet
2232 	u_char *pkt_data;					// pointer to the buffer that contains the current packet
2233 	size_t sendbufsize;			// size for the send buffer
2234 	char *sendbuf;						// temporary buffer in which data to be sent is buffered
2235 	int sendbufidx;						// index which keeps the number of bytes currently buffered
2236 	int status;
2237 
2238 	session = (struct session *) ptr;
2239 
2240 	session->TotCapt = 0;			// counter which is incremented each time a packet is received
2241 
2242 	// Initialize errbuf
2243 	memset(errbuf, 0, sizeof(errbuf));
2244 
2245 	//
2246 	// We need a buffer large enough to hold a buffer large enough
2247 	// for a maximum-size packet for this pcap_t.
2248 	//
2249 	if (pcap_snapshot(session->fp) < 0)
2250 	{
2251 		//
2252 		// The snapshot length is negative.
2253 		// This "should not happen".
2254 		//
2255 		rpcapd_log(LOGPRIO_ERROR,
2256 		    "Unable to allocate the buffer for this child thread: snapshot length of %d is negative",
2257 		        pcap_snapshot(session->fp));
2258 		sendbuf = NULL;	// we can't allocate a buffer, so nothing to free
2259 		goto error;
2260 	}
2261 	//
2262 	// size_t is unsigned, and the result of pcap_snapshot() is signed;
2263 	// on no platform that we support is int larger than size_t.
2264 	// This means that, unless the extra information we prepend to
2265 	// a maximum-sized packet is impossibly large, the sum of the
2266 	// snapshot length and the size of that extra information will
2267 	// fit in a size_t.
2268 	//
2269 	// So we don't need to make sure that sendbufsize will overflow.
2270 	//
2271 	sendbufsize = sizeof(struct rpcap_header) + sizeof(struct rpcap_pkthdr) + pcap_snapshot(session->fp);
2272 	sendbuf = (char *) malloc (sendbufsize);
2273 	if (sendbuf == NULL)
2274 	{
2275 		rpcapd_log(LOGPRIO_ERROR,
2276 		    "Unable to allocate the buffer for this child thread");
2277 		goto error;
2278 	}
2279 
2280 #ifndef _WIN32
2281 	// Modify thread params so that it can be killed at any time
2282 	retval = pthread_setcancelstate(PTHREAD_CANCEL_ENABLE, NULL);
2283 	if (retval != 0)
2284 	{
2285 		pcap_fmt_errmsg_for_errno(errbuf, PCAP_ERRBUF_SIZE,
2286 		    retval, "pthread_setcancelstate");
2287 		rpcapd_log(LOGPRIO_ERROR,
2288 		    "Can't set cancel state on data thread: %s", errbuf);
2289 		goto error;
2290 	}
2291 	retval = pthread_setcanceltype(PTHREAD_CANCEL_ASYNCHRONOUS, NULL);
2292 	if (retval != 0)
2293 	{
2294 		pcap_fmt_errmsg_for_errno(errbuf, PCAP_ERRBUF_SIZE,
2295 		    retval, "pthread_setcanceltype");
2296 		rpcapd_log(LOGPRIO_ERROR,
2297 		    "Can't set cancel type on data thread: %s", errbuf);
2298 		goto error;
2299 	}
2300 #endif
2301 
2302 	// Retrieve the packets
2303 	while ((retval = pcap_next_ex(session->fp, &pkt_header, (const u_char **) &pkt_data)) >= 0)	// cast to avoid a compiler warning
2304 	{
2305 		if (retval == 0)	// Read timeout elapsed
2306 			continue;
2307 
2308 		sendbufidx = 0;
2309 
2310 		// Bufferize the general header
2311 		if (sock_bufferize(NULL, sizeof(struct rpcap_header), NULL,
2312 		    &sendbufidx, sendbufsize, SOCKBUF_CHECKONLY, errbuf,
2313 		    PCAP_ERRBUF_SIZE) == -1)
2314 		{
2315 			rpcapd_log(LOGPRIO_ERROR,
2316 			    "sock_bufferize() error sending packet message: %s",
2317 			    errbuf);
2318 			goto error;
2319 		}
2320 
2321 		rpcap_createhdr((struct rpcap_header *) sendbuf,
2322 		    session->protocol_version, RPCAP_MSG_PACKET, 0,
2323 		    (uint16) (sizeof(struct rpcap_pkthdr) + pkt_header->caplen));
2324 
2325 		net_pkt_header = (struct rpcap_pkthdr *) &sendbuf[sendbufidx];
2326 
2327 		// Bufferize the pkt header
2328 		if (sock_bufferize(NULL, sizeof(struct rpcap_pkthdr), NULL,
2329 		    &sendbufidx, sendbufsize, SOCKBUF_CHECKONLY, errbuf,
2330 		    PCAP_ERRBUF_SIZE) == -1)
2331 		{
2332 			rpcapd_log(LOGPRIO_ERROR,
2333 			    "sock_bufferize() error sending packet message: %s",
2334 			    errbuf);
2335 			goto error;
2336 		}
2337 
2338 		net_pkt_header->caplen = htonl(pkt_header->caplen);
2339 		net_pkt_header->len = htonl(pkt_header->len);
2340 		net_pkt_header->npkt = htonl(++(session->TotCapt));
2341 		net_pkt_header->timestamp_sec = htonl(pkt_header->ts.tv_sec);
2342 		net_pkt_header->timestamp_usec = htonl(pkt_header->ts.tv_usec);
2343 
2344 		// Bufferize the pkt data
2345 		if (sock_bufferize((char *) pkt_data, pkt_header->caplen,
2346 		    sendbuf, &sendbufidx, sendbufsize, SOCKBUF_BUFFERIZE,
2347 		    errbuf, PCAP_ERRBUF_SIZE) == -1)
2348 		{
2349 			rpcapd_log(LOGPRIO_ERROR,
2350 			    "sock_bufferize() error sending packet message: %s",
2351 			    errbuf);
2352 			goto error;
2353 		}
2354 
2355 		// Send the packet
2356 		// If the client dropped the connection, don't report an
2357 		// error, just quit.
2358 		status = sock_send(session->sockdata, sendbuf, sendbufidx, errbuf, PCAP_ERRBUF_SIZE);
2359 		if (status < 0)
2360 		{
2361 			if (status == -1)
2362 			{
2363 				//
2364 				// Error other than "client closed the
2365 				// connection out from under us"; report
2366 				// it.
2367 				//
2368 				rpcapd_log(LOGPRIO_ERROR,
2369 				    "Send of packet to client failed: %s",
2370 				    errbuf);
2371 			}
2372 
2373 			//
2374 			// Give up in either case.
2375 			//
2376 			goto error;
2377 		}
2378 	}
2379 
2380 	if (retval == -1)
2381 	{
2382 		pcap_snprintf(errbuf, PCAP_ERRBUF_SIZE, "Error reading the packets: %s", pcap_geterr(session->fp));
2383 		rpcap_senderror(session->sockctrl_out, session->protocol_version,
2384 		    PCAP_ERR_READEX, errbuf, NULL);
2385 		goto error;
2386 	}
2387 
2388 error:
2389  	closesocket(session->sockdata);
2390 	session->sockdata = 0;
2391 
2392 	free(sendbuf);
2393 
2394 	return 0;
2395 }
2396 
2397 /*!
2398 	\brief It serializes a network address.
2399 
2400 	It accepts a 'sockaddr_storage' structure as input, and it converts it appropriately into a format
2401 	that can be used to be sent on the network. Basically, it applies all the hton()
2402 	conversion required to the input variable.
2403 
2404 	\param sockaddrin a 'sockaddr_storage' pointer to the variable that has to be
2405 	serialized. This variable can be both a 'sockaddr_in' and 'sockaddr_in6'.
2406 
2407 	\param sockaddrout an 'rpcap_sockaddr' pointer to the variable that will contain
2408 	the serialized data. This variable has to be allocated by the user.
2409 
2410 	\warning This function supports only AF_INET and AF_INET6 address families.
2411 */
2412 static void
daemon_seraddr(struct sockaddr_storage * sockaddrin,struct rpcap_sockaddr * sockaddrout)2413 daemon_seraddr(struct sockaddr_storage *sockaddrin, struct rpcap_sockaddr *sockaddrout)
2414 {
2415 	memset(sockaddrout, 0, sizeof(struct sockaddr_storage));
2416 
2417 	// There can be the case in which the sockaddrin is not available
2418 	if (sockaddrin == NULL) return;
2419 
2420 	// Warning: we support only AF_INET and AF_INET6
2421 	switch (sockaddrin->ss_family)
2422 	{
2423 	case AF_INET:
2424 		{
2425 		struct sockaddr_in *sockaddrin_ipv4;
2426 		struct rpcap_sockaddr_in *sockaddrout_ipv4;
2427 
2428 		sockaddrin_ipv4 = (struct sockaddr_in *) sockaddrin;
2429 		sockaddrout_ipv4 = (struct rpcap_sockaddr_in *) sockaddrout;
2430 		sockaddrout_ipv4->family = htons(RPCAP_AF_INET);
2431 		sockaddrout_ipv4->port = htons(sockaddrin_ipv4->sin_port);
2432 		memcpy(&sockaddrout_ipv4->addr, &sockaddrin_ipv4->sin_addr, sizeof(sockaddrout_ipv4->addr));
2433 		memset(sockaddrout_ipv4->zero, 0, sizeof(sockaddrout_ipv4->zero));
2434 		break;
2435 		}
2436 
2437 #ifdef AF_INET6
2438 	case AF_INET6:
2439 		{
2440 		struct sockaddr_in6 *sockaddrin_ipv6;
2441 		struct rpcap_sockaddr_in6 *sockaddrout_ipv6;
2442 
2443 		sockaddrin_ipv6 = (struct sockaddr_in6 *) sockaddrin;
2444 		sockaddrout_ipv6 = (struct rpcap_sockaddr_in6 *) sockaddrout;
2445 		sockaddrout_ipv6->family = htons(RPCAP_AF_INET6);
2446 		sockaddrout_ipv6->port = htons(sockaddrin_ipv6->sin6_port);
2447 		sockaddrout_ipv6->flowinfo = htonl(sockaddrin_ipv6->sin6_flowinfo);
2448 		memcpy(&sockaddrout_ipv6->addr, &sockaddrin_ipv6->sin6_addr, sizeof(sockaddrout_ipv6->addr));
2449 		sockaddrout_ipv6->scope_id = htonl(sockaddrin_ipv6->sin6_scope_id);
2450 		break;
2451 		}
2452 #endif
2453 	}
2454 }
2455 
2456 
2457 /*!
2458 	\brief Suspends a thread for secs seconds.
2459 */
sleep_secs(int secs)2460 void sleep_secs(int secs)
2461 {
2462 #ifdef _WIN32
2463 	Sleep(secs*1000);
2464 #else
2465 	unsigned secs_remaining;
2466 
2467 	if (secs <= 0)
2468 		return;
2469 	secs_remaining = secs;
2470 	while (secs_remaining != 0)
2471 		secs_remaining = sleep(secs_remaining);
2472 #endif
2473 }
2474 
2475 /*
2476  * Read the header of a message.
2477  */
2478 static int
rpcapd_recv_msg_header(SOCKET sock,struct rpcap_header * headerp)2479 rpcapd_recv_msg_header(SOCKET sock, struct rpcap_header *headerp)
2480 {
2481 	int nread;
2482 	char errbuf[PCAP_ERRBUF_SIZE];		// buffer for network errors
2483 
2484 	nread = sock_recv(sock, (char *) headerp, sizeof(struct rpcap_header),
2485 	    SOCK_RECEIVEALL_YES|SOCK_EOF_ISNT_ERROR, errbuf, PCAP_ERRBUF_SIZE);
2486 	if (nread == -1)
2487 	{
2488 		// Network error.
2489 		rpcapd_log(LOGPRIO_ERROR, "Read from client failed: %s", errbuf);
2490 		return -1;
2491 	}
2492 	if (nread == 0)
2493 	{
2494 		// Immediate EOF; that's treated like a close message.
2495 		return -2;
2496 	}
2497 	headerp->plen = ntohl(headerp->plen);
2498 	return 0;
2499 }
2500 
2501 /*
2502  * Read data from a message.
2503  * If we're trying to read more data that remains, puts an error
2504  * message into errmsgbuf and returns -2.  Otherwise, tries to read
2505  * the data and, if that succeeds, subtracts the amount read from
2506  * the number of bytes of data that remains.
2507  * Returns 0 on success, logs a message and returns -1 on a network
2508  * error.
2509  */
2510 static int
rpcapd_recv(SOCKET sock,char * buffer,size_t toread,uint32 * plen,char * errmsgbuf)2511 rpcapd_recv(SOCKET sock, char *buffer, size_t toread, uint32 *plen, char *errmsgbuf)
2512 {
2513 	int nread;
2514 	char errbuf[PCAP_ERRBUF_SIZE];		// buffer for network errors
2515 
2516 	if (toread > *plen)
2517 	{
2518 		// Tell the client and continue.
2519 		pcap_snprintf(errmsgbuf, PCAP_ERRBUF_SIZE, "Message payload is too short");
2520 		return -2;
2521 	}
2522 	nread = sock_recv(sock, buffer, toread,
2523 	    SOCK_RECEIVEALL_YES|SOCK_EOF_IS_ERROR, errbuf, PCAP_ERRBUF_SIZE);
2524 	if (nread == -1)
2525 	{
2526 		rpcapd_log(LOGPRIO_ERROR, "Read from client failed: %s", errbuf);
2527 		return -1;
2528 	}
2529 	*plen -= nread;
2530 	return 0;
2531 }
2532 
2533 /*
2534  * Discard data from a connection.
2535  * Mostly used to discard wrong-sized messages.
2536  * Returns 0 on success, logs a message and returns -1 on a network
2537  * error.
2538  */
2539 static int
rpcapd_discard(SOCKET sock,uint32 len)2540 rpcapd_discard(SOCKET sock, uint32 len)
2541 {
2542 	char errbuf[PCAP_ERRBUF_SIZE + 1];	// keeps the error string, prior to be printed
2543 
2544 	if (len != 0)
2545 	{
2546 		if (sock_discard(sock, len, errbuf, PCAP_ERRBUF_SIZE) == -1)
2547 		{
2548 			// Network error.
2549 			rpcapd_log(LOGPRIO_ERROR, "Read from client failed: %s", errbuf);
2550 			return -1;
2551 		}
2552 	}
2553 	return 0;
2554 }
2555