Supported: Realtime network packet capture, injection,
PCAP dumpfile reading/writing, BPF, timeouts and operation in non-blocking mode.
Also, full support for Windows through winpcap
but see here. The library has been tested on SBCL
(linux/darwin), ClozureCL and
LispWorks (darwin/win32) but should work on every platform
that CFFI supports.
Performance: Minimal/non-existent overhead over plain libpcap. Low memory use with very few dynamic allocations. No GC delays/packet loss due to garbage collection.
NOTE: Read timeouts, non-blocking mode operation and the
use of select/epoll/kqueue on the live interface file descriptor (as returned
by pcap-live-descriptor)
depend on support from operating system/libpcap. If things involving these
operations do not work as they should, consult libpcap documentation
and platform specific notes.
The file descriptor
can not be used with kqueue on OSX (as of 10.5)
although the same file descriptor works fine with select.
Recent FreeBSD versions have fixed this and kqueue works
with no issues on these platforms.
The code comes with a BSD-style license so you can basically do with it whatever you want.
pcap-writer-snaplenpcap-writer-filepcap-writer-datalinkpcap-writer-alive-ppcap-reader-swapped-ppcap-reader-snaplenpcap-reader-minorpcap-reader-majorpcap-reader-filepcap-reader-datalinkpcap-reader-alive-ppcap-live-timeoutpcap-live-snaplenpcap-live-promisc-ppcap-live-interfacepcap-live-descriptorpcap-live-datalinkpcap-live-alive-pThe current STABLE version is 1.3, released November 2009. You can download it here [sig, pubkey] or install it automatically with ASDF-INSTALL. For feature-requests, questions, patches email me at xristos (AT) suspicious.
The latest DEVELOPMENT version is available from git repository. Try it if you are having problems with stable.
List interfaces (addresses will not show up correctly on Win32, patches welcome)
If find-all-devs
returns NIL, make sure you have appropriate permissions for
packet capture (read access on /dev/bpf* devices for OSX/BSD, root/CAP_NET_RAW on Linux).
PLOKAMI> (find-all-devs) (("lo0" NIL 1 (((:ADDR :AF_INET6 "::1") (:NETMASK :AF_INET6 "ffff:ffff:ffff:ffff:ffff:ffff:ffff:ffff")) ((:ADDR :AF_INET "127.0.0.1") (:NETMASK :AF_INET "255.0.0.0")) ((:ADDR :AF_INET6 "fe80::1") (:NETMASK :AF_INET6 "ffff:ffff:ffff:ffff::")) ((:ADDR :AF_LINK "lo0")))) ("en1" NIL 0 (((:ADDR :AF_INET "192.168.1.64") (:NETMASK :AF_INET "255.255.255.0") (:BROADADDR :AF_INET "192.168.1.255")) ((:ADDR :AF_LINK "en1:0.1e.52.70.2f.9e")))) ("en0" NIL 0 (((:ADDR :AF_LINK "en0:0.1b.23.cc.ea.50")))) ("fw0" NIL 0 (((:ADDR :AF_LINK "fw0:0.1d.41.cf.fe.78.b4.ee")))))Read packets from the network in non-blocking mode, filter for IP, process and write them out to a PCAP dumpfile. Interrupt lisp to clean up and exit.
(with-pcap-interface (pcap "en0" :promisc t :snaplen 1500 :nbio t) (with-pcap-writer (writer "session.pcap" :snaplen 1500 :datalink (pcap-live-datalink pcap)) (set-filter pcap "ip") (loop (capture pcap -1 (lambda (sec usec caplen len buffer) (dump writer buffer :length caplen :origlength len :sec sec :usec usec) (format t "Packet length: ~A bytes, on the wire: ~A bytes~%" caplen len))) ;; Better to use select/epoll/kqueue on pcap-live-descriptor (sleep 0.01))))Read all packets available in PCAP dumpfile session.pcap and process them.
(with-pcap-reader (reader "session.pcap" :snaplen 1500) (capture pcap -1 (lambda (sec usec caplen len buffer) ;; Packet processing code here (format t "Packet length: ~A bytes, on the wire: ~A bytes~%" caplen len))))In all cases, BUFFER vector used in callback handler supplied to
capture is
allocated once per pcap instance and is overwritten every time capture
gets called. If packet persistence is required, BUFFER contents should be copied
before capture gets called again.
Under win32/winpcap, SNAPLEN only takes effect when a filter is used. It is therefore advised that an empty filter be installed, (set-filter instance ""), when capturing on this platform. Also see here.
[Special variable]
*pcap-version*
Version of native libpcap library.
[Function]
make-pcap-writer file &key datalink snaplen => pcap-writer
Creates and returns a pcap-writer instance that is used to write packets to a pcap dumpfile.
file is the filename to open and write packets to.
datalink should contain a string that represents the datalink protocol of the network interface used to capture the packets. Default is "EN10MB" for Ethernet. See *supported-datalinks* in pcap.lisp for more.
snaplen should contain the number of bytes read per packet captured and should be the same as the one used when capturing/reading the packets.
[Function]
make-pcap-reader file &key snaplen => pcap-reader
Creates and returns a pcap-reader instance that is used for reading packets from a pcap dumpfile.
file is the filename to open and read packets from.
snaplen should contain the number of bytes read per packet captured. Default is 68 which should be enough for headers.
[Function]
make-pcap-live interface &key promisc nbio timeout snaplen => pcap-live
Creates and returns a pcap-live instance that is used for live packet capture from a network interface.
interface is a string that defines the network interface to use for capture.
promisc should be T for promiscuous mode, NIL otherwise.
nbio should be T when non-blocking operation is required. NIL otherwise (default).
timeout should hold read timeout in milliseconds. 0 will wait forever. Only used when in blocking mode and only in platforms that support it. No guarantee of actually returning within timeout is made. Use non-blocking mode if that is not adequate.
snaplen should contain the number of bytes captured per packet. Default is 68 which should be enough for headers.
[Function]
find-all-devs => list of devices/addresses
Return a list of all network devices that can be opened for capture. Result list mirrors layout explained in pcap_findalldevs(3).
[Macro]
with-pcap-writer (writer file &rest options) &body body => result
CallMAKE-PCAP-WRITERusing file, options as arguments and store the resulting instance in writer. Forms in body are wrapped in an unwind-protect form that takes care of deallocating resources on error.
[Macro]
with-pcap-reader (reader file &rest options) &body body => result
CallMAKE-PCAP-READERusing file, options as arguments and store the resulting instance in reader. Forms in body are wrapped in an unwind-protect form that takes care of deallocating resources on error. A restart is also automatically invoked whenPACKET-FILTER-ERRORis signalled, skipping the filter setup.
[Macro]
with-pcap-interface (pcaplive iface &rest options) &body body => result
CallMAKE-PCAP-LIVEusing iface, options as arguments and store the resulting instance in pcaplive. Forms in body are wrapped in an unwind-protect form that takes care of deallocating resources on error and also returns packet capture statistics when possible. A restart is also automatically invoked whenPACKET-FILTER-ERRORis signalled, skipping the filter setup.
[Generic function]
stop pcap-mixin => result
Deallocates resources for pcap-live, pcap-reader, pcap-writer instance.
[Generic function]
stats pcap-live => result
Returns packet capture statistics from the start of the run to the time of the call for live interface capture only. Statistics are returned as multiple values and correspond to packets received, packets dropped and packets dropped by interface (in this order).NETWORK-INTERFACE-ERRORis signalled on failure.
[Generic function]
set-non-block pcap-live block-mode => result
Sets non-blocking mode if block-mode is T, blocking mode if NIL.BLOCK-MODE-ERRORis signalled on failure and a restart, continue-block-mode is installed, that can be invoked to continue.
[Generic function]
set-filter pcap-process-mixin string => result
Sets a packet filter on a pcap-live or pcap-reader instance. The filter should be given as a BPF expression in string.PACKET-FILTER-ERRORis signalled on failure. A restart, continue-no-filter is installed that can be invoked to continue on error.
[Generic function]
inject pcap-live buffer &key length => result
Injects length bytes to a live pcap interface (size of buffer if omitted).PACKET-INJECT-ERRORis signalled on failure.
[Generic function]
dump pcap-writer data &key length origlength sec usec => result
Writes contents of byte vector data to pcap-writer instance (which corresponds to a pcap dumpfile).
length is the number of bytes to write and is set to the size of data when omitted.
origlength should be set to the number of bytes originally present in the packet and is set to length when omitted.
sec and usec should be set to seconds/microseconds since the UNIX epoch at the time of capture (timeval structure in C) and are set to current values when omitted.CAPTURE-FILE-ERRORis signalled on errors.
[Generic function]
capture pcap-process-mixin packets handler => result
Only works for pcap-live or pcap-reader instances. Captures and processes maximum number of packets. Minimum is zero. Return 0 when no packets available (for dumpfiles: when end of file) otherwise return number of packets processed which can be fewer than the maximum given in packets (due to pcap buffer).
A count of -1 in packets processes all the packets received so far when live capturing, or all the packets in a file when reading a pcap dumpfile. Handler must be a user defined function that accepts five arguments and will get called once for every packet received. The values passed are sec, usec, caplen, len and buffer.
sec and usec correspond to seconds/microseconds since the UNIX epoch (timeval structure in C) at the time of capture.
caplen corresponds to the number of bytes captured.
len corresponds to the number of bytes originally present in the packet but not necessarily captured.
buffer is a statically allocated byte vector with the contents of the captured packet. This means that successive calls of the packet handler will overwrite its contents and if packet persistence is required, contents of buffer should be copied somewhere else from within handler.If an error occurs,
PACKET-CAPTURE-ERRORis signalled for live interfaces andCAPTURE-FILE-ERRORfor pcap dumpfiles. For more details on callback handling, see CFFI callback pcap-handler.
[Generic function]
pcap-writer-snaplen pcap-writer => integer
Number of bytes to write per packet processed.
[Generic function]
pcap-writer-file pcap-writer => string
File to write packets to.
[Generic function]
pcap-writer-datalink pcap-writer => string
Return string representation of the datalink protocol that is used by pcap-writer object.
[Generic function]
pcap-writer-alive-p pcap-writer => boolean
Returns T when pcap-writer object is live and can be used for packet dumping. NIL whenstophas been invoked and object is dead.
[Generic function]
pcap-reader-swapped-p pcap-reader => boolean
T if savefile uses different byte order from host system.
[Generic function]
pcap-reader-snaplen pcap-reader => integer
Number of bytes to read per packet processed.
[Generic function]
pcap-reader-minor pcap-reader => integer
Minor version of savefile.
[Generic function]
pcap-reader-major pcap-reader => integer
Major version of savefile.
[Generic function]
pcap-reader-file pcap-reader => string
File to read packets from.
[Generic function]
pcap-reader-datalink pcap-reader => string
Return string representation of the datalink protocol used by pcap-reader object.
[Generic function]
pcap-reader-alive-p pcap-reader => boolean
Returns T when pcap-reader object is live and can be used forcapture. NIL whenstophas been invoked and object is dead.
[Generic function]
pcap-live-timeout pcap-live => integer
Read timeout in milliseconds. 0 will wait until a packet arrives. Only takes effect in blocking mode/platforms that support it. No guarantee of returning within timeout is made.
[Generic function]
pcap-live-snaplen pcap-live => integer
Return snapshot length (how many bytes to capture per packet).
[Generic function]
pcap-live-promisc-p pcap-live => boolean
T if capturing in promiscuous mode.
[Generic function]
pcap-live-interface pcap-live => string
Return string representation of network interface that is used for packet capture.
[Generic function]
pcap-live-descriptor pcap-live => integer
File descriptor that can be used with epoll/kqueue/select and non-blocking mode.
[Generic function]
pcap-live-datalink pcap-live => string
Return string representation of the datalink protocol that is used by pcap-live object.
[Generic function]
pcap-live-alive-p pcap-live => boolean
Returns T when pcap-live object is live and can be used forcapture. NIL whenstophas been invoked and object is dead.
[Condition type]
plokami-error
Generic condition for this package. Superclass of all other PLOKAMI conditions.
[Condition type]
packet-inject-error
Signaled on errors during packet injection.
[Condition type]
packet-filter-error
Signaled when a Berkeley packet filter could not be established.
[Condition type]
packet-capture-error
Signaled on errors during live packet capture.
[Condition type]
network-interface-error
Signaled on all network interface errors.
[Condition type]
capture-file-error
Signaled on all pcap file errors.
[Condition type]
block-mode-error
Signaled on errors when changing blocking mode.
[Restart]
continue-block-mode
Continue without changing blocking mode.
[Restart]
continue-no-filter
Continue on filter setup error.
This documentation was prepared with DOCUMENTATION-TEMPLATE.
Copyright © 2008-2009 xristos (AT) suspicious.org, All Rights Reserved