2 * Copyright (c) 2002 - 2003
3 * NetGroup, Politecnico di Torino (Italy)
6 * Redistribution and use in source and binary forms, with or without
7 * modification, are permitted provided that the following conditions
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.
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.
39 #include <errno.h> // for the errno variable
40 #include <stdlib.h> // for malloc(), free(), ...
41 #include <string.h> // for strlen(), ...
42 #include <limits.h> // for INT_MAX
45 #include <process.h> // for threads
50 #include <sys/types.h> // for select() and such
51 #include <pwd.h> // for password management
55 #include <shadow.h> // for password management
58 #include <pcap.h> // for libpcap/WinPcap calls
61 #include "sockutils.h" // for socket calls
62 #include "portability.h"
63 #include "rpcap-protocol.h"
68 #include <openssl/ssl.h>
72 #define RPCAP_TIMEOUT_INIT 90 /* Initial timeout for RPCAP connections (default: 90 sec) */
73 #define RPCAP_TIMEOUT_RUNTIME 180 /* Run-time timeout for RPCAP connections (default: 3 min) */
74 #define RPCAP_SUSPEND_WRONGAUTH 1 /* If the authentication is wrong, stops 1 sec before accepting a new auth message */
76 // Parameters for the service loop.
79 SOCKET sockctrl_in
; //!< SOCKET ID of the input side of the control connection
80 SOCKET sockctrl_out
; //!< SOCKET ID of the output side of the control connection
81 SSL
*ssl
; //!< Optional SSL handler for the controlling sockets
82 uint8 protocol_version
; //!< negotiated protocol version
83 int isactive
; //!< Not null if the daemon has to run in active mode
84 int nullAuthAllowed
; //!< '1' if we permit NULL authentication, '0' otherwise
88 * Data for a session managed by a thread.
93 SSL
*ctrl_ssl
, *data_ssl
; // optional SSL handlers for sockctrl_out and sockdata.
94 uint8 protocol_version
;
100 // Structure to refer to a thread.
101 // It includes both a Boolean indicating whether we *have* a thread,
102 // and a platform-dependent (UN*X vs. Windows) identifier for the
103 // thread; on Windows, we could use an invalid handle to indicate
104 // that we don't have a thread, but there *is* no portable "no thread"
105 // value for a pthread_t on UN*X.
107 struct thread_handle
{
116 // Locally defined functions
117 static int daemon_msg_err(SOCKET sockctrl_in
, SSL
*, uint32 plen
);
118 static int daemon_msg_auth_req(struct daemon_slpars
*pars
, uint32 plen
);
119 static int daemon_AuthUserPwd(char *username
, char *password
, char *errbuf
);
121 static int daemon_msg_findallif_req(struct daemon_slpars
*pars
, uint32 plen
);
123 static int daemon_msg_open_req(struct daemon_slpars
*pars
, uint32 plen
, char *source
, size_t sourcelen
);
124 static int daemon_msg_startcap_req(struct daemon_slpars
*pars
, uint32 plen
, struct thread_handle
*threaddata
, char *source
, struct session
**sessionp
, struct rpcap_sampling
*samp_param
, int uses_ssl
);
125 static int daemon_msg_endcap_req(struct daemon_slpars
*pars
, struct session
*session
, struct thread_handle
*threaddata
);
127 static int daemon_msg_updatefilter_req(struct daemon_slpars
*pars
, struct session
*session
, uint32 plen
);
128 static int daemon_unpackapplyfilter(SOCKET sockctrl_in
, SSL
*, struct session
*session
, uint32
*plenp
, char *errbuf
);
130 static int daemon_msg_stats_req(struct daemon_slpars
*pars
, struct session
*session
, uint32 plen
, struct pcap_stat
*stats
, unsigned int svrcapt
);
132 static int daemon_msg_setsampling_req(struct daemon_slpars
*pars
, uint32 plen
, struct rpcap_sampling
*samp_param
);
134 static void daemon_seraddr(struct sockaddr_storage
*sockaddrin
, struct rpcap_sockaddr
*sockaddrout
);
136 static unsigned __stdcall
daemon_thrdatamain(void *ptr
);
138 static void *daemon_thrdatamain(void *ptr
);
141 static int rpcapd_recv_msg_header(SOCKET sock
, SSL
*, struct rpcap_header
*headerp
);
142 static int rpcapd_recv(SOCKET sock
, SSL
*, char *buffer
, size_t toread
, uint32
*plen
, char *errmsgbuf
);
143 static int rpcapd_discard(SOCKET sock
, SSL
*, uint32 len
);
144 static void session_close(struct session
*);
147 daemon_serviceloop(SOCKET sockctrl_in
, SOCKET sockctrl_out
,
148 int isactive
, char *passiveClients
, int nullAuthAllowed
, int uses_ssl
)
150 struct daemon_slpars pars
; // service loop parameters
151 char errbuf
[PCAP_ERRBUF_SIZE
+ 1]; // keeps the error string, prior to be printed
152 char errmsgbuf
[PCAP_ERRBUF_SIZE
+ 1]; // buffer for errors to send to the client
156 struct rpcap_header header
; // RPCAP message general header
157 uint32 plen
; // payload length from header
158 int authenticated
= 0; // 1 if the client has successfully authenticated
159 char source
[PCAP_BUF_SIZE
+1]; // keeps the string that contains the interface to open
160 int got_source
= 0; // 1 if we've gotten the source from an open request
161 struct session
*session
= NULL
; // struct session main variable
162 const char *msg_type_string
; // string for message type
163 int client_told_us_to_close
= 0; // 1 if the client told us to close the capture
165 struct thread_handle threaddata
; // 'read from daemon and send to client' thread
167 // needed to save the values of the statistics
168 struct pcap_stat stats
;
169 unsigned int svrcapt
;
171 struct rpcap_sampling samp_param
; // in case sampling has been requested
173 // Structures needed for the select() call
174 fd_set rfds
; // set of socket descriptors we have to check
175 struct timeval tv
; // maximum time the select() can block waiting for data
176 int retval
; // select() return value
178 // We don't have a thread yet.
179 threaddata
.have_thread
= 0;
181 // We *shouldn't* have to initialize the thread indicator
182 // itself, because the compiler *should* realize that we
183 // only use this if have_thread isn't 0, but we *do* have
184 // to do it, because not all compilers *do* realize that.
186 // There is no "invalid thread handle" value for a UN*X
187 // pthread_t, so we just zero it out.
190 threaddata
.thread
= INVALID_HANDLE_VALUE
;
192 memset(&threaddata
.thread
, 0, sizeof(threaddata
.thread
));
195 *errbuf
= 0; // Initialize errbuf
197 // Set parameters structure
198 pars
.sockctrl_in
= sockctrl_in
;
199 pars
.sockctrl_out
= sockctrl_out
;
200 pars
.protocol_version
= 0; // not yet known
201 pars
.isactive
= isactive
; // active mode
202 pars
.nullAuthAllowed
= nullAuthAllowed
;
206 // We have to upgrade to TLS as soon as possible, so that the
207 // whole protocol goes through the encrypted tunnel, including
208 // early error messages.
210 // Even in active mode, the other end has to initiate the TLS
211 // handshake as we still are the server as far as TLS is concerned,
212 // so we don't check isactive.
216 ssl
= ssl_promotion_rw(1, pars
.sockctrl_in
, pars
.sockctrl_out
, errbuf
, PCAP_ERRBUF_SIZE
);
219 rpcapd_log(LOGPRIO_ERROR
, "TLS handshake on control connection failed: %s",
228 // We have a connection.
230 // If it's a passive mode connection, check whether the connecting
231 // host is among the ones allowed.
233 // In either case, we were handed a copy of the host list; free it
234 // as soon as we're done with it.
239 free(passiveClients
);
240 passiveClients
= NULL
;
244 struct sockaddr_storage from
;
248 // Get the address of the other end of the connection.
250 fromlen
= sizeof(struct sockaddr_storage
);
251 if (getpeername(pars
.sockctrl_in
, (struct sockaddr
*)&from
,
254 sock_geterror("getpeername(): ", errmsgbuf
, PCAP_ERRBUF_SIZE
);
255 if (rpcap_senderror(pars
.sockctrl_out
, pars
.ssl
, 0, PCAP_ERR_NETW
, errmsgbuf
, errbuf
) == -1)
256 rpcapd_log(LOGPRIO_ERROR
, "Send to client failed: %s", errbuf
);
261 // Are they in the list of host/port combinations we allow?
263 host_port_ok
= (sock_check_hostlist(passiveClients
, RPCAP_HOSTLIST_SEP
, &from
, errmsgbuf
, PCAP_ERRBUF_SIZE
) == 0);
264 free(passiveClients
);
265 passiveClients
= NULL
;
269 // Sorry, you're not on the guest list.
271 if (rpcap_senderror(pars
.sockctrl_out
, pars
.ssl
, 0, PCAP_ERR_HOSTNOAUTH
, errmsgbuf
, errbuf
) == -1)
272 rpcapd_log(LOGPRIO_ERROR
, "Send to client failed: %s", errbuf
);
278 // The client must first authenticate; loop until they send us a
279 // message with a version we support and credentials we accept,
280 // they send us a close message indicating that they're giving up,
281 // or we get a network error or other fatal error.
283 while (!authenticated
)
286 // If we're in active mode, we have to check for the
289 // XXX - do this on *every* trip through the loop?
294 // We do not have to block here
295 tv
.tv_sec
= RPCAP_TIMEOUT_INIT
;
298 FD_SET(pars
.sockctrl_in
, &rfds
);
300 retval
= select((int)pars
.sockctrl_in
+ 1, &rfds
, NULL
, NULL
, &tv
);
303 sock_geterror("select failed: ", errmsgbuf
, PCAP_ERRBUF_SIZE
);
304 if (rpcap_senderror(pars
.sockctrl_out
, pars
.ssl
, 0, PCAP_ERR_NETW
, errmsgbuf
, errbuf
) == -1)
305 rpcapd_log(LOGPRIO_ERROR
, "Send to client failed: %s", errbuf
);
309 // The timeout has expired
310 // So, this was a fake connection. Drop it down
313 if (rpcap_senderror(pars
.sockctrl_out
, pars
.ssl
, 0, PCAP_ERR_INITTIMEOUT
, "The RPCAP initial timeout has expired", errbuf
) == -1)
314 rpcapd_log(LOGPRIO_ERROR
, "Send to client failed: %s", errbuf
);
320 // Read the message header from the client.
322 nrecv
= rpcapd_recv_msg_header(pars
.sockctrl_in
, pars
.ssl
, &header
);
330 // Client closed the connection.
337 // Did the client specify a version we can handle?
339 if (!RPCAP_VERSION_IS_SUPPORTED(header
.ver
))
342 // Tell them it's not a valid protocol version.
347 // If RPCAP_MIN_VERSION is 0, no version is too
348 // old, as the oldest supported version is 0,
349 // and there are no negative versions.
351 #if RPCAP_MIN_VERSION != 0
352 if (header
.ver
< RPCAP_MIN_VERSION
)
355 // Their maximum version is too old;
356 // there *is* no version we can both
357 // handle, and they might reject
358 // an error with a version they don't
359 // understand, so reply with the
360 // version they sent. That may
361 // make them retry with that version,
362 // but they'll give up on that
365 reply_version
= header
.ver
;
371 // Their maximum version is too new,
372 // but they might be able to handle
373 // *our* maximum version, so reply
374 // with that version.
376 reply_version
= RPCAP_MAX_VERSION
;
378 if (rpcap_senderror(pars
.sockctrl_out
, pars
.ssl
, reply_version
,
379 PCAP_ERR_WRONGVER
, "RPCAP version number mismatch",
382 // That failed; log a message and give up.
383 rpcapd_log(LOGPRIO_ERROR
, "Send to client failed: %s", errbuf
);
387 // Discard the rest of the message.
388 if (rpcapd_discard(pars
.sockctrl_in
, pars
.ssl
, plen
) == -1)
394 // Let them try again.
399 // OK, we use the version the client specified.
401 pars
.protocol_version
= header
.ver
;
405 case RPCAP_MSG_AUTH_REQ
:
406 retval
= daemon_msg_auth_req(&pars
, plen
);
409 // Fatal error; a message has
410 // been logged, so just give up.
415 // Non-fatal error; we sent back
416 // an error message, so let them
421 // OK, we're authenticated; we sent back
422 // a reply, so start serving requests.
426 case RPCAP_MSG_CLOSE
:
428 // The client is giving up.
429 // Discard the rest of the message, if
430 // there is anything more.
432 (void)rpcapd_discard(pars
.sockctrl_in
, pars
.ssl
, plen
);
433 // We're done with this client.
436 case RPCAP_MSG_ERROR
:
437 // Log this and close the connection?
438 // XXX - is this what happens in active
439 // mode, where *we* initiate the
440 // connection, and the client gives us
441 // an error message rather than a "let
442 // me log in" message, indicating that
443 // we're not allowed to connect to them?
444 (void)daemon_msg_err(pars
.sockctrl_in
, pars
.ssl
, plen
);
447 case RPCAP_MSG_FINDALLIF_REQ
:
448 case RPCAP_MSG_OPEN_REQ
:
449 case RPCAP_MSG_STARTCAP_REQ
:
450 case RPCAP_MSG_UPDATEFILTER_REQ
:
451 case RPCAP_MSG_STATS_REQ
:
452 case RPCAP_MSG_ENDCAP_REQ
:
453 case RPCAP_MSG_SETSAMPLING_REQ
:
455 // These requests can't be sent until
456 // the client is authenticated.
458 msg_type_string
= rpcap_msg_type_string(header
.type
);
459 if (msg_type_string
!= NULL
)
461 pcap_snprintf(errmsgbuf
, PCAP_ERRBUF_SIZE
, "%s request sent before authentication was completed", msg_type_string
);
465 pcap_snprintf(errmsgbuf
, PCAP_ERRBUF_SIZE
, "Message of type %u sent before authentication was completed", header
.type
);
467 if (rpcap_senderror(pars
.sockctrl_out
, pars
.ssl
,
468 pars
.protocol_version
, PCAP_ERR_WRONGMSG
,
469 errmsgbuf
, errbuf
) == -1)
471 rpcapd_log(LOGPRIO_ERROR
, "Send to client failed: %s", errbuf
);
474 // Discard the rest of the message.
475 if (rpcapd_discard(pars
.sockctrl_in
, pars
.ssl
, plen
) == -1)
482 case RPCAP_MSG_PACKET
:
483 case RPCAP_MSG_FINDALLIF_REPLY
:
484 case RPCAP_MSG_OPEN_REPLY
:
485 case RPCAP_MSG_STARTCAP_REPLY
:
486 case RPCAP_MSG_UPDATEFILTER_REPLY
:
487 case RPCAP_MSG_AUTH_REPLY
:
488 case RPCAP_MSG_STATS_REPLY
:
489 case RPCAP_MSG_ENDCAP_REPLY
:
490 case RPCAP_MSG_SETSAMPLING_REPLY
:
492 // These are server-to-client messages.
494 msg_type_string
= rpcap_msg_type_string(header
.type
);
495 if (msg_type_string
!= NULL
)
497 pcap_snprintf(errmsgbuf
, PCAP_ERRBUF_SIZE
, "Server-to-client message %s received from client", msg_type_string
);
501 pcap_snprintf(errmsgbuf
, PCAP_ERRBUF_SIZE
, "Server-to-client message of type %u received from client", header
.type
);
503 if (rpcap_senderror(pars
.sockctrl_out
, pars
.ssl
,
504 pars
.protocol_version
, PCAP_ERR_WRONGMSG
,
505 errmsgbuf
, errbuf
) == -1)
507 rpcapd_log(LOGPRIO_ERROR
, "Send to client failed: %s", errbuf
);
510 // Discard the rest of the message.
511 if (rpcapd_discard(pars
.sockctrl_in
, pars
.ssl
, plen
) == -1)
520 // Unknown message type.
522 pcap_snprintf(errmsgbuf
, PCAP_ERRBUF_SIZE
, "Unknown message type %u", header
.type
);
523 if (rpcap_senderror(pars
.sockctrl_out
, pars
.ssl
,
524 pars
.protocol_version
, PCAP_ERR_WRONGMSG
,
525 errmsgbuf
, errbuf
) == -1)
527 rpcapd_log(LOGPRIO_ERROR
, "Send to client failed: %s", errbuf
);
530 // Discard the rest of the message.
531 if (rpcapd_discard(pars
.sockctrl_in
, pars
.ssl
, plen
) == -1)
541 // OK, the client has authenticated itself, and we can start
542 // processing regular requests from it.
546 // We don't have any statistics yet.
558 errbuf
[0] = 0; // clear errbuf
560 // Avoid zombies connections; check if the connection is opens but no commands are performed
561 // from more than RPCAP_TIMEOUT_RUNTIME
563 // - I have to be in normal mode (no active mode)
564 // - if the device is open, I don't have to be in the middle of a capture (session->sockdata)
565 // - if the device is closed, I have always to check if a new command arrives
567 // Be carefully: the capture can have been started, but an error occurred (so session != NULL, but
569 if ((!pars
.isactive
) && ((session
== NULL
) || ((session
!= NULL
) && (session
->sockdata
== 0))))
571 // Check for the initial timeout
573 // We do not have to block here
574 tv
.tv_sec
= RPCAP_TIMEOUT_RUNTIME
;
577 FD_SET(pars
.sockctrl_in
, &rfds
);
579 retval
= select((int)pars
.sockctrl_in
+ 1, &rfds
, NULL
, NULL
, &tv
);
582 sock_geterror("select failed: ", errmsgbuf
, PCAP_ERRBUF_SIZE
);
583 if (rpcap_senderror(pars
.sockctrl_out
, pars
.ssl
,
584 pars
.protocol_version
, PCAP_ERR_NETW
,
585 errmsgbuf
, errbuf
) == -1)
586 rpcapd_log(LOGPRIO_ERROR
, "Send to client failed: %s", errbuf
);
590 // The timeout has expired
591 // So, this was a fake connection. Drop it down
594 if (rpcap_senderror(pars
.sockctrl_out
, pars
.ssl
,
595 pars
.protocol_version
,
596 PCAP_ERR_INITTIMEOUT
,
597 "The RPCAP initial timeout has expired",
599 rpcapd_log(LOGPRIO_ERROR
, "Send to client failed: %s", errbuf
);
605 // Read the message header from the client.
607 nrecv
= rpcapd_recv_msg_header(pars
.sockctrl_in
, pars
.ssl
, &header
);
615 // Client closed the connection.
622 // Did the client specify the version we negotiated?
624 // For now, there's only one version.
626 if (header
.ver
!= pars
.protocol_version
)
629 // Tell them it's not the negotiated version.
630 // Send the error message with their version,
631 // so they don't reject it as having the wrong
634 if (rpcap_senderror(pars
.sockctrl_out
, pars
.ssl
,
635 header
.ver
, PCAP_ERR_WRONGVER
,
636 "RPCAP version in message isn't the negotiated version",
639 // That failed; log a message and give up.
640 rpcapd_log(LOGPRIO_ERROR
, "Send to client failed: %s", errbuf
);
644 // Discard the rest of the message.
645 (void)rpcapd_discard(pars
.sockctrl_in
, pars
.ssl
, plen
);
652 case RPCAP_MSG_ERROR
: // The other endpoint reported an error
654 (void)daemon_msg_err(pars
.sockctrl_in
, pars
.ssl
, plen
);
655 // Do nothing; just exit; the error code is already into the errbuf
656 // XXX - actually exit....
660 case RPCAP_MSG_FINDALLIF_REQ
:
662 if (daemon_msg_findallif_req(&pars
, plen
) == -1)
664 // Fatal error; a message has
665 // been logged, so just give up.
671 case RPCAP_MSG_OPEN_REQ
:
674 // Process the open request, and keep
675 // the source from it, for use later
676 // when the capture is started.
678 // XXX - we don't care if the client sends
679 // us multiple open requests, the last
682 retval
= daemon_msg_open_req(&pars
, plen
, source
, sizeof(source
));
685 // Fatal error; a message has
686 // been logged, so just give up.
693 case RPCAP_MSG_STARTCAP_REQ
:
697 // They never told us what device
699 if (rpcap_senderror(pars
.sockctrl_out
, pars
.ssl
,
700 pars
.protocol_version
,
701 PCAP_ERR_STARTCAPTURE
,
702 "No capture device was specified",
705 // Fatal error; log an
706 // error and give up.
707 rpcapd_log(LOGPRIO_ERROR
, "Send to client failed: %s", errbuf
);
710 if (rpcapd_discard(pars
.sockctrl_in
, pars
.ssl
, plen
) == -1)
717 if (daemon_msg_startcap_req(&pars
, plen
, &threaddata
, source
, &session
, &samp_param
, uses_ssl
) == -1)
719 // Fatal error; a message has
720 // been logged, so just give up.
726 case RPCAP_MSG_UPDATEFILTER_REQ
:
730 if (daemon_msg_updatefilter_req(&pars
, session
, plen
) == -1)
732 // Fatal error; a message has
733 // been logged, so just give up.
739 if (rpcap_senderror(pars
.sockctrl_out
, pars
.ssl
,
740 pars
.protocol_version
,
741 PCAP_ERR_UPDATEFILTER
,
742 "Device not opened. Cannot update filter",
745 // That failed; log a message and give up.
746 rpcapd_log(LOGPRIO_ERROR
, "Send to client failed: %s", errbuf
);
753 case RPCAP_MSG_CLOSE
: // The other endpoint close the pcap session
756 // Indicate to our caller that the client
757 // closed the control connection.
758 // This is used only in case of active mode.
760 client_told_us_to_close
= 1;
761 rpcapd_log(LOGPRIO_DEBUG
, "The other end system asked to close the connection.");
765 case RPCAP_MSG_STATS_REQ
:
767 if (daemon_msg_stats_req(&pars
, session
, plen
, &stats
, svrcapt
) == -1)
769 // Fatal error; a message has
770 // been logged, so just give up.
776 case RPCAP_MSG_ENDCAP_REQ
: // The other endpoint close the current capture session
780 // Save statistics (we can need them in the future)
781 if (pcap_stats(session
->fp
, &stats
))
783 svrcapt
= session
->TotCapt
;
793 if (daemon_msg_endcap_req(&pars
, session
, &threaddata
) == -1)
797 // Fatal error; a message has
798 // been logged, so just give up.
806 rpcap_senderror(pars
.sockctrl_out
, pars
.ssl
,
807 pars
.protocol_version
,
809 "Device not opened. Cannot close the capture",
815 case RPCAP_MSG_SETSAMPLING_REQ
:
817 if (daemon_msg_setsampling_req(&pars
, plen
, &samp_param
) == -1)
819 // Fatal error; a message has
820 // been logged, so just give up.
826 case RPCAP_MSG_AUTH_REQ
:
829 // We're already authenticated; you don't
830 // get to reauthenticate.
832 rpcapd_log(LOGPRIO_INFO
, "The client sent an RPCAP_MSG_AUTH_REQ message after authentication was completed");
833 if (rpcap_senderror(pars
.sockctrl_out
, pars
.ssl
,
834 pars
.protocol_version
,
836 "RPCAP_MSG_AUTH_REQ request sent after authentication was completed",
839 rpcapd_log(LOGPRIO_ERROR
, "Send to client failed: %s", errbuf
);
842 // Discard the rest of the message.
843 if (rpcapd_discard(pars
.sockctrl_in
, pars
.ssl
, plen
) == -1)
850 case RPCAP_MSG_PACKET
:
851 case RPCAP_MSG_FINDALLIF_REPLY
:
852 case RPCAP_MSG_OPEN_REPLY
:
853 case RPCAP_MSG_STARTCAP_REPLY
:
854 case RPCAP_MSG_UPDATEFILTER_REPLY
:
855 case RPCAP_MSG_AUTH_REPLY
:
856 case RPCAP_MSG_STATS_REPLY
:
857 case RPCAP_MSG_ENDCAP_REPLY
:
858 case RPCAP_MSG_SETSAMPLING_REPLY
:
860 // These are server-to-client messages.
862 msg_type_string
= rpcap_msg_type_string(header
.type
);
863 if (msg_type_string
!= NULL
)
865 rpcapd_log(LOGPRIO_INFO
, "The client sent a %s server-to-client message", msg_type_string
);
866 pcap_snprintf(errmsgbuf
, PCAP_ERRBUF_SIZE
, "Server-to-client message %s received from client", msg_type_string
);
870 rpcapd_log(LOGPRIO_INFO
, "The client sent a server-to-client message of type %u", header
.type
);
871 pcap_snprintf(errmsgbuf
, PCAP_ERRBUF_SIZE
, "Server-to-client message of type %u received from client", header
.type
);
873 if (rpcap_senderror(pars
.sockctrl_out
, pars
.ssl
,
874 pars
.protocol_version
, PCAP_ERR_WRONGMSG
,
875 errmsgbuf
, errbuf
) == -1)
877 rpcapd_log(LOGPRIO_ERROR
, "Send to client failed: %s", errbuf
);
880 // Discard the rest of the message.
881 if (rpcapd_discard(pars
.sockctrl_in
, pars
.ssl
, plen
) == -1)
890 // Unknown message type.
892 rpcapd_log(LOGPRIO_INFO
, "The client sent a message of type %u", header
.type
);
893 pcap_snprintf(errmsgbuf
, PCAP_ERRBUF_SIZE
, "Unknown message type %u", header
.type
);
894 if (rpcap_senderror(pars
.sockctrl_out
, pars
.ssl
,
895 pars
.protocol_version
, PCAP_ERR_WRONGMSG
,
896 errbuf
, errmsgbuf
) == -1)
898 rpcapd_log(LOGPRIO_ERROR
, "Send to client failed: %s", errbuf
);
901 // Discard the rest of the message.
902 if (rpcapd_discard(pars
.sockctrl_in
, pars
.ssl
, plen
) == -1)
913 // The child thread is about to end
915 // perform pcap_t cleanup, in case it has not been done
918 if (threaddata
.have_thread
)
922 // Tell the data connection thread main capture
923 // loop to break out of that loop.
925 pcap_breakloop(session
->fp
);
928 // If it's currently blocked waiting for packets
929 // to arrive, try to wake it up, so it can see
930 // the "break out of the loop" indication.
932 SetEvent(pcap_getevent(session
->fp
));
935 // Wait for the thread to exit, so we don't close
936 // sockets out from under it.
938 // XXX - have a timeout, so we don't wait forever?
940 WaitForSingleObject(threaddata
.thread
, INFINITE
);
943 // Release the thread handle, as we're done with
946 CloseHandle(threaddata
.thread
);
948 pthread_cancel(threaddata
.thread
);
950 threaddata
.have_thread
= 0;
953 session_close(session
);
965 // Print message and return
966 rpcapd_log(LOGPRIO_DEBUG
, "I'm exiting from the child loop");
967 rpcapd_log(LOGPRIO_DEBUG
, "%s", errbuf
);
969 return client_told_us_to_close
;
973 * This handles the RPCAP_MSG_ERR message.
976 daemon_msg_err(SOCKET sockctrl_in
, SSL
*ssl
, uint32 plen
)
978 char errbuf
[PCAP_ERRBUF_SIZE
];
979 char remote_errbuf
[PCAP_ERRBUF_SIZE
];
981 if (plen
>= PCAP_ERRBUF_SIZE
)
984 * Message is too long; just read as much of it as we
985 * can into the buffer provided, and discard the rest.
987 if (sock_recv(sockctrl_in
, ssl
, remote_errbuf
, PCAP_ERRBUF_SIZE
- 1,
988 SOCK_RECEIVEALL_YES
|SOCK_EOF_IS_ERROR
, errbuf
,
989 PCAP_ERRBUF_SIZE
) == -1)
992 rpcapd_log(LOGPRIO_ERROR
, "Read from client failed: %s", errbuf
);
995 if (rpcapd_discard(sockctrl_in
, ssl
, plen
- (PCAP_ERRBUF_SIZE
- 1)) == -1)
1002 * Null-terminate it.
1004 remote_errbuf
[PCAP_ERRBUF_SIZE
- 1] = '\0';
1008 /* Empty error string. */
1009 remote_errbuf
[0] = '\0';
1013 if (sock_recv(sockctrl_in
, ssl
, remote_errbuf
, plen
,
1014 SOCK_RECEIVEALL_YES
|SOCK_EOF_IS_ERROR
, errbuf
,
1015 PCAP_ERRBUF_SIZE
) == -1)
1018 rpcapd_log(LOGPRIO_ERROR
, "Read from client failed: %s", errbuf
);
1023 * Null-terminate it.
1025 remote_errbuf
[plen
] = '\0';
1028 rpcapd_log(LOGPRIO_ERROR
, "Error from client: %s", remote_errbuf
);
1033 * This handles the RPCAP_MSG_AUTH_REQ message.
1034 * It checks if the authentication credentials supplied by the user are valid.
1036 * This function is called if the daemon receives a RPCAP_MSG_AUTH_REQ
1037 * message in its authentication loop. It reads the body of the
1038 * authentication message from the network and checks whether the
1039 * credentials are valid.
1041 * \param sockctrl: the socket for the control connection.
1043 * \param nullAuthAllowed: '1' if the NULL authentication is allowed.
1045 * \param errbuf: a user-allocated buffer in which the error message
1046 * (if one) has to be written. It must be at least PCAP_ERRBUF_SIZE
1049 * \return '0' if everything is fine, '-1' if an unrecoverable error occurred,
1050 * or '-2' if the authentication failed. For errors, an error message is
1051 * returned in the 'errbuf' variable; this gives a message for the
1052 * unrecoverable error or for the authentication failure.
1055 daemon_msg_auth_req(struct daemon_slpars
*pars
, uint32 plen
)
1057 char errbuf
[PCAP_ERRBUF_SIZE
]; // buffer for network errors
1058 char errmsgbuf
[PCAP_ERRBUF_SIZE
]; // buffer for errors to send to the client
1059 struct rpcap_header header
; // RPCAP message general header
1061 struct rpcap_auth auth
; // RPCAP authentication header
1063 status
= rpcapd_recv(pars
->sockctrl_in
, pars
->ssl
, (char *) &auth
, sizeof(struct rpcap_auth
), &plen
, errmsgbuf
);
1073 switch (ntohs(auth
.type
))
1075 case RPCAP_RMTAUTH_NULL
:
1077 if (!pars
->nullAuthAllowed
)
1079 // Send the client an error reply.
1080 pcap_snprintf(errmsgbuf
, PCAP_ERRBUF_SIZE
, "Authentication failed; NULL authentication not permitted.");
1086 case RPCAP_RMTAUTH_PWD
:
1088 char *username
, *passwd
;
1089 uint32 usernamelen
, passwdlen
;
1091 usernamelen
= ntohs(auth
.slen1
);
1092 username
= (char *) malloc (usernamelen
+ 1);
1093 if (username
== NULL
)
1095 pcap_fmt_errmsg_for_errno(errmsgbuf
,
1096 PCAP_ERRBUF_SIZE
, errno
, "malloc() failed");
1099 status
= rpcapd_recv(pars
->sockctrl_in
, pars
->ssl
, username
, usernamelen
, &plen
, errmsgbuf
);
1110 username
[usernamelen
] = '\0';
1112 passwdlen
= ntohs(auth
.slen2
);
1113 passwd
= (char *) malloc (passwdlen
+ 1);
1116 pcap_fmt_errmsg_for_errno(errmsgbuf
,
1117 PCAP_ERRBUF_SIZE
, errno
, "malloc() failed");
1121 status
= rpcapd_recv(pars
->sockctrl_in
, pars
->ssl
, passwd
, passwdlen
, &plen
, errmsgbuf
);
1134 passwd
[passwdlen
] = '\0';
1136 if (daemon_AuthUserPwd(username
, passwd
, errmsgbuf
))
1139 // Authentication failed. Let the client
1144 if (rpcap_senderror(pars
->sockctrl_out
, pars
->ssl
,
1145 pars
->protocol_version
,
1146 PCAP_ERR_AUTH
, errmsgbuf
, errbuf
) == -1)
1148 // That failed; log a message and give up.
1149 rpcapd_log(LOGPRIO_ERROR
, "Send to client failed: %s", errbuf
);
1154 // Suspend for 1 second, so that they can't
1155 // hammer us with repeated tries with an
1156 // attack such as a dictionary attack.
1158 // WARNING: this delay is inserted only
1159 // at this point; if the client closes the
1160 // connection and reconnects, the suspension
1161 // time does not have any effect.
1163 sleep_secs(RPCAP_SUSPEND_WRONGAUTH
);
1173 pcap_snprintf(errmsgbuf
, PCAP_ERRBUF_SIZE
, "Authentication type not recognized.");
1177 // The authentication succeeded; let the client know.
1178 rpcap_createhdr(&header
, pars
->protocol_version
, RPCAP_MSG_AUTH_REPLY
, 0, 0);
1180 // Send the ok message back
1181 if (sock_send(pars
->sockctrl_out
, pars
->ssl
, (char *) &header
, sizeof (struct rpcap_header
), errbuf
, PCAP_ERRBUF_SIZE
) == -1)
1183 // That failed; log a messsage and give up.
1184 rpcapd_log(LOGPRIO_ERROR
, "Send to client failed: %s", errbuf
);
1188 // Check if all the data has been read; if not, discard the data in excess
1189 if (rpcapd_discard(pars
->sockctrl_in
, pars
->ssl
, plen
) == -1)
1197 if (rpcap_senderror(pars
->sockctrl_out
, pars
->ssl
, pars
->protocol_version
,
1198 PCAP_ERR_AUTH
, errmsgbuf
, errbuf
) == -1)
1200 // That failed; log a message and give up.
1201 rpcapd_log(LOGPRIO_ERROR
, "Send to client failed: %s", errbuf
);
1206 // Check if all the data has been read; if not, discard the data in excess
1207 if (rpcapd_discard(pars
->sockctrl_in
, pars
->ssl
, plen
) == -1)
1216 daemon_AuthUserPwd(char *username
, char *password
, char *errbuf
)
1220 * Warning: the user which launches the process must have the
1221 * SE_TCB_NAME right.
1222 * This corresponds to have the "Act as part of the Operating System"
1223 * turned on (administrative tools, local security settings, local
1224 * policies, user right assignment)
1225 * However, it seems to me that if you run it as a service, this
1226 * right should be provided by default.
1229 if (LogonUser(username
, ".", password
, LOGON32_LOGON_NETWORK
, LOGON32_PROVIDER_DEFAULT
, &Token
) == 0)
1233 error
= GetLastError();
1234 FormatMessageA(FORMAT_MESSAGE_FROM_SYSTEM
, NULL
, error
, 0, errbuf
,
1235 PCAP_ERRBUF_SIZE
, NULL
);
1240 // This call should change the current thread to the selected user.
1241 // I didn't test it.
1242 if (ImpersonateLoggedOnUser(Token
) == 0)
1246 error
= GetLastError();
1247 FormatMessageA(FORMAT_MESSAGE_FROM_SYSTEM
, NULL
, error
, 0, errbuf
,
1248 PCAP_ERRBUF_SIZE
, NULL
);
1261 * http://www.unixpapa.com/incnote/passwd.html
1263 * We use the Solaris/Linux shadow password authentication if
1264 * we have getspnam(), otherwise we just do traditional
1265 * authentication, which, on some platforms, might work, even
1266 * with shadow passwords, if we're running as root. Traditional
1267 * authenticaion won't work if we're not running as root, as
1268 * I think these days all UN*Xes either won't return the password
1269 * at all with getpwnam() or will only do so if you're root.
1271 * XXX - perhaps what we *should* be using is PAM, if we have
1272 * it. That might hide all the details of username/password
1273 * authentication, whether it's done with a visible-to-root-
1274 * only password database or some other authentication mechanism,
1277 struct passwd
*user
;
1278 char *user_password
;
1279 #ifdef HAVE_GETSPNAM
1280 struct spwd
*usersp
;
1283 // This call is needed to get the uid
1284 if ((user
= getpwnam(username
)) == NULL
)
1286 pcap_snprintf(errbuf
, PCAP_ERRBUF_SIZE
, "Authentication failed: no such user");
1290 #ifdef HAVE_GETSPNAM
1291 // This call is needed to get the password; otherwise 'x' is returned
1292 if ((usersp
= getspnam(username
)) == NULL
)
1294 pcap_snprintf(errbuf
, PCAP_ERRBUF_SIZE
, "Authentication failed: no such user");
1297 user_password
= usersp
->sp_pwdp
;
1300 * XXX - what about other platforms?
1301 * The unixpapa.com page claims this Just Works on *BSD if you're
1302 * running as root - it's from 2000, so it doesn't indicate whether
1303 * macOS (which didn't come out until 2001, under the name Mac OS
1304 * X) behaves like the *BSDs or not, and might also work on AIX.
1305 * HP-UX does something else.
1307 * Again, hopefully PAM hides all that.
1309 user_password
= user
->pw_passwd
;
1312 if (strcmp(user_password
, (char *) crypt(password
, user_password
)) != 0)
1314 pcap_snprintf(errbuf
, PCAP_ERRBUF_SIZE
, "Authentication failed: password incorrect");
1318 if (setuid(user
->pw_uid
))
1320 pcap_fmt_errmsg_for_errno(errbuf
, PCAP_ERRBUF_SIZE
,
1325 /* if (setgid(user->pw_gid))
1327 pcap_fmt_errmsg_for_errno(errbuf, PCAP_ERRBUF_SIZE,
1339 daemon_msg_findallif_req(struct daemon_slpars
*pars
, uint32 plen
)
1341 char errbuf
[PCAP_ERRBUF_SIZE
]; // buffer for network errors
1342 char errmsgbuf
[PCAP_ERRBUF_SIZE
]; // buffer for errors to send to the client
1343 char sendbuf
[RPCAP_NETBUF_SIZE
]; // temporary buffer in which data to be sent is buffered
1344 int sendbufidx
= 0; // index which keeps the number of bytes currently buffered
1345 pcap_if_t
*alldevs
= NULL
; // pointer to the header of the interface chain
1346 pcap_if_t
*d
; // temp pointer needed to scan the interface chain
1347 struct pcap_addr
*address
; // pcap structure that keeps a network address of an interface
1348 struct rpcap_findalldevs_if
*findalldevs_if
;// rpcap structure that packet all the data of an interface together
1349 uint16 nif
= 0; // counts the number of interface listed
1351 // Discard the rest of the message; there shouldn't be any payload.
1352 if (rpcapd_discard(pars
->sockctrl_in
, pars
->ssl
, plen
) == -1)
1358 // Retrieve the device list
1359 if (pcap_findalldevs(&alldevs
, errmsgbuf
) == -1)
1362 if (alldevs
== NULL
)
1364 if (rpcap_senderror(pars
->sockctrl_out
, pars
->ssl
, pars
->protocol_version
,
1365 PCAP_ERR_NOREMOTEIF
,
1366 "No interfaces found! Make sure libpcap/WinPcap is properly installed"
1367 " and you have the right to access to the remote device.",
1370 rpcapd_log(LOGPRIO_ERROR
, "Send to client failed: %s", errbuf
);
1376 // checks the number of interfaces and it computes the total length of the payload
1377 for (d
= alldevs
; d
!= NULL
; d
= d
->next
)
1382 plen
+= strlen(d
->description
);
1384 plen
+= strlen(d
->name
);
1386 plen
+= sizeof(struct rpcap_findalldevs_if
);
1388 for (address
= d
->addresses
; address
!= NULL
; address
= address
->next
)
1391 * Send only IPv4 and IPv6 addresses over the wire.
1393 switch (address
->addr
->sa_family
)
1399 plen
+= (sizeof(struct rpcap_sockaddr
) * 4);
1408 // RPCAP findalldevs command
1409 if (sock_bufferize(NULL
, sizeof(struct rpcap_header
), NULL
,
1410 &sendbufidx
, RPCAP_NETBUF_SIZE
, SOCKBUF_CHECKONLY
, errmsgbuf
,
1411 PCAP_ERRBUF_SIZE
) == -1)
1414 rpcap_createhdr((struct rpcap_header
*) sendbuf
, pars
->protocol_version
,
1415 RPCAP_MSG_FINDALLIF_REPLY
, nif
, plen
);
1417 // send the interface list
1418 for (d
= alldevs
; d
!= NULL
; d
= d
->next
)
1420 uint16 lname
, ldescr
;
1422 findalldevs_if
= (struct rpcap_findalldevs_if
*) &sendbuf
[sendbufidx
];
1424 if (sock_bufferize(NULL
, sizeof(struct rpcap_findalldevs_if
), NULL
,
1425 &sendbufidx
, RPCAP_NETBUF_SIZE
, SOCKBUF_CHECKONLY
, errmsgbuf
, PCAP_ERRBUF_SIZE
) == -1)
1428 memset(findalldevs_if
, 0, sizeof(struct rpcap_findalldevs_if
));
1430 if (d
->description
) ldescr
= (short) strlen(d
->description
);
1432 if (d
->name
) lname
= (short) strlen(d
->name
);
1435 findalldevs_if
->desclen
= htons(ldescr
);
1436 findalldevs_if
->namelen
= htons(lname
);
1437 findalldevs_if
->flags
= htonl(d
->flags
);
1439 for (address
= d
->addresses
; address
!= NULL
; address
= address
->next
)
1442 * Send only IPv4 and IPv6 addresses over the wire.
1444 switch (address
->addr
->sa_family
)
1450 findalldevs_if
->naddr
++;
1457 findalldevs_if
->naddr
= htons(findalldevs_if
->naddr
);
1459 if (sock_bufferize(d
->name
, lname
, sendbuf
, &sendbufidx
,
1460 RPCAP_NETBUF_SIZE
, SOCKBUF_BUFFERIZE
, errmsgbuf
,
1461 PCAP_ERRBUF_SIZE
) == -1)
1464 if (sock_bufferize(d
->description
, ldescr
, sendbuf
, &sendbufidx
,
1465 RPCAP_NETBUF_SIZE
, SOCKBUF_BUFFERIZE
, errmsgbuf
,
1466 PCAP_ERRBUF_SIZE
) == -1)
1469 // send all addresses
1470 for (address
= d
->addresses
; address
!= NULL
; address
= address
->next
)
1472 struct rpcap_sockaddr
*sockaddr
;
1475 * Send only IPv4 and IPv6 addresses over the wire.
1477 switch (address
->addr
->sa_family
)
1483 sockaddr
= (struct rpcap_sockaddr
*) &sendbuf
[sendbufidx
];
1484 if (sock_bufferize(NULL
, sizeof(struct rpcap_sockaddr
), NULL
,
1485 &sendbufidx
, RPCAP_NETBUF_SIZE
, SOCKBUF_CHECKONLY
, errmsgbuf
, PCAP_ERRBUF_SIZE
) == -1)
1487 daemon_seraddr((struct sockaddr_storage
*) address
->addr
, sockaddr
);
1489 sockaddr
= (struct rpcap_sockaddr
*) &sendbuf
[sendbufidx
];
1490 if (sock_bufferize(NULL
, sizeof(struct rpcap_sockaddr
), NULL
,
1491 &sendbufidx
, RPCAP_NETBUF_SIZE
, SOCKBUF_CHECKONLY
, errmsgbuf
, PCAP_ERRBUF_SIZE
) == -1)
1493 daemon_seraddr((struct sockaddr_storage
*) address
->netmask
, sockaddr
);
1495 sockaddr
= (struct rpcap_sockaddr
*) &sendbuf
[sendbufidx
];
1496 if (sock_bufferize(NULL
, sizeof(struct rpcap_sockaddr
), NULL
,
1497 &sendbufidx
, RPCAP_NETBUF_SIZE
, SOCKBUF_CHECKONLY
, errmsgbuf
, PCAP_ERRBUF_SIZE
) == -1)
1499 daemon_seraddr((struct sockaddr_storage
*) address
->broadaddr
, sockaddr
);
1501 sockaddr
= (struct rpcap_sockaddr
*) &sendbuf
[sendbufidx
];
1502 if (sock_bufferize(NULL
, sizeof(struct rpcap_sockaddr
), NULL
,
1503 &sendbufidx
, RPCAP_NETBUF_SIZE
, SOCKBUF_CHECKONLY
, errmsgbuf
, PCAP_ERRBUF_SIZE
) == -1)
1505 daemon_seraddr((struct sockaddr_storage
*) address
->dstaddr
, sockaddr
);
1514 // We no longer need the device list. Free it.
1515 pcap_freealldevs(alldevs
);
1517 // Send a final command that says "now send it!"
1518 if (sock_send(pars
->sockctrl_out
, pars
->ssl
, sendbuf
, sendbufidx
, errbuf
, PCAP_ERRBUF_SIZE
) == -1)
1520 rpcapd_log(LOGPRIO_ERROR
, "Send to client failed: %s", errbuf
);
1528 pcap_freealldevs(alldevs
);
1530 if (rpcap_senderror(pars
->sockctrl_out
, pars
->ssl
, pars
->protocol_version
,
1531 PCAP_ERR_FINDALLIF
, errmsgbuf
, errbuf
) == -1)
1533 rpcapd_log(LOGPRIO_ERROR
, "Send to client failed: %s", errbuf
);
1540 \param plen: the length of the current message (needed in order to be able
1541 to discard excess data in the message, if present)
1544 daemon_msg_open_req(struct daemon_slpars
*pars
, uint32 plen
, char *source
, size_t sourcelen
)
1546 char errbuf
[PCAP_ERRBUF_SIZE
]; // buffer for network errors
1547 char errmsgbuf
[PCAP_ERRBUF_SIZE
]; // buffer for errors to send to the client
1548 pcap_t
*fp
; // pcap_t main variable
1550 char sendbuf
[RPCAP_NETBUF_SIZE
]; // temporary buffer in which data to be sent is buffered
1551 int sendbufidx
= 0; // index which keeps the number of bytes currently buffered
1552 struct rpcap_openreply
*openreply
; // open reply message
1554 if (plen
> sourcelen
- 1)
1556 pcap_snprintf(errmsgbuf
, PCAP_ERRBUF_SIZE
, "Source string too long");
1560 nread
= sock_recv(pars
->sockctrl_in
, pars
->ssl
, source
, plen
,
1561 SOCK_RECEIVEALL_YES
|SOCK_EOF_IS_ERROR
, errbuf
, PCAP_ERRBUF_SIZE
);
1564 rpcapd_log(LOGPRIO_ERROR
, "Read from client failed: %s", errbuf
);
1567 source
[nread
] = '\0';
1570 // XXX - make sure it's *not* a URL; we don't support opening
1571 // remote devices here.
1573 // Open the selected device
1574 // This is a fake open, since we do that only to get the needed parameters, then we close the device again
1575 if ((fp
= pcap_open_live(source
,
1576 1500 /* fake snaplen */,
1578 1000 /* fake timeout */,
1579 errmsgbuf
)) == NULL
)
1582 // Now, I can send a RPCAP open reply message
1583 if (sock_bufferize(NULL
, sizeof(struct rpcap_header
), NULL
, &sendbufidx
,
1584 RPCAP_NETBUF_SIZE
, SOCKBUF_CHECKONLY
, errmsgbuf
, PCAP_ERRBUF_SIZE
) == -1)
1587 rpcap_createhdr((struct rpcap_header
*) sendbuf
, pars
->protocol_version
,
1588 RPCAP_MSG_OPEN_REPLY
, 0, sizeof(struct rpcap_openreply
));
1590 openreply
= (struct rpcap_openreply
*) &sendbuf
[sendbufidx
];
1592 if (sock_bufferize(NULL
, sizeof(struct rpcap_openreply
), NULL
, &sendbufidx
,
1593 RPCAP_NETBUF_SIZE
, SOCKBUF_CHECKONLY
, errmsgbuf
, PCAP_ERRBUF_SIZE
) == -1)
1596 memset(openreply
, 0, sizeof(struct rpcap_openreply
));
1597 openreply
->linktype
= htonl(pcap_datalink(fp
));
1599 // We're done with the pcap_t.
1603 if (sock_send(pars
->sockctrl_out
, pars
->ssl
, sendbuf
, sendbufidx
, errbuf
, PCAP_ERRBUF_SIZE
) == -1)
1605 rpcapd_log(LOGPRIO_ERROR
, "Send to client failed: %s", errbuf
);
1611 if (rpcap_senderror(pars
->sockctrl_out
, pars
->ssl
, pars
->protocol_version
,
1612 PCAP_ERR_OPEN
, errmsgbuf
, errbuf
) == -1)
1614 // That failed; log a message and give up.
1615 rpcapd_log(LOGPRIO_ERROR
, "Send to client failed: %s", errbuf
);
1619 // Check if all the data has been read; if not, discard the data in excess
1620 if (rpcapd_discard(pars
->sockctrl_in
, pars
->ssl
, plen
) == -1)
1628 \param plen: the length of the current message (needed in order to be able
1629 to discard excess data in the message, if present)
1632 daemon_msg_startcap_req(struct daemon_slpars
*pars
, uint32 plen
, struct thread_handle
*threaddata
, char *source
, struct session
**sessionp
, struct rpcap_sampling
*samp_param _U_
, int uses_ssl
)
1634 char errbuf
[PCAP_ERRBUF_SIZE
]; // buffer for network errors
1635 char errmsgbuf
[PCAP_ERRBUF_SIZE
]; // buffer for errors to send to the client
1636 char portdata
[PCAP_BUF_SIZE
]; // temp variable needed to derive the data port
1637 char peerhost
[PCAP_BUF_SIZE
]; // temp variable needed to derive the host name of our peer
1638 struct session
*session
= NULL
; // saves state of session
1640 char sendbuf
[RPCAP_NETBUF_SIZE
]; // temporary buffer in which data to be sent is buffered
1641 int sendbufidx
= 0; // index which keeps the number of bytes currently buffered
1643 // socket-related variables
1644 SOCKET sockdata
= INVALID_SOCKET
; // socket descriptor of the data connection
1645 struct addrinfo hints
; // temp, needed to open a socket connection
1646 struct addrinfo
*addrinfo
; // temp, needed to open a socket connection
1647 struct sockaddr_storage saddr
; // temp, needed to retrieve the network data port chosen on the local machine
1648 socklen_t saddrlen
; // temp, needed to retrieve the network data port chosen on the local machine
1649 int ret
; // return value from functions
1652 pthread_attr_t detachedAttribute
; // temp, needed to set the created thread as detached
1655 // RPCAP-related variables
1656 struct rpcap_startcapreq startcapreq
; // start capture request message
1657 struct rpcap_startcapreply
*startcapreply
; // start capture reply message
1658 int serveropen_dp
; // keeps who is going to open the data connection
1662 status
= rpcapd_recv(pars
->sockctrl_in
, pars
->ssl
, (char *) &startcapreq
,
1663 sizeof(struct rpcap_startcapreq
), &plen
, errmsgbuf
);
1673 startcapreq
.flags
= ntohs(startcapreq
.flags
);
1675 // Check that the client does not ask for UDP is the server has been asked
1676 // to enforce encryption, as SSL is not supported yet with UDP:
1677 if (uses_ssl
&& (startcapreq
.flags
& RPCAP_STARTCAPREQ_FLAG_DGRAM
))
1679 pcap_snprintf(errbuf
, PCAP_ERRBUF_SIZE
,
1680 "SSL not supported with UDP forward of remote packets");
1684 // Create a session structure
1685 session
= malloc(sizeof(struct session
));
1686 if (session
== NULL
)
1688 pcap_snprintf(errmsgbuf
, PCAP_ERRBUF_SIZE
, "Can't allocate session structure");
1692 session
->ctrl_ssl
= session
->data_ssl
= NULL
;
1694 // Open the selected device
1695 if ((session
->fp
= pcap_open_live(source
,
1696 ntohl(startcapreq
.snaplen
),
1697 (startcapreq
.flags
& RPCAP_STARTCAPREQ_FLAG_PROMISC
) ? 1 : 0 /* local device, other flags not needed */,
1698 ntohl(startcapreq
.read_timeout
),
1699 errmsgbuf
)) == NULL
)
1703 // Apply sampling parameters
1704 fp
->rmt_samp
.method
= samp_param
->method
;
1705 fp
->rmt_samp
.value
= samp_param
->value
;
1709 We're in active mode if:
1710 - we're using TCP, and the user wants us to be in active mode
1713 serveropen_dp
= (startcapreq
.flags
& RPCAP_STARTCAPREQ_FLAG_SERVEROPEN
) || (startcapreq
.flags
& RPCAP_STARTCAPREQ_FLAG_DGRAM
) || pars
->isactive
;
1716 Gets the sockaddr structure referred to the other peer in the ctrl connection
1718 We need that because:
1719 - if we're in passive mode, we need to know the address family we want to use
1720 (the same used for the ctrl socket)
1721 - if we're in active mode, we need to know the network address of the other host
1722 we want to connect to
1724 saddrlen
= sizeof(struct sockaddr_storage
);
1725 if (getpeername(pars
->sockctrl_in
, (struct sockaddr
*) &saddr
, &saddrlen
) == -1)
1727 sock_geterror("getpeername(): ", errmsgbuf
, PCAP_ERRBUF_SIZE
);
1731 memset(&hints
, 0, sizeof(struct addrinfo
));
1732 hints
.ai_socktype
= (startcapreq
.flags
& RPCAP_STARTCAPREQ_FLAG_DGRAM
) ? SOCK_DGRAM
: SOCK_STREAM
;
1733 hints
.ai_family
= saddr
.ss_family
;
1735 // Now we have to create a new socket to send packets
1736 if (serveropen_dp
) // Data connection is opened by the server toward the client
1738 pcap_snprintf(portdata
, sizeof portdata
, "%d", ntohs(startcapreq
.portdata
));
1740 // Get the name of the other peer (needed to connect to that specific network address)
1741 if (getnameinfo((struct sockaddr
*) &saddr
, saddrlen
, peerhost
,
1742 sizeof(peerhost
), NULL
, 0, NI_NUMERICHOST
))
1744 sock_geterror("getnameinfo(): ", errmsgbuf
, PCAP_ERRBUF_SIZE
);
1748 if (sock_initaddress(peerhost
, portdata
, &hints
, &addrinfo
, errmsgbuf
, PCAP_ERRBUF_SIZE
) == -1)
1751 if ((sockdata
= sock_open(addrinfo
, SOCKOPEN_CLIENT
, 0, errmsgbuf
, PCAP_ERRBUF_SIZE
)) == INVALID_SOCKET
)
1754 else // Data connection is opened by the client toward the server
1756 hints
.ai_flags
= AI_PASSIVE
;
1758 // Let's the server socket pick up a free network port for us
1759 if (sock_initaddress(NULL
, "0", &hints
, &addrinfo
, errmsgbuf
, PCAP_ERRBUF_SIZE
) == -1)
1762 if ((sockdata
= sock_open(addrinfo
, SOCKOPEN_SERVER
, 1 /* max 1 connection in queue */, errmsgbuf
, PCAP_ERRBUF_SIZE
)) == INVALID_SOCKET
)
1765 // get the complete sockaddr structure used in the data connection
1766 saddrlen
= sizeof(struct sockaddr_storage
);
1767 if (getsockname(sockdata
, (struct sockaddr
*) &saddr
, &saddrlen
) == -1)
1769 sock_geterror("getsockname(): ", errmsgbuf
, PCAP_ERRBUF_SIZE
);
1773 // Get the local port the system picked up
1774 if (getnameinfo((struct sockaddr
*) &saddr
, saddrlen
, NULL
,
1775 0, portdata
, sizeof(portdata
), NI_NUMERICSERV
))
1777 sock_geterror("getnameinfo(): ", errmsgbuf
, PCAP_ERRBUF_SIZE
);
1782 // addrinfo is no longer used
1783 freeaddrinfo(addrinfo
);
1786 // Needed to send an error on the ctrl connection
1787 session
->sockctrl_out
= pars
->sockctrl_out
;
1788 session
->ctrl_ssl
= pars
->ssl
;
1789 session
->protocol_version
= pars
->protocol_version
;
1791 // Now I can set the filter
1792 ret
= daemon_unpackapplyfilter(pars
->sockctrl_in
, pars
->ssl
, session
, &plen
, errmsgbuf
);
1795 // Fatal error. A message has been logged; just give up.
1800 // Non-fatal error. Send an error message to the client.
1804 // Now, I can send a RPCAP start capture reply message
1805 if (sock_bufferize(NULL
, sizeof(struct rpcap_header
), NULL
, &sendbufidx
,
1806 RPCAP_NETBUF_SIZE
, SOCKBUF_CHECKONLY
, errmsgbuf
, PCAP_ERRBUF_SIZE
) == -1)
1809 rpcap_createhdr((struct rpcap_header
*) sendbuf
, pars
->protocol_version
,
1810 RPCAP_MSG_STARTCAP_REPLY
, 0, sizeof(struct rpcap_startcapreply
));
1812 startcapreply
= (struct rpcap_startcapreply
*) &sendbuf
[sendbufidx
];
1814 if (sock_bufferize(NULL
, sizeof(struct rpcap_startcapreply
), NULL
,
1815 &sendbufidx
, RPCAP_NETBUF_SIZE
, SOCKBUF_CHECKONLY
, errmsgbuf
, PCAP_ERRBUF_SIZE
) == -1)
1818 memset(startcapreply
, 0, sizeof(struct rpcap_startcapreply
));
1819 startcapreply
->bufsize
= htonl(pcap_bufsize(session
->fp
));
1823 unsigned short port
= (unsigned short)strtoul(portdata
,NULL
,10);
1824 startcapreply
->portdata
= htons(port
);
1827 if (sock_send(pars
->sockctrl_out
, pars
->ssl
, sendbuf
, sendbufidx
, errbuf
, PCAP_ERRBUF_SIZE
) == -1)
1829 // That failed; log a message and give up.
1830 rpcapd_log(LOGPRIO_ERROR
, "Send to client failed: %s", errbuf
);
1836 SOCKET socktemp
; // We need another socket, since we're going to accept() a connection
1838 // Connection creation
1839 saddrlen
= sizeof(struct sockaddr_storage
);
1841 socktemp
= accept(sockdata
, (struct sockaddr
*) &saddr
, &saddrlen
);
1843 if (socktemp
== INVALID_SOCKET
)
1845 sock_geterror("accept(): ", errbuf
, PCAP_ERRBUF_SIZE
);
1846 rpcapd_log(LOGPRIO_ERROR
, "Accept of data connection failed: %s",
1851 // Now that I accepted the connection, the server socket is no longer needed
1852 sock_close(sockdata
, NULL
, 0);
1853 sockdata
= socktemp
;
1860 /* In both active or passive cases, wait for the client to initiate the
1861 * TLS handshake. Yes during that time the control socket will not be
1862 * served, but the same was true from the above call to accept(). */
1863 ssl
= ssl_promotion(1, sockdata
, errbuf
, PCAP_ERRBUF_SIZE
);
1866 rpcapd_log(LOGPRIO_ERROR
, "TLS handshake failed: %s", errbuf
);
1871 session
->data_ssl
= ssl
;
1872 session
->sockdata
= sockdata
;
1874 // Now we have to create a new thread to receive packets
1876 threaddata
->thread
= (HANDLE
)_beginthreadex(NULL
, 0, daemon_thrdatamain
,
1877 (void *) session
, 0, NULL
);
1878 if (threaddata
->thread
== 0)
1880 pcap_snprintf(errbuf
, PCAP_ERRBUF_SIZE
, "Error creating the data thread");
1884 /* GV we need this to create the thread as detached. */
1885 /* GV otherwise, the thread handle is not destroyed */
1886 pthread_attr_init(&detachedAttribute
);
1887 pthread_attr_setdetachstate(&detachedAttribute
, PTHREAD_CREATE_DETACHED
);
1888 ret
= pthread_create(&threaddata
->thread
, &detachedAttribute
,
1889 daemon_thrdatamain
, (void *) session
);
1892 pcap_fmt_errmsg_for_errno(errbuf
, PCAP_ERRBUF_SIZE
,
1893 ret
, "Error creating the data thread");
1894 pthread_attr_destroy(&detachedAttribute
);
1897 pthread_attr_destroy(&detachedAttribute
);
1899 threaddata
->have_thread
= 1;
1901 // Check if all the data has been read; if not, discard the data in excess
1902 if (rpcapd_discard(pars
->sockctrl_in
, pars
->ssl
, plen
) == -1)
1905 *sessionp
= session
;
1910 // Not a fatal error, so send the client an error message and
1911 // keep serving client requests.
1916 freeaddrinfo(addrinfo
);
1918 if (threaddata
->have_thread
)
1923 pcap_breakloop(session
->fp
);
1924 SetEvent(pcap_getevent(session
->fp
));
1926 CloseHandle(threaddata
->thread
);
1928 pthread_cancel(threaddata
->thread
);
1930 threaddata
->have_thread
= 0;
1933 if (sockdata
!= INVALID_SOCKET
)
1934 sock_close(sockdata
, NULL
, 0);
1939 pcap_close(session
->fp
);
1941 if (session
->ctrl_ssl
)
1942 SSL_free(session
->ctrl_ssl
);
1943 if (session
->data_ssl
)
1944 SSL_free(session
->data_ssl
);
1949 if (rpcap_senderror(pars
->sockctrl_out
, pars
->ssl
, pars
->protocol_version
,
1950 PCAP_ERR_STARTCAPTURE
, errmsgbuf
, errbuf
) == -1)
1952 // That failed; log a message and give up.
1953 rpcapd_log(LOGPRIO_ERROR
, "Send to client failed: %s", errbuf
);
1957 // Check if all the data has been read; if not, discard the data in excess
1958 if (rpcapd_discard(pars
->sockctrl_in
, pars
->ssl
, plen
) == -1)
1968 // Fatal network error, so don't try to communicate with
1969 // the client, just give up.
1973 if (threaddata
->have_thread
)
1976 if (session
&& session
->fp
)
1979 // Tell the data connection thread main capture
1980 // loop to break out of that loop.
1982 pcap_breakloop(session
->fp
);
1985 // If it's currently blocked waiting for packets
1986 // to arrive, try to wake it up, so it can see
1987 // the "break out of the loop" indication.
1989 SetEvent(pcap_getevent(session
->fp
));
1993 // Wait for the thread to exit, so we don't close
1994 // sockets out from under it.
1996 // XXX - have a timeout, so we don't wait forever?
1998 WaitForSingleObject(threaddata
->thread
, INFINITE
);
2001 // Release the thread handle, as we're done with
2004 CloseHandle(threaddata
->thread
);
2006 pthread_cancel(threaddata
->thread
);
2008 threaddata
->have_thread
= 0;
2011 if (sockdata
!= INVALID_SOCKET
)
2012 sock_close(sockdata
, NULL
, 0);
2017 pcap_close(session
->fp
);
2019 if (session
->ctrl_ssl
)
2020 SSL_free(session
->ctrl_ssl
);
2021 if (session
->data_ssl
)
2022 SSL_free(session
->data_ssl
);
2031 daemon_msg_endcap_req(struct daemon_slpars
*pars
, struct session
*session
, struct thread_handle
*threaddata
)
2033 char errbuf
[PCAP_ERRBUF_SIZE
]; // buffer for network errors
2034 struct rpcap_header header
;
2036 if (threaddata
->have_thread
)
2040 // Tell the data connection thread main capture loop to
2041 // break out of that loop.
2043 pcap_breakloop(session
->fp
);
2046 // If it's currently blocked waiting for packets to
2047 // arrive, try to wake it up, so it can see the "break
2048 // out of the loop" indication.
2050 SetEvent(pcap_getevent(session
->fp
));
2053 // Wait for the thread to exit, so we don't close
2054 // sockets out from under it.
2056 // XXX - have a timeout, so we don't wait forever?
2058 WaitForSingleObject(threaddata
->thread
, INFINITE
);
2061 // Release the thread handle, as we're done with
2064 CloseHandle(threaddata
->thread
);
2066 pthread_cancel(threaddata
->thread
);
2068 threaddata
->have_thread
= 0;
2071 session_close(session
);
2073 rpcap_createhdr(&header
, pars
->protocol_version
,
2074 RPCAP_MSG_ENDCAP_REPLY
, 0, 0);
2076 if (sock_send(pars
->sockctrl_out
, pars
->ssl
, (char *) &header
, sizeof(struct rpcap_header
), errbuf
, PCAP_ERRBUF_SIZE
) == -1)
2078 // That failed; log a message and give up.
2079 rpcapd_log(LOGPRIO_ERROR
, "Send to client failed: %s", errbuf
);
2087 daemon_unpackapplyfilter(SOCKET sockctrl_in
, SSL
*ctrl_ssl
, struct session
*session
, uint32
*plenp
, char *errmsgbuf
)
2090 struct rpcap_filter filter
;
2091 struct rpcap_filterbpf_insn insn
;
2092 struct bpf_insn
*bf_insn
;
2093 struct bpf_program bf_prog
;
2096 status
= rpcapd_recv(sockctrl_in
, ctrl_ssl
, (char *) &filter
,
2097 sizeof(struct rpcap_filter
), plenp
, errmsgbuf
);
2107 bf_prog
.bf_len
= ntohl(filter
.nitems
);
2109 if (ntohs(filter
.filtertype
) != RPCAP_UPDATEFILTER_BPF
)
2111 pcap_snprintf(errmsgbuf
, PCAP_ERRBUF_SIZE
, "Only BPF/NPF filters are currently supported");
2115 bf_insn
= (struct bpf_insn
*) malloc (sizeof(struct bpf_insn
) * bf_prog
.bf_len
);
2116 if (bf_insn
== NULL
)
2118 pcap_fmt_errmsg_for_errno(errmsgbuf
, PCAP_ERRBUF_SIZE
,
2119 errno
, "malloc() failed");
2123 bf_prog
.bf_insns
= bf_insn
;
2125 for (i
= 0; i
< bf_prog
.bf_len
; i
++)
2127 status
= rpcapd_recv(sockctrl_in
, ctrl_ssl
, (char *) &insn
,
2128 sizeof(struct rpcap_filterbpf_insn
), plenp
, errmsgbuf
);
2138 bf_insn
->code
= ntohs(insn
.code
);
2139 bf_insn
->jf
= insn
.jf
;
2140 bf_insn
->jt
= insn
.jt
;
2141 bf_insn
->k
= ntohl(insn
.k
);
2147 // XXX - pcap_setfilter() should do the validation for us.
2149 if (bpf_validate(bf_prog
.bf_insns
, bf_prog
.bf_len
) == 0)
2151 pcap_snprintf(errmsgbuf
, PCAP_ERRBUF_SIZE
, "The filter contains bogus instructions");
2155 if (pcap_setfilter(session
->fp
, &bf_prog
))
2157 pcap_snprintf(errmsgbuf
, PCAP_ERRBUF_SIZE
, "RPCAP error: %s", pcap_geterr(session
->fp
));
2165 daemon_msg_updatefilter_req(struct daemon_slpars
*pars
, struct session
*session
, uint32 plen
)
2167 char errbuf
[PCAP_ERRBUF_SIZE
];
2168 char errmsgbuf
[PCAP_ERRBUF_SIZE
]; // buffer for errors to send to the client
2169 int ret
; // status of daemon_unpackapplyfilter()
2170 struct rpcap_header header
; // keeps the answer to the updatefilter command
2172 ret
= daemon_unpackapplyfilter(pars
->sockctrl_in
, pars
->ssl
, session
, &plen
, errmsgbuf
);
2175 // Fatal error. A message has been logged; just give up.
2180 // Non-fatal error. Send an error reply to the client.
2184 // Check if all the data has been read; if not, discard the data in excess
2185 if (rpcapd_discard(pars
->sockctrl_in
, pars
->ssl
, plen
) == -1)
2191 // A response is needed, otherwise the other host does not know that everything went well
2192 rpcap_createhdr(&header
, pars
->protocol_version
,
2193 RPCAP_MSG_UPDATEFILTER_REPLY
, 0, 0);
2195 if (sock_send(pars
->sockctrl_out
, pars
->ssl
, (char *) &header
, sizeof (struct rpcap_header
), pcap_geterr(session
->fp
), PCAP_ERRBUF_SIZE
))
2197 // That failed; log a messsage and give up.
2198 rpcapd_log(LOGPRIO_ERROR
, "Send to client failed: %s", errbuf
);
2205 if (rpcapd_discard(pars
->sockctrl_in
, pars
->ssl
, plen
) == -1)
2209 rpcap_senderror(pars
->sockctrl_out
, pars
->ssl
, pars
->protocol_version
,
2210 PCAP_ERR_UPDATEFILTER
, errmsgbuf
, NULL
);
2216 \brief Received the sampling parameters from remote host and it stores in the pcap_t structure.
2219 daemon_msg_setsampling_req(struct daemon_slpars
*pars
, uint32 plen
, struct rpcap_sampling
*samp_param
)
2221 char errbuf
[PCAP_ERRBUF_SIZE
]; // buffer for network errors
2222 char errmsgbuf
[PCAP_ERRBUF_SIZE
];
2223 struct rpcap_header header
;
2224 struct rpcap_sampling rpcap_samp
;
2227 status
= rpcapd_recv(pars
->sockctrl_in
, pars
->ssl
, (char *) &rpcap_samp
, sizeof(struct rpcap_sampling
), &plen
, errmsgbuf
);
2237 // Save these settings in the pcap_t
2238 samp_param
->method
= rpcap_samp
.method
;
2239 samp_param
->value
= ntohl(rpcap_samp
.value
);
2241 // A response is needed, otherwise the other host does not know that everything went well
2242 rpcap_createhdr(&header
, pars
->protocol_version
,
2243 RPCAP_MSG_SETSAMPLING_REPLY
, 0, 0);
2245 if (sock_send(pars
->sockctrl_out
, pars
->ssl
, (char *) &header
, sizeof (struct rpcap_header
), errbuf
, PCAP_ERRBUF_SIZE
) == -1)
2247 // That failed; log a messsage and give up.
2248 rpcapd_log(LOGPRIO_ERROR
, "Send to client failed: %s", errbuf
);
2252 if (rpcapd_discard(pars
->sockctrl_in
, pars
->ssl
, plen
) == -1)
2260 if (rpcap_senderror(pars
->sockctrl_out
, pars
->ssl
, pars
->protocol_version
,
2261 PCAP_ERR_AUTH
, errmsgbuf
, errbuf
) == -1)
2263 // That failed; log a message and give up.
2264 rpcapd_log(LOGPRIO_ERROR
, "Send to client failed: %s", errbuf
);
2268 // Check if all the data has been read; if not, discard the data in excess
2269 if (rpcapd_discard(pars
->sockctrl_in
, pars
->ssl
, plen
) == -1)
2278 daemon_msg_stats_req(struct daemon_slpars
*pars
, struct session
*session
, uint32 plen
, struct pcap_stat
*stats
, unsigned int svrcapt
)
2280 char errbuf
[PCAP_ERRBUF_SIZE
]; // buffer for network errors
2281 char errmsgbuf
[PCAP_ERRBUF_SIZE
]; // buffer for errors to send to the client
2282 char sendbuf
[RPCAP_NETBUF_SIZE
]; // temporary buffer in which data to be sent is buffered
2283 int sendbufidx
= 0; // index which keeps the number of bytes currently buffered
2284 struct rpcap_stats
*netstats
; // statistics sent on the network
2286 // Checks that the header does not contain other data; if so, discard it
2287 if (rpcapd_discard(pars
->sockctrl_in
, pars
->ssl
, plen
) == -1)
2293 if (sock_bufferize(NULL
, sizeof(struct rpcap_header
), NULL
,
2294 &sendbufidx
, RPCAP_NETBUF_SIZE
, SOCKBUF_CHECKONLY
, errmsgbuf
, PCAP_ERRBUF_SIZE
) == -1)
2297 rpcap_createhdr((struct rpcap_header
*) sendbuf
, pars
->protocol_version
,
2298 RPCAP_MSG_STATS_REPLY
, 0, (uint16
) sizeof(struct rpcap_stats
));
2300 netstats
= (struct rpcap_stats
*) &sendbuf
[sendbufidx
];
2302 if (sock_bufferize(NULL
, sizeof(struct rpcap_stats
), NULL
,
2303 &sendbufidx
, RPCAP_NETBUF_SIZE
, SOCKBUF_CHECKONLY
, errmsgbuf
, PCAP_ERRBUF_SIZE
) == -1)
2306 if (session
&& session
->fp
)
2308 if (pcap_stats(session
->fp
, stats
) == -1)
2310 pcap_snprintf(errmsgbuf
, PCAP_ERRBUF_SIZE
, "%s", pcap_geterr(session
->fp
));
2314 netstats
->ifdrop
= htonl(stats
->ps_ifdrop
);
2315 netstats
->ifrecv
= htonl(stats
->ps_recv
);
2316 netstats
->krnldrop
= htonl(stats
->ps_drop
);
2317 netstats
->svrcapt
= htonl(session
->TotCapt
);
2321 // We have to keep compatibility with old applications,
2322 // which ask for statistics also when the capture has
2324 netstats
->ifdrop
= htonl(stats
->ps_ifdrop
);
2325 netstats
->ifrecv
= htonl(stats
->ps_recv
);
2326 netstats
->krnldrop
= htonl(stats
->ps_drop
);
2327 netstats
->svrcapt
= htonl(svrcapt
);
2331 if (sock_send(pars
->sockctrl_out
, pars
->ssl
, sendbuf
, sendbufidx
, errbuf
, PCAP_ERRBUF_SIZE
) == -1)
2333 rpcapd_log(LOGPRIO_ERROR
, "Send to client failed: %s", errbuf
);
2340 rpcap_senderror(pars
->sockctrl_out
, pars
->ssl
, pars
->protocol_version
,
2341 PCAP_ERR_GETSTATS
, errmsgbuf
, NULL
);
2346 static unsigned __stdcall
2350 daemon_thrdatamain(void *ptr
)
2352 char errbuf
[PCAP_ERRBUF_SIZE
+ 1]; // error buffer
2353 struct session
*session
; // pointer to the struct session for this session
2354 int retval
; // general variable used to keep the return value of other functions
2355 struct rpcap_pkthdr
*net_pkt_header
;// header of the packet
2356 struct pcap_pkthdr
*pkt_header
; // pointer to the buffer that contains the header of the current packet
2357 u_char
*pkt_data
; // pointer to the buffer that contains the current packet
2358 size_t sendbufsize
; // size for the send buffer
2359 char *sendbuf
; // temporary buffer in which data to be sent is buffered
2360 int sendbufidx
; // index which keeps the number of bytes currently buffered
2363 session
= (struct session
*) ptr
;
2365 session
->TotCapt
= 0; // counter which is incremented each time a packet is received
2367 // Initialize errbuf
2368 memset(errbuf
, 0, sizeof(errbuf
));
2371 // We need a buffer large enough to hold a buffer large enough
2372 // for a maximum-size packet for this pcap_t.
2374 if (pcap_snapshot(session
->fp
) < 0)
2377 // The snapshot length is negative.
2378 // This "should not happen".
2380 rpcapd_log(LOGPRIO_ERROR
,
2381 "Unable to allocate the buffer for this child thread: snapshot length of %d is negative",
2382 pcap_snapshot(session
->fp
));
2383 sendbuf
= NULL
; // we can't allocate a buffer, so nothing to free
2387 // size_t is unsigned, and the result of pcap_snapshot() is signed;
2388 // on no platform that we support is int larger than size_t.
2389 // This means that, unless the extra information we prepend to
2390 // a maximum-sized packet is impossibly large, the sum of the
2391 // snapshot length and the size of that extra information will
2394 // So we don't need to make sure that sendbufsize will overflow.
2396 // However, we *do* need to make sure its value fits in an int,
2397 // because sock_send() can't send more than INT_MAX bytes (it could
2398 // do so on 64-bit UN*Xes, but can't do so on Windows, not even
2399 // 64-bit Windows, as the send() buffer size argument is an int
2402 sendbufsize
= sizeof(struct rpcap_header
) + sizeof(struct rpcap_pkthdr
) + pcap_snapshot(session
->fp
);
2403 if (sendbufsize
> INT_MAX
)
2405 rpcapd_log(LOGPRIO_ERROR
,
2406 "Buffer size for this child thread would be larger than %d",
2408 sendbuf
= NULL
; // we haven't allocated a buffer, so nothing to free
2411 sendbuf
= (char *) malloc (sendbufsize
);
2412 if (sendbuf
== NULL
)
2414 rpcapd_log(LOGPRIO_ERROR
,
2415 "Unable to allocate the buffer for this child thread");
2420 // Modify thread params so that it can be killed at any time
2421 retval
= pthread_setcancelstate(PTHREAD_CANCEL_ENABLE
, NULL
);
2424 pcap_fmt_errmsg_for_errno(errbuf
, PCAP_ERRBUF_SIZE
,
2425 retval
, "pthread_setcancelstate");
2426 rpcapd_log(LOGPRIO_ERROR
,
2427 "Can't set cancel state on data thread: %s", errbuf
);
2430 retval
= pthread_setcanceltype(PTHREAD_CANCEL_ASYNCHRONOUS
, NULL
);
2433 pcap_fmt_errmsg_for_errno(errbuf
, PCAP_ERRBUF_SIZE
,
2434 retval
, "pthread_setcanceltype");
2435 rpcapd_log(LOGPRIO_ERROR
,
2436 "Can't set cancel type on data thread: %s", errbuf
);
2441 // Retrieve the packets
2442 while ((retval
= pcap_next_ex(session
->fp
, &pkt_header
, (const u_char
**) &pkt_data
)) >= 0) // cast to avoid a compiler warning
2444 if (retval
== 0) // Read timeout elapsed
2449 // Bufferize the general header
2450 if (sock_bufferize(NULL
, sizeof(struct rpcap_header
), NULL
,
2451 &sendbufidx
, (int)sendbufsize
, SOCKBUF_CHECKONLY
, errbuf
,
2452 PCAP_ERRBUF_SIZE
) == -1)
2454 rpcapd_log(LOGPRIO_ERROR
,
2455 "sock_bufferize() error sending packet message: %s",
2460 rpcap_createhdr((struct rpcap_header
*) sendbuf
,
2461 session
->protocol_version
, RPCAP_MSG_PACKET
, 0,
2462 (uint16
) (sizeof(struct rpcap_pkthdr
) + pkt_header
->caplen
));
2464 net_pkt_header
= (struct rpcap_pkthdr
*) &sendbuf
[sendbufidx
];
2466 // Bufferize the pkt header
2467 if (sock_bufferize(NULL
, sizeof(struct rpcap_pkthdr
), NULL
,
2468 &sendbufidx
, (int)sendbufsize
, SOCKBUF_CHECKONLY
, errbuf
,
2469 PCAP_ERRBUF_SIZE
) == -1)
2471 rpcapd_log(LOGPRIO_ERROR
,
2472 "sock_bufferize() error sending packet message: %s",
2477 net_pkt_header
->caplen
= htonl(pkt_header
->caplen
);
2478 net_pkt_header
->len
= htonl(pkt_header
->len
);
2479 net_pkt_header
->npkt
= htonl(++(session
->TotCapt
));
2481 // This protocol needs to be updated with a new version
2482 // before 2038-01-19 03:14:07 UTC.
2484 net_pkt_header
->timestamp_sec
= htonl((uint32
)pkt_header
->ts
.tv_sec
);
2485 net_pkt_header
->timestamp_usec
= htonl((uint32
)pkt_header
->ts
.tv_usec
);
2487 // Bufferize the pkt data
2488 if (sock_bufferize((char *) pkt_data
, pkt_header
->caplen
,
2489 sendbuf
, &sendbufidx
, (int)sendbufsize
, SOCKBUF_BUFFERIZE
,
2490 errbuf
, PCAP_ERRBUF_SIZE
) == -1)
2492 rpcapd_log(LOGPRIO_ERROR
,
2493 "sock_bufferize() error sending packet message: %s",
2499 // If the client dropped the connection, don't report an
2500 // error, just quit.
2501 status
= sock_send(session
->sockdata
, session
->data_ssl
, sendbuf
, sendbufidx
, errbuf
, PCAP_ERRBUF_SIZE
);
2507 // Error other than "client closed the
2508 // connection out from under us"; report
2511 rpcapd_log(LOGPRIO_ERROR
,
2512 "Send of packet to client failed: %s",
2517 // Give up in either case.
2525 pcap_snprintf(errbuf
, PCAP_ERRBUF_SIZE
, "Error reading the packets: %s", pcap_geterr(session
->fp
));
2526 rpcap_senderror(session
->sockctrl_out
, session
->ctrl_ssl
, session
->protocol_version
,
2527 PCAP_ERR_READEX
, errbuf
, NULL
);
2532 session_close(session
);
2540 \brief It serializes a network address.
2542 It accepts a 'sockaddr_storage' structure as input, and it converts it appropriately into a format
2543 that can be used to be sent on the network. Basically, it applies all the hton()
2544 conversion required to the input variable.
2546 \param sockaddrin a 'sockaddr_storage' pointer to the variable that has to be
2547 serialized. This variable can be both a 'sockaddr_in' and 'sockaddr_in6'.
2549 \param sockaddrout an 'rpcap_sockaddr' pointer to the variable that will contain
2550 the serialized data. This variable has to be allocated by the user.
2552 \warning This function supports only AF_INET and AF_INET6 address families.
2555 daemon_seraddr(struct sockaddr_storage
*sockaddrin
, struct rpcap_sockaddr
*sockaddrout
)
2557 memset(sockaddrout
, 0, sizeof(struct sockaddr_storage
));
2559 // There can be the case in which the sockaddrin is not available
2560 if (sockaddrin
== NULL
) return;
2562 // Warning: we support only AF_INET and AF_INET6
2563 switch (sockaddrin
->ss_family
)
2567 struct sockaddr_in
*sockaddrin_ipv4
;
2568 struct rpcap_sockaddr_in
*sockaddrout_ipv4
;
2570 sockaddrin_ipv4
= (struct sockaddr_in
*) sockaddrin
;
2571 sockaddrout_ipv4
= (struct rpcap_sockaddr_in
*) sockaddrout
;
2572 sockaddrout_ipv4
->family
= htons(RPCAP_AF_INET
);
2573 sockaddrout_ipv4
->port
= htons(sockaddrin_ipv4
->sin_port
);
2574 memcpy(&sockaddrout_ipv4
->addr
, &sockaddrin_ipv4
->sin_addr
, sizeof(sockaddrout_ipv4
->addr
));
2575 memset(sockaddrout_ipv4
->zero
, 0, sizeof(sockaddrout_ipv4
->zero
));
2582 struct sockaddr_in6
*sockaddrin_ipv6
;
2583 struct rpcap_sockaddr_in6
*sockaddrout_ipv6
;
2585 sockaddrin_ipv6
= (struct sockaddr_in6
*) sockaddrin
;
2586 sockaddrout_ipv6
= (struct rpcap_sockaddr_in6
*) sockaddrout
;
2587 sockaddrout_ipv6
->family
= htons(RPCAP_AF_INET6
);
2588 sockaddrout_ipv6
->port
= htons(sockaddrin_ipv6
->sin6_port
);
2589 sockaddrout_ipv6
->flowinfo
= htonl(sockaddrin_ipv6
->sin6_flowinfo
);
2590 memcpy(&sockaddrout_ipv6
->addr
, &sockaddrin_ipv6
->sin6_addr
, sizeof(sockaddrout_ipv6
->addr
));
2591 sockaddrout_ipv6
->scope_id
= htonl(sockaddrin_ipv6
->sin6_scope_id
);
2600 \brief Suspends a thread for secs seconds.
2602 void sleep_secs(int secs
)
2607 unsigned secs_remaining
;
2611 secs_remaining
= secs
;
2612 while (secs_remaining
!= 0)
2613 secs_remaining
= sleep(secs_remaining
);
2618 * Read the header of a message.
2621 rpcapd_recv_msg_header(SOCKET sock
, SSL
*ssl
, struct rpcap_header
*headerp
)
2624 char errbuf
[PCAP_ERRBUF_SIZE
]; // buffer for network errors
2626 nread
= sock_recv(sock
, ssl
, (char *) headerp
, sizeof(struct rpcap_header
),
2627 SOCK_RECEIVEALL_YES
|SOCK_EOF_ISNT_ERROR
, errbuf
, PCAP_ERRBUF_SIZE
);
2631 rpcapd_log(LOGPRIO_ERROR
, "Read from client failed: %s", errbuf
);
2636 // Immediate EOF; that's treated like a close message.
2639 headerp
->plen
= ntohl(headerp
->plen
);
2644 * Read data from a message.
2645 * If we're trying to read more data that remains, puts an error
2646 * message into errmsgbuf and returns -2. Otherwise, tries to read
2647 * the data and, if that succeeds, subtracts the amount read from
2648 * the number of bytes of data that remains.
2649 * Returns 0 on success, logs a message and returns -1 on a network
2653 rpcapd_recv(SOCKET sock
, SSL
*ssl
, char *buffer
, size_t toread
, uint32
*plen
, char *errmsgbuf
)
2656 char errbuf
[PCAP_ERRBUF_SIZE
]; // buffer for network errors
2660 // Tell the client and continue.
2661 pcap_snprintf(errmsgbuf
, PCAP_ERRBUF_SIZE
, "Message payload is too short");
2664 nread
= sock_recv(sock
, ssl
, buffer
, toread
,
2665 SOCK_RECEIVEALL_YES
|SOCK_EOF_IS_ERROR
, errbuf
, PCAP_ERRBUF_SIZE
);
2668 rpcapd_log(LOGPRIO_ERROR
, "Read from client failed: %s", errbuf
);
2676 * Discard data from a connection.
2677 * Mostly used to discard wrong-sized messages.
2678 * Returns 0 on success, logs a message and returns -1 on a network
2682 rpcapd_discard(SOCKET sock
, SSL
*ssl
, uint32 len
)
2684 char errbuf
[PCAP_ERRBUF_SIZE
+ 1]; // keeps the error string, prior to be printed
2688 if (sock_discard(sock
, ssl
, len
, errbuf
, PCAP_ERRBUF_SIZE
) == -1)
2691 rpcapd_log(LOGPRIO_ERROR
, "Read from client failed: %s", errbuf
);
2699 * Close the socket associated with the session, the optional SSL handle,
2700 * and the underlying packet capture handle. We of course do not touch
2701 * the controlling socket that's also copied into the session.
2703 static void session_close(struct session
*session
)
2706 if (session
->data_ssl
)
2708 SSL_free(session
->data_ssl
); // Must happen *before* the socket is closed
2709 session
->data_ssl
= NULL
;
2713 if (session
->sockdata
)
2715 sock_close(session
->sockdata
, NULL
, 0);
2716 session
->sockdata
= 0;
2719 pcap_close(session
->fp
);