aboutsummaryrefslogtreecommitdiff
path: root/pcap-rpcap.c
diff options
context:
space:
mode:
Diffstat (limited to 'pcap-rpcap.c')
-rw-r--r--pcap-rpcap.c131
1 files changed, 112 insertions, 19 deletions
diff --git a/pcap-rpcap.c b/pcap-rpcap.c
index c85acc2c..f7d4e0cc 100644
--- a/pcap-rpcap.c
+++ b/pcap-rpcap.c
@@ -45,6 +45,7 @@
#include <limits.h> /* for INT_MAX */
#include "sockutils.h"
#include "pcap-int.h"
+#include "pcap-util.h"
#include "rpcap-protocol.h"
#include "pcap-rpcap.h"
@@ -95,6 +96,7 @@ struct activehosts
SOCKET sockctrl;
SSL *ssl;
uint8_t protocol_version;
+ int byte_swapped;
struct activehosts *next;
};
@@ -130,6 +132,7 @@ struct pcap_rpcap {
uint8_t protocol_version; /* negotiated protocol version */
uint8_t uses_ssl; /* User asked for rpcaps scheme */
+ int byte_swapped; /* Server byte order is swapped from ours */
unsigned int TotNetDrops; /* keeps the number of packets that have been dropped by the network */
@@ -684,9 +687,14 @@ static int pcap_read_rpcap(pcap_t *p, int cnt, pcap_handler callback, u_char *us
if (ret == 1)
{
/*
- * We got a packet. Hand it to the callback
- * and count it so we can return the count.
+ * We got a packet.
+ *
+ * Do whatever post-processing is necessary, hand
+ * it to the callback, and count it so we can
+ * return the count.
*/
+ pcap_post_process(p->linktype, pr->byte_swapped,
+ &pkt_header, pkt_data);
(*callback)(user, &pkt_header, pkt_data);
n++;
}
@@ -1945,6 +1953,10 @@ static int pcap_setsampling_remote(pcap_t *fp)
* \param ver: pointer to variable to which to set the protocol version
* number we selected.
*
+ * \param byte_swapped: pointer to variable to which to set 1 if the
+ * byte order the server says it has is byte-swapped from ours, 0
+ * otherwise (whether it's the same as ours or is unknown).
+ *
* \param auth: authentication parameters that have to be sent.
*
* \param errbuf: a pointer to a user-allocated buffer (of size
@@ -1955,7 +1967,8 @@ static int pcap_setsampling_remote(pcap_t *fp)
* \return '0' if everything is fine, '-1' for an error. For errors,
* an error message string is returned in the 'errbuf' variable.
*/
-static int rpcap_doauth(SOCKET sockctrl, SSL *ssl, uint8_t *ver, struct pcap_rmtauth *auth, char *errbuf)
+static int rpcap_doauth(SOCKET sockctrl, SSL *ssl, uint8_t *ver,
+ int *byte_swapped, struct pcap_rmtauth *auth, char *errbuf)
{
char sendbuf[RPCAP_NETBUF_SIZE]; /* temporary buffer in which data that has to be sent is buffered */
int sendbufidx = 0; /* index which keeps the number of bytes currently buffered */
@@ -1967,6 +1980,8 @@ static int rpcap_doauth(SOCKET sockctrl, SSL *ssl, uint8_t *ver, struct pcap_rmt
uint32_t plen;
struct rpcap_authreply authreply; /* authentication reply message */
uint8_t ourvers;
+ int has_byte_order; /* The server sent its version of the byte-order magic number */
+ u_int their_byte_order_magic; /* Here's what it is */
if (auth)
{
@@ -2071,8 +2086,10 @@ static int rpcap_doauth(SOCKET sockctrl, SSL *ssl, uint8_t *ver, struct pcap_rmt
plen = header.plen;
if (plen != 0)
{
- /* Yes - is it big enough to be version information? */
- if (plen < sizeof(struct rpcap_authreply))
+ size_t reply_len;
+
+ /* Yes - is it big enough to include version information? */
+ if (plen < sizeof(struct rpcap_authreply_old))
{
/* No - discard it and fail. */
snprintf(errbuf, PCAP_ERRBUF_SIZE,
@@ -2081,9 +2098,34 @@ static int rpcap_doauth(SOCKET sockctrl, SSL *ssl, uint8_t *ver, struct pcap_rmt
return -1;
}
+ /* Yes - does it include server byte order information? */
+ if (plen == sizeof(struct rpcap_authreply_old))
+ {
+ /* No - just read the version information */
+ has_byte_order = 0;
+ reply_len = sizeof(struct rpcap_authreply_old);
+ }
+ else if (plen >= sizeof(struct rpcap_authreply_old))
+ {
+ /* Yes - read it all. */
+ has_byte_order = 1;
+ reply_len = sizeof(struct rpcap_authreply);
+ }
+ else
+ {
+ /*
+ * Too long for old reply, too short for new reply.
+ * Discard it and fail.
+ */
+ snprintf(errbuf, PCAP_ERRBUF_SIZE,
+ "Authenticaton reply from server is too short");
+ (void)rpcap_discard(sockctrl, ssl, plen, NULL);
+ return -1;
+ }
+
/* Read the reply body */
if (rpcap_recv(sockctrl, ssl, (char *)&authreply,
- sizeof(struct rpcap_authreply), &plen, errbuf) == -1)
+ reply_len, &plen, errbuf) == -1)
{
(void)rpcap_discard(sockctrl, ssl, plen, NULL);
return -1;
@@ -2106,12 +2148,32 @@ static int rpcap_doauth(SOCKET sockctrl, SSL *ssl, uint8_t *ver, struct pcap_rmt
"The server's minimum supported protocol version is greater than its maximum supported protocol version");
return -1;
}
+
+ if (has_byte_order)
+ {
+ their_byte_order_magic = authreply.byte_order_magic;
+ }
+ else
+ {
+ /*
+ * The server didn't tell us what its byte
+ * order is; assume it's ours.
+ */
+ their_byte_order_magic = RPCAP_BYTE_ORDER_MAGIC;;
+ }
}
else
{
/* No - it supports only version 0. */
authreply.minvers = 0;
authreply.maxvers = 0;
+
+ /*
+ * And it didn't tell us what its byte order is; assume
+ * it's ours.
+ */
+ has_byte_order = 0;
+ their_byte_order_magic = RPCAP_BYTE_ORDER_MAGIC;
}
/*
@@ -2144,6 +2206,27 @@ static int rpcap_doauth(SOCKET sockctrl, SSL *ssl, uint8_t *ver, struct pcap_rmt
goto novers;
}
+ /*
+ * Is the server byte order the opposite of ours?
+ */
+ if (their_byte_order_magic == RPCAP_BYTE_ORDER_MAGIC)
+ {
+ /* No, it's the same. */
+ *byte_swapped = 0;
+ }
+ else if (their_byte_order_magic == RPCAP_BYTE_ORDER_MAGIC_SWAPPED)
+ {
+ /* Yes, it's the opposite of ours. */
+ *byte_swapped = 1;
+ }
+ else
+ {
+ /* They sent us something bogus. */
+ snprintf(errbuf, PCAP_ERRBUF_SIZE,
+ "The server did not send us a valid byte order value");
+ return -1;
+ }
+
*ver = ourvers;
return 0;
@@ -2164,7 +2247,8 @@ static const char userinfo_allowed_symbols[] = "-._~!&'()*+,;=";
* struct created from a username and password parsed out of the userinfo
* portion of a URI.
*/
-static int rpcap_doauth_userinfo(SOCKET sockctrl, SSL *ssl, uint8_t *ver, const char *userinfo, char *errbuf)
+static int rpcap_doauth_userinfo(SOCKET sockctrl, SSL *ssl, uint8_t *ver,
+ int *byte_swapped, const char *userinfo, char *errbuf)
{
struct pcap_rmtauth auth;
const char *ptr;
@@ -2222,10 +2306,11 @@ static int rpcap_doauth_userinfo(SOCKET sockctrl, SSL *ssl, uint8_t *ver, const
}
}
- return rpcap_doauth(sockctrl, ssl, ver, &auth, errbuf);
+ return rpcap_doauth(sockctrl, ssl, ver, byte_swapped, &auth,
+ errbuf);
}
- return rpcap_doauth(sockctrl, ssl, ver, NULL, errbuf);
+ return rpcap_doauth(sockctrl, ssl, ver, byte_swapped, NULL, errbuf);
}
@@ -2249,8 +2334,8 @@ pcap_setnonblock_rpcap(pcap_t *p, int nonblock _U_)
static int
rpcap_setup_session(const char *source, struct pcap_rmtauth *auth,
int *activep, SOCKET *sockctrlp, uint8_t *uses_sslp, SSL **sslp,
- int rmt_flags, uint8_t *protocol_versionp, char *host, char *port,
- char *iface, char *errbuf)
+ int rmt_flags, uint8_t *protocol_versionp, int *byte_swappedp,
+ char *host, char *port, char *iface, char *errbuf)
{
int type;
int auth_result;
@@ -2303,6 +2388,7 @@ rpcap_setup_session(const char *source, struct pcap_rmtauth *auth,
*sockctrlp = activeconn->sockctrl;
*sslp = activeconn->ssl;
*protocol_versionp = activeconn->protocol_version;
+ *byte_swappedp = activeconn->byte_swapped;
}
else
{
@@ -2371,13 +2457,13 @@ rpcap_setup_session(const char *source, struct pcap_rmtauth *auth,
if (auth == NULL && *userinfo != '\0')
{
- auth_result = rpcap_doauth_userinfo(*sockctrlp, *sslp, protocol_versionp,
- userinfo, errbuf);
+ auth_result = rpcap_doauth_userinfo(*sockctrlp, *sslp,
+ protocol_versionp, byte_swappedp, userinfo, errbuf);
}
else
{
- auth_result = rpcap_doauth(*sockctrlp, *sslp, protocol_versionp, auth,
- errbuf);
+ auth_result = rpcap_doauth(*sockctrlp, *sslp,
+ protocol_versionp, byte_swappedp, auth, errbuf);
}
if (auth_result == -1)
@@ -2446,6 +2532,7 @@ pcap_t *pcap_open_rpcap(const char *source, int snaplen, int flags, int read_tim
SOCKET sockctrl;
SSL *ssl = NULL;
uint8_t protocol_version; /* negotiated protocol version */
+ int byte_swapped; /* server is known to be byte-swapped */
int active;
uint32_t plen;
char sendbuf[RPCAP_NETBUF_SIZE]; /* temporary buffer in which data to be sent is buffered */
@@ -2491,8 +2578,8 @@ pcap_t *pcap_open_rpcap(const char *source, int snaplen, int flags, int read_tim
* Attempt to set up the session with the server.
*/
if (rpcap_setup_session(fp->opt.device, auth, &active, &sockctrl,
- &pr->uses_ssl, &ssl, flags, &protocol_version, host, ctrlport,
- iface, errbuf) == -1)
+ &pr->uses_ssl, &ssl, flags, &protocol_version, &byte_swapped,
+ host, ctrlport, iface, errbuf) == -1)
{
/* Session setup failed. */
pcap_close(fp);
@@ -2541,6 +2628,7 @@ pcap_t *pcap_open_rpcap(const char *source, int snaplen, int flags, int read_tim
pr->rmt_sockctrl = sockctrl;
pr->ctrl_ssl = ssl;
pr->protocol_version = protocol_version;
+ pr->byte_swapped = byte_swapped;
pr->rmt_clientside = 1;
/* This code is duplicated from the end of this function */
@@ -2612,6 +2700,7 @@ int
pcap_findalldevs_ex_remote(const char *source, struct pcap_rmtauth *auth, pcap_if_t **alldevs, char *errbuf)
{
uint8_t protocol_version; /* protocol version */
+ int byte_swapped; /* Server byte order is swapped from ours */
SOCKET sockctrl; /* socket descriptor of the control connection */
SSL *ssl = NULL; /* optional SSL handler for sockctrl */
uint32_t plen;
@@ -2633,7 +2722,8 @@ pcap_findalldevs_ex_remote(const char *source, struct pcap_rmtauth *auth, pcap_i
* Attempt to set up the session with the server.
*/
if (rpcap_setup_session(source, auth, &active, &sockctrl, &uses_ssl,
- &ssl, 0, &protocol_version, host, port, NULL, errbuf) == -1)
+ &ssl, 0, &protocol_version, &byte_swapped, host, port, NULL,
+ errbuf) == -1)
{
/* Session setup failed. */
return -1;
@@ -2925,6 +3015,7 @@ SOCKET pcap_remoteact_accept_ex(const char *address, const char *port, const cha
SOCKET sockctrl; /* keeps the main socket identifier */
SSL *ssl = NULL; /* Optional SSL handler for sockctrl */
uint8_t protocol_version; /* negotiated protocol version */
+ int byte_swapped; /* 1 if server byte order is known to be the reverse of ours */
struct activehosts *temp, *prev; /* temp var needed to scan he host list chain */
*connectinghost = 0; /* just in case */
@@ -3035,7 +3126,8 @@ SOCKET pcap_remoteact_accept_ex(const char *address, const char *port, const cha
/*
* Send authentication to the remote machine.
*/
- if (rpcap_doauth(sockctrl, ssl, &protocol_version, auth, errbuf) == -1)
+ if (rpcap_doauth(sockctrl, ssl, &protocol_version, &byte_swapped,
+ auth, errbuf) == -1)
{
/* Unrecoverable error. */
rpcap_senderror(sockctrl, ssl, 0, PCAP_ERR_REMOTEACCEPT, errbuf, NULL);
@@ -3100,6 +3192,7 @@ SOCKET pcap_remoteact_accept_ex(const char *address, const char *port, const cha
temp->sockctrl = sockctrl;
temp->ssl = ssl;
temp->protocol_version = protocol_version;
+ temp->byte_swapped = byte_swapped;
temp->next = NULL;
return sockctrl;