| Commit message (Collapse) | Author | Age | Files | Lines |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
* amount
* anymore
* authentication
* availability
* bracket
* captured
* casted
* communications
* compliant
* configurable
* cumulate
* deinitialize
* descriptors
* didn't
* disassembler
* disassociate
* distributions
* divvy
* doing
* entries
* everything
* explicitly
* explosion
* expression
* extracting
* failed
* family
* find
* github
* global
* implementations
* incorrectly
* intel
* interlocked
* justifying
* know
* launched
* libraries
* malloced
* mask
* maximum
* network
* nonexistent
* number
* occurred
* optimizer
* overflow
* overwrite lower
* packet
* packetfilter
* packets
* parse hosts
* payload
* phase
* programmers
* promiscuous
* protocol
* receiving
* redefinition
* sampling
* savefile
* schwartz
* should
* snapshot
* something
* specifies
* straightforward
* stream
* subdir
* support
* surrogate
* suse
* system is
* test with
* than
* those
* unmaintained
* valid
* way
* western
* wireshark
Signed-off-by: Josh Soref <2119212+jsoref@users.noreply.github.com>
|
|
|
|
|
| |
This avoids potential and, in one case (SIMH), actual collisions with
names in other libraries or in applications using libpcap.
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
This change should avoid these cppcheck warnings:
pcap-hurd.c:77:18: warning: 'p->buffer' is of type 'void *'. When using
void pointers in calculations, the behaviour is undefined.
[arithOperationsOnVoidPointer]
pkt = p->buffer + offsetof(struct net_rcv_msg, packet)
^
pcap-hurd.c:78:8: warning: 'p->buffer+offsetof(struct net_rcv_msg,packet)'
is of type 'void *'. When using void pointers in calculations, the
behaviour is undefined. [arithOperationsOnVoidPointer]
+ sizeof(struct packet_header) - ETH_HLEN;
^
pcap-hurd.c:79:25: warning: 'p->buffer' is of type 'void *'. When using
void pointers in calculations, the behaviour is undefined.
[arithOperationsOnVoidPointer]
memmove(pkt, p->buffer + offsetof(struct net_rcv_msg, header),
^
Remove some '(u_char *)' casts accordingly.
|
|
|
|
|
|
|
|
|
|
|
| |
Haiku defines AF_INET as 1, not 2, so update a comment to reflect
reality.
(There has probably never been a version of rpcapd on Haiku built on the
original code, which just put structures directly on the wire, rather
than our version of the code, which has explicit serialization and
deserialization code, so there should be no reason to worry about Haiku
having a diferent value, as it would never appear on the wire.)
|
|
|
|
| |
Signed-off-by: Li kunyu <kunyu@nfschina.com>
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
Stick a byte-order magic number, in the host byte order of the server,
into the authentication reply.
If the authentication reply is large enough to contain that magic
number, extract it and, from it, determine whether the server's byte
order is the opposite of the client's byte order; if it's not present,
assume the server has the same byte order.
If the two byte orders are differen, do the same byte-order fixing of
the packet contents that we do when reading a pcap file or pcapng
section with the opposite byte order, so that host-byte-order fields are
converted from the byte order of the host that sent or wrote them to the
byte order of the host that received or read them.
This change will allow a client to work with all servers, regardless of
whether they provide the byte order or not, although if the server
doesn't provide the byte order, and it happens to be the opposite of the
client's byte order, packets with a link-layer header type that contains
host-byte-order fields will not be able to be processed correctly. It
also allows clients that don't handle the byte order magic number in the
authentication reply to work with all servers, as they will just discard
what they consider extra data at the end of the reply.
(Note: fixing the byte order in the server requires that the client send
a byte order indication to the server, so *either* fix works only
between an updated client and an updated server. We already have
optional data in the authentication reply, to allow updated servers and
clients to negotiate a protocol version while still allowing updated
clients to work with older servers and older clients to work with
updated servers, so this just continues that mechanism.)
|
|
|
|
| |
We weren't providng an error message for this case.
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
When connecting as a client, don't create one socket, using the address
family of the first entry in the address list, and use that for all
entries; on most if not all platforms, an AF_INET socket can't be used
to connect to an IPv6 address and an AF_INET6 socket can't be used to
connect to an IPv4 address. Instead, construct a table of the entries
in the address list, sort it by address family, and cycle through the
entries. If there is no socket yet, create it based on the current
entry's address family; if there is a socket, but it's for a different
address family than the current entry's address family, close it and
open a new one.
If connecting fails for all addresses, don't just construct a long
barely-readable error message consisting of the full errors for each
failure. Instead, construct one that, for each error code, has a list
of the addresses that got that error code; if all the failures had the
same error code, just show the host name, not the complete list of
addresses.
Clean up some error handling routines - fix names, allow some to take a
printf-style argument list, etc..
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
If we don't want a particular port nuber in a sock_initaddress() call,
pass NULL rather than "0". If the service name parameter passsed to
sock_initaddress() is NULL, pass "0" as the service name parameter to
getaddrinfo().
Have get_gai_errstring() precede the host/port name information with an
indication as to whethe it's a host name, port name, or host name and
port name. Don't say "host name" for EAI_NONAME; rely on the
description get_gai_errstring() provides. If there's only a port
number, don't preceded it with ":" in get_gai_errstring().
This makes the error message reported if a host and port are provided
not say that the host name couldn't be resolved, because it could be a
problem with the port name (sadly, getaddinfo() doesn't indicate which
is the one with the problem).
It also makes the error message reported if only a port is provided not
say that it's a problem with the host name or show the "host name" as
":<port>".
|
|
|
|
|
|
| |
Instead of defining intN and uintN types for use in the rpcap protocol -
except on Haiku - just use the C99 intN_t and uintN_t types, as we now
require them to be available.
|
| |
|
|
|
|
|
| |
Fix a typo (pr->priv should be p->priv), and note that the rationale for
clearing out pr->data_ssl no longer appears to be true.
|
| |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
Some read routines don't read a single bufferful of packets and process
just those packets; if packets continue to be made available, they could
conceivably process an arbitrary number of packets.
That would mean that the packet count overflows; either that makes it
look like a negative number, making it look as if an error occurred, or
makes it look like a too-small positive number.
This can't be fixed by making the count 64-bit, as it ultimately gets
returned by pcap_dispatch(), which is defined to return an int.
Instead, if the maximum packet count argument to those routines is a
value that means "no maximum", we set the maximum to INT_MAX. Those
routines are *not* defined to loop forever, so this isn't an issue.
This should fix issue #1087.
|
|
|
|
|
|
|
|
| |
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.
|
|
|
|
|
|
| |
These were format-truncation warnings (See issue #1029).
This is a workaround while waiting for a fix.
|
|
|
|
| |
It does additional checking, and returns better error messages.
|
|
|
|
| |
[skip ci]
|
| |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
The sizeof operator and alignof macro can be given a type "name" that's
anonymous, e.g. sizeof(struct { int a; char *b; }). Have
pcap_create_common() and pcap_open_offline_common() take, as arguments,
the total size of a structure containing both the pcap_t and the private
data as members, and the offset of the private data in that structure,
and define macros that calculate those given, as an argument, the data
type of the private data.
This avoids making assumptions about the alignment of those two items
within the structure; that *might* fix GitHub issue #940 if the issue is
that the ARM compiler being used does 16-byte alignment of the private
structure, rather than the 8-byte alignment we were wiring in.
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
Add a routine pcap_init() that initializes pcap, specifying whether
strings should be treated as being in UTF-8 or a local character
encoding.
On UN*Xes, we don't change our behavior based on that setting; if there
is ever an issue with local character encodings *other* than UTF-8, we
can use it.
On Windows, the local character encoding is the local ANSI code page; if
pcap_init() isn't called, or is called with PCAP_CHAR_ENC_LOCAL, strings
are treated as being in the current ANSI code page, as before, otherwise
they're treated as being in UTF-8. This includes file path names and
error messages.
In addition, if pcap_init() is called, regardless of the options, we
disable pcap_lookupdev(), making it always return NULL, as it retunred
*UTF-16LE* strings (plural!) on Windows NT, and pcap_create() had to
check for UTF-16LE strings to work around that. That workaround is
unsafe (it will read past the end of the input string if the string is
one ASCII character), and is also disabled if pcap_init() is called.
We also make rpcapd send UTF-8 error message strings over the wire;
sending local code page strings is a Bad Idea, as the client has no idea
what the server's code page is. (Do not assume the client and server
are necessarily in the same location.)
Fix the capitalization of "Winsock" while we're at it; Microsoft appears
to spell it "Winsock", rather than "WinSock".
|
| |
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
Require Visual Studio 2015 or later; fail if we don't have it, and
remove checks for older versions.
That means we have C99-compliant snprintf() and vsnprintf(); require
them when configuring for UN*X, and then use them directly, rather than
having wrappers for systems lacking them.
If we're using MSVC, skip the tests for options to request C99
compatibility - either we have VS 2015, which is sufficient, or we
don't, in which case we fail.
|
|
|
|
|
|
|
|
|
| |
It's like pcap_fmt_errmsg_for_errno(), but for Windows error codes.
Use it, rather than calling pcap_win32_err_to_str() and then formatting
a message with pcap_strerror().
Clean up some error messages while we're at it.
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
This lets us get rid of places where we calculate the length that a
formatted string will require, attempt to allocate a buffer for the
string, and then format the string into that buffer; this way, we don't
have to hope we got the calculation correct, we rely on the same code
that formats strings to do the calculation.
Provide versions of asprintf() for:
1) Windows and the MSVC runtime, where we use _vscprintf() to determine
the length;
2) systems that have (what is presumed to be) an snprintf() that, when
handed a too-short buffer, returns the number of characters that would
have been written had the buffer been long enough (as C99 specifies),
where we format to a one-character buffer to determine the length;
3) systems that don't have snprintf(), where we use the asprintf()
provided by the missing/snprintf.c file that also provides snprintf().
While we're at it, include "portability.h" in missing/win_snprintf.c, to
get declaration/definition checking done.
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
Don't format into an on-the-stack buffer and copy it to a mallocated buffer.
Instead, mallocate the buffer for the name first, and then format into
*that* buffer.
This avoids the risk of truncating the string when formatted into the
on-the-stack buffer, squelching some compiler warnings and possibly
squelching truncation.
Use strdup() to mallocate a copy of a string - don't reimplement
strdup() in a more complicated fashion, just use it.
|
|
|
|
|
|
| |
If we're fetching interfaces with pcap_findalldevs_ex() with an
rpcaps:// URL, put rpcaps:// rather than rpcap:// into the URLs that we
return.
|
|
|
|
|
| |
Go to the error label, don't just immediately return, so that, for
example, we discard the rest of the "find all devices" reply.
|
|
|
|
|
|
|
| |
If the minimum version the client supports is 0, the maximum version the
server supports can't be less than that (they're unsigned, hence never
negative), so we don't need to check whether the server maximum version
is less than the client minimum version.
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
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.
|
|
|
|
|
|
|
| |
It handles parsing the URL, checking for using UDP for data if the URL
is an rpcaps:// URL, initializing Winsock, handling active mode, setting
up and connecting the control socket, setting up SSL, and doing
authentication.
|
|
|
|
|
|
|
|
|
| |
Before we shut down the socket, send a shutdown alert. That should
prevent some cases where errors are reported when they shouldn't be (it
was happening if I did a --list-remote-interfaces in tcpdump).
While we're at it, do the SSL shutdown *before* closing the main active
socket; we were doing it *after*. Also, fix a comment.
|
|
|
|
|
|
| |
Before we parse the URL, we don't know whether the URL requests TLS or
not, so we don't know whether we'll need DTLS (which we currently don't
support).
|
|
|
|
|
|
|
|
|
|
|
| |
Treat a failure to get the socket buffer size as an error; we were just
blithely driving on and using the variable into which the size *hadn't*
been put. That means that our caller will be handed the error message;
we presume they do something with it, so that we don't need to print it
as a debugging message.
In other cases, we already were reporting an error and providing the
error message; the same applies there.
|
|
|
|
|
|
| |
We can't change the signature of pcap_remoteact_accept(); add
pcap_remoteact_accept_ex() with the new signature, and have
pcap_remoteact_accept() as a wrapper with the old signature.
|
|\ |
|
| |
| |
| |
| | |
As DTLS is not implemented (yet).
|
| |
| |
| |
| | |
Added one boolean argument to pcap_remoteact_accept().
|
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| | |
This patch also encode the control sockets in adition to the data
socket. Clients performs a TLS handshake when the scheme is rpcaps://
rather than rpcap://. Both active and passive modes are supported, but
transfert via UDP is not (yet) supported (the lib returns an error in
that case).
I did some adaptation to the windows code but couldn't tested so for all
I know it may not even compile.
Also tried to fix the indentation.
|
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| | |
When using rpcapd one may want the forwarded traffic to be encrypted.
When running rpcapd via initd it is relatively easy to add stunnel but
the client still have to implement TLS. Or one could also use an ssh
tunnel but it's a lot of setup. Ultimately, it is simpler than rpcap
protocol could run on SSL natively. So this patch adds a -S option to
rpcapd that will wrap the data socket into a TLS tunnel (in both passive
anbd active mode, as long as it's TCP not UDP).
The start capture message has an additional flag: ssl, asking the client
to initiate a TLS handshake once he is connected to the data socket.
This patch is not polished as I'm more interested in early opinions at
this stage. Please let me know what you think of the idea and its
implementation so far.
Proof of concept:
generate a private key, a self signed root cert:
$ openssl req -newkey rsa:2048 -nodes -keyout key.pem -x509 -days 36500 -out cert.pem
then run rpcapd with option -S (ssl) and -K and -C:
$ rpcapd -n -S -K key.pem -C cert.pem
Once recompiled, tcpdump can attach to this rpcap:// service and the
traffic will be encrypted.
|
| |
| |
| |
| |
| |
| |
| |
| |
| |
| | |
We don't modify the source argument to pcap_findalldevs_ex(), so make
that a promise, so compilers don't get upset when a constant string is
passed.
See, for example:
https://stackoverflow.com/questions/52397129/winpcap-findalldevs-const-char-incompatible-to-char
|
| | |
|
|/
|
|
|
|
|
|
|
|
|
|
|
|
| |
We now depend on the *full* semantics of those routines, including the
return value being usable for truncation checks.
If we're building for a UN*X that has them, define pcap_strl{cpy,cat} to
be strl{cpy,cat}.
If we're building for Windows using MSVC, define pcap_strl{cpy,cat}, not
strl{cpy,cat}.
Otherwise, build our won versions of pcap_strl{cpy,cat} from BSD-derived
source code.
|
|
|
|
|
| |
Probably harmless, but do it to help catch some issues on LP64 (64-bit
UN*X) or LLP64 (64-bit Windows) platforms when compiling on macOS.
|
|\
| |
| | |
Fix using uninitialised file descriptor?
|
| |
| |
| |
| | |
Too quick copy-pasta.
|
| |
| |
| |
| | |
As a follow-up to comit 5f2a5c03e0f91bc2dc2ae33838db273dd6c7d8d9.
|
|/ |
|
| |
|
|
|
|
|
|
| |
The reason we were getting warnings about declarations after statements,
even with -std=gnu99, is that we were *explicitly requesting them* with
-Wdeclaration-after-statement.
|