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.
37 #include <errno.h> // for the errno variable
38 #include <stdlib.h> // for malloc(), free(), ...
39 #include <string.h> // for strlen(), ...
40 #include <limits.h> // for INT_MAX
43 #include <process.h> // for threads
49 #include <sys/types.h> // for select() and such
50 #include <pwd.h> // for password management
54 #include <shadow.h> // for password management
57 #include <pcap.h> // for libpcap/WinPcap calls
60 #include "sockutils.h" // for socket calls
61 #include "portability.h"
62 #include "rpcap-protocol.h"
67 #include <openssl/ssl.h>
72 // Timeout, in seconds, when we're waiting for a client to send us an
73 // authentication request; if they don't send us a request within that
74 // interval, we drop the connection, so we don't stay stuck forever.
76 #define RPCAP_TIMEOUT_INIT 90
79 // Timeout, in seconds, when we're waiting for an authenticated client
80 // to send us a request, if a capture isn't in progress; if they don't
81 // send us a request within that interval, we drop the connection, so
82 // we don't stay stuck forever.
84 #define RPCAP_TIMEOUT_RUNTIME 180
87 // Time, in seconds, that we wait after a failed authentication attempt
88 // before processing the next request; this prevents a client from
89 // rapidly trying different accounts or passwords.
91 #define RPCAP_SUSPEND_WRONGAUTH 1
93 // Parameters for the service loop.
96 PCAP_SOCKET sockctrl
; //!< PCAP_SOCKET ID of the control connection
97 SSL
*ssl
; //!< Optional SSL handler for the controlling sockets
98 int isactive
; //!< Not null if the daemon has to run in active mode
99 int nullAuthAllowed
; //!< '1' if we permit NULL authentication, '0' otherwise
103 // Data for a session managed by a thread.
104 // It includes both a Boolean indicating whether we *have* a thread,
105 // and a platform-dependent (UN*X vs. Windows) identifier for the
106 // thread; on Windows, we could use an invalid handle to indicate
107 // that we don't have a thread, but there *is* no portable "no thread"
108 // value for a pthread_t on UN*X.
111 PCAP_SOCKET sockctrl
;
112 PCAP_SOCKET sockdata
;
113 SSL
*ctrl_ssl
, *data_ssl
; // optional SSL handlers for sockctrl and sockdata.
114 uint8_t protocol_version
;
116 unsigned int TotCapt
;
125 // Locally defined functions
126 static int daemon_msg_err(PCAP_SOCKET sockctrl
, SSL
*, uint32_t plen
);
127 static int daemon_msg_auth_req(struct daemon_slpars
*pars
, uint32_t plen
);
128 static int daemon_AuthUserPwd(char *username
, char *password
, char *errbuf
);
130 static int daemon_msg_findallif_req(uint8_t ver
, struct daemon_slpars
*pars
,
133 static int daemon_msg_open_req(uint8_t ver
, struct daemon_slpars
*pars
,
134 uint32_t plen
, char *source
, size_t sourcelen
);
135 static int daemon_msg_startcap_req(uint8_t ver
, struct daemon_slpars
*pars
,
136 uint32_t plen
, char *source
, char *data_port
, struct session
**sessionp
,
137 struct rpcap_sampling
*samp_param
, int uses_ssl
);
138 static int daemon_msg_endcap_req(uint8_t ver
, struct daemon_slpars
*pars
,
139 struct session
*session
);
141 static int daemon_msg_updatefilter_req(uint8_t ver
, struct daemon_slpars
*pars
,
142 struct session
*session
, uint32_t plen
);
143 static int daemon_unpackapplyfilter(PCAP_SOCKET sockctrl
, SSL
*, struct session
*session
, uint32_t *plenp
, char *errbuf
);
145 static int daemon_msg_stats_req(uint8_t ver
, struct daemon_slpars
*pars
,
146 struct session
*session
, uint32_t plen
, struct pcap_stat
*stats
,
147 unsigned int svrcapt
);
149 static int daemon_msg_setsampling_req(uint8_t ver
, struct daemon_slpars
*pars
,
150 uint32_t plen
, struct rpcap_sampling
*samp_param
);
152 static void daemon_seraddr(struct sockaddr_storage
*sockaddrin
, struct rpcap_sockaddr
*sockaddrout
);
154 static unsigned __stdcall
daemon_thrdatamain(void *ptr
);
156 static void *daemon_thrdatamain(void *ptr
);
157 static void noop_handler(int sign
);
160 static int rpcapd_recv_msg_header(PCAP_SOCKET sock
, SSL
*, struct rpcap_header
*headerp
);
161 static int rpcapd_recv(PCAP_SOCKET sock
, SSL
*, char *buffer
, size_t toread
, uint32_t *plen
, char *errmsgbuf
);
162 static int rpcapd_discard(PCAP_SOCKET sock
, SSL
*, uint32_t len
);
163 static void session_close(struct session
*);
166 // TLS record layer header; used when processing the first message from
167 // the client, in case we aren't doing TLS but they are.
169 struct tls_record_header
{
170 uint8_t type
; // ContentType - will be 22, for Handshake
171 uint8_t version_major
; // TLS protocol major version
172 uint8_t version_injor
; // TLS protocol minor version
173 // This is *not* aligned on a 2-byte boundary; we just
174 // declare it as two bytes. Don't assume any particular
175 // compiler's mechanism for saying "packed"!
176 uint8_t length_hi
; // Upper 8 bits of payload length
177 uint8_t length_lo
; // Low 8 bits of payload length
180 #define TLS_RECORD_HEADER_LEN 5 // Don't use sizeof in case it's padded
182 #define TLS_RECORD_TYPE_ALERT 21
183 #define TLS_RECORD_TYPE_HANDSHAKE 22
186 // TLS alert message.
190 uint8_t alert_description
;
193 #define TLS_ALERT_LEN 2
195 #define TLS_ALERT_LEVEL_FATAL 2
196 #define TLS_ALERT_HANDSHAKE_FAILURE 40
198 static int is_url(const char *source
);
201 * Maximum sizes for fixed-bit-width values.
204 #define UINT16_MAX 65535U
208 #define UINT32_MAX 4294967295U
212 daemon_serviceloop(PCAP_SOCKET sockctrl
, int isactive
, char *passiveClients
,
213 int nullAuthAllowed
, char *data_port
, int uses_ssl
)
216 struct tls_record_header tls_header
;
217 struct tls_alert tls_alert
;
218 struct daemon_slpars pars
; // service loop parameters
219 char errbuf
[PCAP_ERRBUF_SIZE
+ 1]; // keeps the error string, prior to be printed
220 char errmsgbuf
[PCAP_ERRBUF_SIZE
+ 1]; // buffer for errors to send to the client
221 int host_port_check_status
;
224 struct rpcap_header header
; // RPCAP message general header
225 uint32_t plen
; // payload length from header
226 int authenticated
= 0; // 1 if the client has successfully authenticated
227 char source
[PCAP_BUF_SIZE
+1]; // keeps the string that contains the interface to open
228 int got_source
= 0; // 1 if we've gotten the source from an open request
230 struct sigaction action
;
232 struct session
*session
= NULL
; // struct session main variable
233 const char *msg_type_string
; // string for message type
234 int client_told_us_to_close
= 0; // 1 if the client told us to close the capture
236 // needed to save the values of the statistics
237 struct pcap_stat stats
;
238 unsigned int svrcapt
;
240 struct rpcap_sampling samp_param
; // in case sampling has been requested
242 // Structures needed for the select() call
243 fd_set rfds
; // set of socket descriptors we have to check
244 struct timeval tv
; // maximum time the select() can block waiting for data
245 int retval
; // select() return value
247 *errbuf
= 0; // Initialize errbuf
250 // Peek into the socket to determine whether the client sent us
251 // a TLS handshake message or a non-TLS rpcapd message.
253 // The first byte of an rpcapd request is the version number;
254 // the first byte of a TLS handshake message is 22. The
255 // first request to an rpcapd server must be an authentication
256 // request or a close request, and must have a version number
257 // of 0, so it will be possible to distinguish between an
258 // initial plaintext request to a server and an initial TLS
259 // handshake message.
261 nrecv
= sock_recv(sockctrl
, NULL
, (char *)&first_octet
, 1,
262 SOCK_EOF_ISNT_ERROR
|SOCK_MSG_PEEK
, errbuf
, PCAP_ERRBUF_SIZE
);
266 rpcapd_log(LOGPRIO_ERROR
, "Peek from client failed: %s", errbuf
);
271 // Client closed the connection.
277 // We have to upgrade to TLS as soon as possible, so that the
278 // whole protocol goes through the encrypted tunnel, including
279 // early error messages.
281 // Even in active mode, the other end has to initiate the TLS
282 // handshake as we still are the server as far as TLS is concerned,
283 // so we don't check isactive.
288 // We're expecting a TLS handshake message. If this
289 // isn't one, assume it's a non-TLS rpcapd message.
291 // The first octet of a TLS handshake is
292 // TLS_RECORD_TYPE_HANDSHAKE.
294 if (first_octet
!= TLS_RECORD_TYPE_HANDSHAKE
)
297 // We assume this is a non-TLS rpcapd message.
299 // Read the message header from the client.
301 nrecv
= rpcapd_recv_msg_header(sockctrl
, NULL
, &header
);
309 // Client closed the connection.
314 // Discard the rest of the message.
315 if (rpcapd_discard(sockctrl
, NULL
, plen
) == -1)
322 // Send an authentication error, indicating
323 // that we require TLS.
325 if (rpcap_senderror(sockctrl
, NULL
, header
.ver
,
326 PCAP_ERR_TLS_REQUIRED
,
327 "TLS is required by this server", errbuf
) == -1)
329 // That failed; log a message and give up.
330 rpcapd_log(LOGPRIO_ERROR
, "Send to client failed: %s", errbuf
);
334 // Shut the session down.
337 ssl
= ssl_promotion(1, sockctrl
, errbuf
, PCAP_ERRBUF_SIZE
);
340 rpcapd_log(LOGPRIO_ERROR
, "TLS handshake on control connection failed: %s",
349 // We're expecting a non-TLS rpcapd message. If this
350 // looks, instead, like a TLS handshake message, send
351 // a TLS handshake_failed alert.
353 // The first octet of a TLS handshake is
354 // TLS_RECORD_TYPE_HANDSHAKE.
356 if (first_octet
== TLS_RECORD_TYPE_HANDSHAKE
)
360 // Read the record header.
362 nrecv
= sock_recv(sockctrl
, ssl
, (char *) &tls_header
,
363 sizeof tls_header
, SOCK_RECEIVEALL_YES
|SOCK_EOF_ISNT_ERROR
,
364 errbuf
, PCAP_ERRBUF_SIZE
);
368 rpcapd_log(LOGPRIO_ERROR
, "Read from client failed: %s", errbuf
);
376 plen
= (tls_header
.length_hi
<< 8U) | tls_header
.length_lo
;
378 // Discard the rest of the message.
379 if (rpcapd_discard(sockctrl
, NULL
, plen
) == -1)
386 // Send a TLS handshake failure alert.
387 // Use the same version the client sent us.
389 tls_header
.type
= TLS_RECORD_TYPE_ALERT
;
390 tls_header
.length_hi
= 0;
391 tls_header
.length_lo
= TLS_ALERT_LEN
;
393 if (sock_send(sockctrl
, NULL
, (char *) &tls_header
,
394 TLS_RECORD_HEADER_LEN
, errbuf
, PCAP_ERRBUF_SIZE
) == -1)
396 // That failed; log a message and give up.
397 rpcapd_log(LOGPRIO_ERROR
, "Send to client failed: %s", errbuf
);
401 tls_alert
.alert_level
= TLS_ALERT_LEVEL_FATAL
;
402 tls_alert
.alert_description
= TLS_ALERT_HANDSHAKE_FAILURE
;
403 if (sock_send(sockctrl
, NULL
, (char *) &tls_alert
,
404 TLS_ALERT_LEN
, errbuf
, PCAP_ERRBUF_SIZE
) == -1)
406 // That failed; log a message and give up.
407 rpcapd_log(LOGPRIO_ERROR
, "Send to client failed: %s", errbuf
);
417 // Set parameters structure
418 pars
.sockctrl
= sockctrl
;
420 pars
.isactive
= isactive
; // active mode
421 pars
.nullAuthAllowed
= nullAuthAllowed
;
424 // We have a connection.
426 // If it's a passive mode connection, check whether the connecting
427 // host is among the ones allowed.
429 // In either case, we were handed a copy of the host list; free it
430 // as soon as we're done with it.
435 free(passiveClients
);
436 passiveClients
= NULL
;
440 struct sockaddr_storage from
;
444 // Get the address of the other end of the connection.
446 fromlen
= sizeof(struct sockaddr_storage
);
447 if (getpeername(pars
.sockctrl
, (struct sockaddr
*)&from
,
450 sock_geterrmsg(errmsgbuf
, PCAP_ERRBUF_SIZE
,
451 "getpeername() failed");
452 if (rpcap_senderror(pars
.sockctrl
, pars
.ssl
, 0, PCAP_ERR_NETW
, errmsgbuf
, errbuf
) == -1)
453 rpcapd_log(LOGPRIO_ERROR
, "Send to client failed: %s", errbuf
);
458 // Are they in the list of host/port combinations we allow?
460 host_port_check_status
= sock_check_hostlist(passiveClients
, RPCAP_HOSTLIST_SEP
, &from
, errmsgbuf
, PCAP_ERRBUF_SIZE
);
461 free(passiveClients
);
462 passiveClients
= NULL
;
463 if (host_port_check_status
< 0)
465 if (host_port_check_status
== -2) {
467 // We got an error; log it.
469 rpcapd_log(LOGPRIO_ERROR
, "%s", errmsgbuf
);
473 // Sorry, we can't let you in.
475 if (rpcap_senderror(pars
.sockctrl
, pars
.ssl
, 0, PCAP_ERR_HOSTNOAUTH
, errmsgbuf
, errbuf
) == -1)
476 rpcapd_log(LOGPRIO_ERROR
, "Send to client failed: %s", errbuf
);
483 // Catch SIGUSR1, but do nothing. We use it to interrupt the
484 // capture thread to break it out of a loop in which it's
485 // blocked waiting for packets to arrive.
487 // We don't want interrupted system calls to restart, so that
488 // the read routine for the pcap_t gets EINTR rather than
489 // restarting if it's blocked in a system call.
491 memset(&action
, 0, sizeof (action
));
492 action
.sa_handler
= noop_handler
;
494 sigemptyset(&action
.sa_mask
);
495 sigaction(SIGUSR1
, &action
, NULL
);
499 // The client must first authenticate; loop until they send us a
500 // message with a version we support and credentials we accept,
501 // they send us a close message indicating that they're giving up,
502 // or we get a network error or other fatal error.
504 while (!authenticated
)
507 // If we're not in active mode, we use select(), with a
508 // timeout, to wait for an authentication request; if
509 // the timeout expires, we drop the connection, so that
510 // a client can't just connect to us and leave us
516 // We do not have to block here
517 tv
.tv_sec
= RPCAP_TIMEOUT_INIT
;
520 FD_SET(pars
.sockctrl
, &rfds
);
522 retval
= select((int)pars
.sockctrl
+ 1, &rfds
, NULL
, NULL
, &tv
);
525 sock_geterrmsg(errmsgbuf
, PCAP_ERRBUF_SIZE
,
527 if (rpcap_senderror(pars
.sockctrl
, pars
.ssl
, 0, PCAP_ERR_NETW
, errmsgbuf
, errbuf
) == -1)
528 rpcapd_log(LOGPRIO_ERROR
, "Send to client failed: %s", errbuf
);
532 // The timeout has expired
533 // So, this was a fake connection. Drop it down
536 if (rpcap_senderror(pars
.sockctrl
, pars
.ssl
, 0, PCAP_ERR_INITTIMEOUT
, "The RPCAP initial timeout has expired", errbuf
) == -1)
537 rpcapd_log(LOGPRIO_ERROR
, "Send to client failed: %s", errbuf
);
543 // Read the message header from the client.
545 nrecv
= rpcapd_recv_msg_header(pars
.sockctrl
, pars
.ssl
, &header
);
553 // Client closed the connection.
560 // While we're in the authentication phase, all requests
561 // must use version 0.
566 // Send it back to them with their version.
568 if (rpcap_senderror(pars
.sockctrl
, pars
.ssl
, header
.ver
,
570 "RPCAP version in requests in the authentication phase must be 0",
573 // That failed; log a message and give up.
574 rpcapd_log(LOGPRIO_ERROR
, "Send to client failed: %s", errbuf
);
578 // Discard the rest of the message and drop the
580 (void)rpcapd_discard(pars
.sockctrl
, pars
.ssl
, plen
);
586 case RPCAP_MSG_AUTH_REQ
:
587 retval
= daemon_msg_auth_req(&pars
, plen
);
590 // Fatal error; a message has
591 // been logged, so just give up.
596 // Non-fatal error; we sent back
597 // an error message, so let them
602 // OK, we're authenticated; we sent back
603 // a reply, so start serving requests.
607 case RPCAP_MSG_CLOSE
:
609 // The client is giving up.
610 // Discard the rest of the message, if
611 // there is anything more.
613 (void)rpcapd_discard(pars
.sockctrl
, pars
.ssl
, plen
);
614 // We're done with this client.
617 case RPCAP_MSG_ERROR
:
618 // Log this and close the connection?
619 // XXX - is this what happens in active
620 // mode, where *we* initiate the
621 // connection, and the client gives us
622 // an error message rather than a "let
623 // me log in" message, indicating that
624 // we're not allowed to connect to them?
625 (void)daemon_msg_err(pars
.sockctrl
, pars
.ssl
, plen
);
628 case RPCAP_MSG_FINDALLIF_REQ
:
629 case RPCAP_MSG_OPEN_REQ
:
630 case RPCAP_MSG_STARTCAP_REQ
:
631 case RPCAP_MSG_UPDATEFILTER_REQ
:
632 case RPCAP_MSG_STATS_REQ
:
633 case RPCAP_MSG_ENDCAP_REQ
:
634 case RPCAP_MSG_SETSAMPLING_REQ
:
636 // These requests can't be sent until
637 // the client is authenticated.
639 msg_type_string
= rpcap_msg_type_string(header
.type
);
640 if (msg_type_string
!= NULL
)
642 snprintf(errmsgbuf
, PCAP_ERRBUF_SIZE
, "%s request sent before authentication was completed", msg_type_string
);
646 snprintf(errmsgbuf
, PCAP_ERRBUF_SIZE
, "Message of type %u sent before authentication was completed", header
.type
);
648 if (rpcap_senderror(pars
.sockctrl
, pars
.ssl
,
649 header
.ver
, PCAP_ERR_WRONGMSG
,
650 errmsgbuf
, errbuf
) == -1)
652 rpcapd_log(LOGPRIO_ERROR
, "Send to client failed: %s", errbuf
);
655 // Discard the rest of the message.
656 if (rpcapd_discard(pars
.sockctrl
, pars
.ssl
, plen
) == -1)
663 case RPCAP_MSG_PACKET
:
664 case RPCAP_MSG_FINDALLIF_REPLY
:
665 case RPCAP_MSG_OPEN_REPLY
:
666 case RPCAP_MSG_STARTCAP_REPLY
:
667 case RPCAP_MSG_UPDATEFILTER_REPLY
:
668 case RPCAP_MSG_AUTH_REPLY
:
669 case RPCAP_MSG_STATS_REPLY
:
670 case RPCAP_MSG_ENDCAP_REPLY
:
671 case RPCAP_MSG_SETSAMPLING_REPLY
:
673 // These are server-to-client messages.
675 msg_type_string
= rpcap_msg_type_string(header
.type
);
676 if (msg_type_string
!= NULL
)
678 snprintf(errmsgbuf
, PCAP_ERRBUF_SIZE
, "Server-to-client message %s received from client", msg_type_string
);
682 snprintf(errmsgbuf
, PCAP_ERRBUF_SIZE
, "Server-to-client message of type %u received from client", header
.type
);
684 if (rpcap_senderror(pars
.sockctrl
, pars
.ssl
,
685 header
.ver
, PCAP_ERR_WRONGMSG
,
686 errmsgbuf
, errbuf
) == -1)
688 rpcapd_log(LOGPRIO_ERROR
, "Send to client failed: %s", errbuf
);
691 // Discard the rest of the message.
692 if (rpcapd_discard(pars
.sockctrl
, pars
.ssl
, plen
) == -1)
701 // Unknown message type.
703 snprintf(errmsgbuf
, PCAP_ERRBUF_SIZE
, "Unknown message type %u", header
.type
);
704 if (rpcap_senderror(pars
.sockctrl
, pars
.ssl
,
705 header
.ver
, PCAP_ERR_WRONGMSG
,
706 errmsgbuf
, errbuf
) == -1)
708 rpcapd_log(LOGPRIO_ERROR
, "Send to client failed: %s", errbuf
);
711 // Discard the rest of the message.
712 if (rpcapd_discard(pars
.sockctrl
, pars
.ssl
, plen
) == -1)
722 // OK, the client has authenticated itself, and we can start
723 // processing regular requests from it.
727 // We don't have any statistics yet.
739 errbuf
[0] = 0; // clear errbuf
741 // Avoid zombies connections; check if the connection is opens but no commands are performed
742 // from more than RPCAP_TIMEOUT_RUNTIME
744 // - I have to be in normal mode (no active mode)
745 // - if the device is open, I don't have to be in the middle of a capture (session->sockdata)
746 // - if the device is closed, I have always to check if a new command arrives
748 // Be carefully: the capture can have been started, but an error occurred (so session != NULL, but
750 if ((!pars
.isactive
) && (session
== NULL
|| session
->sockdata
== 0))
752 // Check for the initial timeout
754 // We do not have to block here
755 tv
.tv_sec
= RPCAP_TIMEOUT_RUNTIME
;
758 FD_SET(pars
.sockctrl
, &rfds
);
759 #ifdef FUZZING_BUILD_MODE_UNSAFE_FOR_PRODUCTION
762 retval
= select((int)pars
.sockctrl
+ 1, &rfds
, NULL
, NULL
, &tv
);
766 sock_geterrmsg(errmsgbuf
, PCAP_ERRBUF_SIZE
,
768 if (rpcap_senderror(pars
.sockctrl
, pars
.ssl
,
770 errmsgbuf
, errbuf
) == -1)
771 rpcapd_log(LOGPRIO_ERROR
, "Send to client failed: %s", errbuf
);
775 // The timeout has expired
776 // So, this was a fake connection. Drop it down
779 if (rpcap_senderror(pars
.sockctrl
, pars
.ssl
,
780 0, PCAP_ERR_INITTIMEOUT
,
781 "The RPCAP initial timeout has expired",
783 rpcapd_log(LOGPRIO_ERROR
, "Send to client failed: %s", errbuf
);
789 // Read the message header from the client.
791 nrecv
= rpcapd_recv_msg_header(pars
.sockctrl
, pars
.ssl
, &header
);
799 // Client closed the connection.
806 // Did the client specify a protocol version that we
809 if (!RPCAP_VERSION_IS_SUPPORTED(header
.ver
))
812 // Tell them it's not a supported version.
813 // Send the error message with their version,
814 // so they don't reject it as having the wrong
817 if (rpcap_senderror(pars
.sockctrl
, pars
.ssl
,
818 header
.ver
, PCAP_ERR_WRONGVER
,
819 "RPCAP version in message isn't supported by the server",
822 // That failed; log a message and give up.
823 rpcapd_log(LOGPRIO_ERROR
, "Send to client failed: %s", errbuf
);
827 // Discard the rest of the message.
828 (void)rpcapd_discard(pars
.sockctrl
, pars
.ssl
, plen
);
835 case RPCAP_MSG_ERROR
: // The other endpoint reported an error
837 (void)daemon_msg_err(pars
.sockctrl
, pars
.ssl
, plen
);
838 // Do nothing; just exit; the error code is already into the errbuf
839 // XXX - actually exit....
843 case RPCAP_MSG_FINDALLIF_REQ
:
845 if (daemon_msg_findallif_req(header
.ver
, &pars
, plen
) == -1)
847 // Fatal error; a message has
848 // been logged, so just give up.
854 case RPCAP_MSG_OPEN_REQ
:
857 // Process the open request, and keep
858 // the source from it, for use later
859 // when the capture is started.
861 // XXX - we don't care if the client sends
862 // us multiple open requests, the last
865 retval
= daemon_msg_open_req(header
.ver
, &pars
,
866 plen
, source
, sizeof(source
));
869 // Fatal error; a message has
870 // been logged, so just give up.
877 case RPCAP_MSG_STARTCAP_REQ
:
881 // They never told us what device
883 if (rpcap_senderror(pars
.sockctrl
, pars
.ssl
,
885 PCAP_ERR_STARTCAPTURE
,
886 "No capture device was specified",
889 // Fatal error; log an
890 // error and give up.
891 rpcapd_log(LOGPRIO_ERROR
, "Send to client failed: %s", errbuf
);
894 if (rpcapd_discard(pars
.sockctrl
, pars
.ssl
, plen
) == -1)
901 if (daemon_msg_startcap_req(header
.ver
, &pars
,
902 plen
, source
, data_port
, &session
,
903 &samp_param
, uses_ssl
) == -1)
905 // Fatal error; a message has
906 // been logged, so just give up.
912 case RPCAP_MSG_UPDATEFILTER_REQ
:
916 if (daemon_msg_updatefilter_req(header
.ver
,
917 &pars
, session
, plen
) == -1)
919 // Fatal error; a message has
920 // been logged, so just give up.
926 if (rpcap_senderror(pars
.sockctrl
, pars
.ssl
,
928 PCAP_ERR_UPDATEFILTER
,
929 "Device not opened. Cannot update filter",
932 // That failed; log a message and give up.
933 rpcapd_log(LOGPRIO_ERROR
, "Send to client failed: %s", errbuf
);
940 case RPCAP_MSG_CLOSE
: // The other endpoint close the pcap session
943 // Indicate to our caller that the client
944 // closed the control connection.
945 // This is used only in case of active mode.
947 client_told_us_to_close
= 1;
948 rpcapd_log(LOGPRIO_DEBUG
, "The other end system asked to close the connection.");
952 case RPCAP_MSG_STATS_REQ
:
954 if (daemon_msg_stats_req(header
.ver
, &pars
,
955 session
, plen
, &stats
, svrcapt
) == -1)
957 // Fatal error; a message has
958 // been logged, so just give up.
964 case RPCAP_MSG_ENDCAP_REQ
: // The other endpoint close the current capture session
968 // Save statistics (we can need them in the future)
969 if (pcap_stats(session
->fp
, &stats
))
971 svrcapt
= session
->TotCapt
;
981 if (daemon_msg_endcap_req(header
.ver
,
982 &pars
, session
) == -1)
986 // Fatal error; a message has
987 // been logged, so just give up.
995 rpcap_senderror(pars
.sockctrl
, pars
.ssl
,
998 "Device not opened. Cannot close the capture",
1004 case RPCAP_MSG_SETSAMPLING_REQ
:
1006 if (daemon_msg_setsampling_req(header
.ver
,
1007 &pars
, plen
, &samp_param
) == -1)
1009 // Fatal error; a message has
1010 // been logged, so just give up.
1016 case RPCAP_MSG_AUTH_REQ
:
1019 // We're already authenticated; you don't
1020 // get to reauthenticate.
1022 rpcapd_log(LOGPRIO_INFO
, "The client sent an RPCAP_MSG_AUTH_REQ message after authentication was completed");
1023 if (rpcap_senderror(pars
.sockctrl
, pars
.ssl
,
1026 "RPCAP_MSG_AUTH_REQ request sent after authentication was completed",
1029 rpcapd_log(LOGPRIO_ERROR
, "Send to client failed: %s", errbuf
);
1032 // Discard the rest of the message.
1033 if (rpcapd_discard(pars
.sockctrl
, pars
.ssl
, plen
) == -1)
1040 case RPCAP_MSG_PACKET
:
1041 case RPCAP_MSG_FINDALLIF_REPLY
:
1042 case RPCAP_MSG_OPEN_REPLY
:
1043 case RPCAP_MSG_STARTCAP_REPLY
:
1044 case RPCAP_MSG_UPDATEFILTER_REPLY
:
1045 case RPCAP_MSG_AUTH_REPLY
:
1046 case RPCAP_MSG_STATS_REPLY
:
1047 case RPCAP_MSG_ENDCAP_REPLY
:
1048 case RPCAP_MSG_SETSAMPLING_REPLY
:
1050 // These are server-to-client messages.
1052 msg_type_string
= rpcap_msg_type_string(header
.type
);
1053 if (msg_type_string
!= NULL
)
1055 rpcapd_log(LOGPRIO_INFO
, "The client sent a %s server-to-client message", msg_type_string
);
1056 snprintf(errmsgbuf
, PCAP_ERRBUF_SIZE
, "Server-to-client message %s received from client", msg_type_string
);
1060 rpcapd_log(LOGPRIO_INFO
, "The client sent a server-to-client message of type %u", header
.type
);
1061 snprintf(errmsgbuf
, PCAP_ERRBUF_SIZE
, "Server-to-client message of type %u received from client", header
.type
);
1063 if (rpcap_senderror(pars
.sockctrl
, pars
.ssl
,
1064 header
.ver
, PCAP_ERR_WRONGMSG
,
1065 errmsgbuf
, errbuf
) == -1)
1067 rpcapd_log(LOGPRIO_ERROR
, "Send to client failed: %s", errbuf
);
1070 // Discard the rest of the message.
1071 if (rpcapd_discard(pars
.sockctrl
, pars
.ssl
, plen
) == -1)
1080 // Unknown message type.
1082 rpcapd_log(LOGPRIO_INFO
, "The client sent a message of type %u", header
.type
);
1083 snprintf(errmsgbuf
, PCAP_ERRBUF_SIZE
, "Unknown message type %u", header
.type
);
1084 if (rpcap_senderror(pars
.sockctrl
, pars
.ssl
,
1085 header
.ver
, PCAP_ERR_WRONGMSG
,
1086 errbuf
, errmsgbuf
) == -1)
1088 rpcapd_log(LOGPRIO_ERROR
, "Send to client failed: %s", errbuf
);
1091 // Discard the rest of the message.
1092 if (rpcapd_discard(pars
.sockctrl
, pars
.ssl
, plen
) == -1)
1103 // The service loop is finishing up.
1104 // If we have a capture session running, close it.
1107 session_close(session
);
1112 if (passiveClients
) {
1113 free(passiveClients
);
1116 // Finish using the SSL handle for the control socket, if we
1117 // have an SSL connection, and close the control socket.
1122 // Finish using the SSL handle for the socket.
1123 // This must be done *before* the socket is closed.
1127 sock_close(sockctrl
, NULL
, 0);
1129 // Print message and return
1130 rpcapd_log(LOGPRIO_DEBUG
, "I'm exiting from the child loop");
1132 return client_told_us_to_close
;
1136 * This handles the RPCAP_MSG_ERR message.
1139 daemon_msg_err(PCAP_SOCKET sockctrl
, SSL
*ssl
, uint32_t plen
)
1141 char errbuf
[PCAP_ERRBUF_SIZE
];
1142 char remote_errbuf
[PCAP_ERRBUF_SIZE
];
1144 if (plen
>= PCAP_ERRBUF_SIZE
)
1147 * Message is too long; just read as much of it as we
1148 * can into the buffer provided, and discard the rest.
1150 if (sock_recv(sockctrl
, ssl
, remote_errbuf
, PCAP_ERRBUF_SIZE
- 1,
1151 SOCK_RECEIVEALL_YES
|SOCK_EOF_IS_ERROR
, errbuf
,
1152 PCAP_ERRBUF_SIZE
) == -1)
1155 rpcapd_log(LOGPRIO_ERROR
, "Read from client failed: %s", errbuf
);
1158 if (rpcapd_discard(sockctrl
, ssl
, plen
- (PCAP_ERRBUF_SIZE
- 1)) == -1)
1165 * Null-terminate it.
1167 remote_errbuf
[PCAP_ERRBUF_SIZE
- 1] = '\0';
1171 /* Empty error string. */
1172 remote_errbuf
[0] = '\0';
1176 if (sock_recv(sockctrl
, ssl
, remote_errbuf
, plen
,
1177 SOCK_RECEIVEALL_YES
|SOCK_EOF_IS_ERROR
, errbuf
,
1178 PCAP_ERRBUF_SIZE
) == -1)
1181 rpcapd_log(LOGPRIO_ERROR
, "Read from client failed: %s", errbuf
);
1186 * Null-terminate it.
1188 remote_errbuf
[plen
] = '\0';
1191 rpcapd_log(LOGPRIO_ERROR
, "Error from client: %s", remote_errbuf
);
1196 * This handles the RPCAP_MSG_AUTH_REQ message.
1197 * It checks if the authentication credentials supplied by the user are valid.
1199 * This function is called if the daemon receives a RPCAP_MSG_AUTH_REQ
1200 * message in its authentication loop. It reads the body of the
1201 * authentication message from the network and checks whether the
1202 * credentials are valid.
1204 * \param sockctrl: the socket for the control connection.
1206 * \param nullAuthAllowed: '1' if the NULL authentication is allowed.
1208 * \param errbuf: a user-allocated buffer in which the error message
1209 * (if one) has to be written. It must be at least PCAP_ERRBUF_SIZE
1212 * \return '0' if everything is fine, '-1' if an unrecoverable error occurred,
1213 * or '-2' if the authentication failed. For errors, an error message is
1214 * returned in the 'errbuf' variable; this gives a message for the
1215 * unrecoverable error or for the authentication failure.
1218 daemon_msg_auth_req(struct daemon_slpars
*pars
, uint32_t plen
)
1220 char errbuf
[PCAP_ERRBUF_SIZE
]; // buffer for network errors
1221 char errmsgbuf
[PCAP_ERRBUF_SIZE
]; // buffer for errors to send to the client
1223 struct rpcap_auth auth
; // RPCAP authentication header
1224 char sendbuf
[RPCAP_NETBUF_SIZE
]; // temporary buffer in which data to be sent is buffered
1225 int sendbufidx
= 0; // index which keeps the number of bytes currently buffered
1226 struct rpcap_authreply
*authreply
; // authentication reply message
1228 status
= rpcapd_recv(pars
->sockctrl
, pars
->ssl
, (char *) &auth
, sizeof(struct rpcap_auth
), &plen
, errmsgbuf
);
1238 switch (ntohs(auth
.type
))
1240 case RPCAP_RMTAUTH_NULL
:
1242 if (!pars
->nullAuthAllowed
)
1244 // Send the client an error reply.
1245 snprintf(errmsgbuf
, PCAP_ERRBUF_SIZE
,
1246 "Authentication failed; NULL authentication not permitted.");
1247 if (rpcap_senderror(pars
->sockctrl
, pars
->ssl
,
1248 0, PCAP_ERR_AUTH_FAILED
, errmsgbuf
, errbuf
) == -1)
1250 // That failed; log a message and give up.
1251 rpcapd_log(LOGPRIO_ERROR
, "Send to client failed: %s", errbuf
);
1259 case RPCAP_RMTAUTH_PWD
:
1261 char *username
, *passwd
;
1262 uint32_t usernamelen
, passwdlen
;
1264 usernamelen
= ntohs(auth
.slen1
);
1265 username
= (char *) malloc (usernamelen
+ 1);
1266 if (username
== NULL
)
1268 pcapint_fmt_errmsg_for_errno(errmsgbuf
,
1269 PCAP_ERRBUF_SIZE
, errno
, "malloc() failed");
1272 status
= rpcapd_recv(pars
->sockctrl
, pars
->ssl
, username
, usernamelen
, &plen
, errmsgbuf
);
1283 username
[usernamelen
] = '\0';
1285 passwdlen
= ntohs(auth
.slen2
);
1286 passwd
= (char *) malloc (passwdlen
+ 1);
1289 pcapint_fmt_errmsg_for_errno(errmsgbuf
,
1290 PCAP_ERRBUF_SIZE
, errno
, "malloc() failed");
1294 status
= rpcapd_recv(pars
->sockctrl
, pars
->ssl
, passwd
, passwdlen
, &plen
, errmsgbuf
);
1307 passwd
[passwdlen
] = '\0';
1309 if (daemon_AuthUserPwd(username
, passwd
, errmsgbuf
))
1312 // Authentication failed. Let the client
1317 if (rpcap_senderror(pars
->sockctrl
, pars
->ssl
,
1318 0, PCAP_ERR_AUTH_FAILED
, errmsgbuf
, errbuf
) == -1)
1320 // That failed; log a message and give up.
1321 rpcapd_log(LOGPRIO_ERROR
, "Send to client failed: %s", errbuf
);
1326 // Suspend for 1 second, so that they can't
1327 // hammer us with repeated tries with an
1328 // attack such as a dictionary attack.
1330 // WARNING: this delay is inserted only
1331 // at this point; if the client closes the
1332 // connection and reconnects, the suspension
1333 // time does not have any effect.
1335 sleep_secs(RPCAP_SUSPEND_WRONGAUTH
);
1345 snprintf(errmsgbuf
, PCAP_ERRBUF_SIZE
,
1346 "Authentication type not recognized.");
1347 if (rpcap_senderror(pars
->sockctrl
, pars
->ssl
,
1348 0, PCAP_ERR_AUTH_TYPE_NOTSUP
, errmsgbuf
, errbuf
) == -1)
1350 // That failed; log a message and give up.
1351 rpcapd_log(LOGPRIO_ERROR
, "Send to client failed: %s", errbuf
);
1357 // The authentication succeeded; let the client know.
1358 if (sock_bufferize(NULL
, sizeof(struct rpcap_header
), NULL
, &sendbufidx
,
1359 RPCAP_NETBUF_SIZE
, SOCKBUF_CHECKONLY
, errmsgbuf
, PCAP_ERRBUF_SIZE
) == -1)
1362 rpcap_createhdr((struct rpcap_header
*) sendbuf
, 0,
1363 RPCAP_MSG_AUTH_REPLY
, 0, sizeof(struct rpcap_authreply
));
1365 authreply
= (struct rpcap_authreply
*) &sendbuf
[sendbufidx
];
1367 if (sock_bufferize(NULL
, sizeof(struct rpcap_authreply
), NULL
, &sendbufidx
,
1368 RPCAP_NETBUF_SIZE
, SOCKBUF_CHECKONLY
, errmsgbuf
, PCAP_ERRBUF_SIZE
) == -1)
1372 // Indicate to our peer what versions we support and what our
1373 // version of the byte-order magic is (which will tell the
1374 // client whether our byte order differs from theirs, in which
1375 // case they will need to byte-swap some fields in some
1376 // link-layer types' headers).
1378 memset(authreply
, 0, sizeof(struct rpcap_authreply
));
1379 authreply
->minvers
= RPCAP_MIN_VERSION
;
1380 authreply
->maxvers
= RPCAP_MAX_VERSION
;
1381 authreply
->byte_order_magic
= RPCAP_BYTE_ORDER_MAGIC
;
1384 if (sock_send(pars
->sockctrl
, pars
->ssl
, sendbuf
, sendbufidx
, errbuf
, PCAP_ERRBUF_SIZE
) == -1)
1386 // That failed; log a message and give up.
1387 rpcapd_log(LOGPRIO_ERROR
, "Send to client failed: %s", errbuf
);
1391 // Check if all the data has been read; if not, discard the data in excess
1392 if (rpcapd_discard(pars
->sockctrl
, pars
->ssl
, plen
) == -1)
1400 if (rpcap_senderror(pars
->sockctrl
, pars
->ssl
, 0, PCAP_ERR_AUTH
,
1401 errmsgbuf
, errbuf
) == -1)
1403 // That failed; log a message and give up.
1404 rpcapd_log(LOGPRIO_ERROR
, "Send to client failed: %s", errbuf
);
1409 // Check if all the data has been read; if not, discard the data in excess
1410 if (rpcapd_discard(pars
->sockctrl
, pars
->ssl
, plen
) == -1)
1419 daemon_AuthUserPwd(char *username
, char *password
, char *errbuf
)
1423 * Warning: the user which launches the process must have the
1424 * SE_TCB_NAME right.
1425 * This corresponds to have the "Act as part of the Operating System"
1426 * turned on (administrative tools, local security settings, local
1427 * policies, user right assignment)
1428 * However, it seems to me that if you run it as a service, this
1429 * right should be provided by default.
1431 * XXX - hopefully, this returns errors such as ERROR_LOGON_FAILURE,
1432 * which merely indicates that the user name or password is
1433 * incorrect, not whether it's the user name or the password
1434 * that's incorrect, so a client that's trying to brute-force
1435 * accounts doesn't know whether it's the user name or the
1436 * password that's incorrect, so it doesn't know whether to
1437 * stop trying to log in with a given user name and move on
1438 * to another user name.
1442 char errmsgbuf
[PCAP_ERRBUF_SIZE
]; // buffer for errors to log
1444 if (LogonUser(username
, ".", password
, LOGON32_LOGON_NETWORK
, LOGON32_PROVIDER_DEFAULT
, &Token
) == 0)
1446 snprintf(errbuf
, PCAP_ERRBUF_SIZE
, "Authentication failed");
1447 error
= GetLastError();
1448 if (error
!= ERROR_LOGON_FAILURE
)
1450 // Some error other than an authentication error;
1452 pcapint_fmt_errmsg_for_win32_err(errmsgbuf
,
1453 PCAP_ERRBUF_SIZE
, error
, "LogonUser() failed");
1454 rpcapd_log(LOGPRIO_ERROR
, "%s", errmsgbuf
);
1459 // This call should change the current thread to the selected user.
1460 // I didn't test it.
1461 if (ImpersonateLoggedOnUser(Token
) == 0)
1463 snprintf(errbuf
, PCAP_ERRBUF_SIZE
, "Authentication failed");
1464 pcapint_fmt_errmsg_for_win32_err(errmsgbuf
, PCAP_ERRBUF_SIZE
,
1465 GetLastError(), "ImpersonateLoggedOnUser() failed");
1466 rpcapd_log(LOGPRIO_ERROR
, "%s", errmsgbuf
);
1478 * https://www.unixpapa.com/incnote/passwd.html
1480 * We use the Solaris/Linux shadow password authentication if
1481 * we have getspnam(), otherwise we just do traditional
1482 * authentication, which, on some platforms, might work, even
1483 * with shadow passwords, if we're running as root. Traditional
1484 * authentication won't work if we're not running as root, as
1485 * I think these days all UN*Xes either won't return the password
1486 * at all with getpwnam() or will only do so if you're root.
1488 * XXX - perhaps what we *should* be using is PAM, if we have
1489 * it. That might hide all the details of username/password
1490 * authentication, whether it's done with a visible-to-root-
1491 * only password database or some other authentication mechanism,
1495 struct passwd
*user
;
1496 char *user_password
;
1497 #ifdef HAVE_GETSPNAM
1498 struct spwd
*usersp
;
1500 char *crypt_password
;
1502 // This call is needed to get the uid
1503 if ((user
= getpwnam(username
)) == NULL
)
1505 snprintf(errbuf
, PCAP_ERRBUF_SIZE
, "Authentication failed");
1509 #ifdef HAVE_GETSPNAM
1510 // This call is needed to get the password; otherwise 'x' is returned
1511 if ((usersp
= getspnam(username
)) == NULL
)
1513 snprintf(errbuf
, PCAP_ERRBUF_SIZE
, "Authentication failed");
1516 user_password
= usersp
->sp_pwdp
;
1519 * XXX - what about other platforms?
1520 * The unixpapa.com page claims this Just Works on *BSD if you're
1521 * running as root - it's from 2000, so it doesn't indicate whether
1522 * macOS (which didn't come out until 2001, under the name Mac OS
1523 * X) behaves like the *BSDs or not, and might also work on AIX.
1524 * HP-UX does something else.
1526 * Again, hopefully PAM hides all that.
1528 user_password
= user
->pw_passwd
;
1532 // The Single UNIX Specification says that if crypt() fails it
1533 // sets errno, but some implementations that haven't been run
1534 // through the SUS test suite might not do so.
1537 crypt_password
= crypt(password
, user_password
);
1538 if (crypt_password
== NULL
)
1541 snprintf(errbuf
, PCAP_ERRBUF_SIZE
, "Authentication failed");
1544 // It didn't set errno.
1545 rpcapd_log(LOGPRIO_ERROR
, "crypt() failed");
1549 rpcapd_log(LOGPRIO_ERROR
, "crypt() failed: %s",
1554 if (strcmp(user_password
, crypt_password
) != 0)
1556 snprintf(errbuf
, PCAP_ERRBUF_SIZE
, "Authentication failed");
1560 if (setuid(user
->pw_uid
))
1563 pcapint_fmt_errmsg_for_errno(errbuf
, PCAP_ERRBUF_SIZE
,
1565 rpcapd_log(LOGPRIO_ERROR
, "setuid() failed: %s",
1570 /* if (setgid(user->pw_gid))
1573 pcapint_fmt_errmsg_for_errno(errbuf, PCAP_ERRBUF_SIZE,
1575 rpcapd_log(LOGPRIO_ERROR, "setgid() failed: %s",
1587 * Make sure that the reply length won't overflow 32 bits if we add the
1588 * specified amount to it. If it won't, add that amount to it.
1590 * We check whether replylen + itemlen > UINT32_MAX, but subtract itemlen
1591 * from both sides, to prevent overflow.
1593 #define CHECK_AND_INCREASE_REPLY_LEN(itemlen) \
1594 if (replylen > UINT32_MAX - (itemlen)) { \
1595 pcapint_strlcpy(errmsgbuf, "Reply length doesn't fit in 32 bits", \
1596 sizeof (errmsgbuf)); \
1599 replylen += (uint32_t)(itemlen)
1602 daemon_msg_findallif_req(uint8_t ver
, struct daemon_slpars
*pars
, uint32_t plen
)
1604 char errbuf
[PCAP_ERRBUF_SIZE
]; // buffer for network errors
1605 char errmsgbuf
[PCAP_ERRBUF_SIZE
]; // buffer for errors to send to the client
1606 char sendbuf
[RPCAP_NETBUF_SIZE
]; // temporary buffer in which data to be sent is buffered
1607 int sendbufidx
= 0; // index which keeps the number of bytes currently buffered
1608 pcap_if_t
*alldevs
= NULL
; // pointer to the header of the interface chain
1609 pcap_if_t
*d
; // temp pointer needed to scan the interface chain
1610 struct pcap_addr
*address
; // pcap structure that keeps a network address of an interface
1611 uint32_t replylen
; // length of reply payload
1612 uint16_t nif
= 0; // counts the number of interface listed
1614 // Discard the rest of the message; there shouldn't be any payload.
1615 if (rpcapd_discard(pars
->sockctrl
, pars
->ssl
, plen
) == -1)
1621 // Retrieve the device list
1622 if (pcap_findalldevs(&alldevs
, errmsgbuf
) == -1)
1625 if (alldevs
== NULL
)
1627 if (rpcap_senderror(pars
->sockctrl
, pars
->ssl
, ver
,
1628 PCAP_ERR_NOREMOTEIF
,
1629 "No interfaces found! Make sure libpcap/WinPcap is properly installed"
1630 " and you have the right to access to the remote device.",
1633 rpcapd_log(LOGPRIO_ERROR
, "Send to client failed: %s", errbuf
);
1639 // This checks the number of interfaces and computes the total
1640 // length of the payload.
1642 for (d
= alldevs
; d
!= NULL
; d
= d
->next
)
1646 if (d
->description
) {
1647 size_t stringlen
= strlen(d
->description
);
1648 if (stringlen
> UINT16_MAX
) {
1649 pcapint_strlcpy(errmsgbuf
,
1650 "Description length doesn't fit in 16 bits",
1651 sizeof (errmsgbuf
));
1654 CHECK_AND_INCREASE_REPLY_LEN(stringlen
);
1657 size_t stringlen
= strlen(d
->name
);
1658 if (stringlen
> UINT16_MAX
) {
1659 pcapint_strlcpy(errmsgbuf
,
1660 "Name length doesn't fit in 16 bits",
1661 sizeof (errmsgbuf
));
1664 CHECK_AND_INCREASE_REPLY_LEN(stringlen
);
1667 CHECK_AND_INCREASE_REPLY_LEN(sizeof(struct rpcap_findalldevs_if
));
1669 uint16_t naddrs
= 0;
1670 for (address
= d
->addresses
; address
!= NULL
; address
= address
->next
)
1673 * Send only IPv4 and IPv6 addresses over the wire.
1675 switch (address
->addr
->sa_family
)
1681 CHECK_AND_INCREASE_REPLY_LEN(sizeof(struct rpcap_sockaddr
) * 4);
1682 if (naddrs
== UINT16_MAX
) {
1683 pcapint_strlcpy(errmsgbuf
,
1684 "Number of interfaces doesn't fit in 16 bits",
1685 sizeof (errmsgbuf
));
1697 // RPCAP findalldevs reply
1698 if (sock_bufferize(NULL
, sizeof(struct rpcap_header
), NULL
,
1699 &sendbufidx
, RPCAP_NETBUF_SIZE
, SOCKBUF_CHECKONLY
, errmsgbuf
,
1700 PCAP_ERRBUF_SIZE
) == -1)
1703 rpcap_createhdr((struct rpcap_header
*) sendbuf
, ver
,
1704 RPCAP_MSG_FINDALLIF_REPLY
, nif
, replylen
);
1706 // send the interface list
1707 for (d
= alldevs
; d
!= NULL
; d
= d
->next
)
1709 uint16_t lname
, ldescr
;
1711 // Note: the findalldevs_if entries are *not* neatly
1712 // aligned on 4-byte boundaries, because they're
1713 // preceded by strings that aren't padded to 4-byte
1714 // boundaries, so we cannot just cast output buffer
1715 // boundaries to struct rpcap_findalldevs_if pointers
1716 // and store into them - we must fill in a structure and
1717 // then copy the structure to the buffer, as not all
1718 // systems support unaligned access (some, such as
1719 // SPARC, crash; others, such as Arm, may just ignore
1720 // the lower-order bits).
1721 struct rpcap_findalldevs_if findalldevs_if
;
1724 * We've already established that the string lengths
1728 ldescr
= (uint16_t) strlen(d
->description
);
1732 lname
= (uint16_t) strlen(d
->name
);
1736 findalldevs_if
.desclen
= htons(ldescr
);
1737 findalldevs_if
.namelen
= htons(lname
);
1738 findalldevs_if
.flags
= htonl(d
->flags
);
1740 uint16_t naddrs
= 0;
1741 for (address
= d
->addresses
; address
!= NULL
; address
= address
->next
)
1744 * Send only IPv4 and IPv6 addresses over the wire.
1746 switch (address
->addr
->sa_family
)
1759 findalldevs_if
.naddr
= htons(naddrs
);
1760 findalldevs_if
.dummy
= 0;
1762 if (sock_bufferize(&findalldevs_if
, sizeof(struct rpcap_findalldevs_if
), sendbuf
,
1763 &sendbufidx
, RPCAP_NETBUF_SIZE
, SOCKBUF_BUFFERIZE
, errmsgbuf
,
1764 PCAP_ERRBUF_SIZE
) == -1)
1767 if (sock_bufferize(d
->name
, lname
, sendbuf
, &sendbufidx
,
1768 RPCAP_NETBUF_SIZE
, SOCKBUF_BUFFERIZE
, errmsgbuf
,
1769 PCAP_ERRBUF_SIZE
) == -1)
1772 if (sock_bufferize(d
->description
, ldescr
, sendbuf
, &sendbufidx
,
1773 RPCAP_NETBUF_SIZE
, SOCKBUF_BUFFERIZE
, errmsgbuf
,
1774 PCAP_ERRBUF_SIZE
) == -1)
1777 // send all addresses
1778 for (address
= d
->addresses
; address
!= NULL
; address
= address
->next
)
1780 struct rpcap_sockaddr
*sockaddr
;
1783 * Send only IPv4 and IPv6 addresses over the wire.
1785 switch (address
->addr
->sa_family
)
1791 sockaddr
= (struct rpcap_sockaddr
*) &sendbuf
[sendbufidx
];
1792 if (sock_bufferize(NULL
, sizeof(struct rpcap_sockaddr
), NULL
,
1793 &sendbufidx
, RPCAP_NETBUF_SIZE
, SOCKBUF_CHECKONLY
, errmsgbuf
, PCAP_ERRBUF_SIZE
) == -1)
1795 daemon_seraddr((struct sockaddr_storage
*) address
->addr
, sockaddr
);
1797 sockaddr
= (struct rpcap_sockaddr
*) &sendbuf
[sendbufidx
];
1798 if (sock_bufferize(NULL
, sizeof(struct rpcap_sockaddr
), NULL
,
1799 &sendbufidx
, RPCAP_NETBUF_SIZE
, SOCKBUF_CHECKONLY
, errmsgbuf
, PCAP_ERRBUF_SIZE
) == -1)
1801 daemon_seraddr((struct sockaddr_storage
*) address
->netmask
, sockaddr
);
1803 sockaddr
= (struct rpcap_sockaddr
*) &sendbuf
[sendbufidx
];
1804 if (sock_bufferize(NULL
, sizeof(struct rpcap_sockaddr
), NULL
,
1805 &sendbufidx
, RPCAP_NETBUF_SIZE
, SOCKBUF_CHECKONLY
, errmsgbuf
, PCAP_ERRBUF_SIZE
) == -1)
1807 daemon_seraddr((struct sockaddr_storage
*) address
->broadaddr
, sockaddr
);
1809 sockaddr
= (struct rpcap_sockaddr
*) &sendbuf
[sendbufidx
];
1810 if (sock_bufferize(NULL
, sizeof(struct rpcap_sockaddr
), NULL
,
1811 &sendbufidx
, RPCAP_NETBUF_SIZE
, SOCKBUF_CHECKONLY
, errmsgbuf
, PCAP_ERRBUF_SIZE
) == -1)
1813 daemon_seraddr((struct sockaddr_storage
*) address
->dstaddr
, sockaddr
);
1822 // We no longer need the device list. Free it.
1823 pcap_freealldevs(alldevs
);
1825 // Send a final command that says "now send it!"
1826 if (sock_send(pars
->sockctrl
, pars
->ssl
, sendbuf
, sendbufidx
, errbuf
, PCAP_ERRBUF_SIZE
) == -1)
1828 rpcapd_log(LOGPRIO_ERROR
, "Send to client failed: %s", errbuf
);
1836 pcap_freealldevs(alldevs
);
1838 if (rpcap_senderror(pars
->sockctrl
, pars
->ssl
, ver
,
1839 PCAP_ERR_FINDALLIF
, errmsgbuf
, errbuf
) == -1)
1841 rpcapd_log(LOGPRIO_ERROR
, "Send to client failed: %s", errbuf
);
1848 \param plen: the length of the current message (needed in order to be able
1849 to discard excess data in the message, if present)
1852 daemon_msg_open_req(uint8_t ver
, struct daemon_slpars
*pars
, uint32_t plen
,
1853 char *source
, size_t sourcelen
)
1855 char errbuf
[PCAP_ERRBUF_SIZE
]; // buffer for network errors
1856 char errmsgbuf
[PCAP_ERRBUF_SIZE
]; // buffer for errors to send to the client
1857 pcap_t
*fp
; // pcap_t main variable
1859 char sendbuf
[RPCAP_NETBUF_SIZE
]; // temporary buffer in which data to be sent is buffered
1860 int sendbufidx
= 0; // index which keeps the number of bytes currently buffered
1861 struct rpcap_openreply
*openreply
; // open reply message
1863 if (plen
> sourcelen
- 1)
1865 snprintf(errmsgbuf
, PCAP_ERRBUF_SIZE
, "Source string too long");
1869 nread
= sock_recv(pars
->sockctrl
, pars
->ssl
, source
, plen
,
1870 SOCK_RECEIVEALL_YES
|SOCK_EOF_IS_ERROR
, errbuf
, PCAP_ERRBUF_SIZE
);
1873 rpcapd_log(LOGPRIO_ERROR
, "Read from client failed: %s", errbuf
);
1876 source
[nread
] = '\0';
1879 // Is this a URL rather than a device?
1880 // If so, reject it.
1883 snprintf(errmsgbuf
, PCAP_ERRBUF_SIZE
, "Source string refers to a remote device");
1887 // Open the selected device
1888 // This is a fake open, since we do that only to get the needed parameters, then we close the device again
1889 if ((fp
= pcap_open_live(source
,
1890 1500 /* fake snaplen */,
1892 1000 /* fake timeout */,
1893 errmsgbuf
)) == NULL
)
1896 // Now, I can send a RPCAP open reply message
1897 if (sock_bufferize(NULL
, sizeof(struct rpcap_header
), NULL
, &sendbufidx
,
1898 RPCAP_NETBUF_SIZE
, SOCKBUF_CHECKONLY
, errmsgbuf
, PCAP_ERRBUF_SIZE
) == -1)
1901 rpcap_createhdr((struct rpcap_header
*) sendbuf
, ver
,
1902 RPCAP_MSG_OPEN_REPLY
, 0, sizeof(struct rpcap_openreply
));
1904 openreply
= (struct rpcap_openreply
*) &sendbuf
[sendbufidx
];
1906 if (sock_bufferize(NULL
, sizeof(struct rpcap_openreply
), NULL
, &sendbufidx
,
1907 RPCAP_NETBUF_SIZE
, SOCKBUF_CHECKONLY
, errmsgbuf
, PCAP_ERRBUF_SIZE
) == -1)
1910 memset(openreply
, 0, sizeof(struct rpcap_openreply
));
1911 openreply
->linktype
= htonl(pcap_datalink(fp
));
1913 * This is always 0 for live captures; we no longer support it
1914 * as something we read from capture files and supply to
1915 * clients, but we have to send it over the wire, as open
1916 * replies are expected to have 8 bytes of payload by
1919 openreply
->tzoff
= 0;
1921 // We're done with the pcap_t.
1925 if (sock_send(pars
->sockctrl
, pars
->ssl
, sendbuf
, sendbufidx
, errbuf
, PCAP_ERRBUF_SIZE
) == -1)
1927 rpcapd_log(LOGPRIO_ERROR
, "Send to client failed: %s", errbuf
);
1933 if (rpcap_senderror(pars
->sockctrl
, pars
->ssl
, ver
, PCAP_ERR_OPEN
,
1934 errmsgbuf
, errbuf
) == -1)
1936 // That failed; log a message and give up.
1937 rpcapd_log(LOGPRIO_ERROR
, "Send to client failed: %s", errbuf
);
1941 // Check if all the data has been read; if not, discard the data in excess
1942 if (rpcapd_discard(pars
->sockctrl
, pars
->ssl
, plen
) == -1)
1950 \param plen: the length of the current message (needed in order to be able
1951 to discard excess data in the message, if present)
1954 daemon_msg_startcap_req(uint8_t ver
, struct daemon_slpars
*pars
, uint32_t plen
,
1955 char *source
, char *data_port
, struct session
**sessionp
,
1956 struct rpcap_sampling
*samp_param _U_
, int uses_ssl
)
1958 char errbuf
[PCAP_ERRBUF_SIZE
]; // buffer for network errors
1959 char errmsgbuf
[PCAP_ERRBUF_SIZE
]; // buffer for errors to send to the client
1960 char portdata
[PCAP_BUF_SIZE
]; // temp variable needed to derive the data port
1961 char peerhost
[PCAP_BUF_SIZE
]; // temp variable needed to derive the host name of our peer
1962 struct session
*session
= NULL
; // saves state of session
1964 char sendbuf
[RPCAP_NETBUF_SIZE
]; // temporary buffer in which data to be sent is buffered
1965 int sendbufidx
= 0; // index which keeps the number of bytes currently buffered
1967 // socket-related variables
1968 struct addrinfo hints
; // temp, needed to open a socket connection
1969 struct addrinfo
*addrinfo
; // temp, needed to open a socket connection
1970 struct sockaddr_storage saddr
; // temp, needed to retrieve the network data port chosen on the local machine
1971 socklen_t saddrlen
; // temp, needed to retrieve the network data port chosen on the local machine
1972 int ret
; // return value from functions
1974 // RPCAP-related variables
1975 struct rpcap_startcapreq startcapreq
; // start capture request message
1976 struct rpcap_startcapreply
*startcapreply
; // start capture reply message
1977 int serveropen_dp
; // keeps who is going to open the data connection
1981 status
= rpcapd_recv(pars
->sockctrl
, pars
->ssl
, (char *) &startcapreq
,
1982 sizeof(struct rpcap_startcapreq
), &plen
, errmsgbuf
);
1992 startcapreq
.flags
= ntohs(startcapreq
.flags
);
1994 // Check that the client does not ask for UDP is the server has been asked
1995 // to enforce encryption, as SSL is not supported yet with UDP:
1996 if (uses_ssl
&& (startcapreq
.flags
& RPCAP_STARTCAPREQ_FLAG_DGRAM
))
1998 snprintf(errbuf
, PCAP_ERRBUF_SIZE
,
1999 "SSL not supported with UDP forward of remote packets");
2003 // Create a session structure
2004 session
= malloc(sizeof(struct session
));
2005 if (session
== NULL
)
2007 snprintf(errmsgbuf
, PCAP_ERRBUF_SIZE
, "Can't allocate session structure");
2011 session
->sockdata
= INVALID_SOCKET
;
2012 session
->ctrl_ssl
= session
->data_ssl
= NULL
;
2013 // We don't have a thread yet.
2014 session
->have_thread
= 0;
2016 // We *shouldn't* have to initialize the thread indicator
2017 // itself, because the compiler *should* realize that we
2018 // only use this if have_thread isn't 0, but we *do* have
2019 // to do it, because not all compilers *do* realize that.
2021 // There is no "invalid thread handle" value for a UN*X
2022 // pthread_t, so we just zero it out.
2025 session
->thread
= INVALID_HANDLE_VALUE
;
2027 memset(&session
->thread
, 0, sizeof(session
->thread
));
2030 // Open the selected device
2031 if ((session
->fp
= pcap_open_live(source
,
2032 ntohl(startcapreq
.snaplen
),
2033 (startcapreq
.flags
& RPCAP_STARTCAPREQ_FLAG_PROMISC
) ? 1 : 0 /* local device, other flags not needed */,
2034 ntohl(startcapreq
.read_timeout
),
2035 errmsgbuf
)) == NULL
)
2039 // Apply sampling parameters
2040 fp
->rmt_samp
.method
= samp_param
->method
;
2041 fp
->rmt_samp
.value
= samp_param
->value
;
2045 We're in active mode if:
2046 - we're using TCP, and the user wants us to be in active mode
2049 serveropen_dp
= (startcapreq
.flags
& RPCAP_STARTCAPREQ_FLAG_SERVEROPEN
) || (startcapreq
.flags
& RPCAP_STARTCAPREQ_FLAG_DGRAM
) || pars
->isactive
;
2052 Gets the sockaddr structure referred to the other peer in the ctrl connection
2054 We need that because:
2055 - if we're in passive mode, we need to know the address family we want to use
2056 (the same used for the ctrl socket)
2057 - if we're in active mode, we need to know the network address of the other host
2058 we want to connect to
2060 saddrlen
= sizeof(struct sockaddr_storage
);
2061 if (getpeername(pars
->sockctrl
, (struct sockaddr
*) &saddr
, &saddrlen
) == -1)
2063 sock_geterrmsg(errmsgbuf
, PCAP_ERRBUF_SIZE
,
2064 "getpeername() failed");
2068 memset(&hints
, 0, sizeof(struct addrinfo
));
2069 hints
.ai_socktype
= (startcapreq
.flags
& RPCAP_STARTCAPREQ_FLAG_DGRAM
) ? SOCK_DGRAM
: SOCK_STREAM
;
2070 hints
.ai_family
= saddr
.ss_family
;
2072 // Now we have to create a new socket to send packets
2073 if (serveropen_dp
) // Data connection is opened by the server toward the client
2075 snprintf(portdata
, sizeof portdata
, "%d", ntohs(startcapreq
.portdata
));
2077 // Get the name of the other peer (needed to connect to that specific network address)
2078 if (getnameinfo((struct sockaddr
*) &saddr
, saddrlen
, peerhost
,
2079 sizeof(peerhost
), NULL
, 0, NI_NUMERICHOST
))
2081 sock_geterrmsg(errmsgbuf
, PCAP_ERRBUF_SIZE
,
2082 "getnameinfo() failed");
2086 addrinfo
= sock_initaddress(peerhost
, portdata
, &hints
,
2087 errmsgbuf
, PCAP_ERRBUF_SIZE
);
2088 if (addrinfo
== NULL
)
2091 if ((session
->sockdata
= sock_open(peerhost
, addrinfo
, SOCKOPEN_CLIENT
, 0, errmsgbuf
, PCAP_ERRBUF_SIZE
)) == INVALID_SOCKET
)
2094 else // Data connection is opened by the client toward the server
2096 hints
.ai_flags
= AI_PASSIVE
;
2098 if (data_port
[0] != '\0')
2100 // Use the specified network port
2101 addrinfo
= sock_initaddress(NULL
, data_port
, &hints
,
2102 errmsgbuf
, PCAP_ERRBUF_SIZE
);
2106 // Make the server socket pick up a free network port for us
2107 addrinfo
= sock_initaddress(NULL
, NULL
, &hints
,
2108 errmsgbuf
, PCAP_ERRBUF_SIZE
);
2110 if (addrinfo
== NULL
)
2113 if ((session
->sockdata
= sock_open(NULL
, addrinfo
, SOCKOPEN_SERVER
, 1 /* max 1 connection in queue */, errmsgbuf
, PCAP_ERRBUF_SIZE
)) == INVALID_SOCKET
)
2116 // get the complete sockaddr structure used in the data connection
2117 saddrlen
= sizeof(struct sockaddr_storage
);
2118 if (getsockname(session
->sockdata
, (struct sockaddr
*) &saddr
, &saddrlen
) == -1)
2120 sock_geterrmsg(errmsgbuf
, PCAP_ERRBUF_SIZE
,
2121 "getsockname() failed");
2125 // Get the local port the system picked up
2126 if (getnameinfo((struct sockaddr
*) &saddr
, saddrlen
, NULL
,
2127 0, portdata
, sizeof(portdata
), NI_NUMERICSERV
))
2129 sock_geterrmsg(errmsgbuf
, PCAP_ERRBUF_SIZE
,
2130 "getnameinfo() failed");
2135 // addrinfo is no longer used
2136 freeaddrinfo(addrinfo
);
2139 // Needed to send an error on the ctrl connection
2140 session
->sockctrl
= pars
->sockctrl
;
2141 session
->ctrl_ssl
= pars
->ssl
;
2142 session
->protocol_version
= ver
;
2144 // Now I can set the filter
2145 ret
= daemon_unpackapplyfilter(pars
->sockctrl
, pars
->ssl
, session
, &plen
, errmsgbuf
);
2148 // Fatal error. A message has been logged; just give up.
2153 // Non-fatal error. Send an error message to the client.
2157 // Now, I can send a RPCAP start capture reply message
2158 if (sock_bufferize(NULL
, sizeof(struct rpcap_header
), NULL
, &sendbufidx
,
2159 RPCAP_NETBUF_SIZE
, SOCKBUF_CHECKONLY
, errmsgbuf
, PCAP_ERRBUF_SIZE
) == -1)
2162 rpcap_createhdr((struct rpcap_header
*) sendbuf
, ver
,
2163 RPCAP_MSG_STARTCAP_REPLY
, 0, sizeof(struct rpcap_startcapreply
));
2165 startcapreply
= (struct rpcap_startcapreply
*) &sendbuf
[sendbufidx
];
2167 if (sock_bufferize(NULL
, sizeof(struct rpcap_startcapreply
), NULL
,
2168 &sendbufidx
, RPCAP_NETBUF_SIZE
, SOCKBUF_CHECKONLY
, errmsgbuf
, PCAP_ERRBUF_SIZE
) == -1)
2171 memset(startcapreply
, 0, sizeof(struct rpcap_startcapreply
));
2172 startcapreply
->bufsize
= htonl(pcap_bufsize(session
->fp
));
2176 unsigned short port
= (unsigned short)strtoul(portdata
,NULL
,10);
2177 startcapreply
->portdata
= htons(port
);
2180 if (sock_send(pars
->sockctrl
, pars
->ssl
, sendbuf
, sendbufidx
, errbuf
, PCAP_ERRBUF_SIZE
) == -1)
2182 // That failed; log a message and give up.
2183 rpcapd_log(LOGPRIO_ERROR
, "Send to client failed: %s", errbuf
);
2189 PCAP_SOCKET socktemp
; // We need another socket, since we're going to accept() a connection
2191 // Connection creation
2192 saddrlen
= sizeof(struct sockaddr_storage
);
2194 socktemp
= accept(session
->sockdata
, (struct sockaddr
*) &saddr
, &saddrlen
);
2196 if (socktemp
== INVALID_SOCKET
)
2198 sock_geterrmsg(errbuf
, PCAP_ERRBUF_SIZE
,
2200 rpcapd_log(LOGPRIO_ERROR
, "Accept of data connection failed: %s",
2205 // Now that I accepted the connection, the server socket is no longer needed
2206 sock_close(session
->sockdata
, NULL
, 0);
2207 session
->sockdata
= socktemp
;
2214 /* In both active or passive cases, wait for the client to initiate the
2215 * TLS handshake. Yes during that time the control socket will not be
2216 * served, but the same was true from the above call to accept(). */
2217 ssl
= ssl_promotion(1, session
->sockdata
, errbuf
, PCAP_ERRBUF_SIZE
);
2220 rpcapd_log(LOGPRIO_ERROR
, "TLS handshake failed: %s", errbuf
);
2225 session
->data_ssl
= ssl
;
2227 // Now we have to create a new thread to receive packets
2229 session
->thread
= (HANDLE
)_beginthreadex(NULL
, 0, daemon_thrdatamain
,
2230 (void *) session
, 0, NULL
);
2231 if (session
->thread
== 0)
2233 snprintf(errbuf
, PCAP_ERRBUF_SIZE
, "Error creating the data thread");
2237 ret
= pthread_create(&session
->thread
, NULL
, daemon_thrdatamain
,
2241 pcapint_fmt_errmsg_for_errno(errbuf
, PCAP_ERRBUF_SIZE
,
2242 ret
, "Error creating the data thread");
2246 session
->have_thread
= 1;
2248 // Check if all the data has been read; if not, discard the data in excess
2249 if (rpcapd_discard(pars
->sockctrl
, pars
->ssl
, plen
) == -1)
2252 *sessionp
= session
;
2257 // Not a fatal error, so send the client an error message and
2258 // keep serving client requests.
2263 freeaddrinfo(addrinfo
);
2267 session_close(session
);
2271 if (rpcap_senderror(pars
->sockctrl
, pars
->ssl
, ver
,
2272 PCAP_ERR_STARTCAPTURE
, errmsgbuf
, errbuf
) == -1)
2274 // That failed; log a message and give up.
2275 rpcapd_log(LOGPRIO_ERROR
, "Send to client failed: %s", errbuf
);
2279 // Check if all the data has been read; if not, discard the data in excess
2280 if (rpcapd_discard(pars
->sockctrl
, pars
->ssl
, plen
) == -1)
2290 // Fatal network error, so don't try to communicate with
2291 // the client, just give up.
2297 session_close(session
);
2305 daemon_msg_endcap_req(uint8_t ver
, struct daemon_slpars
*pars
,
2306 struct session
*session
)
2308 char errbuf
[PCAP_ERRBUF_SIZE
]; // buffer for network errors
2309 struct rpcap_header header
;
2311 session_close(session
);
2313 rpcap_createhdr(&header
, ver
, RPCAP_MSG_ENDCAP_REPLY
, 0, 0);
2315 if (sock_send(pars
->sockctrl
, pars
->ssl
, (char *) &header
, sizeof(struct rpcap_header
), errbuf
, PCAP_ERRBUF_SIZE
) == -1)
2317 // That failed; log a message and give up.
2318 rpcapd_log(LOGPRIO_ERROR
, "Send to client failed: %s", errbuf
);
2326 // We impose a limit on the filter program size, so that, on Windows,
2327 // where there's only one server process with multiple threads, it's
2328 // harder to eat all the server address space by sending larger filter
2329 // programs. (This isn't an issue on UN*X, where there are multiple
2330 // server processes, one per client connection.)
2332 // We pick a value that limits each filter to 64K; that value is twice
2333 // the in-kernel limit for Linux and 16 times the in-kernel limit for
2336 // It also prevents an overflow on 32-bit platforms when calculating
2337 // the total size of the filter program. (It's not an issue on 64-bit
2338 // platforms with a 64-bit size_t, as the filter size is 32 bits.)
2340 #define RPCAP_BPF_MAXINSNS 8192
2343 daemon_unpackapplyfilter(PCAP_SOCKET sockctrl
, SSL
*ctrl_ssl
, struct session
*session
, uint32_t *plenp
, char *errmsgbuf
)
2346 struct rpcap_filter filter
;
2347 struct rpcap_filterbpf_insn insn
;
2348 struct bpf_insn
*bf_insn
;
2349 struct bpf_program bf_prog
;
2352 status
= rpcapd_recv(sockctrl
, ctrl_ssl
, (char *) &filter
,
2353 sizeof(struct rpcap_filter
), plenp
, errmsgbuf
);
2363 bf_prog
.bf_len
= ntohl(filter
.nitems
);
2365 if (ntohs(filter
.filtertype
) != RPCAP_UPDATEFILTER_BPF
)
2367 snprintf(errmsgbuf
, PCAP_ERRBUF_SIZE
, "Only BPF/NPF filters are currently supported");
2371 if (bf_prog
.bf_len
> RPCAP_BPF_MAXINSNS
)
2373 snprintf(errmsgbuf
, PCAP_ERRBUF_SIZE
,
2374 "Filter program is larger than the maximum size of %d instructions",
2375 RPCAP_BPF_MAXINSNS
);
2378 bf_insn
= (struct bpf_insn
*) malloc (sizeof(struct bpf_insn
) * bf_prog
.bf_len
);
2379 if (bf_insn
== NULL
)
2381 pcapint_fmt_errmsg_for_errno(errmsgbuf
, PCAP_ERRBUF_SIZE
,
2382 errno
, "malloc() failed");
2386 bf_prog
.bf_insns
= bf_insn
;
2388 for (i
= 0; i
< bf_prog
.bf_len
; i
++)
2390 status
= rpcapd_recv(sockctrl
, ctrl_ssl
, (char *) &insn
,
2391 sizeof(struct rpcap_filterbpf_insn
), plenp
, errmsgbuf
);
2401 bf_insn
->code
= ntohs(insn
.code
);
2402 bf_insn
->jf
= insn
.jf
;
2403 bf_insn
->jt
= insn
.jt
;
2404 bf_insn
->k
= ntohl(insn
.k
);
2410 // XXX - pcap_setfilter() should do the validation for us.
2412 if (bpf_validate(bf_prog
.bf_insns
, bf_prog
.bf_len
) == 0)
2414 snprintf(errmsgbuf
, PCAP_ERRBUF_SIZE
, "The filter contains bogus instructions");
2418 if (pcap_setfilter(session
->fp
, &bf_prog
))
2420 snprintf(errmsgbuf
, PCAP_ERRBUF_SIZE
, "RPCAP error: %s", pcap_geterr(session
->fp
));
2428 daemon_msg_updatefilter_req(uint8_t ver
, struct daemon_slpars
*pars
,
2429 struct session
*session
, uint32_t plen
)
2431 char errbuf
[PCAP_ERRBUF_SIZE
];
2432 char errmsgbuf
[PCAP_ERRBUF_SIZE
]; // buffer for errors to send to the client
2433 int ret
; // status of daemon_unpackapplyfilter()
2434 struct rpcap_header header
; // keeps the answer to the updatefilter command
2436 ret
= daemon_unpackapplyfilter(pars
->sockctrl
, pars
->ssl
, session
, &plen
, errmsgbuf
);
2439 // Fatal error. A message has been logged; just give up.
2444 // Non-fatal error. Send an error reply to the client.
2448 // Check if all the data has been read; if not, discard the data in excess
2449 if (rpcapd_discard(pars
->sockctrl
, pars
->ssl
, plen
) == -1)
2455 // A response is needed, otherwise the other host does not know that everything went well
2456 rpcap_createhdr(&header
, ver
, RPCAP_MSG_UPDATEFILTER_REPLY
, 0, 0);
2458 if (sock_send(pars
->sockctrl
, pars
->ssl
, (char *) &header
, sizeof (struct rpcap_header
), errbuf
, PCAP_ERRBUF_SIZE
))
2460 // That failed; log a message and give up.
2461 rpcapd_log(LOGPRIO_ERROR
, "Send to client failed: %s", errbuf
);
2468 if (rpcapd_discard(pars
->sockctrl
, pars
->ssl
, plen
) == -1)
2472 rpcap_senderror(pars
->sockctrl
, pars
->ssl
, ver
, PCAP_ERR_UPDATEFILTER
,
2479 \brief Received the sampling parameters from remote host and it stores in the pcap_t structure.
2482 daemon_msg_setsampling_req(uint8_t ver
, struct daemon_slpars
*pars
, uint32_t plen
,
2483 struct rpcap_sampling
*samp_param
)
2485 char errbuf
[PCAP_ERRBUF_SIZE
]; // buffer for network errors
2486 char errmsgbuf
[PCAP_ERRBUF_SIZE
];
2487 struct rpcap_header header
;
2488 struct rpcap_sampling rpcap_samp
;
2491 status
= rpcapd_recv(pars
->sockctrl
, pars
->ssl
, (char *) &rpcap_samp
, sizeof(struct rpcap_sampling
), &plen
, errmsgbuf
);
2501 // Save these settings in the pcap_t
2502 samp_param
->method
= rpcap_samp
.method
;
2503 samp_param
->value
= ntohl(rpcap_samp
.value
);
2505 // A response is needed, otherwise the other host does not know that everything went well
2506 rpcap_createhdr(&header
, ver
, RPCAP_MSG_SETSAMPLING_REPLY
, 0, 0);
2508 if (sock_send(pars
->sockctrl
, pars
->ssl
, (char *) &header
, sizeof (struct rpcap_header
), errbuf
, PCAP_ERRBUF_SIZE
) == -1)
2510 // That failed; log a message and give up.
2511 rpcapd_log(LOGPRIO_ERROR
, "Send to client failed: %s", errbuf
);
2515 if (rpcapd_discard(pars
->sockctrl
, pars
->ssl
, plen
) == -1)
2523 if (rpcap_senderror(pars
->sockctrl
, pars
->ssl
, ver
, PCAP_ERR_SETSAMPLING
,
2524 errmsgbuf
, errbuf
) == -1)
2526 // That failed; log a message and give up.
2527 rpcapd_log(LOGPRIO_ERROR
, "Send to client failed: %s", errbuf
);
2531 // Check if all the data has been read; if not, discard the data in excess
2532 if (rpcapd_discard(pars
->sockctrl
, pars
->ssl
, plen
) == -1)
2541 daemon_msg_stats_req(uint8_t ver
, struct daemon_slpars
*pars
,
2542 struct session
*session
, uint32_t plen
, struct pcap_stat
*stats
,
2543 unsigned int svrcapt
)
2545 char errbuf
[PCAP_ERRBUF_SIZE
]; // buffer for network errors
2546 char errmsgbuf
[PCAP_ERRBUF_SIZE
]; // buffer for errors to send to the client
2547 char sendbuf
[RPCAP_NETBUF_SIZE
]; // temporary buffer in which data to be sent is buffered
2548 int sendbufidx
= 0; // index which keeps the number of bytes currently buffered
2549 struct rpcap_stats
*netstats
; // statistics sent on the network
2551 // Checks that the header does not contain other data; if so, discard it
2552 if (rpcapd_discard(pars
->sockctrl
, pars
->ssl
, plen
) == -1)
2558 if (sock_bufferize(NULL
, sizeof(struct rpcap_header
), NULL
,
2559 &sendbufidx
, RPCAP_NETBUF_SIZE
, SOCKBUF_CHECKONLY
, errmsgbuf
, PCAP_ERRBUF_SIZE
) == -1)
2562 rpcap_createhdr((struct rpcap_header
*) sendbuf
, ver
,
2563 RPCAP_MSG_STATS_REPLY
, 0, (uint16_t) sizeof(struct rpcap_stats
));
2565 netstats
= (struct rpcap_stats
*) &sendbuf
[sendbufidx
];
2567 if (sock_bufferize(NULL
, sizeof(struct rpcap_stats
), NULL
,
2568 &sendbufidx
, RPCAP_NETBUF_SIZE
, SOCKBUF_CHECKONLY
, errmsgbuf
, PCAP_ERRBUF_SIZE
) == -1)
2571 if (session
&& session
->fp
)
2573 if (pcap_stats(session
->fp
, stats
) == -1)
2575 snprintf(errmsgbuf
, PCAP_ERRBUF_SIZE
, "%s", pcap_geterr(session
->fp
));
2579 netstats
->ifdrop
= htonl(stats
->ps_ifdrop
);
2580 netstats
->ifrecv
= htonl(stats
->ps_recv
);
2581 netstats
->krnldrop
= htonl(stats
->ps_drop
);
2582 netstats
->svrcapt
= htonl(session
->TotCapt
);
2586 // We have to keep compatibility with old applications,
2587 // which ask for statistics also when the capture has
2589 netstats
->ifdrop
= htonl(stats
->ps_ifdrop
);
2590 netstats
->ifrecv
= htonl(stats
->ps_recv
);
2591 netstats
->krnldrop
= htonl(stats
->ps_drop
);
2592 netstats
->svrcapt
= htonl(svrcapt
);
2596 if (sock_send(pars
->sockctrl
, pars
->ssl
, sendbuf
, sendbufidx
, errbuf
, PCAP_ERRBUF_SIZE
) == -1)
2598 rpcapd_log(LOGPRIO_ERROR
, "Send to client failed: %s", errbuf
);
2605 rpcap_senderror(pars
->sockctrl
, pars
->ssl
, ver
, PCAP_ERR_GETSTATS
,
2611 static unsigned __stdcall
2615 daemon_thrdatamain(void *ptr
)
2617 char errbuf
[PCAP_ERRBUF_SIZE
+ 1]; // error buffer
2618 struct session
*session
; // pointer to the struct session for this session
2619 int retval
; // general variable used to keep the return value of other functions
2620 struct rpcap_pkthdr
*net_pkt_header
;// header of the packet
2621 struct pcap_pkthdr
*pkt_header
; // pointer to the buffer that contains the header of the current packet
2622 u_char
*pkt_data
; // pointer to the buffer that contains the current packet
2623 size_t sendbufsize
; // size for the send buffer
2624 char *sendbuf
; // temporary buffer in which data to be sent is buffered
2625 int sendbufidx
; // index which keeps the number of bytes currently buffered
2628 sigset_t sigusr1
; // signal set with just SIGUSR1
2631 session
= (struct session
*) ptr
;
2633 session
->TotCapt
= 0; // counter which is incremented each time a packet is received
2635 // Initialize errbuf
2636 memset(errbuf
, 0, sizeof(errbuf
));
2639 // We need a buffer large enough to hold a buffer large enough
2640 // for a maximum-size packet for this pcap_t.
2642 if (pcap_snapshot(session
->fp
) < 0)
2645 // The snapshot length is negative.
2646 // This "should not happen".
2648 rpcapd_log(LOGPRIO_ERROR
,
2649 "Unable to allocate the buffer for this child thread: snapshot length of %d is negative",
2650 pcap_snapshot(session
->fp
));
2651 sendbuf
= NULL
; // we can't allocate a buffer, so nothing to free
2655 // size_t is unsigned, and the result of pcap_snapshot() is signed;
2656 // on no platform that we support is int larger than size_t.
2657 // This means that, unless the extra information we prepend to
2658 // a maximum-sized packet is impossibly large, the sum of the
2659 // snapshot length and the size of that extra information will
2662 // So we don't need to make sure that sendbufsize will overflow.
2664 // However, we *do* need to make sure its value fits in an int,
2665 // because sock_send() can't send more than INT_MAX bytes (it could
2666 // do so on 64-bit UN*Xes, but can't do so on Windows, not even
2667 // 64-bit Windows, as the send() buffer size argument is an int
2670 sendbufsize
= sizeof(struct rpcap_header
) + sizeof(struct rpcap_pkthdr
) + pcap_snapshot(session
->fp
);
2671 if (sendbufsize
> INT_MAX
)
2673 rpcapd_log(LOGPRIO_ERROR
,
2674 "Buffer size for this child thread would be larger than %d",
2676 sendbuf
= NULL
; // we haven't allocated a buffer, so nothing to free
2679 sendbuf
= (char *) malloc (sendbufsize
);
2680 if (sendbuf
== NULL
)
2682 rpcapd_log(LOGPRIO_ERROR
,
2683 "Unable to allocate the buffer for this child thread");
2689 // Set the signal set to include just SIGUSR1, and block that
2690 // signal; we only want it unblocked when we're reading
2691 // packets - we dn't want any other system calls, such as
2692 // ones being used to send to the client or to log messages,
2693 // to be interrupted.
2695 sigemptyset(&sigusr1
);
2696 sigaddset(&sigusr1
, SIGUSR1
);
2697 pthread_sigmask(SIG_BLOCK
, &sigusr1
, NULL
);
2700 // Retrieve the packets
2705 // Unblock SIGUSR1 while we might be waiting for packets.
2707 pthread_sigmask(SIG_UNBLOCK
, &sigusr1
, NULL
);
2709 retval
= pcap_next_ex(session
->fp
, &pkt_header
, (const u_char
**) &pkt_data
); // cast to avoid a compiler warning
2712 // Now block it again.
2714 pthread_sigmask(SIG_BLOCK
, &sigusr1
, NULL
);
2718 if (retval
== 0) // Read timeout elapsed
2723 // Bufferize the general header
2724 if (sock_bufferize(NULL
, sizeof(struct rpcap_header
), NULL
,
2725 &sendbufidx
, (int)sendbufsize
, SOCKBUF_CHECKONLY
, errbuf
,
2726 PCAP_ERRBUF_SIZE
) == -1)
2728 rpcapd_log(LOGPRIO_ERROR
,
2729 "sock_bufferize() error sending packet message: %s",
2734 rpcap_createhdr((struct rpcap_header
*) sendbuf
,
2735 session
->protocol_version
, RPCAP_MSG_PACKET
, 0,
2736 (uint16_t) (sizeof(struct rpcap_pkthdr
) + pkt_header
->caplen
));
2738 net_pkt_header
= (struct rpcap_pkthdr
*) &sendbuf
[sendbufidx
];
2740 // Bufferize the pkt header
2741 if (sock_bufferize(NULL
, sizeof(struct rpcap_pkthdr
), NULL
,
2742 &sendbufidx
, (int)sendbufsize
, SOCKBUF_CHECKONLY
, errbuf
,
2743 PCAP_ERRBUF_SIZE
) == -1)
2745 rpcapd_log(LOGPRIO_ERROR
,
2746 "sock_bufferize() error sending packet message: %s",
2751 net_pkt_header
->caplen
= htonl(pkt_header
->caplen
);
2752 net_pkt_header
->len
= htonl(pkt_header
->len
);
2753 net_pkt_header
->npkt
= htonl(++(session
->TotCapt
));
2755 // This protocol needs to be updated with a new version
2756 // before 2038-01-19 03:14:07 UTC.
2758 net_pkt_header
->timestamp_sec
= htonl((uint32_t)pkt_header
->ts
.tv_sec
);
2759 net_pkt_header
->timestamp_usec
= htonl((uint32_t)pkt_header
->ts
.tv_usec
);
2761 // Bufferize the pkt data
2762 if (sock_bufferize((char *) pkt_data
, pkt_header
->caplen
,
2763 sendbuf
, &sendbufidx
, (int)sendbufsize
, SOCKBUF_BUFFERIZE
,
2764 errbuf
, PCAP_ERRBUF_SIZE
) == -1)
2766 rpcapd_log(LOGPRIO_ERROR
,
2767 "sock_bufferize() error sending packet message: %s",
2773 // If the client dropped the connection, don't report an
2774 // error, just quit.
2775 status
= sock_send(session
->sockdata
, session
->data_ssl
, sendbuf
, sendbufidx
, errbuf
, PCAP_ERRBUF_SIZE
);
2781 // Error other than "client closed the
2782 // connection out from under us"; report
2785 rpcapd_log(LOGPRIO_ERROR
,
2786 "Send of packet to client failed: %s",
2791 // Give up in either case.
2797 if (retval
< 0 && retval
!= PCAP_ERROR_BREAK
)
2800 // Failed with an error other than "we were told to break
2801 // out of the loop".
2803 // The latter just means that the client told us to stop
2804 // capturing, so there's no error to report.
2806 snprintf(errbuf
, PCAP_ERRBUF_SIZE
, "Error reading the packets: %s", pcap_geterr(session
->fp
));
2807 rpcap_senderror(session
->sockctrl
, session
->ctrl_ssl
, session
->protocol_version
,
2808 PCAP_ERR_READEX
, errbuf
, NULL
);
2813 // The main thread will clean up the session structure.
2822 // Do-nothing handler for SIGUSR1; the sole purpose of SIGUSR1 is to
2823 // interrupt the data thread if it's blocked in a system call waiting
2824 // for packets to arrive.
2826 static void noop_handler(int sign _U_
)
2832 \brief It serializes a network address.
2834 It accepts a 'sockaddr_storage' structure as input, and it converts it appropriately into a format
2835 that can be used to be sent on the network. Basically, it applies all the hton()
2836 conversion required to the input variable.
2838 \param sockaddrin a 'sockaddr_storage' pointer to the variable that has to be
2839 serialized. This variable can be both a 'sockaddr_in' and 'sockaddr_in6'.
2841 \param sockaddrout an 'rpcap_sockaddr' pointer to the variable that will contain
2842 the serialized data. This variable has to be allocated by the user.
2844 \warning This function supports only AF_INET and AF_INET6 address families.
2847 daemon_seraddr(struct sockaddr_storage
*sockaddrin
, struct rpcap_sockaddr
*sockaddrout
)
2849 memset(sockaddrout
, 0, sizeof(struct sockaddr_storage
));
2851 // There can be the case in which the sockaddrin is not available
2852 if (sockaddrin
== NULL
) return;
2854 // Warning: we support only AF_INET and AF_INET6
2856 // Note: as noted above, the output structures are not
2857 // neatly aligned on 4-byte boundaries, so we must fill
2858 // in an aligned structure and then copy it to the output
2859 // buffer with memcpy().
2860 switch (sockaddrin
->ss_family
)
2864 struct sockaddr_in
*sockaddrin_ipv4
;
2865 struct rpcap_sockaddr_in sockaddrout_ipv4
;
2867 sockaddrin_ipv4
= (struct sockaddr_in
*) sockaddrin
;
2869 sockaddrout_ipv4
.family
= htons(RPCAP_AF_INET
);
2870 sockaddrout_ipv4
.port
= htons(sockaddrin_ipv4
->sin_port
);
2871 memcpy(&sockaddrout_ipv4
.addr
, &sockaddrin_ipv4
->sin_addr
, sizeof(sockaddrout_ipv4
.addr
));
2872 memset(sockaddrout_ipv4
.zero
, 0, sizeof(sockaddrout_ipv4
.zero
));
2873 memcpy(sockaddrout
, &sockaddrout_ipv4
, sizeof(struct rpcap_sockaddr_in
));
2880 struct sockaddr_in6
*sockaddrin_ipv6
;
2881 struct rpcap_sockaddr_in6 sockaddrout_ipv6
;
2883 sockaddrin_ipv6
= (struct sockaddr_in6
*) sockaddrin
;
2885 sockaddrout_ipv6
.family
= htons(RPCAP_AF_INET6
);
2886 sockaddrout_ipv6
.port
= htons(sockaddrin_ipv6
->sin6_port
);
2887 sockaddrout_ipv6
.flowinfo
= htonl(sockaddrin_ipv6
->sin6_flowinfo
);
2888 memcpy(&sockaddrout_ipv6
.addr
, &sockaddrin_ipv6
->sin6_addr
, sizeof(sockaddrout_ipv6
.addr
));
2889 sockaddrout_ipv6
.scope_id
= htonl(sockaddrin_ipv6
->sin6_scope_id
);
2890 memcpy(sockaddrout
, &sockaddrout_ipv6
, sizeof(struct rpcap_sockaddr_in6
));
2899 \brief Suspends a thread for secs seconds.
2901 void sleep_secs(int secs
)
2903 #ifndef FUZZING_BUILD_MODE_UNSAFE_FOR_PRODUCTION
2907 unsigned secs_remaining
;
2911 secs_remaining
= secs
;
2912 while (secs_remaining
!= 0)
2913 secs_remaining
= sleep(secs_remaining
);
2919 * Read the header of a message.
2922 rpcapd_recv_msg_header(PCAP_SOCKET sock
, SSL
*ssl
, struct rpcap_header
*headerp
)
2925 char errbuf
[PCAP_ERRBUF_SIZE
]; // buffer for network errors
2927 nread
= sock_recv(sock
, ssl
, (char *) headerp
, sizeof(struct rpcap_header
),
2928 SOCK_RECEIVEALL_YES
|SOCK_EOF_ISNT_ERROR
, errbuf
, PCAP_ERRBUF_SIZE
);
2932 rpcapd_log(LOGPRIO_ERROR
, "Read from client failed: %s", errbuf
);
2937 // Immediate EOF; that's treated like a close message.
2940 headerp
->plen
= ntohl(headerp
->plen
);
2945 * Read data from a message.
2946 * If we're trying to read more data than remains, puts an error
2947 * message into errmsgbuf and returns -2. Otherwise, tries to read
2948 * the data and, if that succeeds, subtracts the amount read from
2949 * the number of bytes of data that remains.
2950 * Returns 0 on success, logs a message and returns -1 on a network
2954 rpcapd_recv(PCAP_SOCKET sock
, SSL
*ssl
, char *buffer
, size_t toread
, uint32_t *plen
, char *errmsgbuf
)
2957 char errbuf
[PCAP_ERRBUF_SIZE
]; // buffer for network errors
2961 // Tell the client and continue.
2962 snprintf(errmsgbuf
, PCAP_ERRBUF_SIZE
, "Message payload is too short");
2965 nread
= sock_recv(sock
, ssl
, buffer
, toread
,
2966 SOCK_RECEIVEALL_YES
|SOCK_EOF_IS_ERROR
, errbuf
, PCAP_ERRBUF_SIZE
);
2969 rpcapd_log(LOGPRIO_ERROR
, "Read from client failed: %s", errbuf
);
2977 * Discard data from a connection.
2978 * Mostly used to discard wrong-sized messages.
2979 * Returns 0 on success, logs a message and returns -1 on a network
2983 rpcapd_discard(PCAP_SOCKET sock
, SSL
*ssl
, uint32_t len
)
2985 char errbuf
[PCAP_ERRBUF_SIZE
+ 1]; // keeps the error string, prior to be printed
2989 if (sock_discard(sock
, ssl
, len
, errbuf
, PCAP_ERRBUF_SIZE
) == -1)
2992 rpcapd_log(LOGPRIO_ERROR
, "Read from client failed: %s", errbuf
);
3000 // Shut down any packet-capture thread associated with the session,
3001 // close the SSL handle for the data socket if we have one, close
3002 // the data socket if we have one, and close the underlying packet
3003 // capture handle if we have one.
3005 // We do not, of course, touch the controlling socket that's also
3006 // copied into the session, as the service loop might still use it.
3008 static void session_close(struct session
*session
)
3010 if (session
->have_thread
)
3013 // Tell the data connection thread main capture loop to
3014 // break out of that loop.
3016 // This may be sufficient to wake up a blocked thread,
3017 // but it's not guaranteed to be sufficient.
3019 pcap_breakloop(session
->fp
);
3023 // Set the event on which a read would block, so that,
3024 // if it's currently blocked waiting for packets to
3025 // arrive, it'll wake up, so it can see the "break
3026 // out of the loop" indication. (pcap_breakloop()
3027 // might do this, but older versions don't. Setting
3028 // it twice should, at worst, cause an extra wakeup,
3029 // which shouldn't be a problem.)
3031 // XXX - what about modules other than NPF?
3033 SetEvent(pcap_getevent(session
->fp
));
3036 // Wait for the thread to exit, so we don't close
3037 // sockets out from under it.
3039 // XXX - have a timeout, so we don't wait forever?
3041 WaitForSingleObject(session
->thread
, INFINITE
);
3044 // Release the thread handle, as we're done with
3047 CloseHandle(session
->thread
);
3048 session
->have_thread
= 0;
3049 session
->thread
= INVALID_HANDLE_VALUE
;
3052 // Send a SIGUSR1 signal to the thread, so that, if
3053 // it's currently blocked waiting for packets to arrive,
3054 // it'll wake up (we've turned off SA_RESTART for
3055 // SIGUSR1, so that the system call in which it's blocked
3056 // should return EINTR rather than restarting).
3058 pthread_kill(session
->thread
, SIGUSR1
);
3061 // Wait for the thread to exit, so we don't close
3062 // sockets out from under it.
3064 // XXX - have a timeout, so we don't wait forever?
3066 pthread_join(session
->thread
, NULL
);
3067 session
->have_thread
= 0;
3068 memset(&session
->thread
, 0, sizeof(session
->thread
));
3073 if (session
->data_ssl
)
3075 // Finish using the SSL handle for the socket.
3076 // This must be done *before* the socket is closed.
3077 ssl_finish(session
->data_ssl
);
3078 session
->data_ssl
= NULL
;
3082 if (session
->sockdata
!= INVALID_SOCKET
)
3084 sock_close(session
->sockdata
, NULL
, 0);
3085 session
->sockdata
= INVALID_SOCKET
;
3090 pcap_close(session
->fp
);
3096 // Check whether a capture source string is a URL or not.
3097 // This includes URLs that refer to a local device; a scheme, followed
3098 // by ://, followed by *another* scheme and ://, is just silly, and
3099 // anybody who supplies that will get an error.
3102 is_url(const char *source
)
3109 * URI = scheme ":" hier-part [ "?" query ] [ "#" fragment ]
3111 * hier-part = "//" authority path-abempty
3116 * authority = [ userinfo "@" ] host [ ":" port ]
3118 * userinfo = *( unreserved / pct-encoded / sub-delims / ":" )
3120 * Step 1: look for the ":" at the end of the scheme.
3121 * A colon in the source is *NOT* sufficient to indicate that
3122 * this is a URL, as interface names on some platforms might
3123 * include colons (e.g., I think some Solaris interfaces
3126 colonp
= strchr(source
, ':');
3130 * The source is the device to open. It's not a URL.
3136 * All schemes must have "//" after them, i.e. we only support
3137 * hier-part = "//" authority path-abempty, not
3138 * hier-part = path-absolute
3139 * hier-part = path-rootless
3140 * hier-part = path-empty
3142 * We need that in order to distinguish between a local device
3143 * name that happens to contain a colon and a URI.
3145 if (strncmp(colonp
+ 1, "//", 2) != 0)
3148 * The source is the device to open. It's not a URL.