Copyright (c) 1994, 1996, 1997
The Regents of the University of California. All rights reserved.
Redistribution and use in source and binary forms, with or without
modification, are permitted provided that: (1) source code distributions
retain the above copyright notice and this paragraph in its entirety, (2)
distributions including binary code include the above copyright notice and
this paragraph in its entirety in the documentation or other materials
provided with the distribution, and (3) all advertising materials mentioning
features or use of this software display the following acknowledgement:
``This product includes software developed by the University of California,
Lawrence Berkeley Laboratory and its contributors.'' Neither the name of
the University nor the names of its contributors may be used to endorse
or promote products derived from this software without specific prior
written permission.
THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR IMPLIED
WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF
MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
#include <pcap/pcap.h>
To open a handle for a live capture, call pcap_create() , set the appropriate options on the handle, and then activate it with pcap_activate() . To open a handle for a ``savefile'' with captured packets, call pcap_open_offline() . Both pcap_create() and pcap_open_offline() return a pointer to a pcap_t , which is the handle used for reading packets from the capture stream or the ``savefile'', and for finding out information about the capture stream or ``savefile''.
The options that can be set on a capture handle include
Reading packets from a network interface may require that you have special privileges:
Under SunOS 3.x or 4.x with NIT or BPF: You must have read access to /dev/nit or /dev/bpf* .
Under Solaris with DLPI: You must have read/write access to the network pseudo device, e.g. /dev/le . On at least some versions of Solaris, however, this is not sufficient to allow tcpdump to capture in promiscuous mode; on those versions of Solaris, you must be root, or the application capturing packets must be installed setuid to root, in order to capture in promiscuous mode. Note that, on many (perhaps all) interfaces, if you don't capture in promiscuous mode, you will not see any outgoing packets, so a capture not done in promiscuous mode may not be very useful.
In newer versions of Solaris, you must have been given the net_rawaccess privilege; this is both necessary and sufficient to give you access to the network pseudo-device - there is no need to change the privileges on that device. A user can be given that privilege by, for example, adding that privilege to the user's defaultpriv key with the usermod (1M) command.Under HP-UX with DLPI: You must be root or the application capturing packets must be installed setuid to root.
Under IRIX with snoop: You must be root or the application capturing packets must be installed setuid to root.
Under Linux: You must be root or the application capturing packets must be installed setuid to root (unless your distribution has a kernel that supports capability bits such as CAP_NET_RAW and code to allow those capability bits to be given to particular accounts and to cause those bits to be set on a user's initial processes when they log in, in which case you must have CAP_NET_RAW in order to capture and CAP_NET_ADMIN to enumerate network devices with, for example, the -D flag).
Under ULTRIX and Digital UNIX/Tru64 UNIX: Any user may capture network traffic. However, no user (not even the super-user) can capture in promiscuous mode on an interface unless the super-user has enabled promiscuous-mode operation on that interface using pfconfig (8), and no user (not even the super-user) can capture unicast traffic received by or sent by the machine on an interface unless the super-user has enabled copy-all-mode operation on that interface using pfconfig , so useful packet capture on an interface probably requires that either promiscuous-mode or copy-all-mode operation, or both modes of operation, be enabled on that interface.
Under BSD (this includes Mac OS X): You must have read access to /dev/bpf* on systems that don't have a cloning BPF device, or to /dev/bpf on systems that do. On BSDs with a devfs (this includes Mac OS X), this might involve more than just having somebody with super-user access setting the ownership or permissions on the BPF devices - it might involve configuring devfs to set the ownership or permissions every time the system is booted, if the system even supports that; if it doesn't support that, you might have to find some other way to make that happen at boot time.
Reading a saved packet file doesn't require special privileges.
To open a ``savefile`` to which to write packets, call pcap_dump_open() . It returns a pointer to a pcap_dumper_t , which is the handle used for writing packets to the ``savefile''.
Packets are read with pcap_dispatch() or pcap_loop() , which process one or more packets, calling a callback routine for each packet, or with pcap_next() or pcap_next_ex() , which return the next packet. The callback for pcap_dispatch() and pcap_loop() is supplied a pointer to a "struct pcap_pkthdr" , which includes the following members:
ts a struct timeval containing the time when the packet was captured
caplen a bpf_u_int32 giving the number of bytes of the packet that are available from the capture
len a bpf_u_int32 giving the length of the packet, in bytes (which might be more than the number of bytes available from the capture, if the length of the packet is larger than the maximum number of bytes to capture).
pcap_next_ex() supplies that pointer through a pointer argument. pcap_next() is passed an argument that points to a struct pcap_pkthdr structure, and fills it in.
The callback is also supplied a const u_char pointer to the first caplen (as given in the struct pcap_pkthdr a pointer to which is passed to the callback routine) bytes of data from the packet. This won't necessarily be the entire packet; to capture the entire packet, you will have to provide a value for snaplen in your call to pcap_open_live() that is sufficiently large to get all of the packet's data - a value of 65535 should be sufficient on most if not all networks). When reading from a ``savefile'', the snapshot length specified when the capture was performed will limit the amount of packet data available. pcap_next() returns that pointer; pcap_next_ex() supplies that pointer through a pointer argument.
In versions of libpcap prior to 1.0, the pcap.h header file was not in a pcap directory on most platforms; if you are writing an application that must work on versions of libpcap prior to 1.0, include <pcap.h> , which will include <pcap/pcap.h> for you, rather than including <pcap/pcap.h> .
pcap_create() and pcap_activate() were not available in versions of libpcap prior to 1.0; if you are writing an application that must work on versions of libpcap prior to 1.0, either use pcap_open_live() to get a handle for a live capture or, if you want to be able to use the additional capabilities offered by using pcap_create() and pcap_activate() , use an autoconf (1) script or some other configuration script to check whether the libpcap 1.0 APIs are available and use them only if they are.
Van Jacobson, Craig Leres and Steven McCanne, all of the Lawrence Berkeley National Laboratory, University of California, Berkeley, CA.
The current version is available from "The Tcpdump Group"'s Web site at
http://www.tcpdump.org/
tcpdump-workers@lists.tcpdump.org