support Linux Frame Relay ARPHRD_FRAD as Frame Relay with an FR
header;
support Linux Frame Relay ARPHRD_DLCI in cooked mode;
current Linux kernels use the name ARPHRD_CISCO for Cisco HDLC
(513).
reading packets from a pcap_t, and make "pcap_read()" call it. That
removes the last place where we have to check for a pcap_t that refers
to a DAG card rather than a live capture, so get rid of the "is_dag" flag.
handles setting a filter for a pcap_t. Have "pcap_setfilter()" call it,
rather than being a per-platform function. The per-platform functions
don't need to check for an offline capture any more, as they're not
called for an offline capture (and the ones that just call
"install_bpf_program()" don't need to exist at all).
getting statistics for a pcap_t. Have "pcap_stats()" call it, rather
than being a per-platform function; have stats routines for non-live
pcap_t's that return an error.
the platform-dependent part of closing a pcap_t (and the
live-vs-savefile part as well, so that function must close the file
descriptor and free up any buffers allocated).
In the Digital UNIX support, add in a check for a memory allocation
failure.
with some interfaces (see bug 599857 in the SourceForge list of libpcap
bugs), and, even if it doesn't cause problems, it's different from
what's done on other platforms.
which supplies different headers from BSD ARCNET, and fixes to the
ARCNET code generator (the protocol ID field is 1 byte, so the values
for it shouldn't be byte-swapped).
Whitespace cleanups.
The "NetBSD-style" ARCNET headers are used in other BSDs as well, so
just call them "BSD-style".
argument to "pcap_open_live()" a "const" pointer.
Constify some additional device name arguments, and update the man page
to reflect some arguments that were already consts.
Young <dyoung@ojctech.com>, with some minor changes by Jason R. Thorpe
<thorpej@netbsd.org>, and further changes by me to support it on BPF
systems lacking BIOCGDLTLIST and other platforms lacking an equivalent
feature.
Update Jason Thorpe's e-mail address (Zembu is going away, if it hasn't
done so already).
Add APIs to map DLT names to DLT values and vice versa.
new 2.2-or-later kernel, with PF_PACKET sockets including SOL_PACKET,
but with an older version of the C library whose headers don't define
SOL_PACKET.
On those systems, define SOL_PACKET to have the value it has in the
2.2.0 kernel; this means we can get rid of the "#ifdef
SOL_PACKET"/#endif stuff wrapped around the code to turn promiscuous
mode on or off (we don't want that #ifdeffed out, as if it's absent we
won't pay attention to the "promiscuous mode" flag argument to
"pcap_open_live()").
1. During termination processing set up by atexit() under a 2.0.x
kernel, if a socket had been previously closed and the handle freed
due to an error, pcap_close_all() and pcap_close_linux() would
nevertheless try to work with these structures and then crash.
pcap_close_linux() is now called directly when necessary during
error processing.
2. atexit() could get called more than once because the did_atexit
flag wasn't being set.
3. If iface_get_arptype() returns an error because the ioctl() call
failed (probably due to "no such device"), live_open_new() now
returns a fatal error to pcap_open_live() and the call to
live_open_old() is short-circuited.
4. Applications using libpcap would appear to listen on an interface
that was down.
a. iface_bind() and iface_bind_old() now check for pending errors
after bind(). In turn, pcap_open_live() now returns an error
status if there was a pending error after bind().
b. After draining the socket, set_kernel_filter() now checks to see
if the error was the expected EAGAIN and returns a fatal error
to pcap_setfilter() if not. In turn, pcap_setfilter() now
returns an error status if there was a network error.
5. pcap_setfilter() was putting an error message into errbuf after a
failed call to install_bpf_program(). This was unnecessary since
install_bpf_program() puts its own error message into errbuf.
return DLT_LINUX_SLL or not, and, if that flag is false, for those
interface types where we'd used DLT_LINUX_SLL, pick a DLT_ type that
works as well as possible in raw mode, or fail.
Pass 1 as that flag if we're using a PF_PACKET socket; pass 0 as that
flag if we're using a PF_INET/SOCK_PACKET socket.
For PF_INET/SOCK_PACKET sockets, try to get the link-layer type and map
it to a DLT_ value *before* turning promiscuous mode on, so that we
don't try to put the interface into promiscuous mode unless we know we
can handle its link-layer type (and thus that we can use the interface).
ARPHRD_IEEE80211_PRISM, for sniffing on Prism II-based 802.11 interfaces
and getting the special Prism header, so we should map it to
DLT_PRISM_HEADER.
Don't subtract "tp_drops" from "tp_packets" - "ps_recv", on BSD,
at least, includes packets dropped due to lack of buffer space,
so it should do so on Linux as well.
The "len" argument to "getsockopt()" is a value-result
parameter, initially containing the size of the buffer being
supplied; set it before the call.
Catch "getsockopt()" errors and, if it's an error other than
EOPNOTSUPP, return an error.
didn't handle; fix the code to do so.
Remove the word "Warning" from the warning - tcpdump will add it when it
prints the warning, as will Ethereal and Tethereal.
Add a new "pcap_findalldevs()" routine to get a list of all
interfaces that can be opened with "pcap_open_live()", and a
"pcap_freealldevs()" routine to free the list.
Make "pcap_lookupdev()" use it, which also arranges that it will
not return a device that cannot be opened by "pcap_open_live()".
Allow the "any" device to be opened, on Linux, with "promisc"
non-zero; ignore the request for promiscuity, and return a
warning message indicating that promiscuous mode isn't supported
on the "any" device.
Document "pcap_findalldevs()" and "pcap_lookupdev()", and clean up some
items in the libpcap man page.
packets before the network-layer header; we already deal with that in
tcpdump, and we could probably try to deal with that in the code
generator, but it's less of a pain to just punt to DLT_LINUX_SLL.
"pcap_setfilter()" if we're not using a kernel filter, in case a
previous call to "pcap_setfilter()" had succeeded in adding a kernel
filter, as if we're doing userland filtering we need to get rid of all
kernel filters that might discard packets that'd pass the userland
filter.
packets queued up on the socket when we set a kernel filter on the
socket, so that if there are any queue-up packets that wouldn't have
passed the new filter, we don't see them. (Some other packet capture
mechanisms do this automatically; this prevents tcpdump, for example,
from showing or saving, when run with a filter, some packets that
wouldn't have passed the filter.)
XXX - do we have to do this on any other platforms?
Choose whether to compile in the code to modify filter programs for use
in the kernel, and to flush queued-up packet and set a kernel filter, on
whether SO_ATTACH_FILTER is defined (i.e., on whether we have kernel
filter support in our build environment), rather than on whether
HAVE_PF_PACKET_SOCKETS is defined (i.e., on whether we have PF_PACKET
support in our build environment), as we choose whether to *use* that
code based on whether SO_ATTACH_FILTER is defined.
the pointer to the beginning of the link-layer header; never use just
"handle->buffer", as, if "handle->offset" is non-zero (as is the case
with many link-layer types, including Ethernet), "handle->buffer"
doesn't point to the beginning of the link-layer header.
compiled on a system that doesn't have it, it'll use it on systems that
do have it.
On systems with MSG_TRUNC support (i.e., 2.2 and later kernels), there's
no need to read in the entire packet in order to find out how large it
is, so just allocate a buffer big enough for a snapshot length's worth
of data, and just read that much data.
There's no need for a "readlen" member of the "pcap_md" structure, as
the byte count to "recvfrom()" is just the "bufsize" member of the
"pcap_t" structure.
that we don't have almost-duplicate code in "live_open_old()" and
"live_open_new()". This fixes a bug wherein "live_open_new()" wasn't
making the buffer size the maximum of "enough to hold packets of the MTU
obtained from the socket" and "the snapshot length" (for some reason,
"recvfrom()" was copying more data than the MTU obtained from the
socket).
SOL_PACKET/PACKET_STATISTICS "getsockopt()" call, on Linux kernels that
support it, to get packet statistics, so that we can report the number
of dropped packets, and always use <linux/if_packet.h> to get
definitions for PF_PACKET sockets, so that we don't depend on glibc's
header files having been updated to support all the latest shiniest
kernel features (many systems with 2.4[.x] kernels don't have a
<netpacket/packet.h> that defines "struct tpacket_stats", for example,
so we wouldn't have been able to support that kernel feature on those
systems).
to DLT_C_HDLC.
Arrange that if "map_arphrd_to_dlt()" supplies DLT_LINUX_SLL as the
link-layer DLT_ value, we capture in cooked mode.
Return DLT_LINUX_SLL for ARPHRD_PPP, as some PPP code in the kernel
supplies no link-layer header whatsoever to PF_PACKET sockets, other PPP
code supplies PPP link-layer headers ("syncppp.c"), and PPP-over-ISDN
appears to supply random link-layer headers (there's code in Ethereal,
for example, to cope with PPP-over-ISDN captures with which the Ethereal
developers have had to cope, heuristically trying to determine which of
the oddball link-layer headers particular packets have).
support PF_PACKET sockets, and, in particular, don't define in
<linux/if_packet.h> any of the stuff needed by the code to handle
PF_PACKET sockets. Define HAVE_PF_PACKET_SOCKETS if either
1) we have <netpacket/packet.h>
or
2) PF_PACKET is defined *and* PACKET_HOST is defined by
<linux/if_packet.h>
and use HAVE_PF_PACKET_SOCKETS, not PF_PACKET, be what we use in #ifdefs
to conditionally compile in support for PF_PACKET sockets.
Not all platforms define ARPHRD_SIT, either; #define it if it's not
already defined.
<net/if_arp.h>, and the stuff we want is in <net/if_arp.h>, so include
that rather than <netinet/if_ether.h>.
At least some libc5 systems don't have <netpacket/packet.h>, but have a
<sys/socket.h> that includes <linux/socket.h>, and the latter defines
SO_ATTACH_FILTER if the kernel is a 2.2 or later kernel, so there exist
systems that have SO_ATTACH_FILTER defined but don't have
<netpacket/packet.h>. Work around that by:
checking whether we have PF_PACKET sockets by checking whether
PF_PACKET is defined, not whether we have <netpacket/packet.h>
(but we still check whether we have <netpacket/packet.h> before
including it);
if PF_PACKET is defined but we don't have <netpacket/packet.h>,
include <linux/if_packet.h> to get the relevant definitions.
Set "off_linktype" to the correct value for the offset of the Ethernet
type field in the fake header for Linux cooked captures, so that the
correct code is generated for tests of that field.
Linux; Linux isn't the only platform whose kernel doesn't support a
read timeout, and even some that *do* don't start the timer until at
least one packet has arrived (Solaris, for example), so no portable
application can depend on "pcap_dispatch()", say, blocking for no longer
than the timeout - they must do a "select()" themselves. For
applications that do the "select()" themselves, or that don't need the
timeout for polling (tcpdump, for example), doing a "select()" in
libpcap just adds another system call to the code path.
at the end of the link-layer header; put it there.
Put in a comment indicating that the layout of the link-layer header
shouldn't be changed; if a new header is necessary, a new DLL_ type
should be introduced for it.
we just treat the frame as an LLC frame (if we care about Novell
IPX-over-raw-802.3 frames, we'd have to handle them by checking for
0xFFFF as the first word - but we'd also have to do that when dissecting
Ethernet frames).
future Linux kernel changes the PACKET_ values out from under us, the
values recorded in the packet header in DLT_LINUX_SLL captures does
*not* change.
Don't map ETH_P_802_2 to the packet length, map it and ETH_P_802_3 to
standardized LINUX_SLL_P_ values, so that even if a future Linux kernel
changes the ETH_P_ values out from under us, the values recorded in the
packet header in DLT_LINUX_SLL captures does *not* change, and so that
you don't have to be running on Linux to be able to handle DLT_LINUX_SLL
captures.
live captures with a "cooked" (SOCK_DGRAM) rather than a "raw"
(SOCK_RAW) PF_PACKET socket; it includes a bunch of the fields from the
"struct sockaddr_ll" you get in a "recvfrom()", including the Ethernet
protocol field.
This requires us to rewrite the BPF program if we're stuffing it into
the kernel; as long as we're doing *ex post facto* rewriting, we might
as well also do the "ret <snaplen>" -> "ret 65535" fixup there as well,
rather than in the code generator.
remember which pcap_t's were opened (with SOCK_PACKET) in promiscuous
mode on interfaces not already in promiscuous mode, turn promiscuous
mode off when closing such a pcap_t, and arrange that, when the program
exits, all pcap_t's of that sort not already closed have their
interfaces taken out of promiscuous mode. (It's not sufficient to do
this on exit - applications may close a pcap_t without exiting, e.g.
Ethereal.)
This won't always work right (if somebody else requests promiscuous mode
after it's opened by libpcap, we'll turn promiscuous mode off when we
close the pcap_t, and if the program doesn't exit cleanly, it won't
clean up the interfaces), but neither of those problems are fixable -
the only way to get things to work correctly is to use PF_PACKET
sockets, which requires a 2.2 or later kernel.
On a 2.0[.x] kernel, when doing a "recvfrom()" on a SOCK_PACKET socket
to read a captured packet, don't pass a byte count value based on the
snapshot length - "recvfrom()" won't return the actual packet length if
you do that. (2.2 and later kernels will return the actual packet
length if MSG_TRUNC is passed in.)
ARPHRD_IEEE802, as the hardware type for Token Ring interfaces. Map
both of them to DLT_IEEE802 (as that has become the DLT_ type for Token
Ring, the fact that it just says "802", not "802_5" or whatever,
nonwithstanding), and, if ARPHRD_IEEE802_TR isn't defined, define it
with the value it has in 2.4 (so that the resulting libpcap will work on
a 2.4 system regardless of whether the system on which it was built
defined ARPHRD_IEEE802_TR).
filter, always attach a copy, as "pcap-linux.c" does; that way, after a
program uses "pcap_setfilter()", it can safely use "pcap_freecode()" to
free up the BPF instructions allocated by "pcap_compile()". Also,
always free it up when the "pcap_t" is closed.
Get rid of the "pcap_t *" argument to "pcap_freecode()", as it's not
necessary.
Document "pcap_freecode()", for the benefit of programs that might
repeatedly compile filter programs and attach them, so that they can
free them up after attaching them and avoid leaking memory for them.
interface index of the interface for the packet is the interface index
of the loopback interface and, if it is, check if the packet is an
outgoing packet; if so, ignore it, as we'll also be seeing that packet
as a received packet.
If we don't handle the arphrd type of an interface, and fall back on
cooked mode, report the arphrd type, so we know what type we should
consider supporting (if that type can't be supported well, e.g. if you
don't get any link-layer header, as happens with PPP, we'd be silent).
filter.
It appears that "recvfrom()", in 2.2 and later kernels, doesn't check
whether the starting buffer address plus the byte count goes into an
unmapped region of the address space - it (or code it calls) presumably
only checks the locations into which it's actually copying data - so
there doesn't appear to be, on systems with 2.2 and later kernels, any
need to ensure that the buffer size is at least large as the snapshot
length. We therefore only do so if we're using the old
PF_INET/SOCK_PACKET mechanism; if we're using PF_PACKET, we're on a
2.2 or later kernel, so we don't do it there.
"HAVE_NETPACKET_PACKET_H" isn't defined, as we won't define them if it's
not defined.
If the packet buffer size, as computed from the MTU of the interface, is
less than the user's requested snapshot length, set it to the user's
requested snapshot length; otherwise, the "recvfrom()" call will fail,
as the length specified in the call is the user's requested snapshot
length, and the kernel checks whether the buffer is big enough for that
much data and rejects the "recvfrom()" call if it's not.
application won't build with any other version of libpcap, which means
that a lot of applications won't use them. In addition,
"pcap_linktype()" needs to return DLT_ values, so that platforms that
build libpcap as a shared library won't break binary compatibility if
they update to this version of libpcap.
Instead, we map from DLT_ values to LINKTYPE_ values when writing
savefiles, and map from LINKTYPE_ values to DLT_ values when reading
savefiles, so that savefiles don't have platform-dependent DLT_ values
in the header as the link type, they have platform-independent LINKTYPE_
values.
This means we don't need to make DLT_ATM_RFC1483, DLT_RAW, etc. have
platform-independent values starting at 100 - only the values in the
savefile header need to be like that.
For those PCAP_ENCAP_ codes corresponding to DLT_ codes that are
(believed to be) the same in all BSDs, the PCAP_ENCAP_ codes have the
same values as the corresponding DLT_ codes.
For those PCAP_ENCAP_ codes corresponding to DLT_ codes that were added
in libpcap 0.5 as "non-kernel" DLT_ codes, or had their values changed
in libpcap 0.5 in order to cope with the fact that those DLT_ codes
have different values in different systems, the PCAP_ENCAP_ codes have
the same values as the corresponding DLT_ codes.
We add some additional PCAP_ENCAP_ codes to handle IEEE 802.11 (which
currently has its link-layer information turned into an Ethernet header
by at least some of the BSDs, but John Hawkinson at MIT wants to add a
DLT_ value for 802.11 and pass up the full link-layer header) and the
Classical IP encapsulation for ATM on Linux (which isn't always the same
as DLT_ATM_RFC1483, from what I can tell, alas).
"pcap-bpf.c" maps DLT_ codes to PCAP_ENCAP_ codes, so as not to supply
to libpcap's callers any DLT_ codes other than the ones that have the
same values on all platforms; it supplies PCAP_ENCAP_ codes for all
others.
In libpcap's "bpf/net/bpf.h", we define the DLT_ values that aren't the
same on all platforms with the new values starting at 100 (to keep them
out of the way of the values various BSDs might assign to them), as we
did in 0.5, but do so only if they're not already defined; platforms
with <net/bpf.h> headers that come with the kernel (e.g., the BSDs)
should define them with the values that they have always had on that
platform, *not* with the values we used in 0.5.
(Code using this version of libpcap should check for the new PCAP_ENCAP_
codes; those are given the values that the corresponding DLT_ values had
in 0.5, so code that checks for them will handle 0.5 libpcap files
correctly even if the platform defines DLT_RAW, say, as something other
than 101. If that code also checks for DLT_RAW - which means it can't
just use a switch statement, as DLT_RAW might be defined as 101 if the
platform doesn't itself define DLT_RAW with some other value - then it
will also handle old DLT_RAW captures, as long as they were made on the
same platform or on another platform that used the same value for
DLT_RAW. It can't handle captures from a platform that uses that value
for another DLT_ code, but that's always been the case, and isn't easily
fixable.)
The intent here is to decouple the values that are returned by
"pcap_datalink()" and put into the header of tcpdump/libpcap save files
from the DLT_ values returned by BIOCGDLT in BSD kernels, allowing the
BSDs to assign values to DLT_ codes, in their kernels, as they choose,
without creating more incompatibilities between tcpdump/libpcap save
files from different platforms.