summaryrefslogtreecommitdiff
path: root/rpcapd
diff options
context:
space:
mode:
authorGuy Harris <guy@alum.mit.edu>2019-01-30 21:09:08 -0800
committerGuy Harris <guy@alum.mit.edu>2019-01-30 21:09:08 -0800
commitdb93927485d0442d81a8010548f33ecd0ad24b27 (patch)
treef5fc7a86acee732771ccea2355c638e3440eb1d3 /rpcapd
parent98ac8fdcff2524469f9e19df72df5c1856f29941 (diff)
downloadlibpcap-db93927485d0442d81a8010548f33ecd0ad24b27.tar.gz
Redo protocol version negotiation.
During the authentication phase, which begins when the connection is made and ends when an authentication reply is received or the connection is closed, require that all request have a version number of 0, and accept version 0 in that phase, regardless of whether we support it once we're authenticated. That means the messages from the client will not be rejected any server with an "unsupported version" error, and also means we can distinguish between a plaintext request and a TLS handshake message. Have the server send out authentication replies with a payload giving the minimum and maximum version number supported by the server. Have the client accept authentication replies whether or not they have that additional information; if the reply has no payload, the server is assumed to support only version 0. This means that old servers that don't supply that information, and new servers that do, can be handled by the new client code; old clients discard extra payload, and only support version 0 (no servers or clients supporting versions other than 0 have been released, yet), so they can also handle both old and new servers. The client then uses that information (sent or implied) to try to find the highest version that it and the server supports. If there is no such version, it's impossible for the client and server to communicate further, so the client just reports an error to its caller and gives up. If there *is* such a version, the client then uses it in all subsequent requests, and the server replies with the version in the request. For data packets, the version used in the "start capture" request is used. This avoids timeouts or dropped connections with old servers due to the initial request having an unsupported version number, and means that the negotiation never requires two authentication requests.
Diffstat (limited to 'rpcapd')
-rw-r--r--rpcapd/daemon.c252
1 files changed, 124 insertions, 128 deletions
diff --git a/rpcapd/daemon.c b/rpcapd/daemon.c
index edc736ae..4f6c5a3b 100644
--- a/rpcapd/daemon.c
+++ b/rpcapd/daemon.c
@@ -97,7 +97,6 @@ struct daemon_slpars
{
SOCKET sockctrl; //!< SOCKET ID of the control connection
SSL *ssl; //!< Optional SSL handler for the controlling sockets
- uint8 protocol_version; //!< negotiated protocol version
int isactive; //!< Not null if the daemon has to run in active mode
int nullAuthAllowed; //!< '1' if we permit NULL authentication, '0' otherwise
};
@@ -130,18 +129,27 @@ 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_AuthUserPwd(char *username, char *password, char *errbuf);
-static int daemon_msg_findallif_req(struct daemon_slpars *pars, uint32 plen);
+static int daemon_msg_findallif_req(uint8 ver, struct daemon_slpars *pars,
+ uint32 plen);
-static int daemon_msg_open_req(struct daemon_slpars *pars, uint32 plen, char *source, size_t sourcelen);
-static int daemon_msg_startcap_req(struct daemon_slpars *pars, uint32 plen, char *source, struct session **sessionp, struct rpcap_sampling *samp_param, int uses_ssl);
-static int daemon_msg_endcap_req(struct daemon_slpars *pars, struct session *session);
+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,
+ struct rpcap_sampling *samp_param, int uses_ssl);
+static int daemon_msg_endcap_req(uint8 ver, struct daemon_slpars *pars,
+ struct session *session);
-static int daemon_msg_updatefilter_req(struct daemon_slpars *pars, struct session *session, uint32 plen);
+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_stats_req(struct daemon_slpars *pars, struct session *session, uint32 plen, struct pcap_stat *stats, unsigned int svrcapt);
+static int daemon_msg_stats_req(uint8 ver, struct daemon_slpars *pars,
+ struct session *session, uint32 plen, struct pcap_stat *stats,
+ unsigned int svrcapt);
-static int daemon_msg_setsampling_req(struct daemon_slpars *pars, uint32 plen, struct rpcap_sampling *samp_param);
+static int daemon_msg_setsampling_req(uint8 ver, struct daemon_slpars *pars,
+ uint32 plen, struct rpcap_sampling *samp_param);
static void daemon_seraddr(struct sockaddr_storage *sockaddrin, struct rpcap_sockaddr *sockaddrout);
#ifdef _WIN32
@@ -232,11 +240,12 @@ daemon_serviceloop(SOCKET sockctrl, int isactive, char *passiveClients,
// a TLS handshake message or a non-TLS rpcapd message.
//
// The first byte of an rpcapd request is the version number;
- // the first byte of a TLS handshake message is 22. We
- // permanently reserve an rpcapd version number of 22, so that
- // we can distinguish between rpcapd messages and TLS handshake
- // messages; if we ever get to rpcapd version 21, and want to
- // introduce a new version after that, we'll jump to version 23.
+ // the first byte of a TLS handshake message is 22. The
+ // first request to an rpcapd server must be an authentication
+ // request or a close request, and must have a version number
+ // of 0, so it will be possible to distinguish between an
+ // initial plaintext request to a server and an initial TLS
+ // handshake message.
//
nrecv = sock_recv(sockctrl, NULL, (char *)&first_octet, 1,
SOCK_EOF_ISNT_ERROR|SOCK_MSG_PEEK, errbuf, PCAP_ERRBUF_SIZE);
@@ -397,7 +406,6 @@ daemon_serviceloop(SOCKET sockctrl, int isactive, char *passiveClients,
// Set parameters structure
pars.sockctrl = sockctrl;
pars.ssl = ssl;
- pars.protocol_version = 0; // not yet known
pars.isactive = isactive; // active mode
pars.nullAuthAllowed = nullAuthAllowed;
@@ -536,49 +544,17 @@ daemon_serviceloop(SOCKET sockctrl, int isactive, char *passiveClients,
plen = header.plen;
//
- // Did the client specify a version we can handle?
+ // While we're in the authentication pharse, all requests
+ // must use version 0.
//
- if (!RPCAP_VERSION_IS_SUPPORTED(header.ver))
+ if (header.ver != 0)
{
//
- // Tell them it's not a valid protocol version.
- //
- uint8 reply_version;
-
- //
- // If RPCAP_MIN_VERSION is 0, no version is too
- // old, as the oldest supported version is 0,
- // and there are no negative versions.
+ // Send it back to them with their version.
//
-#if RPCAP_MIN_VERSION != 0
- if (header.ver < RPCAP_MIN_VERSION)
- {
- //
- // Their maximum version is too old;
- // there *is* no version we can both
- // handle, and they might reject
- // an error with a version they don't
- // understand, so reply with the
- // version they sent. That may
- // make them retry with that version,
- // but they'll give up on that
- // failure.
- //
- reply_version = header.ver;
- }
- else
-#endif
- {
- //
- // Their maximum version is too new,
- // but they might be able to handle
- // *our* maximum version, so reply
- // with that version.
- //
- reply_version = RPCAP_MAX_VERSION;
- }
- if (rpcap_senderror(pars.sockctrl, pars.ssl, reply_version,
- PCAP_ERR_WRONGVER, "RPCAP version number mismatch",
+ if (rpcap_senderror(pars.sockctrl, pars.ssl, header.ver,
+ PCAP_ERR_WRONGVER,
+ "RPCAP version in requests in the authentication phase must be 0",
errbuf) == -1)
{
// That failed; log a message and give up.
@@ -586,22 +562,12 @@ daemon_serviceloop(SOCKET sockctrl, int isactive, char *passiveClients,
goto end;
}
- // Discard the rest of the message.
- if (rpcapd_discard(pars.sockctrl, pars.ssl, plen) == -1)
- {
- // Network error.
- goto end;
- }
-
- // Let them try again.
- continue;
+ // Discard the rest of the message and drop the
+ // connection.
+ (void)rpcapd_discard(pars.sockctrl, pars.ssl, plen);
+ goto end;
}
- //
- // OK, we use the version the client specified.
- //
- pars.protocol_version = header.ver;
-
switch (header.type)
{
case RPCAP_MSG_AUTH_REQ:
@@ -667,7 +633,7 @@ daemon_serviceloop(SOCKET sockctrl, int isactive, char *passiveClients,
pcap_snprintf(errmsgbuf, PCAP_ERRBUF_SIZE, "Message of type %u sent before authentication was completed", header.type);
}
if (rpcap_senderror(pars.sockctrl, pars.ssl,
- pars.protocol_version, PCAP_ERR_WRONGMSG,
+ header.ver, PCAP_ERR_WRONGMSG,
errmsgbuf, errbuf) == -1)
{
rpcapd_log(LOGPRIO_ERROR, "Send to client failed: %s", errbuf);
@@ -703,7 +669,7 @@ daemon_serviceloop(SOCKET sockctrl, int isactive, char *passiveClients,
pcap_snprintf(errmsgbuf, PCAP_ERRBUF_SIZE, "Server-to-client message of type %u received from client", header.type);
}
if (rpcap_senderror(pars.sockctrl, pars.ssl,
- pars.protocol_version, PCAP_ERR_WRONGMSG,
+ header.ver, PCAP_ERR_WRONGMSG,
errmsgbuf, errbuf) == -1)
{
rpcapd_log(LOGPRIO_ERROR, "Send to client failed: %s", errbuf);
@@ -723,7 +689,7 @@ daemon_serviceloop(SOCKET sockctrl, int isactive, char *passiveClients,
//
pcap_snprintf(errmsgbuf, PCAP_ERRBUF_SIZE, "Unknown message type %u", header.type);
if (rpcap_senderror(pars.sockctrl, pars.ssl,
- pars.protocol_version, PCAP_ERR_WRONGMSG,
+ header.ver, PCAP_ERR_WRONGMSG,
errmsgbuf, errbuf) == -1)
{
rpcapd_log(LOGPRIO_ERROR, "Send to client failed: %s", errbuf);
@@ -783,7 +749,7 @@ daemon_serviceloop(SOCKET sockctrl, int isactive, char *passiveClients,
{
sock_geterror("select failed: ", errmsgbuf, PCAP_ERRBUF_SIZE);
if (rpcap_senderror(pars.sockctrl, pars.ssl,
- pars.protocol_version, PCAP_ERR_NETW,
+ header.ver, PCAP_ERR_NETW,
errmsgbuf, errbuf) == -1)
rpcapd_log(LOGPRIO_ERROR, "Send to client failed: %s", errbuf);
goto end;
@@ -794,7 +760,7 @@ daemon_serviceloop(SOCKET sockctrl, int isactive, char *passiveClients,
if (retval == 0)
{
if (rpcap_senderror(pars.sockctrl, pars.ssl,
- pars.protocol_version,
+ header.ver,
PCAP_ERR_INITTIMEOUT,
"The RPCAP initial timeout has expired",
errbuf) == -1)
@@ -821,21 +787,20 @@ daemon_serviceloop(SOCKET sockctrl, int isactive, char *passiveClients,
plen = header.plen;
//
- // Did the client specify the version we negotiated?
+ // Did the client specify a protocol version that we
+ // support?
//
- // For now, there's only one version.
- //
- if (header.ver != pars.protocol_version)
+ if (!RPCAP_VERSION_IS_SUPPORTED(header.ver))
{
//
- // Tell them it's not the negotiated version.
+ // Tell them it's not a supported version.
// Send the error message with their version,
// so they don't reject it as having the wrong
// version.
//
if (rpcap_senderror(pars.sockctrl, pars.ssl,
header.ver, PCAP_ERR_WRONGVER,
- "RPCAP version in message isn't the negotiated version",
+ "RPCAP version in message isn't supported by the server",
errbuf) == -1)
{
// That failed; log a message and give up.
@@ -861,7 +826,7 @@ daemon_serviceloop(SOCKET sockctrl, int isactive, char *passiveClients,
case RPCAP_MSG_FINDALLIF_REQ:
{
- if (daemon_msg_findallif_req(&pars, plen) == -1)
+ if (daemon_msg_findallif_req(header.ver, &pars, plen) == -1)
{
// Fatal error; a message has
// been logged, so just give up.
@@ -881,7 +846,8 @@ daemon_serviceloop(SOCKET sockctrl, int isactive, char *passiveClients,
// us multiple open requests, the last
// one wins.
//
- retval = daemon_msg_open_req(&pars, plen, source, sizeof(source));
+ retval = daemon_msg_open_req(header.ver, &pars,
+ plen, source, sizeof(source));
if (retval == -1)
{
// Fatal error; a message has
@@ -899,7 +865,7 @@ daemon_serviceloop(SOCKET sockctrl, int isactive, char *passiveClients,
// They never told us what device
// to capture on!
if (rpcap_senderror(pars.sockctrl, pars.ssl,
- pars.protocol_version,
+ header.ver,
PCAP_ERR_STARTCAPTURE,
"No capture device was specified",
errbuf) == -1)
@@ -916,7 +882,9 @@ daemon_serviceloop(SOCKET sockctrl, int isactive, char *passiveClients,
break;
}
- if (daemon_msg_startcap_req(&pars, plen, source, &session, &samp_param, uses_ssl) == -1)
+ if (daemon_msg_startcap_req(header.ver, &pars,
+ plen, source, &session, &samp_param,
+ uses_ssl) == -1)
{
// Fatal error; a message has
// been logged, so just give up.
@@ -929,7 +897,8 @@ daemon_serviceloop(SOCKET sockctrl, int isactive, char *passiveClients,
{
if (session)
{
- if (daemon_msg_updatefilter_req(&pars, session, plen) == -1)
+ if (daemon_msg_updatefilter_req(header.ver,
+ &pars, session, plen) == -1)
{
// Fatal error; a message has
// been logged, so just give up.
@@ -939,7 +908,7 @@ daemon_serviceloop(SOCKET sockctrl, int isactive, char *passiveClients,
else
{
if (rpcap_senderror(pars.sockctrl, pars.ssl,
- pars.protocol_version,
+ header.ver,
PCAP_ERR_UPDATEFILTER,
"Device not opened. Cannot update filter",
errbuf) == -1)
@@ -966,7 +935,8 @@ daemon_serviceloop(SOCKET sockctrl, int isactive, char *passiveClients,
case RPCAP_MSG_STATS_REQ:
{
- if (daemon_msg_stats_req(&pars, session, plen, &stats, svrcapt) == -1)
+ if (daemon_msg_stats_req(header.ver, &pars,
+ session, plen, &stats, svrcapt) == -1)
{
// Fatal error; a message has
// been logged, so just give up.
@@ -992,7 +962,8 @@ daemon_serviceloop(SOCKET sockctrl, int isactive, char *passiveClients,
svrcapt = 0;
}
- if (daemon_msg_endcap_req(&pars, session) == -1)
+ if (daemon_msg_endcap_req(header.ver,
+ &pars, session) == -1)
{
free(session);
session = NULL;
@@ -1006,7 +977,7 @@ daemon_serviceloop(SOCKET sockctrl, int isactive, char *passiveClients,
else
{
rpcap_senderror(pars.sockctrl, pars.ssl,
- pars.protocol_version,
+ header.ver,
PCAP_ERR_ENDCAPTURE,
"Device not opened. Cannot close the capture",
errbuf);
@@ -1016,7 +987,8 @@ daemon_serviceloop(SOCKET sockctrl, int isactive, char *passiveClients,
case RPCAP_MSG_SETSAMPLING_REQ:
{
- if (daemon_msg_setsampling_req(&pars, plen, &samp_param) == -1)
+ if (daemon_msg_setsampling_req(header.ver,
+ &pars, plen, &samp_param) == -1)
{
// Fatal error; a message has
// been logged, so just give up.
@@ -1033,7 +1005,7 @@ daemon_serviceloop(SOCKET sockctrl, int isactive, char *passiveClients,
//
rpcapd_log(LOGPRIO_INFO, "The client sent an RPCAP_MSG_AUTH_REQ message after authentication was completed");
if (rpcap_senderror(pars.sockctrl, pars.ssl,
- pars.protocol_version,
+ header.ver,
PCAP_ERR_WRONGMSG,
"RPCAP_MSG_AUTH_REQ request sent after authentication was completed",
errbuf) == -1)
@@ -1073,7 +1045,7 @@ daemon_serviceloop(SOCKET sockctrl, int isactive, char *passiveClients,
pcap_snprintf(errmsgbuf, PCAP_ERRBUF_SIZE, "Server-to-client message of type %u received from client", header.type);
}
if (rpcap_senderror(pars.sockctrl, pars.ssl,
- pars.protocol_version, PCAP_ERR_WRONGMSG,
+ header.ver, PCAP_ERR_WRONGMSG,
errmsgbuf, errbuf) == -1)
{
rpcapd_log(LOGPRIO_ERROR, "Send to client failed: %s", errbuf);
@@ -1094,7 +1066,7 @@ daemon_serviceloop(SOCKET sockctrl, int isactive, char *passiveClients,
rpcapd_log(LOGPRIO_INFO, "The client sent a message of type %u", header.type);
pcap_snprintf(errmsgbuf, PCAP_ERRBUF_SIZE, "Unknown message type %u", header.type);
if (rpcap_senderror(pars.sockctrl, pars.ssl,
- pars.protocol_version, PCAP_ERR_WRONGMSG,
+ header.ver, PCAP_ERR_WRONGMSG,
errbuf, errmsgbuf) == -1)
{
rpcapd_log(LOGPRIO_ERROR, "Send to client failed: %s", errbuf);
@@ -1228,9 +1200,11 @@ daemon_msg_auth_req(struct daemon_slpars *pars, uint32 plen)
{
char errbuf[PCAP_ERRBUF_SIZE]; // buffer for network errors
char errmsgbuf[PCAP_ERRBUF_SIZE]; // buffer for errors to send to the client
- struct rpcap_header header; // RPCAP message general header
int status;
struct rpcap_auth auth; // RPCAP authentication header
+ char sendbuf[RPCAP_NETBUF_SIZE]; // temporary buffer in which data to be sent is buffered
+ int sendbufidx = 0; // index which keeps the number of bytes currently buffered
+ struct rpcap_authreply *authreply; // authentication reply message
status = rpcapd_recv(pars->sockctrl, pars->ssl, (char *) &auth, sizeof(struct rpcap_auth), &plen, errmsgbuf);
if (status == -1)
@@ -1314,8 +1288,7 @@ daemon_msg_auth_req(struct daemon_slpars *pars, uint32 plen)
free(username);
free(passwd);
if (rpcap_senderror(pars->sockctrl, pars->ssl,
- pars->protocol_version,
- PCAP_ERR_AUTH, errmsgbuf, errbuf) == -1)
+ 0, PCAP_ERR_AUTH, errmsgbuf, errbuf) == -1)
{
// That failed; log a message and give up.
rpcapd_log(LOGPRIO_ERROR, "Send to client failed: %s", errbuf);
@@ -1347,10 +1320,28 @@ daemon_msg_auth_req(struct daemon_slpars *pars, uint32 plen)
}
// The authentication succeeded; let the client know.
- rpcap_createhdr(&header, pars->protocol_version, RPCAP_MSG_AUTH_REPLY, 0, 0);
+ if (sock_bufferize(NULL, sizeof(struct rpcap_header), NULL, &sendbufidx,
+ RPCAP_NETBUF_SIZE, SOCKBUF_CHECKONLY, errmsgbuf, PCAP_ERRBUF_SIZE) == -1)
+ goto error;
- // Send the ok message back
- if (sock_send(pars->sockctrl, pars->ssl, (char *) &header, sizeof (struct rpcap_header), errbuf, PCAP_ERRBUF_SIZE) == -1)
+ rpcap_createhdr((struct rpcap_header *) sendbuf, 0,
+ RPCAP_MSG_AUTH_REPLY, 0, sizeof(struct rpcap_authreply));
+
+ authreply = (struct rpcap_authreply *) &sendbuf[sendbufidx];
+
+ if (sock_bufferize(NULL, sizeof(struct rpcap_authreply), NULL, &sendbufidx,
+ RPCAP_NETBUF_SIZE, SOCKBUF_CHECKONLY, errmsgbuf, PCAP_ERRBUF_SIZE) == -1)
+ goto error;
+
+ //
+ // Indicate to our peer what versions we support.
+ //
+ memset(authreply, 0, sizeof(struct rpcap_authreply));
+ authreply->minvers = RPCAP_MIN_VERSION;
+ authreply->maxvers = RPCAP_MAX_VERSION;
+
+ // Send the reply.
+ if (sock_send(pars->sockctrl, pars->ssl, sendbuf, sendbufidx, errbuf, PCAP_ERRBUF_SIZE) == -1)
{
// That failed; log a messsage and give up.
rpcapd_log(LOGPRIO_ERROR, "Send to client failed: %s", errbuf);
@@ -1366,8 +1357,8 @@ daemon_msg_auth_req(struct daemon_slpars *pars, uint32 plen)
return 0;
error:
- if (rpcap_senderror(pars->sockctrl, pars->ssl, pars->protocol_version,
- PCAP_ERR_AUTH, errmsgbuf, errbuf) == -1)
+ if (rpcap_senderror(pars->sockctrl, pars->ssl, 0, PCAP_ERR_AUTH,
+ errmsgbuf, errbuf) == -1)
{
// That failed; log a message and give up.
rpcapd_log(LOGPRIO_ERROR, "Send to client failed: %s", errbuf);
@@ -1498,7 +1489,7 @@ daemon_AuthUserPwd(char *username, char *password, char *errbuf)
}
static int
-daemon_msg_findallif_req(struct daemon_slpars *pars, uint32 plen)
+daemon_msg_findallif_req(uint8 ver, struct daemon_slpars *pars, uint32 plen)
{
char errbuf[PCAP_ERRBUF_SIZE]; // buffer for network errors
char errmsgbuf[PCAP_ERRBUF_SIZE]; // buffer for errors to send to the client
@@ -1523,7 +1514,7 @@ daemon_msg_findallif_req(struct daemon_slpars *pars, uint32 plen)
if (alldevs == NULL)
{
- if (rpcap_senderror(pars->sockctrl, pars->ssl, pars->protocol_version,
+ if (rpcap_senderror(pars->sockctrl, pars->ssl, ver,
PCAP_ERR_NOREMOTEIF,
"No interfaces found! Make sure libpcap/WinPcap is properly installed"
" and you have the right to access to the remote device.",
@@ -1573,7 +1564,7 @@ daemon_msg_findallif_req(struct daemon_slpars *pars, uint32 plen)
PCAP_ERRBUF_SIZE) == -1)
goto error;
- rpcap_createhdr((struct rpcap_header *) sendbuf, pars->protocol_version,
+ rpcap_createhdr((struct rpcap_header *) sendbuf, ver,
RPCAP_MSG_FINDALLIF_REPLY, nif, plen);
// send the interface list
@@ -1689,7 +1680,7 @@ error:
if (alldevs)
pcap_freealldevs(alldevs);
- if (rpcap_senderror(pars->sockctrl, pars->ssl, pars->protocol_version,
+ if (rpcap_senderror(pars->sockctrl, pars->ssl, ver,
PCAP_ERR_FINDALLIF, errmsgbuf, errbuf) == -1)
{
rpcapd_log(LOGPRIO_ERROR, "Send to client failed: %s", errbuf);
@@ -1703,7 +1694,8 @@ error:
to discard excess data in the message, if present)
*/
static int
-daemon_msg_open_req(struct daemon_slpars *pars, uint32 plen, char *source, size_t sourcelen)
+daemon_msg_open_req(uint8 ver, struct daemon_slpars *pars, uint32 plen,
+ char *source, size_t sourcelen)
{
char errbuf[PCAP_ERRBUF_SIZE]; // buffer for network errors
char errmsgbuf[PCAP_ERRBUF_SIZE]; // buffer for errors to send to the client
@@ -1746,7 +1738,7 @@ daemon_msg_open_req(struct daemon_slpars *pars, uint32 plen, char *source, size_
RPCAP_NETBUF_SIZE, SOCKBUF_CHECKONLY, errmsgbuf, PCAP_ERRBUF_SIZE) == -1)
goto error;
- rpcap_createhdr((struct rpcap_header *) sendbuf, pars->protocol_version,
+ rpcap_createhdr((struct rpcap_header *) sendbuf, ver,
RPCAP_MSG_OPEN_REPLY, 0, sizeof(struct rpcap_openreply));
openreply = (struct rpcap_openreply *) &sendbuf[sendbufidx];
@@ -1778,8 +1770,8 @@ daemon_msg_open_req(struct daemon_slpars *pars, uint32 plen, char *source, size_
return 0;
error:
- if (rpcap_senderror(pars->sockctrl, pars->ssl, pars->protocol_version,
- PCAP_ERR_OPEN, errmsgbuf, errbuf) == -1)
+ if (rpcap_senderror(pars->sockctrl, pars->ssl, ver, PCAP_ERR_OPEN,
+ errmsgbuf, errbuf) == -1)
{
// That failed; log a message and give up.
rpcapd_log(LOGPRIO_ERROR, "Send to client failed: %s", errbuf);
@@ -1799,7 +1791,9 @@ error:
to discard excess data in the message, if present)
*/
static int
-daemon_msg_startcap_req(struct daemon_slpars *pars, uint32 plen, char *source, struct session **sessionp, struct rpcap_sampling *samp_param _U_, int uses_ssl)
+daemon_msg_startcap_req(uint8 ver, struct daemon_slpars *pars, uint32 plen,
+ char *source, struct session **sessionp,
+ struct rpcap_sampling *samp_param _U_, int uses_ssl)
{
char errbuf[PCAP_ERRBUF_SIZE]; // buffer for network errors
char errmsgbuf[PCAP_ERRBUF_SIZE]; // buffer for errors to send to the client
@@ -1968,7 +1962,7 @@ daemon_msg_startcap_req(struct daemon_slpars *pars, uint32 plen, char *source, s
// Needed to send an error on the ctrl connection
session->sockctrl = pars->sockctrl;
session->ctrl_ssl = pars->ssl;
- session->protocol_version = pars->protocol_version;
+ session->protocol_version = ver;
// Now I can set the filter
ret = daemon_unpackapplyfilter(pars->sockctrl, pars->ssl, session, &plen, errmsgbuf);
@@ -1988,7 +1982,7 @@ daemon_msg_startcap_req(struct daemon_slpars *pars, uint32 plen, char *source, s
RPCAP_NETBUF_SIZE, SOCKBUF_CHECKONLY, errmsgbuf, PCAP_ERRBUF_SIZE) == -1)
goto error;
- rpcap_createhdr((struct rpcap_header *) sendbuf, pars->protocol_version,
+ rpcap_createhdr((struct rpcap_header *) sendbuf, ver,
RPCAP_MSG_STARTCAP_REPLY, 0, sizeof(struct rpcap_startcapreply));
startcapreply = (struct rpcap_startcapreply *) &sendbuf[sendbufidx];
@@ -2096,7 +2090,7 @@ error:
free(session);
}
- if (rpcap_senderror(pars->sockctrl, pars->ssl, pars->protocol_version,
+ if (rpcap_senderror(pars->sockctrl, pars->ssl, ver,
PCAP_ERR_STARTCAPTURE, errmsgbuf, errbuf) == -1)
{
// That failed; log a message and give up.
@@ -2130,15 +2124,15 @@ fatal_error:
}
static int
-daemon_msg_endcap_req(struct daemon_slpars *pars, struct session *session)
+daemon_msg_endcap_req(uint8 ver, struct daemon_slpars *pars,
+ struct session *session)
{
char errbuf[PCAP_ERRBUF_SIZE]; // buffer for network errors
struct rpcap_header header;
session_close(session);
- rpcap_createhdr(&header, pars->protocol_version,
- RPCAP_MSG_ENDCAP_REPLY, 0, 0);
+ rpcap_createhdr(&header, ver, RPCAP_MSG_ENDCAP_REPLY, 0, 0);
if (sock_send(pars->sockctrl, pars->ssl, (char *) &header, sizeof(struct rpcap_header), errbuf, PCAP_ERRBUF_SIZE) == -1)
{
@@ -2229,7 +2223,8 @@ daemon_unpackapplyfilter(SOCKET sockctrl, SSL *ctrl_ssl, struct session *session
}
static int
-daemon_msg_updatefilter_req(struct daemon_slpars *pars, struct session *session, uint32 plen)
+daemon_msg_updatefilter_req(uint8 ver, struct daemon_slpars *pars,
+ struct session *session, uint32 plen)
{
char errbuf[PCAP_ERRBUF_SIZE];
char errmsgbuf[PCAP_ERRBUF_SIZE]; // buffer for errors to send to the client
@@ -2256,8 +2251,7 @@ daemon_msg_updatefilter_req(struct daemon_slpars *pars, struct session *session,
}
// A response is needed, otherwise the other host does not know that everything went well
- rpcap_createhdr(&header, pars->protocol_version,
- RPCAP_MSG_UPDATEFILTER_REPLY, 0, 0);
+ rpcap_createhdr(&header, ver, RPCAP_MSG_UPDATEFILTER_REPLY, 0, 0);
if (sock_send(pars->sockctrl, pars->ssl, (char *) &header, sizeof (struct rpcap_header), pcap_geterr(session->fp), PCAP_ERRBUF_SIZE))
{
@@ -2273,8 +2267,8 @@ error:
{
return -1;
}
- rpcap_senderror(pars->sockctrl, pars->ssl, pars->protocol_version,
- PCAP_ERR_UPDATEFILTER, errmsgbuf, NULL);
+ rpcap_senderror(pars->sockctrl, pars->ssl, ver, PCAP_ERR_UPDATEFILTER,
+ errmsgbuf, NULL);
return 0;
}
@@ -2283,7 +2277,8 @@ error:
\brief Received the sampling parameters from remote host and it stores in the pcap_t structure.
*/
static int
-daemon_msg_setsampling_req(struct daemon_slpars *pars, uint32 plen, struct rpcap_sampling *samp_param)
+daemon_msg_setsampling_req(uint8 ver, struct daemon_slpars *pars, uint32 plen,
+ struct rpcap_sampling *samp_param)
{
char errbuf[PCAP_ERRBUF_SIZE]; // buffer for network errors
char errmsgbuf[PCAP_ERRBUF_SIZE];
@@ -2306,8 +2301,7 @@ daemon_msg_setsampling_req(struct daemon_slpars *pars, uint32 plen, struct rpcap
samp_param->value = ntohl(rpcap_samp.value);
// A response is needed, otherwise the other host does not know that everything went well
- rpcap_createhdr(&header, pars->protocol_version,
- RPCAP_MSG_SETSAMPLING_REPLY, 0, 0);
+ rpcap_createhdr(&header, ver, RPCAP_MSG_SETSAMPLING_REPLY, 0, 0);
if (sock_send(pars->sockctrl, pars->ssl, (char *) &header, sizeof (struct rpcap_header), errbuf, PCAP_ERRBUF_SIZE) == -1)
{
@@ -2324,8 +2318,8 @@ daemon_msg_setsampling_req(struct daemon_slpars *pars, uint32 plen, struct rpcap
return 0;
error:
- if (rpcap_senderror(pars->sockctrl, pars->ssl, pars->protocol_version,
- PCAP_ERR_AUTH, errmsgbuf, errbuf) == -1)
+ if (rpcap_senderror(pars->sockctrl, pars->ssl, ver, PCAP_ERR_AUTH,
+ errmsgbuf, errbuf) == -1)
{
// That failed; log a message and give up.
rpcapd_log(LOGPRIO_ERROR, "Send to client failed: %s", errbuf);
@@ -2342,7 +2336,9 @@ error:
}
static int
-daemon_msg_stats_req(struct daemon_slpars *pars, struct session *session, uint32 plen, struct pcap_stat *stats, unsigned int svrcapt)
+daemon_msg_stats_req(uint8 ver, struct daemon_slpars *pars,
+ struct session *session, uint32 plen, struct pcap_stat *stats,
+ unsigned int svrcapt)
{
char errbuf[PCAP_ERRBUF_SIZE]; // buffer for network errors
char errmsgbuf[PCAP_ERRBUF_SIZE]; // buffer for errors to send to the client
@@ -2361,7 +2357,7 @@ daemon_msg_stats_req(struct daemon_slpars *pars, struct session *session, uint32
&sendbufidx, RPCAP_NETBUF_SIZE, SOCKBUF_CHECKONLY, errmsgbuf, PCAP_ERRBUF_SIZE) == -1)
goto error;
- rpcap_createhdr((struct rpcap_header *) sendbuf, pars->protocol_version,
+ rpcap_createhdr((struct rpcap_header *) sendbuf, ver,
RPCAP_MSG_STATS_REPLY, 0, (uint16) sizeof(struct rpcap_stats));
netstats = (struct rpcap_stats *) &sendbuf[sendbufidx];
@@ -2404,8 +2400,8 @@ daemon_msg_stats_req(struct daemon_slpars *pars, struct session *session, uint32
return 0;
error:
- rpcap_senderror(pars->sockctrl, pars->ssl, pars->protocol_version,
- PCAP_ERR_GETSTATS, errmsgbuf, NULL);
+ rpcap_senderror(pars->sockctrl, pars->ssl, ver, PCAP_ERR_GETSTATS,
+ errmsgbuf, NULL);
return 0;
}