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 overhead over plain libpcap. Low memory use with few dynamic allocations.
NOTE: Read timeouts, non-blocking mode operation and the
use of select/epoll/kqueue on the live interface descriptor (as returned
by pcap-live-descriptor
)
depend on support from operating system/libpcap. If issues arise,
consult libpcap documentation and platform specific notes.
The descriptor
can not be used with kqueue on OSX (as of 10.5)
although the same 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-snaplen
pcap-writer-file
pcap-writer-datalink
pcap-writer-alive-p
pcap-reader-swapped-p
pcap-reader-snaplen
pcap-reader-minor
pcap-reader-major
pcap-reader-file
pcap-reader-datalink
pcap-reader-alive-p
pcap-live-timeout
pcap-live-snaplen
pcap-live-promisc-p
pcap-live-interface
pcap-live-descriptor
pcap-live-datalink
pcap-live-alive-p
plokami-error-text
The latest version is available from git repository. You can also install it with Quicklisp.
For feature-requests, questions, patches email me at xristos (AT) sdf (DOT) org.
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 /dev/bpf* 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 sec usec :length caplen :origlength len) (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 reader -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 (namestring or pathname) 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.CAPTURE-FILE-WRITE-ERROR
is signaled on errors.
[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 (namestring or pathname) 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.CAPTURE-FILE-READ-ERROR
is signaled on errors.
[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 (default is 50). 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.NETWORK-INTERFACE-ERROR
orBLOCK-MODE-ERROR
is signaled on errors.
[Function]
find-all-devs => list of devices/addresses
Return a list of all network devices that can be opened for capture. Result list layout explained in pcap_findalldevs(3). NIL is returned when no interfaces are available (e.g. permissionissues)
SignalsNETWORK-INTERFACE-ERROR
on errors.
[Macro]
with-pcap-writer (writer file &rest options) &body body => result
CallMAKE-PCAP-WRITER
using 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-READER
using 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-ERROR
is signaled, skipping the filter setup.
[Macro]
with-pcap-interface (live iface &rest options) &body body => result
CallMAKE-PCAP-LIVE
using iface, options as arguments and store the resulting instance in live. 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-ERROR
is signaled, 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 => capture statistics
Return 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 that order).NETWORK-INTERFACE-ERROR
is signaled 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-ERROR
is signaled 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-ERROR
is signaled 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 => integer
Injects length bytes to a live pcap interface (size of buffer if omitted). Return number of bytes injected on success. For performance reasons buffer should be a byte vector allocated with cffi:make-shareable-byte-vector.PACKET-INJECT-ERROR
is signaled on failure.
[Generic function]
dump pcap-writer data sec usec &key length origlength => 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). If you are using your own source buffer (instead of the one used by plokami), it should be allocated with cffi:make-shareable-byte-vector. As libpcap does not return useful value on pcap_dump() no plokami specific conditions, beyond simple assertions of argument checks, are raised by this function.
[Generic function]
capture pcap-process-mixin packets handler => integer
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 (did not pass installed packet filter, end of file for dumpfiles, read timeout expired before packets arrive or no packets available at the time of the call if in non-blocking mode) otherwise return number of packets processed which can be fewer than the maximum given in packets (due to internal libpcap 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 (via cffi:make-shareable-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-ERROR
is signaled for live interfaces andCAPTURE-FILE-READ-ERROR
for 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 (native namestring) to write packets to. Represents a pathname using the native conventions of the operating system.
[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 whenstop
has 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 (native namestring) to read packets from. Represents a pathname using the native conventions of the operating system.
[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 whenstop
has 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 whenstop
has been invoked and object is dead.
[Generic function]
plokami-error-text condition => string
Reader that returns error description for allplokami-error
conditions.
[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-write-error
Signaled on all pcap dumpfile errors.
[Condition type]
capture-file-read-error
Signaled on all pcap readfile 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-2010 xristos (AT) sdf (DOT) org, All Rights Reserved