aboutsummaryrefslogtreecommitdiff
path: root/pcap-rdmasniff.c
Commit message (Collapse)AuthorAgeFilesLines
* Prefix routines declared in pcap-int.h with pcap_.Guy Harris2023-05-261-2/+2
| | | | | This avoids potential and, in one case (SIMH), actual collisions with names in other libraries or in applications using libpcap.
* struct pcap: Update buffer type from "void *" to "u_char *"Francois-Xavier Le Bail2023-05-181-1/+1
| | | | | | | | | | | | | | | | | | | | | 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.
* RDMA: Use PRIu64 to print a uint64_tFrancois-Xavier Le Bail2022-03-011-2/+2
| | | | | | | | | | | | | | | | | In /usr/include/infiniband/verbs.h: struct ibv_wc { uint64_t wr_id; enum ibv_wc_status status; [...] Fix this cppcheck warning: pcap-rdmasniff.c:162:4: warning: %lld in format string (no. 1) requires 'long long' but the argument type is 'unsigned long long'. [invalidPrintfArgType_sint] fprintf(stderr, "failed WC wr_id %lld status %d/%s\n", ^ Remove an unneeded cast.
* Make sure no read routine process more than INT_MAX packets.Guy Harris2022-01-261-1/+17
| | | | | | | | | | | | | | | | | | | 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.
* Handle the pcap_t+private data in a fashion that makes fewer assumptions.Guy Harris2020-07-011-1/+1
| | | | | | | | | | | | | | | 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.
* Plug another memory leak.Guy Harris2019-11-271-1/+5
| | | | | | Again, if ibv_get_device_list() returns a non-null pointer, and sets the "number of devices" value to 0, we still have to free the list pointed to by the non-null pointer.
* Plug a memory leak.Guy Harris2019-11-271-3/+2
| | | | | | | | | | | | | | | | | | | If ibv_get_device_list() returns null, there's obviously no device list to free, so we can just return - and, as ibv_free_device_list() is not guaranteed to do nothing when passed a null pointer and, in fact, will try to dereference the null pointer, we *must* return without calling ibv_free_device_list(). However, if it returns a list, but there are no devices in the list, we still have to free the list - the list is terminated with a null pointer, so it's not empty. The loop for adding devices from the list will terminate immediately if numdev is 0, so don't bother to check whether it's zero, just run the loop, which will do nothing if numdev is 0, and fall through to free the device list. While we're at it, replace a goto with a break that does the same thing.
* Remove some workarounds for old compilers.Guy Harris2019-08-091-11/+11
| | | | | | | | | | | | | 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.
* Squelch more narrowing warnings.Guy Harris2018-09-121-1/+1
|
* Squelch more narrowing warnings.Guy Harris2018-09-121-1/+1
|
* Clean up the declaration of the packet-filtering routines.Guy Harris2018-08-311-1/+1
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | If net/bpf.h declares bpf_filter() one way and libpcap defines it another way, even pcap-bpf.c needs a declaration that matches how libpcap defines it, not how net/bpf.h (mistakenly) declares it. ("Mistakenly" because it should *not* be declaring the kernel's version of bpf_filter() unless it's being used in a *kernel* build; other *BSDs, and macOS, declare it only in kernel builds by testing for a #define such as KERNEL or KERNEL_PRIVATE, but NetBSD doesn't - it *should*, but it doesn't.) So we rename the internal-to-pcap filtering routine as pcap_filter(), which is not exported from libpcap, and have bpf_filter() be a wrapper around pcap_filter() that is exported. Use pcap_filter(), rather than bpf_filter(), for all filtering inside libpcap (except for filtering that uses bpf_filter_with_aux_data(), which we rename pcap_filter_with_aux_data()). Do the same for bpf_validate(), which is *also* declared in net/bpf.h, even for non-kernel builds, in NetBSD. As we're not exporting pcap_filter_with_aux_data(), don't even *declare* it in a public header; don't declare struct bpf_aux_data in a public header, either. That way we can change it without worrying about breaking APIs or ABIs; we may do that if, for example, we want to support the "inbound" and "outbound" filters when reading pcapng files, adding a direction indicator to that structure. Declare bpf_filter() in pcap/bpf.h even on NetBSD and QNX; pcap-bpf.c doesn't include pcap/bpf.h (it sets a #define to force pcap/pcap.h not to include it), so we won't get any collisions if net/bpf.h (which it does include) declares it. The only collisions will occur in programs that include *both* pcap/pcap.h or pcap/bpf.h *and* net/bpf.h, and that will occur only if net/bpf.h declares bpf_filter() even when building userland code, and the correct fix for *that* is to fix net/bpf.h not to declare them in non-kernel builds.
* Add more interface flags to pcap_findalldevs().Guy Harris2018-04-291-0/+4
| | | | | | | | | | | | | | | | | | | | | | | | | | | | We add: PCAP_IF_WIRELESS, which indicates whether the interface is "wireless" or not. PCAP_IF_CONNECTION_STATUS, which is a bitmask for a two-bit field that can have one of the values: PCAP_IF_CONNECTION_STATUS_UNKNOWN if the status of whether the interface is "connected" or "disconnected" is unknown; PCAP_IF_CONNECTION_STATUS_CONNECTED if the interface is "connected"; PCAP_IF_CONNECTION_STATUS_DISCONNECTED if the interface is "disconnected"; PCAP_IF_CONNECTION_STATUS_NOT_APPLICABLE if the notion of "connected" or "disconnected" doesn't apply to this interface. Take that into account when sorting interfaces in the interface list, penalizing "disconnected" interfaces, as you won't see traffic on them if they're not wireless and you'd have to be in some form of "monitor mode" to see traffic on them if they're wireless. This should address GitHub issue #700.
* pcap-rdmasniff: Implement stats_op methodRoland Dreier2017-10-131-0/+15
| | | | | | | | | | Use a really dumb stats implementation, because our RDMA flow steering implementation doesn't support more advanced stats. We need stats_op because otherwise we print an error like pcap_stats: This handle hasn't been activated yet on exit.
* pcap-rdmasniff: Return correct error when ibv_get_cq_event() failsRoland Dreier2017-10-131-2/+8
| | | | | | | | | | | When ibv_get_cq_event() fails, that means that a read() on the underlying fd failed, which usually indicates that a signal was received. If errno is EINTR then we should check if handle->break_loop has been set. If set, we return PCAP_ERROR_BREAK, otherwise just retry. This handles both SIGINT due to a user stopping tcpdump with ctrl-C and also SIGALRM for periodic stats reporting. Other errors "shouldn't happen" so we return PCAP_ERROR immediately, since our state is probably messed up in a way we can't recover from.
* Cast away a warning.Guy Harris2017-09-091-1/+1
| | | | | The snapshot member of the pcap_t structure is an int for historical reasons; we've ensured it's > 0, so just cast it to u_int.
* Get rid of another unused variable.Guy Harris2017-09-091-1/+0
|
* Get rid of unused variables.Guy Harris2017-09-091-2/+1
|
* If you're going to use str*()/mem*() routines, include <string.h>.Guy Harris2017-09-091-0/+1
|
* RDMA sniffing support for pcapRoland Dreier2017-08-251-0/+412
Implement capture support for offloaded RDMA traffic. This uses the RDMA verbs "flow steering" interface, which is available in the Linux kernel since version 3.12. The userspace interface is ibv_create_flow() - so building this support in pcap adds a new dependency on libibverbs. I added a new "rdmasniff" pcap module, which exposes RDMA devices under an interface name equal to their libibverbs name. The module uses the RDMA verbs interface to create a receive queue with a flow steering rule that gets a copy of all packets, even offloaded packets generated by or consumed by the hardware. The autoconf test for a usable version of libibverbs is a bit complicated because ibv_create_flow() is defined as an inline function in the header file, so we need to find the library and header and then try to link a program to check if the API is usable (it appeared in libibverbs 1.1.8).