1
0
mirror of https://github.com/nmap/nmap.git synced 2025-12-24 16:39:03 +00:00

Upgrade libpcap to 1.10.4

This commit is contained in:
dmiller
2023-04-28 14:37:51 +00:00
parent 186bed85c8
commit 585832c41e
121 changed files with 13810 additions and 8968 deletions

View File

@@ -2,7 +2,7 @@
* pcap-linux.c: Packet capture interface to the Linux kernel
*
* Copyright (c) 2000 Torsten Landschoff <torsten@debian.org>
* Sebastian Krahmer <krahmer@cs.uni-potsdam.de>
* Sebastian Krahmer <krahmer@cs.uni-potsdam.de>
*
* License: BSD
*
@@ -100,6 +100,7 @@
#include "pcap-int.h"
#include "pcap/sll.h"
#include "pcap/vlan.h"
#include "pcap/can_socketcan.h"
#include "diag-control.h"
@@ -222,7 +223,7 @@ static int get_if_flags(const char *, bpf_u_int32 *, char *);
static int is_wifi(const char *);
static void map_arphrd_to_dlt(pcap_t *, int, const char *, int);
static int pcap_activate_linux(pcap_t *);
static int activate_pf_packet(pcap_t *, int);
static int setup_socket(pcap_t *, int);
static int setup_mmapped(pcap_t *, int *);
static int pcap_can_set_rfmon_linux(pcap_t *);
static int pcap_inject_linux(pcap_t *, const void *, int);
@@ -314,14 +315,12 @@ static const struct timeval netdown_timeout = {
*/
static int iface_get_id(int fd, const char *device, char *ebuf);
static int iface_get_mtu(int fd, const char *device, char *ebuf);
static int iface_get_arptype(int fd, const char *device, char *ebuf);
static int iface_bind(int fd, int ifindex, char *ebuf, int protocol);
static int iface_get_arptype(int fd, const char *device, char *ebuf);
static int iface_bind(int fd, int ifindex, char *ebuf, int protocol);
static int enter_rfmon_mode(pcap_t *handle, int sock_fd,
const char *device);
#if defined(HAVE_LINUX_NET_TSTAMP_H) && defined(PACKET_TIMESTAMP)
static int iface_ethtool_get_ts_info(const char *device, pcap_t *handle,
static int iface_get_ts_types(const char *device, pcap_t *handle,
char *ebuf);
#endif
static int iface_get_offload(pcap_t *handle);
static int fix_program(pcap_t *handle, struct sock_fprog *fcode);
@@ -348,15 +347,13 @@ pcap_create_interface(const char *device, char *ebuf)
handle->activate_op = pcap_activate_linux;
handle->can_set_rfmon_op = pcap_can_set_rfmon_linux;
#if defined(HAVE_LINUX_NET_TSTAMP_H) && defined(PACKET_TIMESTAMP)
/*
* See what time stamp types we support.
*/
if (iface_ethtool_get_ts_info(device, handle, ebuf) == -1) {
if (iface_get_ts_types(device, handle, ebuf) == -1) {
pcap_close(handle);
return NULL;
}
#endif
/*
* We claim that we support microsecond and nanosecond time
@@ -845,7 +842,10 @@ static void pcap_cleanup_linux( pcap_t *handle )
handlep->device = NULL;
}
close(handlep->poll_breakloop_fd);
if (handlep->poll_breakloop_fd != -1) {
close(handlep->poll_breakloop_fd);
handlep->poll_breakloop_fd = -1;
}
pcap_cleanup_live_common(handle);
}
@@ -944,7 +944,41 @@ static void pcap_breakloop_linux(pcap_t *handle)
uint64_t value = 1;
/* XXX - what if this fails? */
(void)write(handlep->poll_breakloop_fd, &value, sizeof(value));
if (handlep->poll_breakloop_fd != -1)
(void)write(handlep->poll_breakloop_fd, &value, sizeof(value));
}
/*
* Set the offset at which to insert VLAN tags.
* That should be the offset of the type field.
*/
static void
set_vlan_offset(pcap_t *handle)
{
struct pcap_linux *handlep = handle->priv;
switch (handle->linktype) {
case DLT_EN10MB:
/*
* The type field is after the destination and source
* MAC address.
*/
handlep->vlan_offset = 2 * ETH_ALEN;
break;
case DLT_LINUX_SLL:
/*
* The type field is in the last 2 bytes of the
* DLT_LINUX_SLL header.
*/
handlep->vlan_offset = SLL_HDR_LEN - 2;
break;
default:
handlep->vlan_offset = -1; /* unknown */
break;
}
}
/*
@@ -980,6 +1014,11 @@ pcap_activate_linux(pcap_t *handle)
* we'll be copying it, that won't fit.
*/
if (strlen(device) >= sizeof(ifr.ifr_name)) {
/*
* There's nothing more to say, so clear the error
* message.
*/
handle->errbuf[0] = '\0';
status = PCAP_ERROR_NO_SUCH_DEVICE;
goto fail;
}
@@ -1035,7 +1074,7 @@ pcap_activate_linux(pcap_t *handle)
* If the "any" device is specified, try to open a SOCK_DGRAM.
* Otherwise, open a SOCK_RAW.
*/
ret = activate_pf_packet(handle, is_any_device);
ret = setup_socket(handle, is_any_device);
if (ret < 0) {
/*
* Fatal error; the return value is the error code,
@@ -1111,6 +1150,13 @@ static int
pcap_set_datalink_linux(pcap_t *handle, int dlt)
{
handle->linktype = dlt;
/*
* Update the offset at which to insert VLAN tags for the
* new link-layer type.
*/
set_vlan_offset(handle);
return 0;
}
@@ -1144,9 +1190,12 @@ linux_check_direction(const pcap_t *handle, const struct sockaddr_ll *sll)
* easily distinguish packets looped back by the CAN
* layer than those received by the CAN layer, so we
* eliminate this packet instead.
*
* We check whether this is a CAN or CAN FD frame
* by checking whether the device's hardware type
* is ARPHRD_CAN.
*/
if ((sll->sll_protocol == LINUX_SLL_P_CAN ||
sll->sll_protocol == LINUX_SLL_P_CANFD) &&
if (sll->sll_hatype == ARPHRD_CAN &&
handle->direction != PCAP_D_OUT)
return 0;
@@ -1440,7 +1489,7 @@ get_if_ioctl_socket(void)
* capture on them, "why do no interfaces show up?" - when the
* real problem is a permissions problem. Error reports of that
* type require a lot more back-and-forth to debug, as evidenced
* by many Wireshark bugs/mailing list questions/Q&A questoins.)
* by many Wireshark bugs/mailing list questions/Q&A questions.)
*
* So:
*
@@ -1612,8 +1661,8 @@ get_if_flags(const char *name, bpf_u_int32 *flags, char *errbuf)
}
}
fclose(fh);
free(pathstr);
}
free(pathstr);
}
#ifdef ETHTOOL_GLINK
@@ -1815,7 +1864,7 @@ static void map_arphrd_to_dlt(pcap_t *handle, int arptype,
* XXX - are there any other sorts of "fake Ethernet" that
* have ARPHRD_ETHER but that shouldn't offer DLT_DOCSIS as
* a Cisco CMTS won't put traffic onto it or get traffic
* bridged onto it? ISDN is handled in "activate_pf_packet()",
* bridged onto it? ISDN is handled in "setup_socket()",
* as we fall back on cooked mode there, and we use
* is_wifi() to check for 802.11 devices; are there any
* others?
@@ -1882,14 +1931,7 @@ static void map_arphrd_to_dlt(pcap_t *handle, int arptype,
#define ARPHRD_CAN 280
#endif
case ARPHRD_CAN:
/*
* Map this to DLT_LINUX_SLL; that way, CAN frames will
* have ETH_P_CAN/LINUX_SLL_P_CAN as the protocol and
* CAN FD frames will have ETH_P_CANFD/LINUX_SLL_P_CANFD
* as the protocol, so they can be distinguished by the
* protocol in the SLL header.
*/
handle->linktype = DLT_LINUX_SLL;
handle->linktype = DLT_CAN_SOCKETCAN;
break;
#ifndef ARPHRD_IEEE802_TR
@@ -2171,7 +2213,7 @@ static void map_arphrd_to_dlt(pcap_t *handle, int arptype,
/* We need to save packet direction for IrDA decoding,
* so let's use "Linux-cooked" mode. Jean II
*
* XXX - this is handled in activate_pf_packet(). */
* XXX - this is handled in setup_socket(). */
/* handlep->cooked = 1; */
break;
@@ -2213,7 +2255,7 @@ static void map_arphrd_to_dlt(pcap_t *handle, int arptype,
* pick up the netlink protocol type such as NETLINK_ROUTE,
* NETLINK_GENERIC, NETLINK_FIB_LOOKUP, etc.
*
* XXX - this is handled in activate_pf_packet().
* XXX - this is handled in setup_socket().
*/
/* handlep->cooked = 1; */
break;
@@ -2231,59 +2273,36 @@ static void map_arphrd_to_dlt(pcap_t *handle, int arptype,
}
}
#ifdef PACKET_RESERVE
static void
set_dlt_list_cooked(pcap_t *handle, int sock_fd)
set_dlt_list_cooked(pcap_t *handle)
{
socklen_t len;
unsigned int tp_reserve;
/*
* Support both DLT_LINUX_SLL and DLT_LINUX_SLL2.
*/
handle->dlt_list = (u_int *) malloc(sizeof(u_int) * 2);
/*
* If we can't do PACKET_RESERVE, we can't reserve extra space
* for a DLL_LINUX_SLL2 header, so we can't support DLT_LINUX_SLL2.
* If that failed, just leave the list empty.
*/
len = sizeof(tp_reserve);
if (getsockopt(sock_fd, SOL_PACKET, PACKET_RESERVE, &tp_reserve,
&len) == 0) {
/*
* Yes, we can do DLL_LINUX_SLL2.
*/
handle->dlt_list = (u_int *) malloc(sizeof(u_int) * 2);
/*
* If that fails, just leave the list empty.
*/
if (handle->dlt_list != NULL) {
handle->dlt_list[0] = DLT_LINUX_SLL;
handle->dlt_list[1] = DLT_LINUX_SLL2;
handle->dlt_count = 2;
}
if (handle->dlt_list != NULL) {
handle->dlt_list[0] = DLT_LINUX_SLL;
handle->dlt_list[1] = DLT_LINUX_SLL2;
handle->dlt_count = 2;
}
}
#else/* PACKET_RESERVE */
/*
* The build environment doesn't define PACKET_RESERVE, so we can't reserve
* extra space for a DLL_LINUX_SLL2 header, so we can't support DLT_LINUX_SLL2.
*/
static void
set_dlt_list_cooked(pcap_t *handle _U_, int sock_fd _U_)
{
}
#endif /* PACKET_RESERVE */
/*
* Try to set up a PF_PACKET socket.
* Returns 0 on success and a PCAP_ERROR_ value on failure.
*/
static int
activate_pf_packet(pcap_t *handle, int is_any_device)
setup_socket(pcap_t *handle, int is_any_device)
{
struct pcap_linux *handlep = handle->priv;
const char *device = handle->opt.device;
int status = 0;
int sock_fd, arptype;
#ifdef HAVE_PACKET_AUXDATA
int val;
#endif
int err = 0;
struct packet_mreq mr;
#if defined(SO_BPF_EXTENSIONS) && defined(SKF_AD_VLAN_TAG_PRESENT)
@@ -2312,6 +2331,8 @@ activate_pf_packet(pcap_t *handle, int is_any_device)
* socket.
*/
status = PCAP_ERROR_PERM_DENIED;
snprintf(handle->errbuf, PCAP_ERRBUF_SIZE,
"Attempt to create packet socket failed - CAP_NET_RAW may be required");
} else {
/*
* Other error.
@@ -2439,7 +2460,7 @@ activate_pf_packet(pcap_t *handle, int is_any_device)
free(handle->dlt_list);
handle->dlt_list = NULL;
handle->dlt_count = 0;
set_dlt_list_cooked(handle, sock_fd);
set_dlt_list_cooked(handle);
}
if (handle->linktype == -1) {
@@ -2505,7 +2526,7 @@ activate_pf_packet(pcap_t *handle, int is_any_device)
handle->linktype = DLT_LINUX_SLL;
handle->dlt_list = NULL;
handle->dlt_count = 0;
set_dlt_list_cooked(handle, sock_fd);
set_dlt_list_cooked(handle);
/*
* We're not bound to a device.
@@ -2552,9 +2573,15 @@ activate_pf_packet(pcap_t *handle, int is_any_device)
}
}
/* Enable auxiliary data if supported and reserve room for
* reconstructing VLAN headers. */
#ifdef HAVE_PACKET_AUXDATA
/*
* Enable auxiliary data and reserve room for reconstructing
* VLAN headers.
*
* XXX - is enabling auxiliary data necessary, now that we
* only support memory-mapped capture? The kernel's memory-mapped
* capture code doesn't seem to check whether auxiliary data
* is enabled, it seems to provide it whether it is or not.
*/
val = 1;
if (setsockopt(sock_fd, SOL_PACKET, PACKET_AUXDATA, &val,
sizeof(val)) == -1 && errno != ENOPROTOOPT) {
@@ -2564,7 +2591,6 @@ activate_pf_packet(pcap_t *handle, int is_any_device)
return PCAP_ERROR;
}
handle->offset += VLAN_TAG_LEN;
#endif /* HAVE_PACKET_AUXDATA */
/*
* If we're in cooked mode, make the snapshot length
@@ -2584,30 +2610,8 @@ activate_pf_packet(pcap_t *handle, int is_any_device)
/*
* Set the offset at which to insert VLAN tags.
* That should be the offset of the type field.
*/
switch (handle->linktype) {
case DLT_EN10MB:
/*
* The type field is after the destination and source
* MAC address.
*/
handlep->vlan_offset = 2 * ETH_ALEN;
break;
case DLT_LINUX_SLL:
/*
* The type field is in the last 2 bytes of the
* DLT_LINUX_SLL header.
*/
handlep->vlan_offset = SLL_HDR_LEN - 2;
break;
default:
handlep->vlan_offset = -1; /* unknown */
break;
}
set_vlan_offset(handle);
if (handle->opt.tstamp_precision == PCAP_TSTAMP_PRECISION_NANO) {
int nsec_tstamps = 1;
@@ -2678,6 +2682,7 @@ setup_mmapped(pcap_t *handle, int *status)
ret = prepare_tpacket_socket(handle);
if (ret == -1) {
free(handlep->oneshot_buffer);
handlep->oneshot_buffer = NULL;
*status = PCAP_ERROR;
return ret;
}
@@ -2688,6 +2693,7 @@ setup_mmapped(pcap_t *handle, int *status)
* fail. create_ring() has set *status.
*/
free(handlep->oneshot_buffer);
handlep->oneshot_buffer = NULL;
return -1;
}
@@ -2889,40 +2895,30 @@ create_ring(pcap_t *handle, int *status)
tp_reserve = VLAN_TAG_LEN;
/*
* If we're using DLT_LINUX_SLL2, reserve space for a
* DLT_LINUX_SLL2 header.
* If we're capturing in cooked mode, reserve space for
* a DLT_LINUX_SLL2 header; we don't know yet whether
* we'll be using DLT_LINUX_SLL or DLT_LINUX_SLL2, as
* that can be changed on an open device, so we reserve
* space for the larger of the two.
*
* XXX - we assume that the kernel is still adding
* 16 bytes of extra space; that happens to
* correspond to SLL_HDR_LEN (whether intentionally
* or not - the kernel code has a raw "16" in
* the expression), so we subtract SLL_HDR_LEN
* from SLL2_HDR_LEN to get the additional space
* needed. That also means we don't bother reserving
* any additional space if we're using DLT_LINUX_SLL.
* 16 bytes of extra space, so we subtract 16 from
* SLL2_HDR_LEN to get the additional space needed.
* (Are they doing that for DLT_LINUX_SLL, the link-
* layer header for which is 16 bytes?)
*
* XXX - should we use TPACKET_ALIGN(SLL2_HDR_LEN - SLL_HDR_LEN)?
* XXX - should we use TPACKET_ALIGN(SLL2_HDR_LEN - 16)?
*/
if (handle->linktype == DLT_LINUX_SLL2)
tp_reserve += SLL2_HDR_LEN - SLL_HDR_LEN;
if (handlep->cooked)
tp_reserve += SLL2_HDR_LEN - 16;
/*
* Try to request that amount of reserve space.
* This must be done before creating the ring buffer.
* If PACKET_RESERVE is supported, creating the ring
* buffer should be, although if creating the ring
* buffer fails, the PACKET_RESERVE call has no effect,
* so falling back on read-from-the-socket capturing
* won't be affected.
*/
len = sizeof(tp_reserve);
if (setsockopt(handle->fd, SOL_PACKET, PACKET_RESERVE,
&tp_reserve, len) < 0) {
/*
* We treat ENOPROTOOPT as an error, as we
* already determined that we support
* TPACKET_V2 and later; see above.
*/
pcap_fmt_errmsg_for_errno(handle->errbuf,
PCAP_ERRBUF_SIZE, errno,
"setsockopt (PACKET_RESERVE)");
@@ -3118,6 +3114,9 @@ create_ring(pcap_t *handle, int *status)
pcap_strlcpy(ifr.ifr_name, handle->opt.device, sizeof(ifr.ifr_name));
ifr.ifr_data = (void *)&hwconfig;
/*
* This may require CAP_NET_ADMIN.
*/
if (ioctl(handle->fd, SIOCSHWTSTAMP, &ifr) < 0) {
switch (errno) {
@@ -3130,6 +3129,8 @@ create_ring(pcap_t *handle, int *status)
* try requesting hardware time stamps.
*/
*status = PCAP_ERROR_PERM_DENIED;
snprintf(handle->errbuf, PCAP_ERRBUF_SIZE,
"Attempt to set hardware timestamp failed - CAP_NET_ADMIN may be required");
return -1;
case EOPNOTSUPP:
@@ -3378,7 +3379,23 @@ pcap_setnonblock_linux(pcap_t *handle, int nonblock)
*/
handlep->timeout = ~handlep->timeout;
}
if (handlep->poll_breakloop_fd != -1) {
/* Close the eventfd; we do not need it in nonblock mode. */
close(handlep->poll_breakloop_fd);
handlep->poll_breakloop_fd = -1;
}
} else {
if (handlep->poll_breakloop_fd == -1) {
/* If we did not have an eventfd, open one now that we are blocking. */
if ( ( handlep->poll_breakloop_fd = eventfd(0, EFD_NONBLOCK) ) == -1 ) {
int save_errno = errno;
snprintf(handle->errbuf, PCAP_ERRBUF_SIZE,
"Could not open eventfd: %s",
strerror(errno));
errno = save_errno;
return -1;
}
}
if (handlep->timeout < 0) {
handlep->timeout = ~handlep->timeout;
}
@@ -3422,10 +3439,24 @@ static int pcap_wait_for_frames_mmap(pcap_t *handle)
struct ifreq ifr;
int ret;
struct pollfd pollinfo[2];
int numpollinfo;
pollinfo[0].fd = handle->fd;
pollinfo[0].events = POLLIN;
pollinfo[1].fd = handlep->poll_breakloop_fd;
pollinfo[1].events = POLLIN;
if ( handlep->poll_breakloop_fd == -1 ) {
numpollinfo = 1;
pollinfo[1].revents = 0;
/*
* We set pollinfo[1].revents to zero, even though
* numpollinfo = 1 meaning that poll() doesn't see
* pollinfo[1], so that we do not have to add a
* conditional of numpollinfo > 1 below when we
* test pollinfo[1].revents.
*/
} else {
pollinfo[1].fd = handlep->poll_breakloop_fd;
pollinfo[1].events = POLLIN;
numpollinfo = 2;
}
/*
* Keep polling until we either get some packets to read, see
@@ -3467,7 +3498,7 @@ static int pcap_wait_for_frames_mmap(pcap_t *handle)
* don't need to poll.
*/
for (;;) {
/*
/*
* Yes, we do this even in non-blocking mode, as it's
* the only way to get error indications from a
* tpacket socket.
@@ -3490,7 +3521,7 @@ static int pcap_wait_for_frames_mmap(pcap_t *handle)
if (timeout != 0)
timeout = 1;
}
ret = poll(pollinfo, 2, timeout);
ret = poll(pollinfo, numpollinfo, timeout);
if (ret < 0) {
/*
* Error. If it's not EINTR, report it.
@@ -3772,6 +3803,7 @@ static int pcap_handle_packet_mmap(
unsigned char *bp;
struct sockaddr_ll *sll;
struct pcap_pkthdr pcaphdr;
pcap_can_socketcan_hdr *canhdr;
unsigned int snaplen = tp_snaplen;
struct utsname utsname;
@@ -3890,6 +3922,68 @@ static int pcap_handle_packet_mmap(
snaplen += sizeof(struct sll_header);
}
} else {
/*
* If this is a packet from a CAN device, so that
* sll->sll_hatype is ARPHRD_CAN, then, as we're
* not capturing in cooked mode, its link-layer
* type is DLT_CAN_SOCKETCAN. Fix up the header
* provided by the code below us to match what
* DLT_CAN_SOCKETCAN is expected to provide.
*/
if (sll->sll_hatype == ARPHRD_CAN) {
/*
* DLT_CAN_SOCKETCAN is specified as having the
* CAN ID and flags in network byte order, but
* capturing on a CAN device provides it in host
* byte order. Convert it to network byte order.
*/
canhdr = (pcap_can_socketcan_hdr *)bp;
canhdr->can_id = htonl(canhdr->can_id);
/*
* In addition, set the CANFD_FDF flag if
* the protocol is LINUX_SLL_P_CANFD, as
* the protocol field itself isn't in
* the packet to indicate that it's a
* CAN FD packet.
*/
uint16_t protocol = ntohs(sll->sll_protocol);
if (protocol == LINUX_SLL_P_CANFD) {
canhdr->fd_flags |= CANFD_FDF;
/*
* Zero out all the unknown bits in
* fd_flags and clear the reserved
* fields, so that a program reading
* this can assume that CANFD_FDF
* is set because we set it, not
* because some uninitialized crap
* was provided in the fd_flags
* field.
*
* (At least some LINKTYPE_CAN_SOCKETCAN
* files attached to Wireshark bugs
* had uninitialized junk there, so it
* does happen.)
*
* Update this if Linux adds more flag
* bits to the fd_flags field or uses
* either of the reserved fields for
* FD frames.
*/
canhdr->fd_flags &= ~(CANFD_FDF|CANFD_ESI|CANFD_BRS);
canhdr->reserved1 = 0;
canhdr->reserved2 = 0;
} else {
/*
* Clear CANFD_FDF if it's set (probably
* again meaning that this field is
* uninitialized junk).
*/
canhdr->fd_flags &= ~CANFD_FDF;
}
}
}
if (handlep->filter_in_userland && handle->fcode.bf_insns) {
@@ -4002,9 +4096,22 @@ pcap_read_linux_mmap_v2(pcap_t *handle, int max_packets, pcap_handler callback,
}
}
/* non-positive values of max_packets are used to require all
* packets currently available in the ring */
while ((pkts < max_packets) || PACKET_COUNT_IS_UNLIMITED(max_packets)) {
/*
* This can conceivably process more than INT_MAX packets,
* which would overflow the packet count, causing it either
* to look like a negative number, and thus cause us to
* return a value that looks like an error, or overflow
* back into positive territory, and thus cause us to
* return a too-low count.
*
* Therefore, if the packet count is unlimited, we clip
* it at INT_MAX; this routine is not expected to
* process packets indefinitely, so that's not an issue.
*/
if (PACKET_COUNT_IS_UNLIMITED(max_packets))
max_packets = INT_MAX;
while (pkts < max_packets) {
/*
* Get the current ring buffer frame, and break if
* it's still owned by the kernel.
@@ -4097,9 +4204,22 @@ again:
return pkts;
}
/* non-positive values of max_packets are used to require all
* packets currently available in the ring */
while ((pkts < max_packets) || PACKET_COUNT_IS_UNLIMITED(max_packets)) {
/*
* This can conceivably process more than INT_MAX packets,
* which would overflow the packet count, causing it either
* to look like a negative number, and thus cause us to
* return a value that looks like an error, or overflow
* back into positive territory, and thus cause us to
* return a too-low count.
*
* Therefore, if the packet count is unlimited, we clip
* it at INT_MAX; this routine is not expected to
* process packets indefinitely, so that's not an issue.
*/
if (PACKET_COUNT_IS_UNLIMITED(max_packets))
max_packets = INT_MAX;
while (pkts < max_packets) {
int packets_to_read;
if (handlep->current_packet == NULL) {
@@ -4112,12 +4232,12 @@ again:
}
packets_to_read = handlep->packets_left;
if (!PACKET_COUNT_IS_UNLIMITED(max_packets) &&
packets_to_read > (max_packets - pkts)) {
if (packets_to_read > (max_packets - pkts)) {
/*
* We've been given a maximum number of packets
* to process, and there are more packets in
* this buffer than that. Only process enough
* There are more packets in the buffer than
* the number of packets we have left to
* process to get up to the maximum number
* of packets to process. Only process enough
* of them to get us up to that maximum.
*/
packets_to_read = max_packets - pkts;
@@ -4322,7 +4442,18 @@ pcap_setfilter_linux(pcap_t *handle, struct bpf_program *filter)
* the filter for a reason other than "this kernel
* isn't configured to support socket filters.
*/
if (errno != ENOPROTOOPT && errno != EOPNOTSUPP) {
if (errno == ENOMEM) {
/*
* Either a kernel memory allocation
* failure occurred, or there's too
* much "other/option memory" allocated
* for this socket. Suggest that they
* increase the "other/option memory"
* limit.
*/
fprintf(stderr,
"Warning: Couldn't allocate kernel memory for filter: try increasing net.core.optmem_max with sysctl\n");
} else if (errno != ENOPROTOOPT && errno != EOPNOTSUPP) {
fprintf(stderr,
"Warning: Kernel filter failed: %s\n",
pcap_strerror(errno));
@@ -4465,12 +4596,18 @@ iface_bind(int fd, int ifindex, char *ebuf, int protocol)
*/
return PCAP_ERROR_IFACE_NOT_UP;
}
if (errno == ENODEV)
if (errno == ENODEV) {
/*
* There's nothing more to say, so clear the
* error message.
*/
ebuf[0] = '\0';
ret = PCAP_ERROR_NO_SUCH_DEVICE;
else
} else {
ret = PCAP_ERROR;
pcap_fmt_errmsg_for_errno(ebuf, PCAP_ERRBUF_SIZE,
errno, "bind");
pcap_fmt_errmsg_for_errno(ebuf, PCAP_ERRBUF_SIZE,
errno, "bind");
}
return ret;
}
@@ -4681,12 +4818,12 @@ iface_set_all_ts_types(pcap_t *handle, char *ebuf)
return 0;
}
#ifdef ETHTOOL_GET_TS_INFO
/*
* Get a list of time stamping capabilities.
* Get a list of time stamp types.
*/
#ifdef ETHTOOL_GET_TS_INFO
static int
iface_ethtool_get_ts_info(const char *device, pcap_t *handle, char *ebuf)
iface_get_ts_types(const char *device, pcap_t *handle, char *ebuf)
{
int fd;
struct ifreq ifr;
@@ -4773,6 +4910,8 @@ iface_ethtool_get_ts_info(const char *device, pcap_t *handle, char *ebuf)
* report HWTSTAMP_FILTER_ALL but map it to only
* time stamping a few PTP packets. See
* http://marc.info/?l=linux-netdev&m=146318183529571&w=2
*
* Maybe that got fixed later.
*/
handle->tstamp_type_list = NULL;
return 0;
@@ -4804,7 +4943,7 @@ iface_ethtool_get_ts_info(const char *device, pcap_t *handle, char *ebuf)
}
#else /* ETHTOOL_GET_TS_INFO */
static int
iface_ethtool_get_ts_info(const char *device, pcap_t *handle, char *ebuf)
iface_get_ts_types(const char *device, pcap_t *handle, char *ebuf)
{
/*
* This doesn't apply to the "any" device; you can't say "turn on
@@ -4827,7 +4966,15 @@ iface_ethtool_get_ts_info(const char *device, pcap_t *handle, char *ebuf)
return 0;
}
#endif /* ETHTOOL_GET_TS_INFO */
#else /* defined(HAVE_LINUX_NET_TSTAMP_H) && defined(PACKET_TIMESTAMP) */
static int
iface_get_ts_types(const char *device _U_, pcap_t *p _U_, char *ebuf _U_)
{
/*
* Nothing to fetch, so it always "succeeds".
*/
return 0;
}
#endif /* defined(HAVE_LINUX_NET_TSTAMP_H) && defined(PACKET_TIMESTAMP) */
/*
@@ -5093,12 +5240,17 @@ iface_get_arptype(int fd, const char *device, char *ebuf)
if (errno == ENODEV) {
/*
* No such device.
*
* There's nothing more to say, so clear
* the error message.
*/
ret = PCAP_ERROR_NO_SUCH_DEVICE;
} else
ebuf[0] = '\0';
} else {
ret = PCAP_ERROR;
pcap_fmt_errmsg_for_errno(ebuf, PCAP_ERRBUF_SIZE,
errno, "SIOCGIFHWADDR");
pcap_fmt_errmsg_for_errno(ebuf, PCAP_ERRBUF_SIZE,
errno, "SIOCGIFHWADDR");
}
return ret;
}