104 lines
4.3 KiB
Diff
104 lines
4.3 KiB
Diff
From f72f48a26abdd2eb11a4a8fb3596ee67b8f8cbe6 Mon Sep 17 00:00:00 2001
|
|
From: Guy Harris <gharris@sonic.net>
|
|
Date: Wed, 21 Jul 2021 23:50:32 -0700
|
|
Subject: [PATCH] rpcap: don't do pointless integer->string and then
|
|
string->integer conversions.
|
|
|
|
The string->integer conversion was also broken, as it passed a pointer
|
|
to a 16-bit integer to a sscanf() call that used %d rather than %hd.
|
|
It'd overwrite 2 bytes past the 16-bit integer; it may set the integer
|
|
"correctly" on a little-endian, but wouldn't even do *that* on a
|
|
big-endian machine.
|
|
|
|
(cherry picked from commit efaddfe8eae4dab252bb2d35e004a40e4b72db24)
|
|
|
|
Conflict:Replacing snprintf with pcap_snprintf
|
|
context adapt
|
|
Reference:https://github.com/the-tcpdump-group/libpcap/commit/f72f48a26abdd2eb11a4a8fb3596ee67b8f8cbe6
|
|
|
|
---
|
|
pcap-rpcap.c | 34 ++++++++++++++++++++++++----------
|
|
1 file changed, 24 insertions(+), 10 deletions(-)
|
|
|
|
diff --git a/pcap-rpcap.c b/pcap-rpcap.c
|
|
index 705f06f..d9609c7 100644
|
|
--- a/pcap-rpcap.c
|
|
+++ b/pcap-rpcap.c
|
|
@@ -1014,7 +1014,7 @@ static int pcap_startcapture_remote(pcap_t *fp)
|
|
struct pcap_rpcap *pr = fp->priv; /* structure used when doing a remote live capture */
|
|
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 */
|
|
- char portdata[PCAP_BUF_SIZE]; /* temp variable needed to keep the network port for the data connection */
|
|
+ uint16 portdata = 0; /* temp variable needed to keep the network port for the data connection */
|
|
uint32 plen;
|
|
int active = 0; /* '1' if we're in active mode */
|
|
struct activehosts *temp; /* temp var needed to scan the host list chain, to detect if we're in active mode */
|
|
@@ -1027,6 +1027,8 @@ static int pcap_startcapture_remote(pcap_t *fp)
|
|
struct sockaddr_storage saddr; /* temp, needed to retrieve the network data port chosen on the local machine */
|
|
socklen_t saddrlen; /* temp, needed to retrieve the network data port chosen on the local machine */
|
|
int ai_family; /* temp, keeps the address family used by the control connection */
|
|
+ struct sockaddr_in *sin4;
|
|
+ struct sockaddr_in6 *sin6;
|
|
|
|
/* RPCAP-related variables*/
|
|
struct rpcap_header header; /* header of the RPCAP packet */
|
|
@@ -1121,11 +1123,22 @@ static int pcap_startcapture_remote(pcap_t *fp)
|
|
goto error_nodiscard;
|
|
}
|
|
|
|
- /* Get the local port the system picked up */
|
|
- if (getnameinfo((struct sockaddr *) &saddr, saddrlen, NULL,
|
|
- 0, portdata, sizeof(portdata), NI_NUMERICSERV))
|
|
- {
|
|
- sock_geterror("getnameinfo()", fp->errbuf, PCAP_ERRBUF_SIZE);
|
|
+ switch (saddr.ss_family) {
|
|
+
|
|
+ case AF_INET:
|
|
+ sin4 = (struct sockaddr_in *)&saddr;
|
|
+ portdata = sin4->sin_port;
|
|
+ break;
|
|
+
|
|
+ case AF_INET6:
|
|
+ sin6 = (struct sockaddr_in6 *)&saddr;
|
|
+ portdata = sin6->sin6_port;
|
|
+ break;
|
|
+
|
|
+ default:
|
|
+ pcap_snprintf(fp->errbuf, PCAP_ERRBUF_SIZE,
|
|
+ "Local address has unknown address family %u",
|
|
+ saddr.ss_family);
|
|
goto error_nodiscard;
|
|
}
|
|
}
|
|
@@ -1158,8 +1171,7 @@ static int pcap_startcapture_remote(pcap_t *fp)
|
|
/* portdata on the openreq is meaningful only if we're in active mode */
|
|
if ((active) || (pr->rmt_flags & PCAP_OPENFLAG_DATATX_UDP))
|
|
{
|
|
- sscanf(portdata, "%d", (int *)&(startcapreq->portdata)); /* cast to avoid a compiler warning */
|
|
- startcapreq->portdata = htons(startcapreq->portdata);
|
|
+ startcapreq->portdata = portdata;
|
|
}
|
|
|
|
startcapreq->snaplen = htonl(fp->snapshot);
|
|
@@ -1208,13 +1220,15 @@ static int pcap_startcapture_remote(pcap_t *fp)
|
|
{
|
|
if (!active)
|
|
{
|
|
+ char portstring[PCAP_BUF_SIZE];
|
|
+
|
|
memset(&hints, 0, sizeof(struct addrinfo));
|
|
hints.ai_family = ai_family; /* Use the same address family of the control socket */
|
|
hints.ai_socktype = (pr->rmt_flags & PCAP_OPENFLAG_DATATX_UDP) ? SOCK_DGRAM : SOCK_STREAM;
|
|
- pcap_snprintf(portdata, PCAP_BUF_SIZE, "%d", ntohs(startcapreply.portdata));
|
|
+ pcap_snprintf(portstring, PCAP_BUF_SIZE, "%d", ntohs(startcapreply.portdata));
|
|
|
|
/* Let's the server pick up a free network port for us */
|
|
- if (sock_initaddress(host, portdata, &hints, &addrinfo, fp->errbuf, PCAP_ERRBUF_SIZE) == -1)
|
|
+ if (sock_initaddress(host, portstring, &hints, &addrinfo, fp->errbuf, PCAP_ERRBUF_SIZE) == -1)
|
|
goto error;
|
|
|
|
if ((sockdata = sock_open(addrinfo, SOCKOPEN_CLIENT, 0, fp->errbuf, PCAP_ERRBUF_SIZE)) == INVALID_SOCKET)
|
|
--
|
|
2.33.0
|
|
|