diff options
author | Guy Harris <guy@alum.mit.edu> | 2020-01-29 14:25:15 -0800 |
---|---|---|
committer | Guy Harris <guy@alum.mit.edu> | 2020-01-29 14:25:34 -0800 |
commit | a973128a85d7dd75c7ea6fdcf746fc143a987d03 (patch) | |
tree | 244eab6a441630b5ff7832c9a8157ce29b228dde /pcap_get_selectable_fd.3pcap | |
parent | e97a651aff28c4bae6696958afbb94f88d80645b (diff) |
On Linux, return error on interface going away, not just going down.
This is a pain to detect, because the PF_PACKET socket code appears to
get separate "interface went down" and "interface went away"
notifications in my "unplug a USB Wi-Fi adapter" tests on my VMware
Fusion Ubuntu 18.04 virtual machine (5.3.0 kernel), and the first
notification delivers a wakeup and returns ENETDOWN while the second
notificaiton delivers *no* wakeup and sets the ifindex member of the
struct packet_sock for the socket, so there's nothing we can test after
the wakeup that's guaranteed to indicate that the interface has
disappeared.
So what we have to do is remember the ENETDOWN but not return it as an
error, and then arrange to periodically check whether the interface is
still there; if it isn't, we *then* return the "interface went away"
error, and, if we see traffic or see that the interface is up, we clear
the remembered ENETDOWN and stop doing the periodic checks.
This is tricky, because it needs to work not only for blocking pcap_t's,
where we're in a loop doing poll() calls, so we can keep checking within
the loop, but also for non-blocking pcap_t's on which the caller is
doing select()/poll()/epoll_wait().
In order to make *that* work, we need to tweak the semantics of
pcap_get_required_select_timeout() so that it's not guaranteed that it
will always return the same value, so that it should be called within
event loops rather than called once outside the event loop. Normally,
there is no timeout required for Linux PF_PACKET sockets, but when we're
doing the periodic tests, the timeout is required.
While we're doing that, we make the return value of
pcap_get_required_select_timeout() a const pointer - there was no good
reason for the caller to modify it (it doesn't belong to the caller).
If poll() returns POLLERR, use getsockopt(SO_ERROR) to get the socket
error, rather than a read().
Update the documentation to reflect this, and make various other
cleanups (including documenting the error return value for
pcap_get_selectable_fd() to -1 rather than PCAP_ERROR - it's not an
error code, it's just a specific error value). Also note that, for
kqueues on *BSD/macOS and for select/poll on Linux, the timeout needn't
be used as a timeout for the call - you can have a timer, so that when
that *particular* timer fires, you try calling pcap_dispatch() on the
pcap_t to which it corresponds.
Update selpolltest to add more capabilities needed when testing this on
Linux.
This should address GitHub issue #859 and pull request #858.
Diffstat (limited to 'pcap_get_selectable_fd.3pcap')
-rw-r--r-- | pcap_get_selectable_fd.3pcap | 8 |
1 files changed, 4 insertions, 4 deletions
diff --git a/pcap_get_selectable_fd.3pcap b/pcap_get_selectable_fd.3pcap index 883aae8c..5e200dd7 100644 --- a/pcap_get_selectable_fd.3pcap +++ b/pcap_get_selectable_fd.3pcap @@ -43,7 +43,7 @@ do a or other such call to wait for it to be possible to read packets without blocking, if such a descriptor exists, or -.BR PCAP_ERROR , +.BR \-1 , if no such descriptor exists. .PP Some network devices opened with @@ -54,7 +54,7 @@ or with .BR pcap_open_live (3PCAP), do not support those calls (for example, regular network devices on FreeBSD 4.3 and 4.4, and Endace DAG devices), so -.B PCAP_ERROR +.B \-1 is returned for those devices. In that case, those calls must be given a timeout less than or equal to the timeout returned by @@ -62,7 +62,7 @@ than or equal to the timeout returned by for the device for which .BR pcap_get_selectable_fd () returned -.BR PCAP_ERROR , +.BR \-1 , the device must be put in non-blocking mode with a call to .BR \%pcap_setnonblock (3PCAP), and an attempt must always be made to read packets from the device @@ -145,7 +145,7 @@ work on that descriptor in Mac OS X 10.6 and later. is not available on Windows. .SH RETURN VALUE A selectable file descriptor is returned if one exists; otherwise, -.B PCAP_ERROR +.B \-1 is returned. .SH SEE ALSO .BR pcap (3PCAP), |