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