aboutsummaryrefslogtreecommitdiff
path: root/rpcapd/daemon.c
diff options
context:
space:
mode:
Diffstat (limited to 'rpcapd/daemon.c')
-rw-r--r--rpcapd/daemon.c166
1 files changed, 94 insertions, 72 deletions
diff --git a/rpcapd/daemon.c b/rpcapd/daemon.c
index 362f4b9b..0f3dd271 100644
--- a/rpcapd/daemon.c
+++ b/rpcapd/daemon.c
@@ -113,7 +113,7 @@ struct session {
SOCKET sockctrl;
SOCKET sockdata;
SSL *ctrl_ssl, *data_ssl; // optional SSL handlers for sockctrl and sockdata.
- uint8 protocol_version;
+ uint8_t protocol_version;
pcap_t *fp;
unsigned int TotCapt;
int have_thread;
@@ -125,31 +125,31 @@ struct session {
};
// Locally defined functions
-static int daemon_msg_err(SOCKET sockctrl, SSL *, uint32 plen);
-static int daemon_msg_auth_req(struct daemon_slpars *pars, uint32 plen);
+static int daemon_msg_err(SOCKET sockctrl, SSL *, uint32_t plen);
+static int daemon_msg_auth_req(struct daemon_slpars *pars, uint32_t plen);
static int daemon_AuthUserPwd(char *username, char *password, char *errbuf);
-static int daemon_msg_findallif_req(uint8 ver, struct daemon_slpars *pars,
- uint32 plen);
+static int daemon_msg_findallif_req(uint8_t ver, struct daemon_slpars *pars,
+ uint32_t plen);
-static int daemon_msg_open_req(uint8 ver, struct daemon_slpars *pars,
- uint32 plen, char *source, size_t sourcelen);
-static int daemon_msg_startcap_req(uint8 ver, struct daemon_slpars *pars,
- uint32 plen, char *source, struct session **sessionp,
+static int daemon_msg_open_req(uint8_t ver, struct daemon_slpars *pars,
+ uint32_t plen, char *source, size_t sourcelen);
+static int daemon_msg_startcap_req(uint8_t ver, struct daemon_slpars *pars,
+ uint32_t plen, char *source, char *data_port, struct session **sessionp,
struct rpcap_sampling *samp_param, int uses_ssl);
-static int daemon_msg_endcap_req(uint8 ver, struct daemon_slpars *pars,
+static int daemon_msg_endcap_req(uint8_t ver, struct daemon_slpars *pars,
struct session *session);
-static int daemon_msg_updatefilter_req(uint8 ver, struct daemon_slpars *pars,
- struct session *session, uint32 plen);
-static int daemon_unpackapplyfilter(SOCKET sockctrl, SSL *, struct session *session, uint32 *plenp, char *errbuf);
+static int daemon_msg_updatefilter_req(uint8_t ver, struct daemon_slpars *pars,
+ struct session *session, uint32_t plen);
+static int daemon_unpackapplyfilter(SOCKET sockctrl, SSL *, struct session *session, uint32_t *plenp, char *errbuf);
-static int daemon_msg_stats_req(uint8 ver, struct daemon_slpars *pars,
- struct session *session, uint32 plen, struct pcap_stat *stats,
+static int daemon_msg_stats_req(uint8_t ver, struct daemon_slpars *pars,
+ struct session *session, uint32_t plen, struct pcap_stat *stats,
unsigned int svrcapt);
-static int daemon_msg_setsampling_req(uint8 ver, struct daemon_slpars *pars,
- uint32 plen, struct rpcap_sampling *samp_param);
+static int daemon_msg_setsampling_req(uint8_t ver, struct daemon_slpars *pars,
+ uint32_t plen, struct rpcap_sampling *samp_param);
static void daemon_seraddr(struct sockaddr_storage *sockaddrin, struct rpcap_sockaddr *sockaddrout);
#ifdef _WIN32
@@ -160,8 +160,8 @@ static void noop_handler(int sign);
#endif
static int rpcapd_recv_msg_header(SOCKET sock, SSL *, struct rpcap_header *headerp);
-static int rpcapd_recv(SOCKET sock, SSL *, char *buffer, size_t toread, uint32 *plen, char *errmsgbuf);
-static int rpcapd_discard(SOCKET sock, SSL *, uint32 len);
+static int rpcapd_recv(SOCKET sock, SSL *, char *buffer, size_t toread, uint32_t *plen, char *errmsgbuf);
+static int rpcapd_discard(SOCKET sock, SSL *, uint32_t len);
static void session_close(struct session *);
//
@@ -169,14 +169,14 @@ static void session_close(struct session *);
// the client, in case we aren't doing TLS but they are.
//
struct tls_record_header {
- uint8 type; // ContentType - will be 22, for Handshake
- uint8 version_major; // TLS protocol major version
- uint8 version_injor; // TLS protocol minor version
+ uint8_t type; // ContentType - will be 22, for Handshake
+ uint8_t version_major; // TLS protocol major version
+ uint8_t version_injor; // TLS protocol minor version
// This is *not* aligned on a 2-byte boundary; we just
// declare it as two bytes. Don't assume any particular
// compiler's mechanism for saying "packed"!
- uint8 length_hi; // Upper 8 bits of payload length
- uint8 length_lo; // Low 8 bits of payload length
+ uint8_t length_hi; // Upper 8 bits of payload length
+ uint8_t length_lo; // Low 8 bits of payload length
};
#define TLS_RECORD_HEADER_LEN 5 // Don't use sizeof in case it's padded
@@ -188,8 +188,8 @@ struct tls_record_header {
// TLS alert message.
//
struct tls_alert {
- uint8 alert_level;
- uint8 alert_description;
+ uint8_t alert_level;
+ uint8_t alert_description;
};
#define TLS_ALERT_LEN 2
@@ -212,9 +212,9 @@ static int is_url(const char *source);
int
daemon_serviceloop(SOCKET sockctrl, int isactive, char *passiveClients,
- int nullAuthAllowed, int uses_ssl)
+ int nullAuthAllowed, char *data_port, int uses_ssl)
{
- uint8 first_octet;
+ uint8_t first_octet;
struct tls_record_header tls_header;
struct tls_alert tls_alert;
struct daemon_slpars pars; // service loop parameters
@@ -224,7 +224,7 @@ daemon_serviceloop(SOCKET sockctrl, int isactive, char *passiveClients,
SSL *ssl = NULL;
int nrecv;
struct rpcap_header header; // RPCAP message general header
- uint32 plen; // payload length from header
+ uint32_t plen; // payload length from header
int authenticated = 0; // 1 if the client has successfully authenticated
char source[PCAP_BUF_SIZE+1]; // keeps the string that contains the interface to open
int got_source = 0; // 1 if we've gotten the source from an open request
@@ -449,7 +449,8 @@ daemon_serviceloop(SOCKET sockctrl, int isactive, char *passiveClients,
if (getpeername(pars.sockctrl, (struct sockaddr *)&from,
&fromlen) == -1)
{
- sock_geterror("getpeername()", errmsgbuf, PCAP_ERRBUF_SIZE);
+ sock_geterrmsg(errmsgbuf, PCAP_ERRBUF_SIZE,
+ "getpeername() failed");
if (rpcap_senderror(pars.sockctrl, pars.ssl, 0, PCAP_ERR_NETW, errmsgbuf, errbuf) == -1)
rpcapd_log(LOGPRIO_ERROR, "Send to client failed: %s", errbuf);
goto end;
@@ -523,7 +524,8 @@ daemon_serviceloop(SOCKET sockctrl, int isactive, char *passiveClients,
retval = select((int)pars.sockctrl + 1, &rfds, NULL, NULL, &tv);
if (retval == -1)
{
- sock_geterror("select() failed", errmsgbuf, PCAP_ERRBUF_SIZE);
+ sock_geterrmsg(errmsgbuf, PCAP_ERRBUF_SIZE,
+ "select() failed");
if (rpcap_senderror(pars.sockctrl, pars.ssl, 0, PCAP_ERR_NETW, errmsgbuf, errbuf) == -1)
rpcapd_log(LOGPRIO_ERROR, "Send to client failed: %s", errbuf);
goto end;
@@ -763,7 +765,8 @@ daemon_serviceloop(SOCKET sockctrl, int isactive, char *passiveClients,
#endif
if (retval == -1)
{
- sock_geterror("select() failed", errmsgbuf, PCAP_ERRBUF_SIZE);
+ sock_geterrmsg(errmsgbuf, PCAP_ERRBUF_SIZE,
+ "select() failed");
if (rpcap_senderror(pars.sockctrl, pars.ssl,
0, PCAP_ERR_NETW,
errmsgbuf, errbuf) == -1)
@@ -898,8 +901,8 @@ daemon_serviceloop(SOCKET sockctrl, int isactive, char *passiveClients,
}
if (daemon_msg_startcap_req(header.ver, &pars,
- plen, source, &session, &samp_param,
- uses_ssl) == -1)
+ plen, source, data_port, &session,
+ &samp_param, uses_ssl) == -1)
{
// Fatal error; a message has
// been logged, so just give up.
@@ -1135,7 +1138,7 @@ end:
* This handles the RPCAP_MSG_ERR message.
*/
static int
-daemon_msg_err(SOCKET sockctrl, SSL *ssl, uint32 plen)
+daemon_msg_err(SOCKET sockctrl, SSL *ssl, uint32_t plen)
{
char errbuf[PCAP_ERRBUF_SIZE];
char remote_errbuf[PCAP_ERRBUF_SIZE];
@@ -1214,7 +1217,7 @@ daemon_msg_err(SOCKET sockctrl, SSL *ssl, uint32 plen)
* unrecoverable error or for the authentication failure.
*/
static int
-daemon_msg_auth_req(struct daemon_slpars *pars, uint32 plen)
+daemon_msg_auth_req(struct daemon_slpars *pars, uint32_t plen)
{
char errbuf[PCAP_ERRBUF_SIZE]; // buffer for network errors
char errmsgbuf[PCAP_ERRBUF_SIZE]; // buffer for errors to send to the client
@@ -1258,7 +1261,7 @@ daemon_msg_auth_req(struct daemon_slpars *pars, uint32 plen)
case RPCAP_RMTAUTH_PWD:
{
char *username, *passwd;
- uint32 usernamelen, passwdlen;
+ uint32_t usernamelen, passwdlen;
usernamelen = ntohs(auth.slen1);
username = (char *) malloc (usernamelen + 1);
@@ -1368,11 +1371,16 @@ daemon_msg_auth_req(struct daemon_slpars *pars, uint32 plen)
goto error;
//
- // Indicate to our peer what versions we support.
+ // Indicate to our peer what versions we support and what our
+ // version of the byte-order magic is (which will tell the
+ // client whether our byte order differs from theirs, in which
+ // case they will need to byte-swap some fields in some
+ // link-layer types' headers).
//
memset(authreply, 0, sizeof(struct rpcap_authreply));
authreply->minvers = RPCAP_MIN_VERSION;
authreply->maxvers = RPCAP_MAX_VERSION;
+ authreply->byte_order_magic = RPCAP_BYTE_ORDER_MAGIC;
// Send the reply.
if (sock_send(pars->sockctrl, pars->ssl, sendbuf, sendbufidx, errbuf, PCAP_ERRBUF_SIZE) == -1)
@@ -1590,10 +1598,10 @@ daemon_AuthUserPwd(char *username, char *password, char *errbuf)
sizeof (errmsgbuf)); \
goto error; \
} \
- replylen += (uint32)(itemlen)
+ replylen += (uint32_t)(itemlen)
static int
-daemon_msg_findallif_req(uint8 ver, struct daemon_slpars *pars, uint32 plen)
+daemon_msg_findallif_req(uint8_t ver, struct daemon_slpars *pars, uint32_t plen)
{
char errbuf[PCAP_ERRBUF_SIZE]; // buffer for network errors
char errmsgbuf[PCAP_ERRBUF_SIZE]; // buffer for errors to send to the client
@@ -1602,8 +1610,8 @@ daemon_msg_findallif_req(uint8 ver, struct daemon_slpars *pars, uint32 plen)
pcap_if_t *alldevs = NULL; // pointer to the header of the interface chain
pcap_if_t *d; // temp pointer needed to scan the interface chain
struct pcap_addr *address; // pcap structure that keeps a network address of an interface
- uint32 replylen; // length of reply payload
- uint16 nif = 0; // counts the number of interface listed
+ uint32_t replylen; // length of reply payload
+ uint16_t nif = 0; // counts the number of interface listed
// Discard the rest of the message; there shouldn't be any payload.
if (rpcapd_discard(pars->sockctrl, pars->ssl, plen) == -1)
@@ -1700,7 +1708,7 @@ daemon_msg_findallif_req(uint8 ver, struct daemon_slpars *pars, uint32 plen)
// send the interface list
for (d = alldevs; d != NULL; d = d->next)
{
- uint16 lname, ldescr;
+ uint16_t lname, ldescr;
// Note: the findalldevs_if entries are *not* neatly
// aligned on 4-byte boundaries, because they're
@@ -1719,11 +1727,11 @@ daemon_msg_findallif_req(uint8 ver, struct daemon_slpars *pars, uint32 plen)
* fit in 16 bits.
*/
if (d->description)
- ldescr = (uint16) strlen(d->description);
+ ldescr = (uint16_t) strlen(d->description);
else
ldescr = 0;
if (d->name)
- lname = (uint16) strlen(d->name);
+ lname = (uint16_t) strlen(d->name);
else
lname = 0;
@@ -1843,7 +1851,7 @@ error:
to discard excess data in the message, if present)
*/
static int
-daemon_msg_open_req(uint8 ver, struct daemon_slpars *pars, uint32 plen,
+daemon_msg_open_req(uint8_t ver, struct daemon_slpars *pars, uint32_t plen,
char *source, size_t sourcelen)
{
char errbuf[PCAP_ERRBUF_SIZE]; // buffer for network errors
@@ -1882,7 +1890,7 @@ daemon_msg_open_req(uint8 ver, struct daemon_slpars *pars, uint32 plen,
// This is a fake open, since we do that only to get the needed parameters, then we close the device again
if ((fp = pcap_open_live(source,
1500 /* fake snaplen */,
- 0 /* no promis */,
+ 0 /* no promisc */,
1000 /* fake timeout */,
errmsgbuf)) == NULL)
goto error;
@@ -1945,8 +1953,8 @@ error:
to discard excess data in the message, if present)
*/
static int
-daemon_msg_startcap_req(uint8 ver, struct daemon_slpars *pars, uint32 plen,
- char *source, struct session **sessionp,
+daemon_msg_startcap_req(uint8_t ver, struct daemon_slpars *pars, uint32_t plen,
+ char *source, char *data_port, struct session **sessionp,
struct rpcap_sampling *samp_param _U_, int uses_ssl)
{
char errbuf[PCAP_ERRBUF_SIZE]; // buffer for network errors
@@ -2054,7 +2062,8 @@ daemon_msg_startcap_req(uint8 ver, struct daemon_slpars *pars, uint32 plen,
saddrlen = sizeof(struct sockaddr_storage);
if (getpeername(pars->sockctrl, (struct sockaddr *) &saddr, &saddrlen) == -1)
{
- sock_geterror("getpeername()", errmsgbuf, PCAP_ERRBUF_SIZE);
+ sock_geterrmsg(errmsgbuf, PCAP_ERRBUF_SIZE,
+ "getpeername() failed");
goto error;
}
@@ -2071,32 +2080,43 @@ daemon_msg_startcap_req(uint8 ver, struct daemon_slpars *pars, uint32 plen,
if (getnameinfo((struct sockaddr *) &saddr, saddrlen, peerhost,
sizeof(peerhost), NULL, 0, NI_NUMERICHOST))
{
- sock_geterror("getnameinfo()", errmsgbuf, PCAP_ERRBUF_SIZE);
+ sock_geterrmsg(errmsgbuf, PCAP_ERRBUF_SIZE,
+ "getnameinfo() failed");
goto error;
}
if (sock_initaddress(peerhost, portdata, &hints, &addrinfo, errmsgbuf, PCAP_ERRBUF_SIZE) == -1)
goto error;
- if ((session->sockdata = sock_open(addrinfo, SOCKOPEN_CLIENT, 0, errmsgbuf, PCAP_ERRBUF_SIZE)) == INVALID_SOCKET)
+ if ((session->sockdata = sock_open(peerhost, addrinfo, SOCKOPEN_CLIENT, 0, errmsgbuf, PCAP_ERRBUF_SIZE)) == INVALID_SOCKET)
goto error;
}
else // Data connection is opened by the client toward the server
{
hints.ai_flags = AI_PASSIVE;
- // Let's the server socket pick up a free network port for us
- if (sock_initaddress(NULL, "0", &hints, &addrinfo, errmsgbuf, PCAP_ERRBUF_SIZE) == -1)
- goto error;
+ if (data_port[0] != '\0')
+ {
+ // Use the specified network port
+ if (sock_initaddress(NULL, data_port, &hints, &addrinfo, errmsgbuf, PCAP_ERRBUF_SIZE) == -1)
+ goto error;
+ }
+ else
+ {
+ // Make the server socket pick up a free network port for us
+ if (sock_initaddress(NULL, NULL, &hints, &addrinfo, errmsgbuf, PCAP_ERRBUF_SIZE) == -1)
+ goto error;
+ }
- if ((session->sockdata = sock_open(addrinfo, SOCKOPEN_SERVER, 1 /* max 1 connection in queue */, errmsgbuf, PCAP_ERRBUF_SIZE)) == INVALID_SOCKET)
+ if ((session->sockdata = sock_open(NULL, addrinfo, SOCKOPEN_SERVER, 1 /* max 1 connection in queue */, errmsgbuf, PCAP_ERRBUF_SIZE)) == INVALID_SOCKET)
goto error;
// get the complete sockaddr structure used in the data connection
saddrlen = sizeof(struct sockaddr_storage);
if (getsockname(session->sockdata, (struct sockaddr *) &saddr, &saddrlen) == -1)
{
- sock_geterror("getsockname()", errmsgbuf, PCAP_ERRBUF_SIZE);
+ sock_geterrmsg(errmsgbuf, PCAP_ERRBUF_SIZE,
+ "getsockname() failed");
goto error;
}
@@ -2104,7 +2124,8 @@ daemon_msg_startcap_req(uint8 ver, struct daemon_slpars *pars, uint32 plen,
if (getnameinfo((struct sockaddr *) &saddr, saddrlen, NULL,
0, portdata, sizeof(portdata), NI_NUMERICSERV))
{
- sock_geterror("getnameinfo()", errmsgbuf, PCAP_ERRBUF_SIZE);
+ sock_geterrmsg(errmsgbuf, PCAP_ERRBUF_SIZE,
+ "getnameinfo() failed");
goto error;
}
}
@@ -2172,7 +2193,8 @@ daemon_msg_startcap_req(uint8 ver, struct daemon_slpars *pars, uint32 plen,
if (socktemp == INVALID_SOCKET)
{
- sock_geterror("accept()", errbuf, PCAP_ERRBUF_SIZE);
+ sock_geterrmsg(errbuf, PCAP_ERRBUF_SIZE,
+ "accept() failed");
rpcapd_log(LOGPRIO_ERROR, "Accept of data connection failed: %s",
errbuf);
goto error;
@@ -2278,7 +2300,7 @@ fatal_error:
}
static int
-daemon_msg_endcap_req(uint8 ver, struct daemon_slpars *pars,
+daemon_msg_endcap_req(uint8_t ver, struct daemon_slpars *pars,
struct session *session)
{
char errbuf[PCAP_ERRBUF_SIZE]; // buffer for network errors
@@ -2316,7 +2338,7 @@ daemon_msg_endcap_req(uint8 ver, struct daemon_slpars *pars,
#define RPCAP_BPF_MAXINSNS 8192
static int
-daemon_unpackapplyfilter(SOCKET sockctrl, SSL *ctrl_ssl, struct session *session, uint32 *plenp, char *errmsgbuf)
+daemon_unpackapplyfilter(SOCKET sockctrl, SSL *ctrl_ssl, struct session *session, uint32_t *plenp, char *errmsgbuf)
{
int status;
struct rpcap_filter filter;
@@ -2401,8 +2423,8 @@ daemon_unpackapplyfilter(SOCKET sockctrl, SSL *ctrl_ssl, struct session *session
}
static int
-daemon_msg_updatefilter_req(uint8 ver, struct daemon_slpars *pars,
- struct session *session, uint32 plen)
+daemon_msg_updatefilter_req(uint8_t ver, struct daemon_slpars *pars,
+ struct session *session, uint32_t plen)
{
char errbuf[PCAP_ERRBUF_SIZE];
char errmsgbuf[PCAP_ERRBUF_SIZE]; // buffer for errors to send to the client
@@ -2455,7 +2477,7 @@ error:
\brief Received the sampling parameters from remote host and it stores in the pcap_t structure.
*/
static int
-daemon_msg_setsampling_req(uint8 ver, struct daemon_slpars *pars, uint32 plen,
+daemon_msg_setsampling_req(uint8_t ver, struct daemon_slpars *pars, uint32_t plen,
struct rpcap_sampling *samp_param)
{
char errbuf[PCAP_ERRBUF_SIZE]; // buffer for network errors
@@ -2514,8 +2536,8 @@ error:
}
static int
-daemon_msg_stats_req(uint8 ver, struct daemon_slpars *pars,
- struct session *session, uint32 plen, struct pcap_stat *stats,
+daemon_msg_stats_req(uint8_t ver, struct daemon_slpars *pars,
+ struct session *session, uint32_t plen, struct pcap_stat *stats,
unsigned int svrcapt)
{
char errbuf[PCAP_ERRBUF_SIZE]; // buffer for network errors
@@ -2536,7 +2558,7 @@ daemon_msg_stats_req(uint8 ver, struct daemon_slpars *pars,
goto error;
rpcap_createhdr((struct rpcap_header *) sendbuf, ver,
- RPCAP_MSG_STATS_REPLY, 0, (uint16) sizeof(struct rpcap_stats));
+ RPCAP_MSG_STATS_REPLY, 0, (uint16_t) sizeof(struct rpcap_stats));
netstats = (struct rpcap_stats *) &sendbuf[sendbufidx];
@@ -2709,7 +2731,7 @@ daemon_thrdatamain(void *ptr)
rpcap_createhdr((struct rpcap_header *) sendbuf,
session->protocol_version, RPCAP_MSG_PACKET, 0,
- (uint16) (sizeof(struct rpcap_pkthdr) + pkt_header->caplen));
+ (uint16_t) (sizeof(struct rpcap_pkthdr) + pkt_header->caplen));
net_pkt_header = (struct rpcap_pkthdr *) &sendbuf[sendbufidx];
@@ -2731,8 +2753,8 @@ daemon_thrdatamain(void *ptr)
// This protocol needs to be updated with a new version
// before 2038-01-19 03:14:07 UTC.
//
- net_pkt_header->timestamp_sec = htonl((uint32)pkt_header->ts.tv_sec);
- net_pkt_header->timestamp_usec = htonl((uint32)pkt_header->ts.tv_usec);
+ net_pkt_header->timestamp_sec = htonl((uint32_t)pkt_header->ts.tv_sec);
+ net_pkt_header->timestamp_usec = htonl((uint32_t)pkt_header->ts.tv_usec);
// Bufferize the pkt data
if (sock_bufferize((char *) pkt_data, pkt_header->caplen,
@@ -2927,7 +2949,7 @@ rpcapd_recv_msg_header(SOCKET sock, SSL *ssl, struct rpcap_header *headerp)
* error.
*/
static int
-rpcapd_recv(SOCKET sock, SSL *ssl, char *buffer, size_t toread, uint32 *plen, char *errmsgbuf)
+rpcapd_recv(SOCKET sock, SSL *ssl, char *buffer, size_t toread, uint32_t *plen, char *errmsgbuf)
{
int nread;
char errbuf[PCAP_ERRBUF_SIZE]; // buffer for network errors
@@ -2956,7 +2978,7 @@ rpcapd_recv(SOCKET sock, SSL *ssl, char *buffer, size_t toread, uint32 *plen, ch
* error.
*/
static int
-rpcapd_discard(SOCKET sock, SSL *ssl, uint32 len)
+rpcapd_discard(SOCKET sock, SSL *ssl, uint32_t len)
{
char errbuf[PCAP_ERRBUF_SIZE + 1]; // keeps the error string, prior to be printed