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