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
51 #include <sys/types.h> // for select() and such
52 #include <pwd.h> // for password management
56 #include <shadow.h> // for password management
59 #include <pcap.h> // for libpcap/WinPcap calls
62 #include "sockutils.h" // for socket calls
63 #include "portability.h"
64 #include "rpcap-protocol.h"
69 #include <openssl/ssl.h>
73 #define RPCAP_TIMEOUT_INIT 90 /* Initial timeout for RPCAP connections (default: 90 sec) */
74 #define RPCAP_TIMEOUT_RUNTIME 180 /* Run-time timeout for RPCAP connections (default: 3 min) */
75 #define RPCAP_SUSPEND_WRONGAUTH 1 /* If the authentication is wrong, stops 1 sec before accepting a new auth message */
77 // Parameters for the service loop.
80 SOCKET sockctrl
; //!< SOCKET ID 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.
89 // It includes both a Boolean indicating whether we *have* a thread,
90 // and a platform-dependent (UN*X vs. Windows) identifier for the
91 // thread; on Windows, we could use an invalid handle to indicate
92 // that we don't have a thread, but there *is* no portable "no thread"
93 // value for a pthread_t on UN*X.
98 SSL
*ctrl_ssl
, *data_ssl
; // optional SSL handlers for sockctrl and sockdata.
99 uint8 protocol_version
;
101 unsigned int TotCapt
;
110 // Locally defined functions
111 static int daemon_msg_err(SOCKET sockctrl
, SSL
*, uint32 plen
);
112 static int daemon_msg_auth_req(struct daemon_slpars
*pars
, uint32 plen
);
113 static int daemon_AuthUserPwd(char *username
, char *password
, char *errbuf
);
115 static int daemon_msg_findallif_req(struct daemon_slpars
*pars
, uint32 plen
);
117 static int daemon_msg_open_req(struct daemon_slpars
*pars
, uint32 plen
, char *source
, size_t sourcelen
);
118 static int daemon_msg_startcap_req(struct daemon_slpars
*pars
, uint32 plen
, char *source
, struct session
**sessionp
, struct rpcap_sampling
*samp_param
, int uses_ssl
);
119 static int daemon_msg_endcap_req(struct daemon_slpars
*pars
, struct session
*session
);
121 static int daemon_msg_updatefilter_req(struct daemon_slpars
*pars
, struct session
*session
, uint32 plen
);
122 static int daemon_unpackapplyfilter(SOCKET sockctrl
, SSL
*, struct session
*session
, uint32
*plenp
, char *errbuf
);
124 static int daemon_msg_stats_req(struct daemon_slpars
*pars
, struct session
*session
, uint32 plen
, struct pcap_stat
*stats
, unsigned int svrcapt
);
126 static int daemon_msg_setsampling_req(struct daemon_slpars
*pars
, uint32 plen
, struct rpcap_sampling
*samp_param
);
128 static void daemon_seraddr(struct sockaddr_storage
*sockaddrin
, struct rpcap_sockaddr
*sockaddrout
);
130 static unsigned __stdcall
daemon_thrdatamain(void *ptr
);
132 static void *daemon_thrdatamain(void *ptr
);
133 static void noop_handler(int sign
);
136 static int rpcapd_recv_msg_header(SOCKET sock
, SSL
*, struct rpcap_header
*headerp
);
137 static int rpcapd_recv(SOCKET sock
, SSL
*, char *buffer
, size_t toread
, uint32
*plen
, char *errmsgbuf
);
138 static int rpcapd_discard(SOCKET sock
, SSL
*, uint32 len
);
139 static void session_close(struct session
*);
142 daemon_serviceloop(SOCKET sockctrl
, int isactive
, char *passiveClients
,
143 int nullAuthAllowed
, int uses_ssl
)
145 struct daemon_slpars pars
; // service loop parameters
146 char errbuf
[PCAP_ERRBUF_SIZE
+ 1]; // keeps the error string, prior to be printed
147 char errmsgbuf
[PCAP_ERRBUF_SIZE
+ 1]; // buffer for errors to send to the client
148 int host_port_check_status
;
151 struct rpcap_header header
; // RPCAP message general header
152 uint32 plen
; // payload length from header
153 int authenticated
= 0; // 1 if the client has successfully authenticated
154 char source
[PCAP_BUF_SIZE
+1]; // keeps the string that contains the interface to open
155 int got_source
= 0; // 1 if we've gotten the source from an open request
157 struct sigaction action
;
159 struct session
*session
= NULL
; // struct session main variable
160 const char *msg_type_string
; // string for message type
161 int client_told_us_to_close
= 0; // 1 if the client told us to close the capture
163 // needed to save the values of the statistics
164 struct pcap_stat stats
;
165 unsigned int svrcapt
;
167 struct rpcap_sampling samp_param
; // in case sampling has been requested
169 // Structures needed for the select() call
170 fd_set rfds
; // set of socket descriptors we have to check
171 struct timeval tv
; // maximum time the select() can block waiting for data
172 int retval
; // select() return value
174 *errbuf
= 0; // Initialize errbuf
178 // We have to upgrade to TLS as soon as possible, so that the
179 // whole protocol goes through the encrypted tunnel, including
180 // early error messages.
182 // Even in active mode, the other end has to initiate the TLS
183 // handshake as we still are the server as far as TLS is concerned,
184 // so we don't check isactive.
188 ssl
= ssl_promotion(1, sockctrl
, errbuf
, PCAP_ERRBUF_SIZE
);
191 rpcapd_log(LOGPRIO_ERROR
, "TLS handshake on control connection failed: %s",
198 // Set parameters structure
199 pars
.sockctrl
= sockctrl
;
201 pars
.protocol_version
= 0; // not yet known
202 pars
.isactive
= isactive
; // active mode
203 pars
.nullAuthAllowed
= nullAuthAllowed
;
206 // We have a connection.
208 // If it's a passive mode connection, check whether the connecting
209 // host is among the ones allowed.
211 // In either case, we were handed a copy of the host list; free it
212 // as soon as we're done with it.
217 free(passiveClients
);
218 passiveClients
= NULL
;
222 struct sockaddr_storage from
;
226 // Get the address of the other end of the connection.
228 fromlen
= sizeof(struct sockaddr_storage
);
229 if (getpeername(pars
.sockctrl
, (struct sockaddr
*)&from
,
232 sock_geterror("getpeername(): ", errmsgbuf
, PCAP_ERRBUF_SIZE
);
233 if (rpcap_senderror(pars
.sockctrl
, pars
.ssl
, 0, PCAP_ERR_NETW
, errmsgbuf
, errbuf
) == -1)
234 rpcapd_log(LOGPRIO_ERROR
, "Send to client failed: %s", errbuf
);
239 // Are they in the list of host/port combinations we allow?
241 host_port_check_status
= sock_check_hostlist(passiveClients
, RPCAP_HOSTLIST_SEP
, &from
, errmsgbuf
, PCAP_ERRBUF_SIZE
);
242 free(passiveClients
);
243 passiveClients
= NULL
;
244 if (host_port_check_status
< 0)
247 // Sorry, we can't let you in.
249 if (rpcap_senderror(pars
.sockctrl
, pars
.ssl
, 0, PCAP_ERR_HOSTNOAUTH
, errmsgbuf
, errbuf
) == -1)
250 rpcapd_log(LOGPRIO_ERROR
, "Send to client failed: %s", errbuf
);
257 // Catch SIGUSR1, but do nothing. We use it to interrupt the
258 // capture thread to break it out of a loop in which it's
259 // blocked waiting for packets to arrive.
261 // We don't want interrupted system calls to restart, so that
262 // the read routine for the pcap_t gets EINTR rather than
263 // restarting if it's blocked in a system call.
265 memset(&action
, 0, sizeof (action
));
266 action
.sa_handler
= noop_handler
;
268 sigemptyset(&action
.sa_mask
);
269 sigaction(SIGUSR1
, &action
, NULL
);
273 // The client must first authenticate; loop until they send us a
274 // message with a version we support and credentials we accept,
275 // they send us a close message indicating that they're giving up,
276 // or we get a network error or other fatal error.
278 while (!authenticated
)
281 // If we're in active mode, we have to check for the
284 // XXX - do this on *every* trip through the loop?
289 // We do not have to block here
290 tv
.tv_sec
= RPCAP_TIMEOUT_INIT
;
293 FD_SET(pars
.sockctrl
, &rfds
);
295 retval
= select((int)pars
.sockctrl
+ 1, &rfds
, NULL
, NULL
, &tv
);
298 sock_geterror("select failed: ", errmsgbuf
, PCAP_ERRBUF_SIZE
);
299 if (rpcap_senderror(pars
.sockctrl
, pars
.ssl
, 0, PCAP_ERR_NETW
, errmsgbuf
, errbuf
) == -1)
300 rpcapd_log(LOGPRIO_ERROR
, "Send to client failed: %s", errbuf
);
304 // The timeout has expired
305 // So, this was a fake connection. Drop it down
308 if (rpcap_senderror(pars
.sockctrl
, pars
.ssl
, 0, PCAP_ERR_INITTIMEOUT
, "The RPCAP initial timeout has expired", errbuf
) == -1)
309 rpcapd_log(LOGPRIO_ERROR
, "Send to client failed: %s", errbuf
);
315 // Read the message header from the client.
317 nrecv
= rpcapd_recv_msg_header(pars
.sockctrl
, pars
.ssl
, &header
);
325 // Client closed the connection.
332 // Did the client specify a version we can handle?
334 if (!RPCAP_VERSION_IS_SUPPORTED(header
.ver
))
337 // Tell them it's not a valid protocol version.
342 // If RPCAP_MIN_VERSION is 0, no version is too
343 // old, as the oldest supported version is 0,
344 // and there are no negative versions.
346 #if RPCAP_MIN_VERSION != 0
347 if (header
.ver
< RPCAP_MIN_VERSION
)
350 // Their maximum version is too old;
351 // there *is* no version we can both
352 // handle, and they might reject
353 // an error with a version they don't
354 // understand, so reply with the
355 // version they sent. That may
356 // make them retry with that version,
357 // but they'll give up on that
360 reply_version
= header
.ver
;
366 // Their maximum version is too new,
367 // but they might be able to handle
368 // *our* maximum version, so reply
369 // with that version.
371 reply_version
= RPCAP_MAX_VERSION
;
373 if (rpcap_senderror(pars
.sockctrl
, pars
.ssl
, reply_version
,
374 PCAP_ERR_WRONGVER
, "RPCAP version number mismatch",
377 // That failed; log a message and give up.
378 rpcapd_log(LOGPRIO_ERROR
, "Send to client failed: %s", errbuf
);
382 // Discard the rest of the message.
383 if (rpcapd_discard(pars
.sockctrl
, pars
.ssl
, plen
) == -1)
389 // Let them try again.
394 // OK, we use the version the client specified.
396 pars
.protocol_version
= header
.ver
;
400 case RPCAP_MSG_AUTH_REQ
:
401 retval
= daemon_msg_auth_req(&pars
, plen
);
404 // Fatal error; a message has
405 // been logged, so just give up.
410 // Non-fatal error; we sent back
411 // an error message, so let them
416 // OK, we're authenticated; we sent back
417 // a reply, so start serving requests.
421 case RPCAP_MSG_CLOSE
:
423 // The client is giving up.
424 // Discard the rest of the message, if
425 // there is anything more.
427 (void)rpcapd_discard(pars
.sockctrl
, pars
.ssl
, plen
);
428 // We're done with this client.
431 case RPCAP_MSG_ERROR
:
432 // Log this and close the connection?
433 // XXX - is this what happens in active
434 // mode, where *we* initiate the
435 // connection, and the client gives us
436 // an error message rather than a "let
437 // me log in" message, indicating that
438 // we're not allowed to connect to them?
439 (void)daemon_msg_err(pars
.sockctrl
, pars
.ssl
, plen
);
442 case RPCAP_MSG_FINDALLIF_REQ
:
443 case RPCAP_MSG_OPEN_REQ
:
444 case RPCAP_MSG_STARTCAP_REQ
:
445 case RPCAP_MSG_UPDATEFILTER_REQ
:
446 case RPCAP_MSG_STATS_REQ
:
447 case RPCAP_MSG_ENDCAP_REQ
:
448 case RPCAP_MSG_SETSAMPLING_REQ
:
450 // These requests can't be sent until
451 // the client is authenticated.
453 msg_type_string
= rpcap_msg_type_string(header
.type
);
454 if (msg_type_string
!= NULL
)
456 pcap_snprintf(errmsgbuf
, PCAP_ERRBUF_SIZE
, "%s request sent before authentication was completed", msg_type_string
);
460 pcap_snprintf(errmsgbuf
, PCAP_ERRBUF_SIZE
, "Message of type %u sent before authentication was completed", header
.type
);
462 if (rpcap_senderror(pars
.sockctrl
, pars
.ssl
,
463 pars
.protocol_version
, PCAP_ERR_WRONGMSG
,
464 errmsgbuf
, errbuf
) == -1)
466 rpcapd_log(LOGPRIO_ERROR
, "Send to client failed: %s", errbuf
);
469 // Discard the rest of the message.
470 if (rpcapd_discard(pars
.sockctrl
, pars
.ssl
, plen
) == -1)
477 case RPCAP_MSG_PACKET
:
478 case RPCAP_MSG_FINDALLIF_REPLY
:
479 case RPCAP_MSG_OPEN_REPLY
:
480 case RPCAP_MSG_STARTCAP_REPLY
:
481 case RPCAP_MSG_UPDATEFILTER_REPLY
:
482 case RPCAP_MSG_AUTH_REPLY
:
483 case RPCAP_MSG_STATS_REPLY
:
484 case RPCAP_MSG_ENDCAP_REPLY
:
485 case RPCAP_MSG_SETSAMPLING_REPLY
:
487 // These are server-to-client messages.
489 msg_type_string
= rpcap_msg_type_string(header
.type
);
490 if (msg_type_string
!= NULL
)
492 pcap_snprintf(errmsgbuf
, PCAP_ERRBUF_SIZE
, "Server-to-client message %s received from client", msg_type_string
);
496 pcap_snprintf(errmsgbuf
, PCAP_ERRBUF_SIZE
, "Server-to-client message of type %u received from client", header
.type
);
498 if (rpcap_senderror(pars
.sockctrl
, pars
.ssl
,
499 pars
.protocol_version
, PCAP_ERR_WRONGMSG
,
500 errmsgbuf
, errbuf
) == -1)
502 rpcapd_log(LOGPRIO_ERROR
, "Send to client failed: %s", errbuf
);
505 // Discard the rest of the message.
506 if (rpcapd_discard(pars
.sockctrl
, pars
.ssl
, plen
) == -1)
515 // Unknown message type.
517 pcap_snprintf(errmsgbuf
, PCAP_ERRBUF_SIZE
, "Unknown message type %u", header
.type
);
518 if (rpcap_senderror(pars
.sockctrl
, pars
.ssl
,
519 pars
.protocol_version
, PCAP_ERR_WRONGMSG
,
520 errmsgbuf
, errbuf
) == -1)
522 rpcapd_log(LOGPRIO_ERROR
, "Send to client failed: %s", errbuf
);
525 // Discard the rest of the message.
526 if (rpcapd_discard(pars
.sockctrl
, pars
.ssl
, plen
) == -1)
536 // OK, the client has authenticated itself, and we can start
537 // processing regular requests from it.
541 // We don't have any statistics yet.
553 errbuf
[0] = 0; // clear errbuf
555 // Avoid zombies connections; check if the connection is opens but no commands are performed
556 // from more than RPCAP_TIMEOUT_RUNTIME
558 // - I have to be in normal mode (no active mode)
559 // - if the device is open, I don't have to be in the middle of a capture (session->sockdata)
560 // - if the device is closed, I have always to check if a new command arrives
562 // Be carefully: the capture can have been started, but an error occurred (so session != NULL, but
564 if ((!pars
.isactive
) && ((session
== NULL
) || ((session
!= NULL
) && (session
->sockdata
== 0))))
566 // Check for the initial timeout
568 // We do not have to block here
569 tv
.tv_sec
= RPCAP_TIMEOUT_RUNTIME
;
572 FD_SET(pars
.sockctrl
, &rfds
);
574 retval
= select((int)pars
.sockctrl
+ 1, &rfds
, NULL
, NULL
, &tv
);
577 sock_geterror("select failed: ", errmsgbuf
, PCAP_ERRBUF_SIZE
);
578 if (rpcap_senderror(pars
.sockctrl
, pars
.ssl
,
579 pars
.protocol_version
, PCAP_ERR_NETW
,
580 errmsgbuf
, errbuf
) == -1)
581 rpcapd_log(LOGPRIO_ERROR
, "Send to client failed: %s", errbuf
);
585 // The timeout has expired
586 // So, this was a fake connection. Drop it down
589 if (rpcap_senderror(pars
.sockctrl
, pars
.ssl
,
590 pars
.protocol_version
,
591 PCAP_ERR_INITTIMEOUT
,
592 "The RPCAP initial timeout has expired",
594 rpcapd_log(LOGPRIO_ERROR
, "Send to client failed: %s", errbuf
);
600 // Read the message header from the client.
602 nrecv
= rpcapd_recv_msg_header(pars
.sockctrl
, pars
.ssl
, &header
);
610 // Client closed the connection.
617 // Did the client specify the version we negotiated?
619 // For now, there's only one version.
621 if (header
.ver
!= pars
.protocol_version
)
624 // Tell them it's not the negotiated version.
625 // Send the error message with their version,
626 // so they don't reject it as having the wrong
629 if (rpcap_senderror(pars
.sockctrl
, pars
.ssl
,
630 header
.ver
, PCAP_ERR_WRONGVER
,
631 "RPCAP version in message isn't the negotiated version",
634 // That failed; log a message and give up.
635 rpcapd_log(LOGPRIO_ERROR
, "Send to client failed: %s", errbuf
);
639 // Discard the rest of the message.
640 (void)rpcapd_discard(pars
.sockctrl
, pars
.ssl
, plen
);
647 case RPCAP_MSG_ERROR
: // The other endpoint reported an error
649 (void)daemon_msg_err(pars
.sockctrl
, pars
.ssl
, plen
);
650 // Do nothing; just exit; the error code is already into the errbuf
651 // XXX - actually exit....
655 case RPCAP_MSG_FINDALLIF_REQ
:
657 if (daemon_msg_findallif_req(&pars
, plen
) == -1)
659 // Fatal error; a message has
660 // been logged, so just give up.
666 case RPCAP_MSG_OPEN_REQ
:
669 // Process the open request, and keep
670 // the source from it, for use later
671 // when the capture is started.
673 // XXX - we don't care if the client sends
674 // us multiple open requests, the last
677 retval
= daemon_msg_open_req(&pars
, plen
, source
, sizeof(source
));
680 // Fatal error; a message has
681 // been logged, so just give up.
688 case RPCAP_MSG_STARTCAP_REQ
:
692 // They never told us what device
694 if (rpcap_senderror(pars
.sockctrl
, pars
.ssl
,
695 pars
.protocol_version
,
696 PCAP_ERR_STARTCAPTURE
,
697 "No capture device was specified",
700 // Fatal error; log an
701 // error and give up.
702 rpcapd_log(LOGPRIO_ERROR
, "Send to client failed: %s", errbuf
);
705 if (rpcapd_discard(pars
.sockctrl
, pars
.ssl
, plen
) == -1)
712 if (daemon_msg_startcap_req(&pars
, plen
, source
, &session
, &samp_param
, uses_ssl
) == -1)
714 // Fatal error; a message has
715 // been logged, so just give up.
721 case RPCAP_MSG_UPDATEFILTER_REQ
:
725 if (daemon_msg_updatefilter_req(&pars
, session
, plen
) == -1)
727 // Fatal error; a message has
728 // been logged, so just give up.
734 if (rpcap_senderror(pars
.sockctrl
, pars
.ssl
,
735 pars
.protocol_version
,
736 PCAP_ERR_UPDATEFILTER
,
737 "Device not opened. Cannot update filter",
740 // That failed; log a message and give up.
741 rpcapd_log(LOGPRIO_ERROR
, "Send to client failed: %s", errbuf
);
748 case RPCAP_MSG_CLOSE
: // The other endpoint close the pcap session
751 // Indicate to our caller that the client
752 // closed the control connection.
753 // This is used only in case of active mode.
755 client_told_us_to_close
= 1;
756 rpcapd_log(LOGPRIO_DEBUG
, "The other end system asked to close the connection.");
760 case RPCAP_MSG_STATS_REQ
:
762 if (daemon_msg_stats_req(&pars
, session
, plen
, &stats
, svrcapt
) == -1)
764 // Fatal error; a message has
765 // been logged, so just give up.
771 case RPCAP_MSG_ENDCAP_REQ
: // The other endpoint close the current capture session
775 // Save statistics (we can need them in the future)
776 if (pcap_stats(session
->fp
, &stats
))
778 svrcapt
= session
->TotCapt
;
788 if (daemon_msg_endcap_req(&pars
, session
) == -1)
792 // Fatal error; a message has
793 // been logged, so just give up.
801 rpcap_senderror(pars
.sockctrl
, pars
.ssl
,
802 pars
.protocol_version
,
804 "Device not opened. Cannot close the capture",
810 case RPCAP_MSG_SETSAMPLING_REQ
:
812 if (daemon_msg_setsampling_req(&pars
, plen
, &samp_param
) == -1)
814 // Fatal error; a message has
815 // been logged, so just give up.
821 case RPCAP_MSG_AUTH_REQ
:
824 // We're already authenticated; you don't
825 // get to reauthenticate.
827 rpcapd_log(LOGPRIO_INFO
, "The client sent an RPCAP_MSG_AUTH_REQ message after authentication was completed");
828 if (rpcap_senderror(pars
.sockctrl
, pars
.ssl
,
829 pars
.protocol_version
,
831 "RPCAP_MSG_AUTH_REQ request sent after authentication was completed",
834 rpcapd_log(LOGPRIO_ERROR
, "Send to client failed: %s", errbuf
);
837 // Discard the rest of the message.
838 if (rpcapd_discard(pars
.sockctrl
, pars
.ssl
, plen
) == -1)
845 case RPCAP_MSG_PACKET
:
846 case RPCAP_MSG_FINDALLIF_REPLY
:
847 case RPCAP_MSG_OPEN_REPLY
:
848 case RPCAP_MSG_STARTCAP_REPLY
:
849 case RPCAP_MSG_UPDATEFILTER_REPLY
:
850 case RPCAP_MSG_AUTH_REPLY
:
851 case RPCAP_MSG_STATS_REPLY
:
852 case RPCAP_MSG_ENDCAP_REPLY
:
853 case RPCAP_MSG_SETSAMPLING_REPLY
:
855 // These are server-to-client messages.
857 msg_type_string
= rpcap_msg_type_string(header
.type
);
858 if (msg_type_string
!= NULL
)
860 rpcapd_log(LOGPRIO_INFO
, "The client sent a %s server-to-client message", msg_type_string
);
861 pcap_snprintf(errmsgbuf
, PCAP_ERRBUF_SIZE
, "Server-to-client message %s received from client", msg_type_string
);
865 rpcapd_log(LOGPRIO_INFO
, "The client sent a server-to-client message of type %u", header
.type
);
866 pcap_snprintf(errmsgbuf
, PCAP_ERRBUF_SIZE
, "Server-to-client message of type %u received from client", header
.type
);
868 if (rpcap_senderror(pars
.sockctrl
, pars
.ssl
,
869 pars
.protocol_version
, PCAP_ERR_WRONGMSG
,
870 errmsgbuf
, errbuf
) == -1)
872 rpcapd_log(LOGPRIO_ERROR
, "Send to client failed: %s", errbuf
);
875 // Discard the rest of the message.
876 if (rpcapd_discard(pars
.sockctrl
, pars
.ssl
, plen
) == -1)
885 // Unknown message type.
887 rpcapd_log(LOGPRIO_INFO
, "The client sent a message of type %u", header
.type
);
888 pcap_snprintf(errmsgbuf
, PCAP_ERRBUF_SIZE
, "Unknown message type %u", header
.type
);
889 if (rpcap_senderror(pars
.sockctrl
, pars
.ssl
,
890 pars
.protocol_version
, PCAP_ERR_WRONGMSG
,
891 errbuf
, errmsgbuf
) == -1)
893 rpcapd_log(LOGPRIO_ERROR
, "Send to client failed: %s", errbuf
);
896 // Discard the rest of the message.
897 if (rpcapd_discard(pars
.sockctrl
, pars
.ssl
, plen
) == -1)
908 // The service loop is finishing up.
909 // If we have a capture session running, close it.
912 session_close(session
);
918 // Free the SSL handle for the control socket, if we have one,
919 // and close the control socket.
927 sock_close(sockctrl
, NULL
, 0);
929 // Print message and return
930 rpcapd_log(LOGPRIO_DEBUG
, "I'm exiting from the child loop");
931 rpcapd_log(LOGPRIO_DEBUG
, "%s", errbuf
);
933 return client_told_us_to_close
;
937 * This handles the RPCAP_MSG_ERR message.
940 daemon_msg_err(SOCKET sockctrl
, SSL
*ssl
, uint32 plen
)
942 char errbuf
[PCAP_ERRBUF_SIZE
];
943 char remote_errbuf
[PCAP_ERRBUF_SIZE
];
945 if (plen
>= PCAP_ERRBUF_SIZE
)
948 * Message is too long; just read as much of it as we
949 * can into the buffer provided, and discard the rest.
951 if (sock_recv(sockctrl
, ssl
, remote_errbuf
, PCAP_ERRBUF_SIZE
- 1,
952 SOCK_RECEIVEALL_YES
|SOCK_EOF_IS_ERROR
, errbuf
,
953 PCAP_ERRBUF_SIZE
) == -1)
956 rpcapd_log(LOGPRIO_ERROR
, "Read from client failed: %s", errbuf
);
959 if (rpcapd_discard(sockctrl
, ssl
, plen
- (PCAP_ERRBUF_SIZE
- 1)) == -1)
968 remote_errbuf
[PCAP_ERRBUF_SIZE
- 1] = '\0';
972 /* Empty error string. */
973 remote_errbuf
[0] = '\0';
977 if (sock_recv(sockctrl
, ssl
, remote_errbuf
, plen
,
978 SOCK_RECEIVEALL_YES
|SOCK_EOF_IS_ERROR
, errbuf
,
979 PCAP_ERRBUF_SIZE
) == -1)
982 rpcapd_log(LOGPRIO_ERROR
, "Read from client failed: %s", errbuf
);
989 remote_errbuf
[plen
] = '\0';
992 rpcapd_log(LOGPRIO_ERROR
, "Error from client: %s", remote_errbuf
);
997 * This handles the RPCAP_MSG_AUTH_REQ message.
998 * It checks if the authentication credentials supplied by the user are valid.
1000 * This function is called if the daemon receives a RPCAP_MSG_AUTH_REQ
1001 * message in its authentication loop. It reads the body of the
1002 * authentication message from the network and checks whether the
1003 * credentials are valid.
1005 * \param sockctrl: the socket for the control connection.
1007 * \param nullAuthAllowed: '1' if the NULL authentication is allowed.
1009 * \param errbuf: a user-allocated buffer in which the error message
1010 * (if one) has to be written. It must be at least PCAP_ERRBUF_SIZE
1013 * \return '0' if everything is fine, '-1' if an unrecoverable error occurred,
1014 * or '-2' if the authentication failed. For errors, an error message is
1015 * returned in the 'errbuf' variable; this gives a message for the
1016 * unrecoverable error or for the authentication failure.
1019 daemon_msg_auth_req(struct daemon_slpars
*pars
, uint32 plen
)
1021 char errbuf
[PCAP_ERRBUF_SIZE
]; // buffer for network errors
1022 char errmsgbuf
[PCAP_ERRBUF_SIZE
]; // buffer for errors to send to the client
1023 struct rpcap_header header
; // RPCAP message general header
1025 struct rpcap_auth auth
; // RPCAP authentication header
1027 status
= rpcapd_recv(pars
->sockctrl
, pars
->ssl
, (char *) &auth
, sizeof(struct rpcap_auth
), &plen
, errmsgbuf
);
1037 switch (ntohs(auth
.type
))
1039 case RPCAP_RMTAUTH_NULL
:
1041 if (!pars
->nullAuthAllowed
)
1043 // Send the client an error reply.
1044 pcap_snprintf(errmsgbuf
, PCAP_ERRBUF_SIZE
, "Authentication failed; NULL authentication not permitted.");
1050 case RPCAP_RMTAUTH_PWD
:
1052 char *username
, *passwd
;
1053 uint32 usernamelen
, passwdlen
;
1055 usernamelen
= ntohs(auth
.slen1
);
1056 username
= (char *) malloc (usernamelen
+ 1);
1057 if (username
== NULL
)
1059 pcap_fmt_errmsg_for_errno(errmsgbuf
,
1060 PCAP_ERRBUF_SIZE
, errno
, "malloc() failed");
1063 status
= rpcapd_recv(pars
->sockctrl
, pars
->ssl
, username
, usernamelen
, &plen
, errmsgbuf
);
1074 username
[usernamelen
] = '\0';
1076 passwdlen
= ntohs(auth
.slen2
);
1077 passwd
= (char *) malloc (passwdlen
+ 1);
1080 pcap_fmt_errmsg_for_errno(errmsgbuf
,
1081 PCAP_ERRBUF_SIZE
, errno
, "malloc() failed");
1085 status
= rpcapd_recv(pars
->sockctrl
, pars
->ssl
, passwd
, passwdlen
, &plen
, errmsgbuf
);
1098 passwd
[passwdlen
] = '\0';
1100 if (daemon_AuthUserPwd(username
, passwd
, errmsgbuf
))
1103 // Authentication failed. Let the client
1108 if (rpcap_senderror(pars
->sockctrl
, pars
->ssl
,
1109 pars
->protocol_version
,
1110 PCAP_ERR_AUTH
, errmsgbuf
, errbuf
) == -1)
1112 // That failed; log a message and give up.
1113 rpcapd_log(LOGPRIO_ERROR
, "Send to client failed: %s", errbuf
);
1118 // Suspend for 1 second, so that they can't
1119 // hammer us with repeated tries with an
1120 // attack such as a dictionary attack.
1122 // WARNING: this delay is inserted only
1123 // at this point; if the client closes the
1124 // connection and reconnects, the suspension
1125 // time does not have any effect.
1127 sleep_secs(RPCAP_SUSPEND_WRONGAUTH
);
1137 pcap_snprintf(errmsgbuf
, PCAP_ERRBUF_SIZE
, "Authentication type not recognized.");
1141 // The authentication succeeded; let the client know.
1142 rpcap_createhdr(&header
, pars
->protocol_version
, RPCAP_MSG_AUTH_REPLY
, 0, 0);
1144 // Send the ok message back
1145 if (sock_send(pars
->sockctrl
, pars
->ssl
, (char *) &header
, sizeof (struct rpcap_header
), errbuf
, PCAP_ERRBUF_SIZE
) == -1)
1147 // That failed; log a messsage and give up.
1148 rpcapd_log(LOGPRIO_ERROR
, "Send to client failed: %s", errbuf
);
1152 // Check if all the data has been read; if not, discard the data in excess
1153 if (rpcapd_discard(pars
->sockctrl
, pars
->ssl
, plen
) == -1)
1161 if (rpcap_senderror(pars
->sockctrl
, pars
->ssl
, pars
->protocol_version
,
1162 PCAP_ERR_AUTH
, errmsgbuf
, errbuf
) == -1)
1164 // That failed; log a message and give up.
1165 rpcapd_log(LOGPRIO_ERROR
, "Send to client failed: %s", errbuf
);
1170 // Check if all the data has been read; if not, discard the data in excess
1171 if (rpcapd_discard(pars
->sockctrl
, pars
->ssl
, plen
) == -1)
1180 daemon_AuthUserPwd(char *username
, char *password
, char *errbuf
)
1184 * Warning: the user which launches the process must have the
1185 * SE_TCB_NAME right.
1186 * This corresponds to have the "Act as part of the Operating System"
1187 * turned on (administrative tools, local security settings, local
1188 * policies, user right assignment)
1189 * However, it seems to me that if you run it as a service, this
1190 * right should be provided by default.
1193 if (LogonUser(username
, ".", password
, LOGON32_LOGON_NETWORK
, LOGON32_PROVIDER_DEFAULT
, &Token
) == 0)
1195 pcap_win32_err_to_str(GetLastError(), errbuf
);
1199 // This call should change the current thread to the selected user.
1200 // I didn't test it.
1201 if (ImpersonateLoggedOnUser(Token
) == 0)
1203 pcap_win32_err_to_str(GetLastError(), errbuf
);
1215 * http://www.unixpapa.com/incnote/passwd.html
1217 * We use the Solaris/Linux shadow password authentication if
1218 * we have getspnam(), otherwise we just do traditional
1219 * authentication, which, on some platforms, might work, even
1220 * with shadow passwords, if we're running as root. Traditional
1221 * authenticaion won't work if we're not running as root, as
1222 * I think these days all UN*Xes either won't return the password
1223 * at all with getpwnam() or will only do so if you're root.
1225 * XXX - perhaps what we *should* be using is PAM, if we have
1226 * it. That might hide all the details of username/password
1227 * authentication, whether it's done with a visible-to-root-
1228 * only password database or some other authentication mechanism,
1231 struct passwd
*user
;
1232 char *user_password
;
1233 #ifdef HAVE_GETSPNAM
1234 struct spwd
*usersp
;
1237 // This call is needed to get the uid
1238 if ((user
= getpwnam(username
)) == NULL
)
1240 pcap_snprintf(errbuf
, PCAP_ERRBUF_SIZE
, "Authentication failed: no such user");
1244 #ifdef HAVE_GETSPNAM
1245 // This call is needed to get the password; otherwise 'x' is returned
1246 if ((usersp
= getspnam(username
)) == NULL
)
1248 pcap_snprintf(errbuf
, PCAP_ERRBUF_SIZE
, "Authentication failed: no such user");
1251 user_password
= usersp
->sp_pwdp
;
1254 * XXX - what about other platforms?
1255 * The unixpapa.com page claims this Just Works on *BSD if you're
1256 * running as root - it's from 2000, so it doesn't indicate whether
1257 * macOS (which didn't come out until 2001, under the name Mac OS
1258 * X) behaves like the *BSDs or not, and might also work on AIX.
1259 * HP-UX does something else.
1261 * Again, hopefully PAM hides all that.
1263 user_password
= user
->pw_passwd
;
1266 if (strcmp(user_password
, (char *) crypt(password
, user_password
)) != 0)
1268 pcap_snprintf(errbuf
, PCAP_ERRBUF_SIZE
, "Authentication failed: password incorrect");
1272 if (setuid(user
->pw_uid
))
1274 pcap_fmt_errmsg_for_errno(errbuf
, PCAP_ERRBUF_SIZE
,
1279 /* if (setgid(user->pw_gid))
1281 pcap_fmt_errmsg_for_errno(errbuf, PCAP_ERRBUF_SIZE,
1293 daemon_msg_findallif_req(struct daemon_slpars
*pars
, uint32 plen
)
1295 char errbuf
[PCAP_ERRBUF_SIZE
]; // buffer for network errors
1296 char errmsgbuf
[PCAP_ERRBUF_SIZE
]; // buffer for errors to send to the client
1297 char sendbuf
[RPCAP_NETBUF_SIZE
]; // temporary buffer in which data to be sent is buffered
1298 int sendbufidx
= 0; // index which keeps the number of bytes currently buffered
1299 pcap_if_t
*alldevs
= NULL
; // pointer to the header of the interface chain
1300 pcap_if_t
*d
; // temp pointer needed to scan the interface chain
1301 struct pcap_addr
*address
; // pcap structure that keeps a network address of an interface
1302 struct rpcap_findalldevs_if
*findalldevs_if
;// rpcap structure that packet all the data of an interface together
1303 uint16 nif
= 0; // counts the number of interface listed
1305 // Discard the rest of the message; there shouldn't be any payload.
1306 if (rpcapd_discard(pars
->sockctrl
, pars
->ssl
, plen
) == -1)
1312 // Retrieve the device list
1313 if (pcap_findalldevs(&alldevs
, errmsgbuf
) == -1)
1316 if (alldevs
== NULL
)
1318 if (rpcap_senderror(pars
->sockctrl
, pars
->ssl
, pars
->protocol_version
,
1319 PCAP_ERR_NOREMOTEIF
,
1320 "No interfaces found! Make sure libpcap/WinPcap is properly installed"
1321 " and you have the right to access to the remote device.",
1324 rpcapd_log(LOGPRIO_ERROR
, "Send to client failed: %s", errbuf
);
1330 // checks the number of interfaces and it computes the total length of the payload
1331 for (d
= alldevs
; d
!= NULL
; d
= d
->next
)
1336 plen
+= strlen(d
->description
);
1338 plen
+= strlen(d
->name
);
1340 plen
+= sizeof(struct rpcap_findalldevs_if
);
1342 for (address
= d
->addresses
; address
!= NULL
; address
= address
->next
)
1345 * Send only IPv4 and IPv6 addresses over the wire.
1347 switch (address
->addr
->sa_family
)
1353 plen
+= (sizeof(struct rpcap_sockaddr
) * 4);
1362 // RPCAP findalldevs command
1363 if (sock_bufferize(NULL
, sizeof(struct rpcap_header
), NULL
,
1364 &sendbufidx
, RPCAP_NETBUF_SIZE
, SOCKBUF_CHECKONLY
, errmsgbuf
,
1365 PCAP_ERRBUF_SIZE
) == -1)
1368 rpcap_createhdr((struct rpcap_header
*) sendbuf
, pars
->protocol_version
,
1369 RPCAP_MSG_FINDALLIF_REPLY
, nif
, plen
);
1371 // send the interface list
1372 for (d
= alldevs
; d
!= NULL
; d
= d
->next
)
1374 uint16 lname
, ldescr
;
1376 findalldevs_if
= (struct rpcap_findalldevs_if
*) &sendbuf
[sendbufidx
];
1378 if (sock_bufferize(NULL
, sizeof(struct rpcap_findalldevs_if
), NULL
,
1379 &sendbufidx
, RPCAP_NETBUF_SIZE
, SOCKBUF_CHECKONLY
, errmsgbuf
, PCAP_ERRBUF_SIZE
) == -1)
1382 memset(findalldevs_if
, 0, sizeof(struct rpcap_findalldevs_if
));
1384 if (d
->description
) ldescr
= (short) strlen(d
->description
);
1386 if (d
->name
) lname
= (short) strlen(d
->name
);
1389 findalldevs_if
->desclen
= htons(ldescr
);
1390 findalldevs_if
->namelen
= htons(lname
);
1391 findalldevs_if
->flags
= htonl(d
->flags
);
1393 for (address
= d
->addresses
; address
!= NULL
; address
= address
->next
)
1396 * Send only IPv4 and IPv6 addresses over the wire.
1398 switch (address
->addr
->sa_family
)
1404 findalldevs_if
->naddr
++;
1411 findalldevs_if
->naddr
= htons(findalldevs_if
->naddr
);
1413 if (sock_bufferize(d
->name
, lname
, sendbuf
, &sendbufidx
,
1414 RPCAP_NETBUF_SIZE
, SOCKBUF_BUFFERIZE
, errmsgbuf
,
1415 PCAP_ERRBUF_SIZE
) == -1)
1418 if (sock_bufferize(d
->description
, ldescr
, sendbuf
, &sendbufidx
,
1419 RPCAP_NETBUF_SIZE
, SOCKBUF_BUFFERIZE
, errmsgbuf
,
1420 PCAP_ERRBUF_SIZE
) == -1)
1423 // send all addresses
1424 for (address
= d
->addresses
; address
!= NULL
; address
= address
->next
)
1426 struct rpcap_sockaddr
*sockaddr
;
1429 * Send only IPv4 and IPv6 addresses over the wire.
1431 switch (address
->addr
->sa_family
)
1437 sockaddr
= (struct rpcap_sockaddr
*) &sendbuf
[sendbufidx
];
1438 if (sock_bufferize(NULL
, sizeof(struct rpcap_sockaddr
), NULL
,
1439 &sendbufidx
, RPCAP_NETBUF_SIZE
, SOCKBUF_CHECKONLY
, errmsgbuf
, PCAP_ERRBUF_SIZE
) == -1)
1441 daemon_seraddr((struct sockaddr_storage
*) address
->addr
, sockaddr
);
1443 sockaddr
= (struct rpcap_sockaddr
*) &sendbuf
[sendbufidx
];
1444 if (sock_bufferize(NULL
, sizeof(struct rpcap_sockaddr
), NULL
,
1445 &sendbufidx
, RPCAP_NETBUF_SIZE
, SOCKBUF_CHECKONLY
, errmsgbuf
, PCAP_ERRBUF_SIZE
) == -1)
1447 daemon_seraddr((struct sockaddr_storage
*) address
->netmask
, sockaddr
);
1449 sockaddr
= (struct rpcap_sockaddr
*) &sendbuf
[sendbufidx
];
1450 if (sock_bufferize(NULL
, sizeof(struct rpcap_sockaddr
), NULL
,
1451 &sendbufidx
, RPCAP_NETBUF_SIZE
, SOCKBUF_CHECKONLY
, errmsgbuf
, PCAP_ERRBUF_SIZE
) == -1)
1453 daemon_seraddr((struct sockaddr_storage
*) address
->broadaddr
, sockaddr
);
1455 sockaddr
= (struct rpcap_sockaddr
*) &sendbuf
[sendbufidx
];
1456 if (sock_bufferize(NULL
, sizeof(struct rpcap_sockaddr
), NULL
,
1457 &sendbufidx
, RPCAP_NETBUF_SIZE
, SOCKBUF_CHECKONLY
, errmsgbuf
, PCAP_ERRBUF_SIZE
) == -1)
1459 daemon_seraddr((struct sockaddr_storage
*) address
->dstaddr
, sockaddr
);
1468 // We no longer need the device list. Free it.
1469 pcap_freealldevs(alldevs
);
1471 // Send a final command that says "now send it!"
1472 if (sock_send(pars
->sockctrl
, pars
->ssl
, sendbuf
, sendbufidx
, errbuf
, PCAP_ERRBUF_SIZE
) == -1)
1474 rpcapd_log(LOGPRIO_ERROR
, "Send to client failed: %s", errbuf
);
1482 pcap_freealldevs(alldevs
);
1484 if (rpcap_senderror(pars
->sockctrl
, pars
->ssl
, pars
->protocol_version
,
1485 PCAP_ERR_FINDALLIF
, errmsgbuf
, errbuf
) == -1)
1487 rpcapd_log(LOGPRIO_ERROR
, "Send to client failed: %s", errbuf
);
1494 \param plen: the length of the current message (needed in order to be able
1495 to discard excess data in the message, if present)
1498 daemon_msg_open_req(struct daemon_slpars
*pars
, uint32 plen
, char *source
, size_t sourcelen
)
1500 char errbuf
[PCAP_ERRBUF_SIZE
]; // buffer for network errors
1501 char errmsgbuf
[PCAP_ERRBUF_SIZE
]; // buffer for errors to send to the client
1502 pcap_t
*fp
; // pcap_t main variable
1504 char sendbuf
[RPCAP_NETBUF_SIZE
]; // temporary buffer in which data to be sent is buffered
1505 int sendbufidx
= 0; // index which keeps the number of bytes currently buffered
1506 struct rpcap_openreply
*openreply
; // open reply message
1508 if (plen
> sourcelen
- 1)
1510 pcap_snprintf(errmsgbuf
, PCAP_ERRBUF_SIZE
, "Source string too long");
1514 nread
= sock_recv(pars
->sockctrl
, pars
->ssl
, source
, plen
,
1515 SOCK_RECEIVEALL_YES
|SOCK_EOF_IS_ERROR
, errbuf
, PCAP_ERRBUF_SIZE
);
1518 rpcapd_log(LOGPRIO_ERROR
, "Read from client failed: %s", errbuf
);
1521 source
[nread
] = '\0';
1524 // XXX - make sure it's *not* a URL; we don't support opening
1525 // remote devices here.
1527 // Open the selected device
1528 // This is a fake open, since we do that only to get the needed parameters, then we close the device again
1529 if ((fp
= pcap_open_live(source
,
1530 1500 /* fake snaplen */,
1532 1000 /* fake timeout */,
1533 errmsgbuf
)) == NULL
)
1536 // Now, I can send a RPCAP open reply message
1537 if (sock_bufferize(NULL
, sizeof(struct rpcap_header
), NULL
, &sendbufidx
,
1538 RPCAP_NETBUF_SIZE
, SOCKBUF_CHECKONLY
, errmsgbuf
, PCAP_ERRBUF_SIZE
) == -1)
1541 rpcap_createhdr((struct rpcap_header
*) sendbuf
, pars
->protocol_version
,
1542 RPCAP_MSG_OPEN_REPLY
, 0, sizeof(struct rpcap_openreply
));
1544 openreply
= (struct rpcap_openreply
*) &sendbuf
[sendbufidx
];
1546 if (sock_bufferize(NULL
, sizeof(struct rpcap_openreply
), NULL
, &sendbufidx
,
1547 RPCAP_NETBUF_SIZE
, SOCKBUF_CHECKONLY
, errmsgbuf
, PCAP_ERRBUF_SIZE
) == -1)
1550 memset(openreply
, 0, sizeof(struct rpcap_openreply
));
1551 openreply
->linktype
= htonl(pcap_datalink(fp
));
1553 // We're done with the pcap_t.
1557 if (sock_send(pars
->sockctrl
, pars
->ssl
, sendbuf
, sendbufidx
, errbuf
, PCAP_ERRBUF_SIZE
) == -1)
1559 rpcapd_log(LOGPRIO_ERROR
, "Send to client failed: %s", errbuf
);
1565 if (rpcap_senderror(pars
->sockctrl
, pars
->ssl
, pars
->protocol_version
,
1566 PCAP_ERR_OPEN
, errmsgbuf
, errbuf
) == -1)
1568 // That failed; log a message and give up.
1569 rpcapd_log(LOGPRIO_ERROR
, "Send to client failed: %s", errbuf
);
1573 // Check if all the data has been read; if not, discard the data in excess
1574 if (rpcapd_discard(pars
->sockctrl
, pars
->ssl
, plen
) == -1)
1582 \param plen: the length of the current message (needed in order to be able
1583 to discard excess data in the message, if present)
1586 daemon_msg_startcap_req(struct daemon_slpars
*pars
, uint32 plen
, char *source
, struct session
**sessionp
, struct rpcap_sampling
*samp_param _U_
, int uses_ssl
)
1588 char errbuf
[PCAP_ERRBUF_SIZE
]; // buffer for network errors
1589 char errmsgbuf
[PCAP_ERRBUF_SIZE
]; // buffer for errors to send to the client
1590 char portdata
[PCAP_BUF_SIZE
]; // temp variable needed to derive the data port
1591 char peerhost
[PCAP_BUF_SIZE
]; // temp variable needed to derive the host name of our peer
1592 struct session
*session
= NULL
; // saves state of session
1594 char sendbuf
[RPCAP_NETBUF_SIZE
]; // temporary buffer in which data to be sent is buffered
1595 int sendbufidx
= 0; // index which keeps the number of bytes currently buffered
1597 // socket-related variables
1598 struct addrinfo hints
; // temp, needed to open a socket connection
1599 struct addrinfo
*addrinfo
; // temp, needed to open a socket connection
1600 struct sockaddr_storage saddr
; // temp, needed to retrieve the network data port chosen on the local machine
1601 socklen_t saddrlen
; // temp, needed to retrieve the network data port chosen on the local machine
1602 int ret
; // return value from functions
1604 // RPCAP-related variables
1605 struct rpcap_startcapreq startcapreq
; // start capture request message
1606 struct rpcap_startcapreply
*startcapreply
; // start capture reply message
1607 int serveropen_dp
; // keeps who is going to open the data connection
1611 status
= rpcapd_recv(pars
->sockctrl
, pars
->ssl
, (char *) &startcapreq
,
1612 sizeof(struct rpcap_startcapreq
), &plen
, errmsgbuf
);
1622 startcapreq
.flags
= ntohs(startcapreq
.flags
);
1624 // Check that the client does not ask for UDP is the server has been asked
1625 // to enforce encryption, as SSL is not supported yet with UDP:
1626 if (uses_ssl
&& (startcapreq
.flags
& RPCAP_STARTCAPREQ_FLAG_DGRAM
))
1628 pcap_snprintf(errbuf
, PCAP_ERRBUF_SIZE
,
1629 "SSL not supported with UDP forward of remote packets");
1633 // Create a session structure
1634 session
= malloc(sizeof(struct session
));
1635 if (session
== NULL
)
1637 pcap_snprintf(errmsgbuf
, PCAP_ERRBUF_SIZE
, "Can't allocate session structure");
1641 session
->sockdata
= INVALID_SOCKET
;
1642 session
->ctrl_ssl
= session
->data_ssl
= NULL
;
1643 // We don't have a thread yet.
1644 session
->have_thread
= 0;
1646 // We *shouldn't* have to initialize the thread indicator
1647 // itself, because the compiler *should* realize that we
1648 // only use this if have_thread isn't 0, but we *do* have
1649 // to do it, because not all compilers *do* realize that.
1651 // There is no "invalid thread handle" value for a UN*X
1652 // pthread_t, so we just zero it out.
1655 session
->thread
= INVALID_HANDLE_VALUE
;
1657 memset(&session
->thread
, 0, sizeof(session
->thread
));
1660 // Open the selected device
1661 if ((session
->fp
= pcap_open_live(source
,
1662 ntohl(startcapreq
.snaplen
),
1663 (startcapreq
.flags
& RPCAP_STARTCAPREQ_FLAG_PROMISC
) ? 1 : 0 /* local device, other flags not needed */,
1664 ntohl(startcapreq
.read_timeout
),
1665 errmsgbuf
)) == NULL
)
1669 // Apply sampling parameters
1670 fp
->rmt_samp
.method
= samp_param
->method
;
1671 fp
->rmt_samp
.value
= samp_param
->value
;
1675 We're in active mode if:
1676 - we're using TCP, and the user wants us to be in active mode
1679 serveropen_dp
= (startcapreq
.flags
& RPCAP_STARTCAPREQ_FLAG_SERVEROPEN
) || (startcapreq
.flags
& RPCAP_STARTCAPREQ_FLAG_DGRAM
) || pars
->isactive
;
1682 Gets the sockaddr structure referred to the other peer in the ctrl connection
1684 We need that because:
1685 - if we're in passive mode, we need to know the address family we want to use
1686 (the same used for the ctrl socket)
1687 - if we're in active mode, we need to know the network address of the other host
1688 we want to connect to
1690 saddrlen
= sizeof(struct sockaddr_storage
);
1691 if (getpeername(pars
->sockctrl
, (struct sockaddr
*) &saddr
, &saddrlen
) == -1)
1693 sock_geterror("getpeername(): ", errmsgbuf
, PCAP_ERRBUF_SIZE
);
1697 memset(&hints
, 0, sizeof(struct addrinfo
));
1698 hints
.ai_socktype
= (startcapreq
.flags
& RPCAP_STARTCAPREQ_FLAG_DGRAM
) ? SOCK_DGRAM
: SOCK_STREAM
;
1699 hints
.ai_family
= saddr
.ss_family
;
1701 // Now we have to create a new socket to send packets
1702 if (serveropen_dp
) // Data connection is opened by the server toward the client
1704 pcap_snprintf(portdata
, sizeof portdata
, "%d", ntohs(startcapreq
.portdata
));
1706 // Get the name of the other peer (needed to connect to that specific network address)
1707 if (getnameinfo((struct sockaddr
*) &saddr
, saddrlen
, peerhost
,
1708 sizeof(peerhost
), NULL
, 0, NI_NUMERICHOST
))
1710 sock_geterror("getnameinfo(): ", errmsgbuf
, PCAP_ERRBUF_SIZE
);
1714 if (sock_initaddress(peerhost
, portdata
, &hints
, &addrinfo
, errmsgbuf
, PCAP_ERRBUF_SIZE
) == -1)
1717 if ((session
->sockdata
= sock_open(addrinfo
, SOCKOPEN_CLIENT
, 0, errmsgbuf
, PCAP_ERRBUF_SIZE
)) == INVALID_SOCKET
)
1720 else // Data connection is opened by the client toward the server
1722 hints
.ai_flags
= AI_PASSIVE
;
1724 // Let's the server socket pick up a free network port for us
1725 if (sock_initaddress(NULL
, "0", &hints
, &addrinfo
, errmsgbuf
, PCAP_ERRBUF_SIZE
) == -1)
1728 if ((session
->sockdata
= sock_open(addrinfo
, SOCKOPEN_SERVER
, 1 /* max 1 connection in queue */, errmsgbuf
, PCAP_ERRBUF_SIZE
)) == INVALID_SOCKET
)
1731 // get the complete sockaddr structure used in the data connection
1732 saddrlen
= sizeof(struct sockaddr_storage
);
1733 if (getsockname(session
->sockdata
, (struct sockaddr
*) &saddr
, &saddrlen
) == -1)
1735 sock_geterror("getsockname(): ", errmsgbuf
, PCAP_ERRBUF_SIZE
);
1739 // Get the local port the system picked up
1740 if (getnameinfo((struct sockaddr
*) &saddr
, saddrlen
, NULL
,
1741 0, portdata
, sizeof(portdata
), NI_NUMERICSERV
))
1743 sock_geterror("getnameinfo(): ", errmsgbuf
, PCAP_ERRBUF_SIZE
);
1748 // addrinfo is no longer used
1749 freeaddrinfo(addrinfo
);
1752 // Needed to send an error on the ctrl connection
1753 session
->sockctrl
= pars
->sockctrl
;
1754 session
->ctrl_ssl
= pars
->ssl
;
1755 session
->protocol_version
= pars
->protocol_version
;
1757 // Now I can set the filter
1758 ret
= daemon_unpackapplyfilter(pars
->sockctrl
, pars
->ssl
, session
, &plen
, errmsgbuf
);
1761 // Fatal error. A message has been logged; just give up.
1766 // Non-fatal error. Send an error message to the client.
1770 // Now, I can send a RPCAP start capture reply message
1771 if (sock_bufferize(NULL
, sizeof(struct rpcap_header
), NULL
, &sendbufidx
,
1772 RPCAP_NETBUF_SIZE
, SOCKBUF_CHECKONLY
, errmsgbuf
, PCAP_ERRBUF_SIZE
) == -1)
1775 rpcap_createhdr((struct rpcap_header
*) sendbuf
, pars
->protocol_version
,
1776 RPCAP_MSG_STARTCAP_REPLY
, 0, sizeof(struct rpcap_startcapreply
));
1778 startcapreply
= (struct rpcap_startcapreply
*) &sendbuf
[sendbufidx
];
1780 if (sock_bufferize(NULL
, sizeof(struct rpcap_startcapreply
), NULL
,
1781 &sendbufidx
, RPCAP_NETBUF_SIZE
, SOCKBUF_CHECKONLY
, errmsgbuf
, PCAP_ERRBUF_SIZE
) == -1)
1784 memset(startcapreply
, 0, sizeof(struct rpcap_startcapreply
));
1785 startcapreply
->bufsize
= htonl(pcap_bufsize(session
->fp
));
1789 unsigned short port
= (unsigned short)strtoul(portdata
,NULL
,10);
1790 startcapreply
->portdata
= htons(port
);
1793 if (sock_send(pars
->sockctrl
, pars
->ssl
, sendbuf
, sendbufidx
, errbuf
, PCAP_ERRBUF_SIZE
) == -1)
1795 // That failed; log a message and give up.
1796 rpcapd_log(LOGPRIO_ERROR
, "Send to client failed: %s", errbuf
);
1802 SOCKET socktemp
; // We need another socket, since we're going to accept() a connection
1804 // Connection creation
1805 saddrlen
= sizeof(struct sockaddr_storage
);
1807 socktemp
= accept(session
->sockdata
, (struct sockaddr
*) &saddr
, &saddrlen
);
1809 if (socktemp
== INVALID_SOCKET
)
1811 sock_geterror("accept(): ", errbuf
, PCAP_ERRBUF_SIZE
);
1812 rpcapd_log(LOGPRIO_ERROR
, "Accept of data connection failed: %s",
1817 // Now that I accepted the connection, the server socket is no longer needed
1818 sock_close(session
->sockdata
, NULL
, 0);
1819 session
->sockdata
= socktemp
;
1826 /* In both active or passive cases, wait for the client to initiate the
1827 * TLS handshake. Yes during that time the control socket will not be
1828 * served, but the same was true from the above call to accept(). */
1829 ssl
= ssl_promotion(1, session
->sockdata
, errbuf
, PCAP_ERRBUF_SIZE
);
1832 rpcapd_log(LOGPRIO_ERROR
, "TLS handshake failed: %s", errbuf
);
1837 session
->data_ssl
= ssl
;
1839 // Now we have to create a new thread to receive packets
1841 session
->thread
= (HANDLE
)_beginthreadex(NULL
, 0, daemon_thrdatamain
,
1842 (void *) session
, 0, NULL
);
1843 if (session
->thread
== 0)
1845 pcap_snprintf(errbuf
, PCAP_ERRBUF_SIZE
, "Error creating the data thread");
1849 ret
= pthread_create(&session
->thread
, NULL
, daemon_thrdatamain
,
1853 pcap_fmt_errmsg_for_errno(errbuf
, PCAP_ERRBUF_SIZE
,
1854 ret
, "Error creating the data thread");
1858 session
->have_thread
= 1;
1860 // Check if all the data has been read; if not, discard the data in excess
1861 if (rpcapd_discard(pars
->sockctrl
, pars
->ssl
, plen
) == -1)
1864 *sessionp
= session
;
1869 // Not a fatal error, so send the client an error message and
1870 // keep serving client requests.
1875 freeaddrinfo(addrinfo
);
1879 session_close(session
);
1883 if (rpcap_senderror(pars
->sockctrl
, pars
->ssl
, pars
->protocol_version
,
1884 PCAP_ERR_STARTCAPTURE
, errmsgbuf
, errbuf
) == -1)
1886 // That failed; log a message and give up.
1887 rpcapd_log(LOGPRIO_ERROR
, "Send to client failed: %s", errbuf
);
1891 // Check if all the data has been read; if not, discard the data in excess
1892 if (rpcapd_discard(pars
->sockctrl
, pars
->ssl
, plen
) == -1)
1902 // Fatal network error, so don't try to communicate with
1903 // the client, just give up.
1909 session_close(session
);
1917 daemon_msg_endcap_req(struct daemon_slpars
*pars
, struct session
*session
)
1919 char errbuf
[PCAP_ERRBUF_SIZE
]; // buffer for network errors
1920 struct rpcap_header header
;
1922 session_close(session
);
1924 rpcap_createhdr(&header
, pars
->protocol_version
,
1925 RPCAP_MSG_ENDCAP_REPLY
, 0, 0);
1927 if (sock_send(pars
->sockctrl
, pars
->ssl
, (char *) &header
, sizeof(struct rpcap_header
), errbuf
, PCAP_ERRBUF_SIZE
) == -1)
1929 // That failed; log a message and give up.
1930 rpcapd_log(LOGPRIO_ERROR
, "Send to client failed: %s", errbuf
);
1938 daemon_unpackapplyfilter(SOCKET sockctrl
, SSL
*ctrl_ssl
, struct session
*session
, uint32
*plenp
, char *errmsgbuf
)
1941 struct rpcap_filter filter
;
1942 struct rpcap_filterbpf_insn insn
;
1943 struct bpf_insn
*bf_insn
;
1944 struct bpf_program bf_prog
;
1947 status
= rpcapd_recv(sockctrl
, ctrl_ssl
, (char *) &filter
,
1948 sizeof(struct rpcap_filter
), plenp
, errmsgbuf
);
1958 bf_prog
.bf_len
= ntohl(filter
.nitems
);
1960 if (ntohs(filter
.filtertype
) != RPCAP_UPDATEFILTER_BPF
)
1962 pcap_snprintf(errmsgbuf
, PCAP_ERRBUF_SIZE
, "Only BPF/NPF filters are currently supported");
1966 bf_insn
= (struct bpf_insn
*) malloc (sizeof(struct bpf_insn
) * bf_prog
.bf_len
);
1967 if (bf_insn
== NULL
)
1969 pcap_fmt_errmsg_for_errno(errmsgbuf
, PCAP_ERRBUF_SIZE
,
1970 errno
, "malloc() failed");
1974 bf_prog
.bf_insns
= bf_insn
;
1976 for (i
= 0; i
< bf_prog
.bf_len
; i
++)
1978 status
= rpcapd_recv(sockctrl
, ctrl_ssl
, (char *) &insn
,
1979 sizeof(struct rpcap_filterbpf_insn
), plenp
, errmsgbuf
);
1989 bf_insn
->code
= ntohs(insn
.code
);
1990 bf_insn
->jf
= insn
.jf
;
1991 bf_insn
->jt
= insn
.jt
;
1992 bf_insn
->k
= ntohl(insn
.k
);
1998 // XXX - pcap_setfilter() should do the validation for us.
2000 if (bpf_validate(bf_prog
.bf_insns
, bf_prog
.bf_len
) == 0)
2002 pcap_snprintf(errmsgbuf
, PCAP_ERRBUF_SIZE
, "The filter contains bogus instructions");
2006 if (pcap_setfilter(session
->fp
, &bf_prog
))
2008 pcap_snprintf(errmsgbuf
, PCAP_ERRBUF_SIZE
, "RPCAP error: %s", pcap_geterr(session
->fp
));
2016 daemon_msg_updatefilter_req(struct daemon_slpars
*pars
, struct session
*session
, uint32 plen
)
2018 char errbuf
[PCAP_ERRBUF_SIZE
];
2019 char errmsgbuf
[PCAP_ERRBUF_SIZE
]; // buffer for errors to send to the client
2020 int ret
; // status of daemon_unpackapplyfilter()
2021 struct rpcap_header header
; // keeps the answer to the updatefilter command
2023 ret
= daemon_unpackapplyfilter(pars
->sockctrl
, pars
->ssl
, session
, &plen
, errmsgbuf
);
2026 // Fatal error. A message has been logged; just give up.
2031 // Non-fatal error. Send an error reply to the client.
2035 // Check if all the data has been read; if not, discard the data in excess
2036 if (rpcapd_discard(pars
->sockctrl
, pars
->ssl
, plen
) == -1)
2042 // A response is needed, otherwise the other host does not know that everything went well
2043 rpcap_createhdr(&header
, pars
->protocol_version
,
2044 RPCAP_MSG_UPDATEFILTER_REPLY
, 0, 0);
2046 if (sock_send(pars
->sockctrl
, pars
->ssl
, (char *) &header
, sizeof (struct rpcap_header
), pcap_geterr(session
->fp
), PCAP_ERRBUF_SIZE
))
2048 // That failed; log a messsage and give up.
2049 rpcapd_log(LOGPRIO_ERROR
, "Send to client failed: %s", errbuf
);
2056 if (rpcapd_discard(pars
->sockctrl
, pars
->ssl
, plen
) == -1)
2060 rpcap_senderror(pars
->sockctrl
, pars
->ssl
, pars
->protocol_version
,
2061 PCAP_ERR_UPDATEFILTER
, errmsgbuf
, NULL
);
2067 \brief Received the sampling parameters from remote host and it stores in the pcap_t structure.
2070 daemon_msg_setsampling_req(struct daemon_slpars
*pars
, uint32 plen
, struct rpcap_sampling
*samp_param
)
2072 char errbuf
[PCAP_ERRBUF_SIZE
]; // buffer for network errors
2073 char errmsgbuf
[PCAP_ERRBUF_SIZE
];
2074 struct rpcap_header header
;
2075 struct rpcap_sampling rpcap_samp
;
2078 status
= rpcapd_recv(pars
->sockctrl
, pars
->ssl
, (char *) &rpcap_samp
, sizeof(struct rpcap_sampling
), &plen
, errmsgbuf
);
2088 // Save these settings in the pcap_t
2089 samp_param
->method
= rpcap_samp
.method
;
2090 samp_param
->value
= ntohl(rpcap_samp
.value
);
2092 // A response is needed, otherwise the other host does not know that everything went well
2093 rpcap_createhdr(&header
, pars
->protocol_version
,
2094 RPCAP_MSG_SETSAMPLING_REPLY
, 0, 0);
2096 if (sock_send(pars
->sockctrl
, pars
->ssl
, (char *) &header
, sizeof (struct rpcap_header
), errbuf
, PCAP_ERRBUF_SIZE
) == -1)
2098 // That failed; log a messsage and give up.
2099 rpcapd_log(LOGPRIO_ERROR
, "Send to client failed: %s", errbuf
);
2103 if (rpcapd_discard(pars
->sockctrl
, pars
->ssl
, plen
) == -1)
2111 if (rpcap_senderror(pars
->sockctrl
, pars
->ssl
, pars
->protocol_version
,
2112 PCAP_ERR_AUTH
, errmsgbuf
, errbuf
) == -1)
2114 // That failed; log a message and give up.
2115 rpcapd_log(LOGPRIO_ERROR
, "Send to client failed: %s", errbuf
);
2119 // Check if all the data has been read; if not, discard the data in excess
2120 if (rpcapd_discard(pars
->sockctrl
, pars
->ssl
, plen
) == -1)
2129 daemon_msg_stats_req(struct daemon_slpars
*pars
, struct session
*session
, uint32 plen
, struct pcap_stat
*stats
, unsigned int svrcapt
)
2131 char errbuf
[PCAP_ERRBUF_SIZE
]; // buffer for network errors
2132 char errmsgbuf
[PCAP_ERRBUF_SIZE
]; // buffer for errors to send to the client
2133 char sendbuf
[RPCAP_NETBUF_SIZE
]; // temporary buffer in which data to be sent is buffered
2134 int sendbufidx
= 0; // index which keeps the number of bytes currently buffered
2135 struct rpcap_stats
*netstats
; // statistics sent on the network
2137 // Checks that the header does not contain other data; if so, discard it
2138 if (rpcapd_discard(pars
->sockctrl
, pars
->ssl
, plen
) == -1)
2144 if (sock_bufferize(NULL
, sizeof(struct rpcap_header
), NULL
,
2145 &sendbufidx
, RPCAP_NETBUF_SIZE
, SOCKBUF_CHECKONLY
, errmsgbuf
, PCAP_ERRBUF_SIZE
) == -1)
2148 rpcap_createhdr((struct rpcap_header
*) sendbuf
, pars
->protocol_version
,
2149 RPCAP_MSG_STATS_REPLY
, 0, (uint16
) sizeof(struct rpcap_stats
));
2151 netstats
= (struct rpcap_stats
*) &sendbuf
[sendbufidx
];
2153 if (sock_bufferize(NULL
, sizeof(struct rpcap_stats
), NULL
,
2154 &sendbufidx
, RPCAP_NETBUF_SIZE
, SOCKBUF_CHECKONLY
, errmsgbuf
, PCAP_ERRBUF_SIZE
) == -1)
2157 if (session
&& session
->fp
)
2159 if (pcap_stats(session
->fp
, stats
) == -1)
2161 pcap_snprintf(errmsgbuf
, PCAP_ERRBUF_SIZE
, "%s", pcap_geterr(session
->fp
));
2165 netstats
->ifdrop
= htonl(stats
->ps_ifdrop
);
2166 netstats
->ifrecv
= htonl(stats
->ps_recv
);
2167 netstats
->krnldrop
= htonl(stats
->ps_drop
);
2168 netstats
->svrcapt
= htonl(session
->TotCapt
);
2172 // We have to keep compatibility with old applications,
2173 // which ask for statistics also when the capture has
2175 netstats
->ifdrop
= htonl(stats
->ps_ifdrop
);
2176 netstats
->ifrecv
= htonl(stats
->ps_recv
);
2177 netstats
->krnldrop
= htonl(stats
->ps_drop
);
2178 netstats
->svrcapt
= htonl(svrcapt
);
2182 if (sock_send(pars
->sockctrl
, pars
->ssl
, sendbuf
, sendbufidx
, errbuf
, PCAP_ERRBUF_SIZE
) == -1)
2184 rpcapd_log(LOGPRIO_ERROR
, "Send to client failed: %s", errbuf
);
2191 rpcap_senderror(pars
->sockctrl
, pars
->ssl
, pars
->protocol_version
,
2192 PCAP_ERR_GETSTATS
, errmsgbuf
, NULL
);
2197 static unsigned __stdcall
2201 daemon_thrdatamain(void *ptr
)
2203 char errbuf
[PCAP_ERRBUF_SIZE
+ 1]; // error buffer
2204 struct session
*session
; // pointer to the struct session for this session
2205 int retval
; // general variable used to keep the return value of other functions
2206 struct rpcap_pkthdr
*net_pkt_header
;// header of the packet
2207 struct pcap_pkthdr
*pkt_header
; // pointer to the buffer that contains the header of the current packet
2208 u_char
*pkt_data
; // pointer to the buffer that contains the current packet
2209 size_t sendbufsize
; // size for the send buffer
2210 char *sendbuf
; // temporary buffer in which data to be sent is buffered
2211 int sendbufidx
; // index which keeps the number of bytes currently buffered
2214 sigset_t sigusr1
; // signal set with just SIGUSR1
2217 session
= (struct session
*) ptr
;
2219 session
->TotCapt
= 0; // counter which is incremented each time a packet is received
2221 // Initialize errbuf
2222 memset(errbuf
, 0, sizeof(errbuf
));
2225 // We need a buffer large enough to hold a buffer large enough
2226 // for a maximum-size packet for this pcap_t.
2228 if (pcap_snapshot(session
->fp
) < 0)
2231 // The snapshot length is negative.
2232 // This "should not happen".
2234 rpcapd_log(LOGPRIO_ERROR
,
2235 "Unable to allocate the buffer for this child thread: snapshot length of %d is negative",
2236 pcap_snapshot(session
->fp
));
2237 sendbuf
= NULL
; // we can't allocate a buffer, so nothing to free
2241 // size_t is unsigned, and the result of pcap_snapshot() is signed;
2242 // on no platform that we support is int larger than size_t.
2243 // This means that, unless the extra information we prepend to
2244 // a maximum-sized packet is impossibly large, the sum of the
2245 // snapshot length and the size of that extra information will
2248 // So we don't need to make sure that sendbufsize will overflow.
2250 // However, we *do* need to make sure its value fits in an int,
2251 // because sock_send() can't send more than INT_MAX bytes (it could
2252 // do so on 64-bit UN*Xes, but can't do so on Windows, not even
2253 // 64-bit Windows, as the send() buffer size argument is an int
2256 sendbufsize
= sizeof(struct rpcap_header
) + sizeof(struct rpcap_pkthdr
) + pcap_snapshot(session
->fp
);
2257 if (sendbufsize
> INT_MAX
)
2259 rpcapd_log(LOGPRIO_ERROR
,
2260 "Buffer size for this child thread would be larger than %d",
2262 sendbuf
= NULL
; // we haven't allocated a buffer, so nothing to free
2265 sendbuf
= (char *) malloc (sendbufsize
);
2266 if (sendbuf
== NULL
)
2268 rpcapd_log(LOGPRIO_ERROR
,
2269 "Unable to allocate the buffer for this child thread");
2275 // Set the signal set to include just SIGUSR1, and block that
2276 // signal; we only want it unblocked when we're reading
2277 // packets - we dn't want any other system calls, such as
2278 // ones being used to send to the client or to log messages,
2279 // to be interrupted.
2281 sigemptyset(&sigusr1
);
2282 sigaddset(&sigusr1
, SIGUSR1
);
2283 sigprocmask(SIG_BLOCK
, &sigusr1
, NULL
);
2286 // Retrieve the packets
2291 // Unblock SIGUSR1 while we might be waiting for packets.
2293 sigprocmask(SIG_UNBLOCK
, &sigusr1
, NULL
);
2295 retval
= pcap_next_ex(session
->fp
, &pkt_header
, (const u_char
**) &pkt_data
); // cast to avoid a compiler warning
2298 // Now block it again.
2300 sigprocmask(SIG_BLOCK
, &sigusr1
, NULL
);
2304 if (retval
== 0) // Read timeout elapsed
2309 // Bufferize the general header
2310 if (sock_bufferize(NULL
, sizeof(struct rpcap_header
), NULL
,
2311 &sendbufidx
, (int)sendbufsize
, SOCKBUF_CHECKONLY
, errbuf
,
2312 PCAP_ERRBUF_SIZE
) == -1)
2314 rpcapd_log(LOGPRIO_ERROR
,
2315 "sock_bufferize() error sending packet message: %s",
2320 rpcap_createhdr((struct rpcap_header
*) sendbuf
,
2321 session
->protocol_version
, RPCAP_MSG_PACKET
, 0,
2322 (uint16
) (sizeof(struct rpcap_pkthdr
) + pkt_header
->caplen
));
2324 net_pkt_header
= (struct rpcap_pkthdr
*) &sendbuf
[sendbufidx
];
2326 // Bufferize the pkt header
2327 if (sock_bufferize(NULL
, sizeof(struct rpcap_pkthdr
), NULL
,
2328 &sendbufidx
, (int)sendbufsize
, SOCKBUF_CHECKONLY
, errbuf
,
2329 PCAP_ERRBUF_SIZE
) == -1)
2331 rpcapd_log(LOGPRIO_ERROR
,
2332 "sock_bufferize() error sending packet message: %s",
2337 net_pkt_header
->caplen
= htonl(pkt_header
->caplen
);
2338 net_pkt_header
->len
= htonl(pkt_header
->len
);
2339 net_pkt_header
->npkt
= htonl(++(session
->TotCapt
));
2341 // This protocol needs to be updated with a new version
2342 // before 2038-01-19 03:14:07 UTC.
2344 net_pkt_header
->timestamp_sec
= htonl((uint32
)pkt_header
->ts
.tv_sec
);
2345 net_pkt_header
->timestamp_usec
= htonl((uint32
)pkt_header
->ts
.tv_usec
);
2347 // Bufferize the pkt data
2348 if (sock_bufferize((char *) pkt_data
, pkt_header
->caplen
,
2349 sendbuf
, &sendbufidx
, (int)sendbufsize
, SOCKBUF_BUFFERIZE
,
2350 errbuf
, PCAP_ERRBUF_SIZE
) == -1)
2352 rpcapd_log(LOGPRIO_ERROR
,
2353 "sock_bufferize() error sending packet message: %s",
2359 // If the client dropped the connection, don't report an
2360 // error, just quit.
2361 status
= sock_send(session
->sockdata
, session
->data_ssl
, sendbuf
, sendbufidx
, errbuf
, PCAP_ERRBUF_SIZE
);
2367 // Error other than "client closed the
2368 // connection out from under us"; report
2371 rpcapd_log(LOGPRIO_ERROR
,
2372 "Send of packet to client failed: %s",
2377 // Give up in either case.
2383 if (retval
< 0 && retval
!= PCAP_ERROR_BREAK
)
2386 // Failed with an error other than "we were told to break
2387 // out of the loop".
2389 // The latter just means that the client told us to stop
2390 // capturing, so there's no error to report.
2392 pcap_snprintf(errbuf
, PCAP_ERRBUF_SIZE
, "Error reading the packets: %s", pcap_geterr(session
->fp
));
2393 rpcap_senderror(session
->sockctrl
, session
->ctrl_ssl
, session
->protocol_version
,
2394 PCAP_ERR_READEX
, errbuf
, NULL
);
2399 // The main thread will clean up the session structure.
2408 // Do-nothing handler for SIGUSR1; the sole purpose of SIGUSR1 is to
2409 // interrupt the data thread if it's blocked in a system call waiting
2410 // for packets to arrive.
2412 static void noop_handler(int sign _U_
)
2418 \brief It serializes a network address.
2420 It accepts a 'sockaddr_storage' structure as input, and it converts it appropriately into a format
2421 that can be used to be sent on the network. Basically, it applies all the hton()
2422 conversion required to the input variable.
2424 \param sockaddrin a 'sockaddr_storage' pointer to the variable that has to be
2425 serialized. This variable can be both a 'sockaddr_in' and 'sockaddr_in6'.
2427 \param sockaddrout an 'rpcap_sockaddr' pointer to the variable that will contain
2428 the serialized data. This variable has to be allocated by the user.
2430 \warning This function supports only AF_INET and AF_INET6 address families.
2433 daemon_seraddr(struct sockaddr_storage
*sockaddrin
, struct rpcap_sockaddr
*sockaddrout
)
2435 memset(sockaddrout
, 0, sizeof(struct sockaddr_storage
));
2437 // There can be the case in which the sockaddrin is not available
2438 if (sockaddrin
== NULL
) return;
2440 // Warning: we support only AF_INET and AF_INET6
2441 switch (sockaddrin
->ss_family
)
2445 struct sockaddr_in
*sockaddrin_ipv4
;
2446 struct rpcap_sockaddr_in
*sockaddrout_ipv4
;
2448 sockaddrin_ipv4
= (struct sockaddr_in
*) sockaddrin
;
2449 sockaddrout_ipv4
= (struct rpcap_sockaddr_in
*) sockaddrout
;
2450 sockaddrout_ipv4
->family
= htons(RPCAP_AF_INET
);
2451 sockaddrout_ipv4
->port
= htons(sockaddrin_ipv4
->sin_port
);
2452 memcpy(&sockaddrout_ipv4
->addr
, &sockaddrin_ipv4
->sin_addr
, sizeof(sockaddrout_ipv4
->addr
));
2453 memset(sockaddrout_ipv4
->zero
, 0, sizeof(sockaddrout_ipv4
->zero
));
2460 struct sockaddr_in6
*sockaddrin_ipv6
;
2461 struct rpcap_sockaddr_in6
*sockaddrout_ipv6
;
2463 sockaddrin_ipv6
= (struct sockaddr_in6
*) sockaddrin
;
2464 sockaddrout_ipv6
= (struct rpcap_sockaddr_in6
*) sockaddrout
;
2465 sockaddrout_ipv6
->family
= htons(RPCAP_AF_INET6
);
2466 sockaddrout_ipv6
->port
= htons(sockaddrin_ipv6
->sin6_port
);
2467 sockaddrout_ipv6
->flowinfo
= htonl(sockaddrin_ipv6
->sin6_flowinfo
);
2468 memcpy(&sockaddrout_ipv6
->addr
, &sockaddrin_ipv6
->sin6_addr
, sizeof(sockaddrout_ipv6
->addr
));
2469 sockaddrout_ipv6
->scope_id
= htonl(sockaddrin_ipv6
->sin6_scope_id
);
2478 \brief Suspends a thread for secs seconds.
2480 void sleep_secs(int secs
)
2485 unsigned secs_remaining
;
2489 secs_remaining
= secs
;
2490 while (secs_remaining
!= 0)
2491 secs_remaining
= sleep(secs_remaining
);
2496 * Read the header of a message.
2499 rpcapd_recv_msg_header(SOCKET sock
, SSL
*ssl
, struct rpcap_header
*headerp
)
2502 char errbuf
[PCAP_ERRBUF_SIZE
]; // buffer for network errors
2504 nread
= sock_recv(sock
, ssl
, (char *) headerp
, sizeof(struct rpcap_header
),
2505 SOCK_RECEIVEALL_YES
|SOCK_EOF_ISNT_ERROR
, errbuf
, PCAP_ERRBUF_SIZE
);
2509 rpcapd_log(LOGPRIO_ERROR
, "Read from client failed: %s", errbuf
);
2514 // Immediate EOF; that's treated like a close message.
2517 headerp
->plen
= ntohl(headerp
->plen
);
2522 * Read data from a message.
2523 * If we're trying to read more data that remains, puts an error
2524 * message into errmsgbuf and returns -2. Otherwise, tries to read
2525 * the data and, if that succeeds, subtracts the amount read from
2526 * the number of bytes of data that remains.
2527 * Returns 0 on success, logs a message and returns -1 on a network
2531 rpcapd_recv(SOCKET sock
, SSL
*ssl
, char *buffer
, size_t toread
, uint32
*plen
, char *errmsgbuf
)
2534 char errbuf
[PCAP_ERRBUF_SIZE
]; // buffer for network errors
2538 // Tell the client and continue.
2539 pcap_snprintf(errmsgbuf
, PCAP_ERRBUF_SIZE
, "Message payload is too short");
2542 nread
= sock_recv(sock
, ssl
, buffer
, toread
,
2543 SOCK_RECEIVEALL_YES
|SOCK_EOF_IS_ERROR
, errbuf
, PCAP_ERRBUF_SIZE
);
2546 rpcapd_log(LOGPRIO_ERROR
, "Read from client failed: %s", errbuf
);
2554 * Discard data from a connection.
2555 * Mostly used to discard wrong-sized messages.
2556 * Returns 0 on success, logs a message and returns -1 on a network
2560 rpcapd_discard(SOCKET sock
, SSL
*ssl
, uint32 len
)
2562 char errbuf
[PCAP_ERRBUF_SIZE
+ 1]; // keeps the error string, prior to be printed
2566 if (sock_discard(sock
, ssl
, len
, errbuf
, PCAP_ERRBUF_SIZE
) == -1)
2569 rpcapd_log(LOGPRIO_ERROR
, "Read from client failed: %s", errbuf
);
2577 // Shut down any packet-capture thread associated with the session,
2578 // close the SSL handle for the data socket if we have one, close
2579 // the data socket if we have one, and close the underlying packet
2580 // capture handle if we have one.
2582 // We do not, of course, touch the controlling socket that's also
2583 // copied into the session, as the service loop might still use it.
2585 static void session_close(struct session
*session
)
2587 if (session
->have_thread
)
2590 // Tell the data connection thread main capture loop to
2591 // break out of that loop.
2593 // This may be sufficient to wake up a blocked thread,
2594 // but it's not guaranteed to be sufficient.
2596 pcap_breakloop(session
->fp
);
2600 // Set the event on which a read would block, so that,
2601 // if it's currently blocked waiting for packets to
2602 // arrive, it'll wake up, so it can see the "break
2603 // out of the loop" indication. (pcap_breakloop()
2604 // might do this, but older versions don't. Setting
2605 // it twice should, at worst, cause an extra wakeup,
2606 // which shouldn't be a problem.)
2608 // XXX - what about modules other than NPF?
2610 SetEvent(pcap_getevent(session
->fp
));
2613 // Wait for the thread to exit, so we don't close
2614 // sockets out from under it.
2616 // XXX - have a timeout, so we don't wait forever?
2618 WaitForSingleObject(session
->thread
, INFINITE
);
2621 // Release the thread handle, as we're done with
2624 CloseHandle(session
->thread
);
2625 session
->have_thread
= 0;
2626 session
->thread
= INVALID_HANDLE
;
2629 // Send a SIGUSR1 signal to the thread, so that, if
2630 // it's currently blocked waiting for packets to arrive,
2631 // it'll wake up (we've turned off SA_RESTART for
2632 // SIGUSR1, so that the system call in which it's blocked
2633 // should return EINTR rather than restarting).
2635 pthread_kill(session
->thread
, SIGUSR1
);
2638 // Wait for the thread to exit, so we don't close
2639 // sockets out from under it.
2641 // XXX - have a timeout, so we don't wait forever?
2643 pthread_join(session
->thread
, NULL
);
2644 session
->have_thread
= 0;
2645 memset(&session
->thread
, 0, sizeof(session
->thread
));
2650 if (session
->data_ssl
)
2652 SSL_free(session
->data_ssl
); // Must happen *before* the socket is closed
2653 session
->data_ssl
= NULL
;
2657 if (session
->sockdata
!= INVALID_SOCKET
)
2659 sock_close(session
->sockdata
, NULL
, 0);
2660 session
->sockdata
= INVALID_SOCKET
;
2665 pcap_close(session
->fp
);