-
Notifications
You must be signed in to change notification settings - Fork 2.5k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Remove use of pcap-int.h on Windows #426
Comments
…pened. This patch is for the issue: nmap/nmap#426
Hi @dmiller-nmap , I have fixed this issue, starting from Npcap 0.07 R16, Try this feature with latest Npcap installer at: As Nmap will use Npcap definitely, I hope you could replace the |
OK, a couple of points: Whether a given UN*X platform supports If you are trying to get notified of packet arrival as soon as the packet is seen by the networking software, you can, with newer versions of libpcap, turn on "immediate mode", which means BPF immediate mode with BPF, using TPACKET_V2 on Linux with memory-mapped capture, using a zero bufmod timeout with Solaris 10 and earlier, and not turning on ENBATCH on Tru64 UNIX (and making some attempts on SunOS prior to 5.0, but I'm just guessing there, and with Endace DAG cards). On Windows, it calls "Immediate mode" has to be set before activating the "Immediate mode" may still do buffering, if packets arrive between the point at which the kernel delivers a wakeup and the point at which pcap actually tries getting packets, so it makes no guarantee of one-packet-per-wakeup. All it does is indicate that you should get a wakeup as soon as the first new packet arrives.
Actually, it has changed significantly. In libpcap 1.5, for example, a lot of variables were moved into per-pcap-XXX.c structures, with a
Unfortunately, on Linux, with TPACKET_V3, it looks as if that can only be set when the packet ring buffer is created, and can't be adjusted afterwards. On {OS X, *BSD}, it could be done, and it's probably supported on Solaris 11 as well. On earlier versions of Solaris, I think it could be done as well. But "on Linux, with TPACKET_V3" is a big roadblock, unless you don't need to change the timeouts after So what is the underlying issue nmap is trying to solve here? |
BTW, be careful when extending libpcap APIs for Npcap - they may not be as extensible as you'd like, and you may have to maintain the source changes indefinitely if you don't discuss them on tcpdump-users first. If supporting changing the read timeout after opening/activating, on platforms where it's possible, is necessary, that would, in libpcap, have to be done by adding a new function pointer for the "change timeout" operator, and the Linux version would, if TPACKET_V3 is being used (which it would be, with kernel versions that support it and libpcap versions that know about it, unless immediate mode is specified), just return PCAP_ERROR_ACTIVATED. |
I didn't fully understand the details here, but what seems to be is that the latest libpcap has solved this issue? Then I think the current manner is just a workaround. In fact, I'm working on the latest libpcap's integration with Npcap. So I personally think this issue will be gone automatically when the work is done. UPDATE: Now Npcap has moved to latest libpcap 1.8.0. So it seems that we can use the new immediate mode @guyharris mentioned now. I think all we need to do is to call But according to @dmiller-nmap , our goal is |
Hi @bonsaiviking @dmiller-nmap , I have found out why Nmap crashes with Npcap with libpcap 1.8.0. Nmap includes a internal header of libpcap: In the old 1.0.0 pcap-int.h: the offset is 0. So Nmap got the wrong adapter value when linking with the new Npcap. The solutions are:
I think we can go 1. as a workaround. But I think 2. is better. Because Nmap should not rely on an internal-use header. I didn't add the feature of |
OK, so:
BPF device FDs, which are what you'd get from That bug was fixed in FreeBSD 4.6, NetBSD 3.0, OpenBSD 2.4, and OS X 10.7, and may never have been present in DragonFly BSD (if it forked from FreeBSD in 4.6 or later). So, with Lion and later, OS X does have selectable pcap file handles. I don't know whether the other UN*Xes using BPF - AIX and Solaris 11 - the FD is selectable. (I don't have an AIX system on which I have privileges to test this, but I should try it on my Solaris 11 VM.) I don't know whether Tru64 UNIX's packetfilter descriptors are selectable. The packetfilter(7) man page says that "Normally, a packet filter application blocks in the read system call until a received packet is available for reading. There are several ways to avoid blocking indefinitely: an application can use the select(2) system call, it can set a ``timeout'' for the packet filter file, or it can request the delivery of a signal (see sigvec(2)) when a packet matches the filter.", but I don't know whether that means that On other UN*Xes, the FDs should always have been selectable, with This means that As for
because all of those systems do buffering. (Well, on Linux with memory-mapped capture, it's not reading packets into the buffer - the buffer is a ring shared between the kernel and userland - but, as far as I know, it's possible that if you do a
So, if the goal is to wait no more than X seconds (where X could be a fraction) for a packet, in a loop that doesn't have to multiplex operations on other descriptors (which appears to be the case, from a quick look at
|
But that all raises the question "what is it you're trying to do here?" What, at a high level (above all of the implementation details of pcap on different platforms) is There may be a different, and better, way of accomplishing this. |
@guyharris Thank you so much for your analysis. I think that what I would like to do is accomplish this in 2 stages: First, a stop-the-bleeding fix that gets us functional on both WinPcap and Npcap without the use of To accomplish the first goal, I think it will be possible to take this approach:
I'd appreciate your thoughts on that approach. As far as the intent of
I think, for example, that |
The timeout mechanisms in various capture mechanisms don't handle waiting until some absolute time; they wait for some relative time (mostly "relative to when a read is done", although on at least some versions of Solaris it's "relative to when the first packet arrives"). So you'd have to use some other mechanism for that. If your goal is to ensure that, when that absolute time arrives, the main loop will not be blocked waiting for packets, the best way to do that, on platforms where either
The "process input packets" and "if the absolute time has arrived, send packets" can be swapped here if that's what's appropriate.
The capture mechanisms should all buffer packets that arrive while a read isn't pending, so that should be OK.
If you mean "see incoming packets as soon as possible after they arrive", the best way to do that is to use immediate mode. |
pcap-int.h
contains pcap "internals" that we shouldn't really be using. On Windows, we use it to peek into thestruct pcap
in order to retrieve theADAPTER *adapter
member to use in a call toPacketSetReadTimeout
intcpip.cc
. The reason for this call is explained in this nmap-dev post from 2010.Since this header contains internal implementation-specific details, we shouldn't rely on it not changing (though it hasn't in almost a decade). Instead, we should find a way to accomplish the same task (setting varying timeouts on a single pcap descriptor) in a way that works on all platforms. This might be accomplished via #123, but it might require separate or extra effort.
The text was updated successfully, but these errors were encountered: