Jason R. Coombs avatar Jason R. Coombs committed 2fc055e

Adding code as found in 0.10.5

Comments (0)

Files changed (19)

+2007-03-27  Max Caceres <max@coresecurity.com>
+	* pcapobj.cc: wrapped pcap_sendpacket for sending packets in all platforms.
+
+2005-12-09  Max Caceres <max@coresecurity.com>
+	* pcapy.cc: open_live doesn't raise an exception anymore when network/netmask information is not available (i.e. when sniffing on devices without an assigned IP address). Reported by Scott Raynel.
+	
+2005-09-14  Max Caceres <max@coresecurity.com>
+	* pcapobj.cc: fixed bug where exceptions thrown inside a callback where not handled properly. Fix relies on fairly new pcap_breakloop function.
+	* pcapy.cc: in Windows uses findalldevs() packaged with new Winpcap 3.1
+	
+2005-08-15  Max Caceres <max@coresecurity.com>
+	* pcapy.cc: fixed bug where getnet() and getmask() always returned 0.0.0.0 (reported by Jeff Connelly)
+
+2005-07-28  Max Caceres <max@coresecurity.com>
+	* pcapobj.cc: fixed a memory leak in PythonCallback (reported by fraca7 _at_ free.fr).
+	
+2004-01-05  Javier Kohen  <jkohen@coresecurity.com>
+
+	* setup.py: force linking with G++ when using GCC, to avoid a missing symbol in some setups.
+
+2003-11-28  Javier Kohen  <jkohen@coresecurity.com>
+
+	* dcerpc_v4.py: Fixed self.bind variable having the same name than a method.
+Licencing
+---------
+
+We provide this software under a slightly modified version of the
+Apache Software License. The only changes to the document were the
+replacement of "Apache" with "Pcapy" and "Apache Software Foundation"
+with "CORE Security Technologies". Feel free to compare the resulting
+document to the official Apache license.
+
+The `Apache Software License' is an Open Source Initiative Approved
+License.
+
+
+The Apache Software License, Version 1.1
+Modifications by CORE Security Technologies (see above)
+
+Copyright (c) 2000 The Apache Software Foundation.  All rights
+reserved.
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions
+are met:
+
+1. Redistributions of source code must retain the above copyright
+   notice, this list of conditions and the following disclaimer.
+
+2. Redistributions in binary form must reproduce the above copyright
+   notice, this list of conditions and the following disclaimer in
+   the documentation and/or other materials provided with the
+   distribution.
+
+3. The end-user documentation included with the redistribution,
+   if any, must include the following acknowledgment:
+      "This product includes software developed by
+       CORE Security Technologies (http://www.coresecurity.com/)."
+   Alternately, this acknowledgment may appear in the software itself,
+   if and wherever such third-party acknowledgments normally appear.
+
+4. The names "Pcapy" and "CORE Security Technologies" must
+   not be used to endorse or promote products derived from this
+   software without prior written permission. For written
+   permission, please contact oss@coresecurity.com.
+
+5. Products derived from this software may not be called "Pcapy",
+   nor may "Pcapy" appear in their name, without prior written
+   permission of CORE Security Technologies.
+
+THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
+WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+DISCLAIMED.  IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR
+ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
+USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
+OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
+OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+SUCH DAMAGE.
+include MANIFEST.in
+include LICENSE
+include ChangeLog
+include pcapy.xml
+include pcapy.html
+include *.h
+recursive-include win32 *.cc
+Metadata-Version: 1.0
+Name: pcapy
+Version: 0.10.5
+Summary: Python pcap extension
+Home-page: http://oss.coresecurity.com/projects/pcapy.html
+Author: Maximiliano Caceres
+Author-email: max@coresecurity.com
+License: UNKNOWN
+Description: UNKNOWN
+Platform: UNKNOWN
+This file is an extract from the the online documentation at
+http://oss.coresecurity.com/pcapy/.
+
+
+What is Pcapy?
+==============
+
+Pcapy is a Python extension module that enables software written in
+Python to access the routines from the pcap packet capture library.
+
+From libpcap's documentation: "Libpcap is a system-independent
+interface for user-level packet capture. Libpcap provides a portable
+framework for low-level network monitoring. Applications include
+network statistics collection, security monitoring, network debugging,
+etc."
+
+What makes pcapy different from the others?
+-------------------------------------------
+
+ * works with Python threads.
+ * works both in UNIX with libpcap and Windows with WinPcap.
+ * provides a simpler Object Oriented API.
+
+
+Getting Pcapy
+=============
+
+Current and past releases are available from
+http://oss.coresecurity.com/pcapy/.
+
+
+Setup
+=====
+
+Quick start
+-----------
+
+Grab the latest stable release, unpack it and run 'python setup.py
+install' from the directory where you placed it. Isn't that easy?
+
+
+Requirements
+------------
+
+ * A Python interpreter. Versions 2.1.3 and newer are known to work.
+ * A C++ compiler. GCC G++ 2.95, as well as Microsoft Visual Studio
+   6.0, are known to work.
+ * Libpcap 0.7.2 or newer. Windows user are best to check WinPcap 3.0
+   or newer.
+ * A recent release of Pcapy.
+
+Compiling the source and installing
+-----------------------------------
+
+As this extension is written in C++ it needs to be compiled for the
+host system before it can be accessed from Python. Fortunately this
+process has been made easy by the setup.py script. In order to compile
+and install the source execute the following command from the
+directory where the pcapy's distribution has been unpacked: 'python
+setup.py install'. This will install the extension into the default
+Python's modules path; note that you might need special permissions to
+write there. For more information on what commands and options are
+available from setup.py, run 'python setup.py --help-commands'.
+
+This extension has been tested under Linux and Windows 2000 systems
+and is known to work there, but it ought to work out-of-the-box on any
+system where Python and libpcap are available.
+
+
+Licensing
+=========
+
+This software is provided under under a slightly modified version of
+the Apache Software License. See the accompanying LICENSE file for
+more information.
+
+
+Contact Us
+==========
+
+Whether you want to report a bug, send a patch or give some
+suggestions on this package, drop us a few lines at
+oss@coresecurity.com.
+
+$Id: README,v 1.3 2003/10/27 17:45:51 jkohen Exp $
+/*
+ * Copyright (c) 2003 CORE Security Technologies
+ *
+ * This software is provided under under a slightly modified version
+ * of the Apache Software License. See the accompanying LICENSE file
+ * for more information.
+ *
+ * $Id: bpfobj.cc,v 1.4 2003/10/24 18:49:33 jkohen Exp $
+ */
+
+#include <pcap.h>
+#include <Python.h>
+
+#include "bpfobj.h"
+#include "pcapy.h"
+
+
+// internal bpfobject
+typedef struct {
+	PyObject_HEAD
+	struct bpf_program bpf;
+} bpfobject;
+
+
+// BPFProgramType
+
+static void
+bpfprog_dealloc(register bpfobject* bpf)
+{
+#ifndef WIN32 // XXX: is this missing from winpcap 2.3?
+  pcap_freecode(&bpf->bpf);
+#endif
+  PyObject_Del(bpf);
+}
+
+
+// BPFProgram methods
+static PyObject* p_filter(register bpfobject* bpf, PyObject* args);
+
+
+static PyMethodDef bpf_methods[] = {
+  {"filter", (PyCFunction) p_filter, METH_VARARGS, "filter() filters a given packet"},
+  {NULL, NULL}	/* sentinel */
+};
+
+static PyObject*
+bpfprog_getattr(bpfobject* pp, char* name)
+{
+  return Py_FindMethod(bpf_methods, (PyObject*)pp, name);
+}
+
+
+PyTypeObject BPFProgramtype = {
+  PyObject_HEAD_INIT(NULL)
+  0,
+  "Bpf",
+  sizeof(bpfobject),
+  0,
+  
+  /* methods */
+  (destructor)bpfprog_dealloc,  /*tp_dealloc*/
+  0,			  /*tp_print*/
+  (getattrfunc)bpfprog_getattr, /*tp_getattr*/
+  0,			  /*tp_setattr*/
+  0,			  /*tp_compare*/
+  0,			  /*tp_repr*/
+  0,			  /*tp_as_number*/
+  0,			  /*tp_as_sequence*/
+  0,			  /*tp_as_mapping*/
+};
+
+
+PyObject*
+new_bpfobject(const struct bpf_program &bpfprog)
+{
+  bpfobject *bpf;
+  bpf = PyObject_New(bpfobject, &BPFProgramtype);
+  if (bpf == NULL)
+    return NULL;
+  
+  bpf->bpf = bpfprog;
+  return (PyObject*)bpf;
+}
+
+
+static PyObject* 
+p_filter(register bpfobject* bpf, PyObject* args)
+{
+  int status;
+  u_char* packet;
+  unsigned int len;
+
+  if (bpf->ob_type != &BPFProgramtype)
+    {
+      PyErr_SetString(PcapError, "Not a bpfprogram object");
+	return NULL;
+    }
+
+  if (!PyArg_ParseTuple(args,"s#:filter",&packet, &len))
+    return NULL;
+
+  status = bpf_filter(bpf->bpf.bf_insns,
+		      packet,
+		      len, len);
+
+  return Py_BuildValue("i", status);
+}
+/*
+ * Copyright (c) 2003 CORE Security Technologies
+ *
+ * This software is provided under under a slightly modified version
+ * of the Apache Software License. See the accompanying LICENSE file
+ * for more information.
+ *
+ * $Id: bpfobj.h,v 1.3 2003/10/24 18:49:33 jkohen Exp $
+ */
+
+#ifndef __bpfobj__
+#define __bpfobj__
+
+PyObject*
+new_bpfobject(const struct bpf_program &bpf);
+
+extern PyTypeObject Pcaptype;
+
+#endif // __bpfobj__
+/*
+ * Copyright (c) 2003 CORE Security Technologies
+ *
+ * This software is provided under under a slightly modified version
+ * of the Apache Software License. See the accompanying LICENSE file
+ * for more information.
+ *
+ * $Id: pcap_pkthdr.cc,v 1.3 2003/10/23 20:00:53 jkohen Exp $
+ */
+
+#include <Python.h>
+#include <pcap.h>
+
+#include "pcapy.h"
+#include "pcap_pkthdr.h"
+
+#ifdef WIN32
+#include <winsock2.h>
+#else
+#include <netinet/in.h>
+#endif
+
+
+// internal pcapobject
+typedef struct {
+	PyObject_HEAD
+	struct timeval ts;
+	bpf_u_int32 caplen;
+	bpf_u_int32 len;
+} pkthdr;
+
+
+// Pkthdr_Type
+
+static void
+pcap_dealloc(register pkthdr* pp)
+{
+  PyObject_Del(pp);
+}
+
+
+// pcap methods
+static PyObject* p_getts(register pkthdr* pp, PyObject* args);
+static PyObject* p_getcaplen(register pkthdr* pp, PyObject* args);
+static PyObject* p_getlen(register pkthdr* pp, PyObject* args);
+
+
+static PyMethodDef p_methods[] = {
+  {"getts", (PyCFunction) p_getts, METH_VARARGS, "get timestamp tuple (seconds, microseconds) since the Epoch"},
+  {"getcaplen", (PyCFunction) p_getcaplen, METH_VARARGS, "returns the length of portion present"},
+  {"getlen", (PyCFunction) p_getlen, METH_VARARGS, "returns the length of the packet (off wire)"},
+  {NULL, NULL}	/* sentinel */
+};
+
+static PyObject*
+pcap_getattr(pkthdr* pp, char* name)
+{
+  return Py_FindMethod(p_methods, (PyObject*)pp, name);
+}
+
+
+PyTypeObject Pkthdr_type = {
+  PyObject_HEAD_INIT(NULL)
+  0,
+  "Pkthdr",
+  sizeof(pkthdr),
+  0,
+
+  /* methods */
+  (destructor)pcap_dealloc,  /*tp_dealloc*/
+  0,			  /*tp_print*/
+  (getattrfunc)pcap_getattr, /*tp_getattr*/
+  0,			  /*tp_setattr*/
+  0,			  /*tp_compare*/
+  0,			  /*tp_repr*/
+  0,			  /*tp_as_number*/
+  0,			  /*tp_as_sequence*/
+  0,			  /*tp_as_mapping*/
+};
+
+
+PyObject*
+new_pcap_pkthdr(const struct pcap_pkthdr* hdr)
+{
+  pkthdr *pp;
+
+  pp = PyObject_New(pkthdr, &Pkthdr_type);
+  if (pp == NULL)
+    return NULL;
+
+  pp->ts = hdr->ts;
+  pp->caplen = hdr->caplen;
+  pp->len = hdr->len;
+
+  return (PyObject*)pp;
+}
+
+static PyObject*
+p_getts(register pkthdr* pp, PyObject* args)
+{
+  if (pp->ob_type != &Pkthdr_type) {
+	  PyErr_SetString(PcapError, "Not a pkthdr object");
+	  return NULL;
+  }
+
+  return Py_BuildValue("(ll)", pp->ts.tv_sec, pp->ts.tv_usec);
+}
+
+static PyObject*
+p_getcaplen(register pkthdr* pp, PyObject* args)
+{
+  if (pp->ob_type != &Pkthdr_type) {
+	  PyErr_SetString(PcapError, "Not a pkthdr object");
+	  return NULL;
+  }
+
+  return Py_BuildValue("l", pp->caplen);
+}
+
+static PyObject*
+p_getlen(register pkthdr* pp, PyObject* args)
+{
+  if (pp->ob_type != &Pkthdr_type) {
+	  PyErr_SetString(PcapError, "Not a pkthdr object");
+	  return NULL;
+  }
+
+  return Py_BuildValue("l", pp->len);
+}
+
+int
+pkthdr_to_native(PyObject *pyhdr, struct pcap_pkthdr *hdr)
+{
+  if (pyhdr->ob_type != &Pkthdr_type) {
+	  PyErr_SetString(PcapError, "Not a pkthdr object");
+	  return -1;
+  }
+
+  pkthdr *pp = (pkthdr *) pyhdr;
+
+  hdr->ts = pp->ts;
+  hdr->caplen = pp->caplen;
+  hdr->len = pp->len;
+
+  return 0;
+}
+/*
+ * Copyright (c) 2003 CORE Security Technologies
+ *
+ * This software is provided under under a slightly modified version
+ * of the Apache Software License. See the accompanying LICENSE file
+ * for more information.
+ *
+ * $Id: pcap_pkthdr.h,v 1.2 2003/10/23 20:00:53 jkohen Exp $
+ */
+
+#ifndef __pcap_pkthdr__
+#define __pcap_pkthdr__
+
+#include <pcap.h>
+
+PyObject*
+new_pcap_pkthdr(const struct pcap_pkthdr* hdr);
+int
+pkthdr_to_native(PyObject *pyhdr, struct pcap_pkthdr *hdr);
+
+extern PyTypeObject Pkthdr_type;
+
+#endif // __pcap_pkthdr__
+/*
+ * Copyright (c) 2003 CORE Security Technologies
+ *
+ * This software is provided under under a slightly modified version
+ * of the Apache Software License. See the accompanying LICENSE file
+ * for more information.
+ *
+ * $Id: pcapdumper.cc,v 1.3 2003/10/23 20:00:53 jkohen Exp $
+ */
+
+#include <Python.h>
+#include <pcap.h>
+
+#include "pcapdumper.h"
+#include "pcap_pkthdr.h"
+#include "pcapy.h"
+
+// internal pcapdumper
+typedef struct {
+	PyObject_HEAD
+	pcap_dumper_t *dumper;
+} pcapdumper;
+
+
+// Pdumpertype
+
+static void
+pcap_dealloc(register pcapdumper* pp)
+{
+  if ( pp->dumper )
+    pcap_dump_close(pp->dumper);
+
+  pp->dumper = NULL;
+
+  PyObject_Del(pp);
+}
+
+
+// pcap methods
+//static PyObject* p_close(register pcapdumper* pp, PyObject* args);
+static PyObject* p_dump(register pcapdumper* pp, PyObject* args);
+
+
+static PyMethodDef p_methods[] = {
+//  {"close", (PyCFunction) p_close, METH_VARARGS, "loops packet dispatching"},
+  {"dump", (PyCFunction) p_dump, METH_VARARGS, "dump a packet to the file"},
+  {NULL, NULL}	/* sentinel */
+};
+
+static PyObject*
+pcap_getattr(pcapdumper* pp, char* name)
+{
+  return Py_FindMethod(p_methods, (PyObject*)pp, name);
+}
+
+
+PyTypeObject Pdumpertype = {
+  PyObject_HEAD_INIT(NULL)
+  0,
+  "Dumper",
+  sizeof(pcapdumper),
+  0,
+
+  /* methods */
+  (destructor)pcap_dealloc,  /*tp_dealloc*/
+  0,			  /*tp_print*/
+  (getattrfunc)pcap_getattr, /*tp_getattr*/
+  0,			  /*tp_setattr*/
+  0,			  /*tp_compare*/
+  0,			  /*tp_repr*/
+  0,			  /*tp_as_number*/
+  0,			  /*tp_as_sequence*/
+  0,			  /*tp_as_mapping*/
+};
+
+
+PyObject*
+new_pcapdumper(pcap_dumper_t *dumper)
+{
+  pcapdumper *pp;
+
+  pp = PyObject_New(pcapdumper, &Pdumpertype);
+  if (pp == NULL)
+    return NULL;
+
+  pp->dumper = dumper;
+
+  return (PyObject*)pp;
+}
+
+static PyObject*
+p_dump(register pcapdumper* pp, PyObject* args)
+{
+	PyObject *pyhdr;
+	u_char *data;
+	int       len;
+
+	if (pp->ob_type != &Pdumpertype) {
+		PyErr_SetString(PcapError, "Not a pcapdumper object");
+		return NULL;
+	}
+
+	if (!PyArg_ParseTuple(args,"Os#",&pyhdr,&data,&len))
+		return NULL;
+
+	struct pcap_pkthdr hdr;
+	if (-1 == pkthdr_to_native(pyhdr, &hdr))
+		return NULL;
+
+	pcap_dump((u_char *)pp->dumper, &hdr, data);
+
+	Py_INCREF(Py_None);
+	return Py_None;
+}
+/*
+ * Copyright (c) 2003 CORE Security Technologies
+ *
+ * This software is provided under under a slightly modified version
+ * of the Apache Software License. See the accompanying LICENSE file
+ * for more information.
+ *
+ * $Id: pcapdumper.h,v 1.2 2003/10/23 20:00:53 jkohen Exp $
+ */
+
+#ifndef __pcapdumper__
+#define __pcapdumper__
+
+
+PyObject*
+new_pcapdumper(pcap_dumper_t *dumper);
+
+extern PyTypeObject Pdumpertype;
+
+#endif // __pcapdumper__
+/*
+ * Copyright (c) 2003 CORE Security Technologies
+ *
+ * This software is provided under under a slightly modified version
+ * of the Apache Software License. See the accompanying LICENSE file
+ * for more information.
+ *
+ * $Id: pcapobj.cc,v 1.10 2007/03/27 17:26:13 max Exp $
+ */
+
+#include <Python.h>
+#include <pcap.h>
+
+#include "pcapobj.h"
+#include "pcapy.h"
+#include "pcapdumper.h"
+#include "pcap_pkthdr.h"
+
+#ifdef WIN32
+#include <winsock2.h>
+#else
+#include <netinet/in.h>
+#endif
+
+
+// internal pcapobject
+typedef struct {
+	PyObject_HEAD
+	pcap_t *pcap;
+	bpf_u_int32 net;
+	bpf_u_int32 mask;
+} pcapobject;
+
+
+// PcapType
+
+static void
+pcap_dealloc(register pcapobject* pp)
+{
+  if ( pp->pcap )
+    pcap_close(pp->pcap);
+
+  pp->pcap = NULL;
+
+  PyObject_Del(pp);
+}
+
+
+// pcap methods
+static PyObject* p_getnet(register pcapobject* pp, PyObject* args);
+static PyObject* p_getmask(register pcapobject* pp, PyObject* args);
+static PyObject* p_setfilter( register pcapobject* pp, PyObject* args );
+static PyObject* p_next(register pcapobject* pp, PyObject* args);
+static PyObject* p_dispatch(register pcapobject* pp, PyObject* args);
+static PyObject* p_loop(register pcapobject* pp, PyObject* args);
+static PyObject* p_datalink(register pcapobject* pp, PyObject* args);
+static PyObject* p_setnonblock(register pcapobject* pp, PyObject* args);
+static PyObject* p_getnonblock(register pcapobject* pp, PyObject* args);
+static PyObject* p_dump_open(register pcapobject* pp, PyObject* args);
+static PyObject* p_sendpacket(register pcapobject* pp, PyObject* args);
+
+
+static PyMethodDef p_methods[] = {
+  {"loop", (PyCFunction) p_loop, METH_VARARGS, "loops packet dispatching"},
+  {"dispatch", (PyCFunction) p_dispatch, METH_VARARGS, "dispatchs packets"},
+  {"next", (PyCFunction) p_next, METH_VARARGS, "returns next packet"},
+  {"setfilter", (PyCFunction) p_setfilter, METH_VARARGS, "compiles and sets a BPF capture filter"},
+  {"getnet", (PyCFunction) p_getnet, METH_VARARGS, "returns the network address for the device"},
+  {"getmask", (PyCFunction) p_getmask, METH_VARARGS, "returns the netmask for the device"},
+  {"datalink", (PyCFunction) p_datalink, METH_VARARGS, "returns the link layer type"},
+  {"getnonblock", (PyCFunction) p_getnonblock, METH_VARARGS, "returns the current `non-blocking' state"},
+  {"setnonblock", (PyCFunction) p_setnonblock, METH_VARARGS, "puts into `non-blocking' mode, or take it out, depending on the argument"},
+  {"dump_open", (PyCFunction) p_dump_open, METH_VARARGS, "creates a dumper object"},
+  {"sendpacket", (PyCFunction) p_sendpacket, METH_VARARGS, "sends a packet through the interface"},
+  {NULL, NULL}	/* sentinel */
+};
+
+static PyObject*
+pcap_getattr(pcapobject* pp, char* name)
+{
+  return Py_FindMethod(p_methods, (PyObject*)pp, name);
+}
+
+
+PyTypeObject Pcaptype = {
+  PyObject_HEAD_INIT(NULL)
+  0,
+  "Reader",
+  sizeof(pcapobject),
+  0,
+
+  /* methods */
+  (destructor)pcap_dealloc,  /*tp_dealloc*/
+  0,			  /*tp_print*/
+  (getattrfunc)pcap_getattr, /*tp_getattr*/
+  0,			  /*tp_setattr*/
+  0,			  /*tp_compare*/
+  0,			  /*tp_repr*/
+  0,			  /*tp_as_number*/
+  0,			  /*tp_as_sequence*/
+  0,			  /*tp_as_mapping*/
+};
+
+
+PyObject*
+new_pcapobject(pcap_t *pcap, bpf_u_int32 net, bpf_u_int32 mask)
+{
+  pcapobject *pp;
+
+  pp = PyObject_New(pcapobject, &Pcaptype);
+  if (pp == NULL)
+    return NULL;
+
+  pp->pcap = pcap;
+  pp->net = net;
+  pp->mask = mask;
+
+  return (PyObject*)pp;
+}
+
+static void ntos(char* dst, unsigned int n, int ip)
+{
+  ip = htonl(ip);
+  snprintf(dst, n, "%i.%i.%i.%i",
+	   ((ip >> 24) & 0xFF),
+	   ((ip >> 16) & 0xFF),
+	   ((ip >> 8) & 0xFF),
+	   (ip & 0xFF));
+}
+
+static PyObject*
+p_getnet(register pcapobject* pp, PyObject* args)
+{
+  if (pp->ob_type != &Pcaptype)
+    {
+      PyErr_SetString(PcapError, "Not a pcap object");
+      return NULL;
+    }
+
+  char ip_str[20];
+  ntos(ip_str, sizeof(ip_str), pp->net);
+  return Py_BuildValue("s", ip_str);
+}
+
+static PyObject*
+p_getmask(register pcapobject* pp, PyObject* args)
+{
+  if (pp->ob_type != &Pcaptype)
+    {
+      PyErr_SetString(PcapError, "Not a pcap object");
+      return NULL;
+    }
+
+  char ip_str[20];
+  ntos(ip_str, sizeof(ip_str), pp->mask);
+  return Py_BuildValue("s", ip_str);
+}
+
+static PyObject*
+p_setfilter(register pcapobject* pp, PyObject* args)
+{
+  struct bpf_program bpfprog;
+  int status;
+  char* str;
+
+  if (pp->ob_type != &Pcaptype)
+    {
+      PyErr_SetString(PcapError, "Not a pcap object");
+	return NULL;
+    }
+
+  if (!PyArg_ParseTuple(args,"s:setfilter",&str))
+    return NULL;
+
+  status = pcap_compile(pp->pcap, &bpfprog, str, 1, pp->mask);
+  if (status)
+    {
+      PyErr_SetString(PcapError, pcap_geterr(pp->pcap));
+      return NULL;
+    }
+
+  status = pcap_setfilter(pp->pcap, &bpfprog);
+  if (status)
+    {
+      PyErr_SetString(PcapError, pcap_geterr(pp->pcap));
+      return NULL;
+    }
+
+  Py_INCREF(Py_None);
+  return Py_None;
+}
+
+static PyObject*
+p_next(register pcapobject* pp, PyObject* args)
+{
+  struct pcap_pkthdr hdr;
+  const unsigned char *buf;
+
+  if (pp->ob_type != &Pcaptype)
+    {
+      PyErr_SetString(PcapError, "Not a pcap object");
+      return NULL;
+    }
+
+  // allow threads as this might block
+  Py_BEGIN_ALLOW_THREADS;
+  buf = pcap_next(pp->pcap, &hdr);
+  Py_END_ALLOW_THREADS;
+
+  if(!buf)
+    {
+      PyErr_SetString(PcapError, pcap_geterr(pp->pcap));
+      return NULL;
+    }
+
+  PyObject *pkthdr = new_pcap_pkthdr(&hdr);
+
+  return Py_BuildValue("(Os#)", pkthdr, buf, hdr.caplen);
+}
+
+
+struct PcapCallbackContext {
+  PcapCallbackContext(pcap_t* p, PyObject* f, PyThreadState* ts)
+    : ppcap_t(p), pyfunc(f), thread_state(ts)
+  {
+    Py_INCREF(pyfunc);
+  }
+  ~PcapCallbackContext()
+  {
+    Py_DECREF(pyfunc);
+  }
+
+  pcap_t* ppcap_t;
+  PyObject *pyfunc;
+  PyThreadState *thread_state;
+
+};
+
+
+static void
+PythonCallBack(u_char *user,
+	       const struct pcap_pkthdr *header,
+	       const u_char *packetdata)
+{
+  PyObject *arglist, *result;
+  unsigned int *len;
+  PcapCallbackContext *pctx;
+  len    = (unsigned int *)&header->caplen;
+  pctx = (PcapCallbackContext *)user;
+
+  PyEval_RestoreThread(pctx->thread_state);
+
+  PyObject *hdr = new_pcap_pkthdr(header);
+
+  arglist = Py_BuildValue("Os#", hdr, packetdata, *len);
+  result = PyEval_CallObject(pctx->pyfunc,arglist);
+
+  Py_XDECREF(arglist);
+  if (result)
+    Py_DECREF(result);
+
+  Py_DECREF(hdr);
+
+  if (!result)
+    pcap_breakloop(pctx->ppcap_t);
+
+  PyEval_SaveThread();
+}
+
+static PyObject*
+p_dispatch(register pcapobject* pp, PyObject* args)
+{
+  int cant, ret;
+  PyObject *PyFunc;
+
+  if (pp->ob_type != &Pcaptype)
+    {
+      PyErr_SetString(PcapError, "Not a pcap object");
+      return NULL;
+    }
+
+  if(!PyArg_ParseTuple(args,"iO:dispatch",&cant,&PyFunc))
+    return NULL;
+
+  PcapCallbackContext ctx(pp->pcap, PyFunc, PyThreadState_Get());
+  PyEval_SaveThread();
+  ret = pcap_dispatch(pp->pcap, cant, PythonCallBack, (u_char*)&ctx);
+  PyEval_RestoreThread(ctx.thread_state);
+
+  if(ret<0) {
+    if (ret!=-2)  
+      /* pcap error, pcap_breakloop was not called so error is not set */
+      PyErr_SetString(PcapError, pcap_geterr(pp->pcap));
+    return NULL;
+  }
+
+  return Py_BuildValue("i", ret);
+}
+
+static PyObject*
+p_dump_open(register pcapobject* pp, PyObject* args)
+{
+  char *filename;
+  pcap_dumper_t *ret;
+
+  if (pp->ob_type != &Pcaptype)
+    {
+      PyErr_SetString(PcapError, "Not a pcap object");
+      return NULL;
+    }
+
+  if(!PyArg_ParseTuple(args,"s",&filename))
+    return NULL;
+
+  ret = pcap_dump_open(pp->pcap, filename);
+
+  if (ret==NULL) {
+    PyErr_SetString(PcapError, pcap_geterr(pp->pcap));
+    return NULL;
+  }
+
+  return new_pcapdumper(ret);
+}
+
+
+static PyObject*
+p_loop(register pcapobject* pp, PyObject* args)
+{
+  int cant, ret;
+  PyObject *PyFunc;
+
+  if (pp->ob_type != &Pcaptype)
+    {
+      PyErr_SetString(PcapError, "Not a pcap object");
+      return NULL;
+    }
+
+  if(!PyArg_ParseTuple(args,"iO:loop",&cant,&PyFunc))
+    return NULL;
+
+  PcapCallbackContext ctx(pp->pcap, PyFunc, PyThreadState_Get());
+  PyEval_SaveThread();
+  ret = pcap_loop(pp->pcap, cant, PythonCallBack, (u_char*)&ctx);
+  PyEval_RestoreThread(ctx.thread_state);
+
+  if(ret<0) {
+    if (ret!=-2)  
+      /* pcap error, pcap_breakloop was not called so error is not set */
+      PyErr_SetString(PcapError, pcap_geterr(pp->pcap));
+    return NULL;
+  }
+
+  Py_INCREF(Py_None);
+  return Py_None;
+}
+
+
+static PyObject*
+p_datalink(register pcapobject* pp, PyObject* args)
+{
+	if (pp->ob_type != &Pcaptype) {
+		PyErr_SetString(PcapError, "Not a pcap object");
+		return NULL;
+	}
+
+	int type = pcap_datalink(pp->pcap);
+
+	return Py_BuildValue("i", type);
+}
+
+static PyObject*
+p_setnonblock(register pcapobject* pp, PyObject* args)
+{
+	if (pp->ob_type != &Pcaptype) {
+		PyErr_SetString(PcapError, "Not a pcap object");
+		return NULL;
+	}
+
+	int state;
+
+	if (!PyArg_ParseTuple(args, "i", &state))
+		return NULL;
+
+	char errbuf[PCAP_ERRBUF_SIZE];
+	int ret = pcap_setnonblock(pp->pcap, state, errbuf);
+	if (-1 == ret) {
+		PyErr_SetString(PcapError, errbuf);
+		return NULL;
+	}
+
+	Py_INCREF(Py_None);
+	return Py_None;
+}
+
+static PyObject*
+p_getnonblock(register pcapobject* pp, PyObject* args)
+{
+	if (pp->ob_type != &Pcaptype) {
+		PyErr_SetString(PcapError, "Not a pcap object");
+		return NULL;
+	}
+
+	char errbuf[PCAP_ERRBUF_SIZE];
+	int state = pcap_getnonblock(pp->pcap, errbuf);
+	if (-1 == state) {
+		PyErr_SetString(PcapError, errbuf);
+		return NULL;
+	}
+
+	return Py_BuildValue("i", state);
+}
+
+static PyObject*
+p_sendpacket(register pcapobject* pp, PyObject* args)
+{
+  int status;
+  unsigned char* str;
+  unsigned int length;
+
+  if (pp->ob_type != &Pcaptype)
+    {
+      PyErr_SetString(PcapError, "Not a pcap object");
+      return NULL;
+    }
+
+  if (!PyArg_ParseTuple(args,"s#", &str, &length))
+    return NULL;
+
+  status = pcap_sendpacket(pp->pcap, str, length);
+  if (status)
+    {
+      PyErr_SetString(PcapError, pcap_geterr(pp->pcap));
+      return NULL;
+    }
+
+  Py_INCREF(Py_None);
+  return Py_None;
+}
+/*
+ * Copyright (c) 2003 CORE Security Technologies
+ *
+ * This software is provided under under a slightly modified version
+ * of the Apache Software License. See the accompanying LICENSE file
+ * for more information.
+ *
+ * $Id: pcapobj.h,v 1.3 2003/10/23 20:00:53 jkohen Exp $
+ */
+
+#ifndef __pcapobj__
+#define __pcapobj__
+
+
+PyObject*
+new_pcapobject(pcap_t *pcap, bpf_u_int32 net=0, bpf_u_int32 mask=0);
+
+extern PyTypeObject Pcaptype;
+
+#endif // __pcapobj__
+/*
+ * Copyright (c) 2003 CORE Security Technologies
+ *
+ * This software is provided under under a slightly modified version
+ * of the Apache Software License. See the accompanying LICENSE file
+ * for more information.
+ *
+ * $Id: pcapy.cc,v 1.7 2005/12/09 15:07:04 max Exp $
+ */
+
+#include <pcap.h>
+#include <Python.h>
+
+#include "pcapy.h"
+#include "pcapobj.h"
+#include "bpfobj.h"
+
+
+PyObject *PcapError;
+
+
+
+// module methods
+
+static PyObject* 
+lookupdev(PyObject* self, PyObject* args)
+{
+  char errbuff[PCAP_ERRBUF_SIZE];
+  char* dev;
+  
+  dev = pcap_lookupdev(errbuff);
+  if(!dev)
+    {
+      PyErr_SetString(PcapError, errbuff);
+      return NULL;
+    }
+  
+  return Py_BuildValue("u", dev);
+}
+
+static PyObject*
+findalldevs(PyObject *self, PyObject *args)
+{
+  char errbuff[PCAP_ERRBUF_SIZE];
+  pcap_if_t *devs;
+
+  int status = pcap_findalldevs(&devs, errbuff);
+  if(status)
+    {
+      PyErr_SetString(PcapError, errbuff);
+      return NULL;
+    }
+
+  if(devs==NULL)
+    {
+      PyErr_SetString(PcapError, "No valid interfaces to open");
+      return NULL;
+    }
+
+  pcap_if_t *cursor = devs;
+  PyObject* list = PyList_New(0);
+  while(cursor)
+    {
+      PyList_Append(list, Py_BuildValue("s", cursor->name));
+      cursor = cursor->next;
+    }
+
+  pcap_freealldevs(devs);
+  
+  return list;
+}
+
+static PyObject*
+open_live(PyObject *self, PyObject *args)
+{
+  char errbuff[PCAP_ERRBUF_SIZE];
+  char * device;
+  int  snaplen;
+  int  promisc;
+  int  to_ms;
+  
+  bpf_u_int32 net, mask;
+  
+  
+  if(!PyArg_ParseTuple(args,"siii:open_live",&device,&snaplen,&promisc,&to_ms))
+    return NULL;
+  
+  int status = pcap_lookupnet(device, &net, &mask, errbuff);
+  if(status)
+    {
+      net = 0;
+      mask = 0;
+    }
+  
+  pcap_t* pt;
+	
+  pt = pcap_open_live(device, snaplen, promisc!=0, to_ms, errbuff);
+  if(!pt)
+    {
+      PyErr_SetString(PcapError, errbuff);
+      return NULL;
+    }
+#ifdef WIN32
+  pcap_setmintocopy(pt, 0);
+#endif
+
+  return new_pcapobject( pt, net, mask );
+}
+
+static PyObject*
+open_offline(PyObject *self, PyObject *args)
+{
+  char errbuff[PCAP_ERRBUF_SIZE];
+  char * filename;
+  
+  
+  if(!PyArg_ParseTuple(args,"s",&filename))
+    return NULL;
+  
+  pcap_t* pt;
+	
+  pt = pcap_open_offline(filename, errbuff);
+  if(!pt)
+    {
+      PyErr_SetString(PcapError, errbuff);
+      return NULL;
+    }
+#ifdef WIN32
+  pcap_setmintocopy(pt, 0);
+#endif
+
+  return new_pcapobject( pt );
+}
+
+
+static PyObject*
+bpf_compile(PyObject* self, PyObject* args)
+{
+  int linktype;
+  int  snaplen;
+  char *filter;
+  int optimize;
+  int netmask;
+  
+  if(!PyArg_ParseTuple(args, 
+		       "iisii:compile",
+		       &linktype,
+		       &snaplen,
+		       &filter,
+		       &optimize,
+		       &netmask))
+    return NULL;
+  
+  pcap_t *pp;
+
+  pp = pcap_open_dead(linktype, snaplen);
+  if(pp == NULL)
+    return NULL;
+
+  struct bpf_program bpf;
+  int status = pcap_compile(pp, &bpf, filter, optimize, netmask);
+  pcap_close(pp);
+
+  if(status)
+    {
+      PyErr_SetString(PcapError, pcap_geterr(pp));
+      return NULL;
+    }
+  
+  return new_bpfobject( bpf );
+}
+
+
+static PyMethodDef pcap_methods[] = {
+  {"open_live", open_live, METH_VARARGS, "open_live(device, snaplen, promisc, to_ms) opens a pcap device"},
+  {"open_offline", open_offline, METH_VARARGS, "open_offline(filename) opens a pcap formated file"},
+  {"lookupdev", lookupdev, METH_VARARGS, "lookupdev() looks up a pcap device"},
+  {"findalldevs", findalldevs, METH_VARARGS, "findalldevs() lists all available interfaces"},
+  {"compile", bpf_compile, METH_VARARGS, "compile(linktype, snaplen, filter, optimize, netmask) creates a bpfprogram object"},
+  {NULL, NULL}
+};
+
+
+static char *pcap_doc =
+"\nA wrapper for the Packet Capture (PCAP) library\n";
+
+
+void
+initpcapy(void)
+{
+  PyObject *m, *d;
+
+  Pcaptype.ob_type =  &PyType_Type;
+  m = Py_InitModule3("pcapy", pcap_methods, pcap_doc);
+
+  /* Direct from pcap's net/bpf.h. */
+  PyModule_AddIntConstant(m, "DLT_NULL", 0);
+  PyModule_AddIntConstant(m, "DLT_EN10MB", 1);
+  PyModule_AddIntConstant(m, "DLT_IEEE802", 6);
+  PyModule_AddIntConstant(m, "DLT_ARCNET", 7);
+  PyModule_AddIntConstant(m, "DLT_SLIP", 8);
+  PyModule_AddIntConstant(m, "DLT_PPP", 9);
+  PyModule_AddIntConstant(m, "DLT_FDDI", 10);
+  PyModule_AddIntConstant(m, "DLT_ATM_RFC1483", 11);
+  PyModule_AddIntConstant(m, "DLT_RAW", 12);
+  PyModule_AddIntConstant(m, "DLT_PPP_SERIAL", 50);
+  PyModule_AddIntConstant(m, "DLT_PPP_ETHER", 51);
+  PyModule_AddIntConstant(m, "DLT_C_HDLC", 104);
+  PyModule_AddIntConstant(m, "DLT_IEEE802_11", 105);
+  PyModule_AddIntConstant(m, "DLT_LOOP", 108);
+  PyModule_AddIntConstant(m, "DLT_LINUX_SLL", 113);
+  PyModule_AddIntConstant(m, "DLT_LTALK", 114);
+
+  d = PyModule_GetDict(m);
+  PcapError = PyErr_NewException("pcapy.PcapError", NULL, NULL );
+  if( PcapError )
+    PyDict_SetItemString( d, "PcapError", PcapError );
+}
+/*
+ * Copyright (c) 2003 CORE Security Technologies
+ *
+ * This software is provided under under a slightly modified version
+ * of the Apache Software License. See the accompanying LICENSE file
+ * for more information.
+ *
+ * $Id: pcapy.h,v 1.2 2003/10/23 20:00:53 jkohen Exp $
+ */
+
+#ifndef __PCAPY_H__
+
+
+extern "C" {
+#ifdef WIN32
+__declspec(dllexport)
+#endif
+void initpcapy(void);
+}
+
+// exception object
+extern PyObject* PcapError;
+
+#endif // __PCAPY_H__
+<html><head><meta content="text/html; charset=ISO-8859-1" http-equiv="Content-Type"><title>Part I. Pcapy Reference</title><meta name="generator" content="DocBook XSL Stylesheets V1.40"><meta name="keywords" content="pcap, packet, capture, python"></head><body bgcolor="white" text="black" link="#0000FF" vlink="#840084" alink="#0000FF"><div class="part" id="id2720626"><div class="titlepage"><div><h1 class="title"><a name="id2720626"></a>Pcapy Reference</h1></div><div><h3 class="corpauthor">CORE SECURITY TECHNOLOGIES</h3></div><div><p class="copyright">Copyright � 2003 CORE SECURITY TECHNOLOGIES</p></div><div><div class="revhistory"><table border="1" width="100%" summary="Revision history"><tr><th align="left" valign="top" colspan="3"><b>Revision History</b></th></tr><tr><td align="left">Revision $Revision: 1.2 $</td><td align="left">$Date: 2003/10/23 17:24:27 $</td><td align="left">$Author: jkohen $</td></tr><tr><td align="left" colspan="3">Initial revision</td></tr></table></div></div></div><div class="toc"><p><b>Table of Contents</b></p><dl><dt>I <a href="#id2720790">Pcapy Module Reference</a></dt><dd><dl><dt><a href="#id2720796">open_live</a></dt><dt><a href="#id2720974">open_offline</a></dt><dt><a href="#id2721096">lookupdev</a></dt><dt><a href="#id2716618">findalldevs</a></dt><dt><a href="#id2766688">compile</a></dt></dl></dd><dt>II <a href="#id2720711">Reader Object Reference</a></dt><dd><dl><dt><a href="#id2720717">dispatch</a></dt><dt><a href="#id2723103">next</a></dt><dt><a href="#id2723279">setfilter</a></dt><dt><a href="#id2723348">getnet</a></dt><dt><a href="#id2723448">datalink</a></dt><dt><a href="#id2718490">getnonblock</a></dt><dt><a href="#id2718128">dump_open</a></dt></dl></dd><dt>III <a href="#id2718727">Dumper Object Reference</a></dt><dd><dl><dt><a href="#id2718732">dump</a></dt></dl></dd><dt>IV <a href="#id2718829">Pkthdr Object Reference</a></dt><dd><dl><dt><a href="#id2718835">getts</a></dt></dl></dd><dt>V <a href="#id2781073">Bpf Object Reference</a></dt><dd><dl><dt><a href="#id2781080">filter</a></dt></dl></dd><dt><a href="#id2781178">Bibliography</a></dt></dl></div><div class="reference"><div class="titlepage"><div><h1 class="title"><a name="id2720790"></a>Pcapy Module Reference</h1></div><hr></div><div class="toc"><p><b>Table of Contents</b></p><dl><dt><a href="#id2720796">open_live</a></dt><dt><a href="#id2720974">open_offline</a></dt><dt><a href="#id2721096">lookupdev</a></dt><dt><a href="#id2716618">findalldevs</a></dt><dt><a href="#id2766688">compile</a></dt></dl></div><div class="refentry"><h1 class="title"><a name="id2720796"></a>open_live</h1><div class="refnamediv"><a name="id2720799"></a><h2>Name</h2>open_live &#8212; Obtain a packet capture descriptor to look at packets on the network</div><div class="refsynopsisdiv"><a name="id2720813"></a><h2>Synopsis</h2><div class="funcsynopsis" id="id2720817"><a name="id2720817"></a><p><code><code class="funcdef">Reader <b class="fsfunc">open_live</b></code>(<var class="pdparam">device</var>, <var class="pdparam">snaplen</var>, <var class="pdparam">promisc</var>, <var class="pdparam">to_ms</var>);<br>string <var class="pdparam">device</var>;<br>int <var class="pdparam">snaplen</var>;<br>int <var class="pdparam">promisc</var>;<br>int <var class="pdparam">to_ms</var>;</code></p></div></div><div class="refsect1"><a name="id2720875"></a><h2><a name="id2720875"></a>DESCRIPTION</h2><p>
+	  <tt>open_live</tt> is used to obtain a packet
+	  capture descriptor to look at packets on the network.
+	  <i><tt>device</tt></i> is a string that specifies the
+	  network device to open; on Linux systems with 2.2 or later
+	  kernels, a device argument of <tt>any</tt> or
+	  <tt>NULL</tt> can be used to capture packets
+	  from all interfaces. <i><tt>snaplen</tt></i>
+	  specifies the maximum number of bytes to capture.
+	  <i><tt>promisc</tt></i> specifies if the interface is
+	  to be put into promiscuous mode. (Note that even if this
+	  parameter is false, the interface could well be in
+	  promiscuous mode for some other reason.) For now, this
+	  doesn't work on the <tt>any</tt> device; if an
+	  argument of <tt>any</tt> or
+	  <tt>NULL</tt> is supplied, the
+	  <i><tt>promisc</tt></i> flag is ignored.
+	  <i><tt>to_ms</tt></i> specifies the read timeout in
+	  milliseconds. The read timeout is used to arrange that the
+	  read not necessarily return immediately when a packet is
+	  seen, but that it wait for some amount of time to allow more
+	  packets to arrive and to read multiple packets from the OS
+	  kernel in one operation. Not all platforms support a read
+	  timeout; on platforms that don't, the read timeout is
+	  ignored.
+	</p></div></div><div class="refentry"><h1 class="title"><a name="id2720974"></a>open_offline</h1><div class="refnamediv"><a name="id2720977"></a><h2>Name</h2>open_offline &#8212; Obtain a packet capture descriptor to look at packets on a <i>savefile</i></div><div class="refsynopsisdiv"><a name="id2720994"></a><h2>Synopsis</h2><div class="funcsynopsis" id="id2720997"><a name="id2720997"></a><p><code><code class="funcdef">Reader <b class="fsfunc">open_offline</b></code>(<var class="pdparam">filename</var>);<br>string <var class="pdparam">filename</var>;</code></p></div></div><div class="refsect1"><a name="id2721028"></a><h2><a name="id2721028"></a>DESCRIPTION</h2><p>
+	  <tt>open_offline</tt> is called to open a
+	  <i>savefile</i> for reading. <i><tt>filename</tt></i>
+	  specifies the name of the file to open. The file has the
+	  same format as those used by
+	  tcpdump(8) and
+	  tcpslice(8). The name
+	  <tt>-</tt> is a synonym for
+	  <tt>stdin</tt>.
+	</p></div></div><div class="refentry"><h1 class="title"><a name="id2721096"></a>lookupdev</h1><div class="refnamediv"><a name="id2721099"></a><h2>Name</h2>lookupdev &#8212; Return a network device suitable for use with
+	  <tt>open_live</tt></div><div class="refsynopsisdiv"><a name="id2721118"></a><h2>Synopsis</h2><div class="funcsynopsis" id="id2721121"><a name="id2721121"></a><p><code><code class="funcdef">string <b class="fsfunc">lookupdev</b></code>();</code></p></div></div><div class="refsect1"><a name="id2721144"></a><h2><a name="id2721144"></a>DESCRIPTION</h2><p>
+	  <tt>lookupdev</tt> returns the name of a network
+	  device suitable for use with <tt>open_live</tt>.
+	</p></div></div><div class="refentry"><h1 class="title"><a name="id2716618"></a>findalldevs</h1><div class="refnamediv"><a name="id2766659"></a><h2>Name</h2>findalldevs &#8212; Obtain the list of available network devices</div><div class="refsynopsisdiv"><a name="id2780797"></a><h2>Synopsis</h2><div class="funcsynopsis" id="id2780800"><a name="id2780800"></a><p><code><code class="funcdef">string[] <b class="fsfunc">findalldevs</b></code>();</code></p></div></div><div class="refsect1"><a name="id2766782"></a><h2><a name="id2766782"></a>DESCRIPTION</h2><p>
+	  <tt>findalldevs</tt> constructs a list of
+	  network devices that can be opened with
+	  <tt>open_live</tt>. (Note that there may be
+	  network devices that cannot be opened with
+	  <tt>open_live</tt>, because, for example, that
+	  process might not have sufficient privileges to open them
+	  for capturing; if so, those devices will not appear on the
+	  list.)
+	</p></div></div><div class="refentry"><h1 class="title"><a name="id2766688"></a>compile</h1><div class="refnamediv"><a name="id2766691"></a><h2>Name</h2>compile &#8212; Compile a BPF filter</div><div class="refsynopsisdiv"><a name="id2766704"></a><h2>Synopsis</h2><div class="funcsynopsis" id="id2766707"><a name="id2766707"></a><p><code><code class="funcdef">Bpf <b class="fsfunc">compile</b></code>(<var class="pdparam">linktype</var>, <var class="pdparam">snaplen</var>, <var class="pdparam">filter</var>, <var class="pdparam">optimize</var>, <var class="pdparam">netmask</var>);<br>int <var class="pdparam">linktype</var>;<br>int <var class="pdparam">snaplen</var>;<br>string <var class="pdparam">filter</var>;<br>int <var class="pdparam">optimize</var>;<br>int32 <var class="pdparam">netmask</var>;</code></p></div></div><div class="refsect1"><a name="id2720660"></a><h2><a name="id2720660"></a>DESCRIPTION</h2><p>
+	  <tt>compile</tt> is used to compile the
+	  <i><tt>filter</tt></i> into a filter program.
+	  <tt>snaplen</tt> specifies the maximum number of
+	  bytes to capture. <i><tt>optimize</tt></i> controls
+	  whether optimization on the resulting code is performed.
+	  <i><tt>netmask</tt></i> specifies the netmask of the
+	  local network.
+	</p></div></div></div><div class="reference"><div class="titlepage"><div><h1 class="title"><a name="id2720711"></a>Reader Object Reference</h1></div><hr></div><div class="toc"><p><b>Table of Contents</b></p><dl><dt><a href="#id2720717">dispatch</a></dt><dt><a href="#id2723103">next</a></dt><dt><a href="#id2723279">setfilter</a></dt><dt><a href="#id2723348">getnet</a></dt><dt><a href="#id2723448">datalink</a></dt><dt><a href="#id2718490">getnonblock</a></dt><dt><a href="#id2718128">dump_open</a></dt></dl></div><div class="refentry"><h1 class="title"><a name="id2720717"></a>dispatch</h1><div class="refnamediv"><a name="id2720720"></a><h2>Name</h2>dispatch, loop &#8212; Collect and process packets</div><div class="refsynopsisdiv"><a name="id2718931"></a><h2>Synopsis</h2><div class="funcsynopsis" id="id2718935"><a name="id2718935"></a><p><code><code class="funcdef">int <b class="fsfunc">dispatch</b></code>(<var class="pdparam">maxcant</var>, <var class="pdparam">(* callback)</var>);<br>int <var class="pdparam">maxcant</var>;<br>void <var class="pdparam">(* callback)</var>
+	      (Pkthdr, string);</code></p><p><code><code class="funcdef">int <b class="fsfunc">loop</b></code>(<var class="pdparam">maxcant</var>, <var class="pdparam">(* callback)</var>);<br>int <var class="pdparam">maxcant</var>;<br>void <var class="pdparam">(* callback)</var>
+	      (Pkthdr, string);</code></p></div></div><div class="refsect1"><a name="id2719017"></a><h2><a name="id2719017"></a>DESCRIPTION</h2><p>
+	  <tt>dispatch</tt> is used to collect and process
+	  packets. <i><tt>maxcant</tt></i> specifies the
+	  maximum number of packets to process before returning. This
+	  is not a minimum number; when reading a live capture, only
+	  one bufferful of packets is read at a time, so fewer than
+	  <i><tt>maxcant</tt></i> packets may be processed. A
+	  <i><tt>cnt</tt></i> of <tt>-1</tt>
+	  processes all the packets received in one buffer when
+	  reading a live capture, or all the packets in the file when
+	  reading a <i>savefile</i>. <i><tt>callback</tt></i>
+	  specifies a routine to be called with two arguments: a
+	  <tt>Pkthdr</tt> instance describing the data
+	  passed and the data itself.
+	</p><p>
+	  The number of packets read is returned.
+	  0 is returned if no packets were
+	  read from a live capture (if, for example, they were
+	  discarded because they didn't pass the packet filter, or if,
+	  on platforms that support a read timeout that starts before
+	  any packets arrive, the timeout expires before any  packets
+	  arrive, or if the file descriptor for the capture device is
+	  in non&#8211;blocking mode and no packets were available to be
+	  read) or if no more packets are available in a <i>savefile</i>.
+	</p><div class="note" style="margin-left: 0.5in; margin-right: 0.5in;"><h3 class="title"><a name="id2723188"></a>Note</h3><p>
+	    When reading a live capture, <tt>dispatch</tt>
+	    will not necessarily return when the read times out; on
+	    some platforms, the read timeout isn't supported, and, on
+	    other platforms, the timer doesn't start until at least
+	    one packet arrives. This means that the read timeout
+	    should <i>not</i> be used in, for example,
+	    an interactive application, to allow the packet capture
+	    loop to poll for user input periodically, as there's no
+	    guarantee that <tt>dispatch</tt> will return
+	    after the timeout expires.
+	  </p></div><p>
+	  <tt>loop</tt> is similar to
+	  <tt>dispatch</tt> except it keeps reading
+	  packets until <i><tt>maxcant</tt></i> packets are
+	  processed or an error occurs. It does
+	  <i>not</i> return when live read timeouts
+	  occur. Rather, specifying a non&#8211;zero read timeout to
+	  <tt>open_live</tt> and then calling
+	  <tt>dispatch</tt> allows the reception and
+	  processing of any packets that arrive when the timeout
+	  occurs. A negative <i><tt>maxcant</tt></i> causes
+	  <tt>loop</tt> to loop forever (or at least until
+	  an error occurs). 0 is returned
+	  if <i><tt>maxcant</tt></i> is exhausted.
+	</p></div></div><div class="refentry"><h1 class="title"><a name="id2723103"></a>next</h1><div class="refnamediv"><a name="id2723106"></a><h2>Name</h2>next &#8212; Collect the next packet</div><div class="refsynopsisdiv"><a name="id2723120"></a><h2>Synopsis</h2><div class="funcsynopsis" id="id2723123"><a name="id2723123"></a><p><code><code class="funcdef">(Pkthdr, string) <b class="fsfunc">next</b></code>();</code></p></div></div><div class="refsect1"><a name="id2723147"></a><h2><a name="id2723147"></a>DESCRIPTION</h2><p>
+	  <tt>next</tt> reads the next packet (by calling
+	  <tt>dispatch</tt> with a
+	  <i><tt>maxcant</tt></i> of <tt>1</tt>)
+	  and returns a tuple (header, data) where
+	  <i><tt>header</tt></i> is a
+	  <tt>Pkthdr</tt> instance describing the data
+	  passed and <i><tt>data</tt></i> is the data itself.
+	</p></div></div><div class="refentry"><h1 class="title"><a name="id2723279"></a>setfilter</h1><div class="refnamediv"><a name="id2723282"></a><h2>Name</h2>setfilter &#8212; Specify a filter</div><div class="refsynopsisdiv"><a name="id2723294"></a><h2>Synopsis</h2><div class="funcsynopsis" id="id2723298"><a name="id2723298"></a><p><code><code class="funcdef"><b class="fsfunc">setfilter</b></code>(<var class="pdparam">filter</var>);<br>string <var class="pdparam">filter</var>;</code></p></div></div><div class="refsect1"><a name="id2723327"></a><h2><a name="id2723327"></a>DESCRIPTION</h2><p>
+	  <tt>setfilter</tt> is used to specify a filter
+	  for this object.
+	</p></div></div><div class="refentry"><h1 class="title"><a name="id2723348"></a>getnet</h1><div class="refnamediv"><a name="id2723351"></a><h2>Name</h2>getnet, getmask &#8212; Get the associated network number and mask</div><div class="refsynopsisdiv"><a name="id2723367"></a><h2>Synopsis</h2><div class="funcsynopsis" id="id2723370"><a name="id2723370"></a><p><code><code class="funcdef">int32 <b class="fsfunc">getnet</b></code>();</code></p></div><div class="funcsynopsis" id="id2723392"><a name="id2723392"></a><p><code><code class="funcdef">int32 <b class="fsfunc">getmask</b></code>();</code></p></div></div><div class="refsect1"><a name="id2723415"></a><h2><a name="id2723415"></a>DESCRIPTION</h2><p>
+	  <tt>getnet</tt> and <tt>getmask</tt>
+	  are used to determine the network number and mask associated
+	  with the network device attached to this
+	  <tt>Reader</tt>.
+	</p></div></div><div class="refentry"><h1 class="title"><a name="id2723448"></a>datalink</h1><div class="refnamediv"><a name="id2723451"></a><h2>Name</h2>datalink &#8212; Obtain the link layer type</div><div class="refsynopsisdiv"><a name="id2723463"></a><h2>Synopsis</h2><div class="funcsynopsis" id="id2723466"><a name="id2723466"></a><p><code><code class="funcdef">int <b class="fsfunc">datalink</b></code>();</code></p></div></div><div class="refsect1"><a name="id2723489"></a><h2><a name="id2723489"></a>DESCRIPTION</h2><p>
+	  <tt>datalink</tt> returns the link layer type; link layer types it can return include:
+	  <div class="variablelist"><dl><dt><a name="id2723510"></a><span class="term"><tt>DLT_NULL</tt></span></dt><dd><p>
+		  BSD loopback encapsulation; the
+		  link layer header is a 4&#8211;byte field, in host
+		  byte order, containing a <tt>PF_</tt>
+		  value from <tt>socket.h</tt> for the
+		  network&#8211;layer protocol of the packet.
+		</p><div class="note" style="margin-left: 0.5in; margin-right: 0.5in;"><h3 class="title"><a name="id2723550"></a>Note</h3><p>
+		    &#8220;host byte order&#8221; is the byte order
+		    of the machine on which the packets are captured,
+		    and the <tt>PF_</tt> values are for
+		    the OS of the machine on which
+		    the packets are captured; if a live capture is
+		    being done, &#8220;host byte order&#8221; is the
+		    byte order of the machine capturing the packets,
+		    and the <tt>PF_</tt> values are those
+		    of the OS of the machine
+		    capturing the packets, but if a <i>savefile</i> is being
+		    read, the byte order and <tt>PF_</tt>
+		    values are <i>not</i> necessarily
+		    those of the machine reading the capture file.
+		  </p></div></dd><dt><a name="id2723606"></a><span class="term"><tt>DLT_EN10MB</tt></span></dt><dd><p>Ethernet (10Mb, 100Mb, 1000Mb, and up)</p></dd><dt><a name="id2723624"></a><span class="term"><tt>DLT_IEEE802</tt></span></dt><dd><p>IEEE 802.5 Token Ring</p></dd><dt><a name="id2723645"></a><span class="term"><tt>DLT_ARCNET</tt></span></dt><dd><p>ARCNET</p></dd><dt><a name="id2723536"></a><span class="term"><tt>DLT_SLIP</tt></span></dt><dd><p><a name="id2717681"></a>
+		  SLIP; the link layer header contains, in order:
+		  <div class="itemizedlist"><ul><li><a name="id2717695"></a><p>
+			a 1&#8211;byte flag, which is
+			<tt>0</tt> for packets received by
+			the machine and <tt>1</tt> for
+			packets sent by the machine.
+		      </p></li><li><p><a name="id2717721"></a>
+			a 1&#8211;byte field, the upper 4 bits of which indicate the type of packet, as per RFC 1144:
+
+			<div class="itemizedlist"><ul><li><a name="id2717736"></a><p>
+			      <tt>0x40</tt>; an unmodified
+			      IP datagram
+			      (<tt>TYPE_IP</tt>)
+			    </p></li><li><a name="id2717760"></a><p>
+			      <tt>0x70</tt>; an
+			      uncompressed&#8211;TCP/IP
+			      datagram
+			      (<tt>UNCOMPRESSED_TCP</tt>),
+			      with that byte being the first byte of
+			      the raw IP header on
+			      the wire, containing the connection
+			      number in the protocol field
+			    </p></li><li><a name="id2717791"></a><p>
+			      <tt>0x80</tt>; a
+			      compressed&#8211;TCP/IP
+			      datagram
+			      (<tt>COMPRESSED_TCP</tt>),
+			      with that byte being the first byte of
+			      the compressed TCP/IP
+			      datagram header
+			    </p></li></ul></div>
+		      </p></li><li><a name="id2717824"></a><p>
+			for <tt>UNCOMPRESSED_TCP</tt>, the
+			rest of the modified IP
+			header, and for
+			<tt>COMPRESSED_TCP</tt>, the
+			compressed TCP/IP datagram
+			header
+		      </p></li></ul></div>
+		  for a total of 16 bytes; the uncompressed IP datagram follows the header.
+		</p></dd><dt><a name="id2717860"></a><span class="term"><tt>DLT_PPP</tt></span></dt><dd><p>
+		  PPP; if the first 2 bytes are
+		  <tt>0xff</tt> and <tt>0x03</tt>,
+		  it's PPP in
+		  HDLC&#8211;like framing, with the
+		  PPP header following those two
+		  bytes, otherwise it's PPP without
+		  framing, and the packet begins with the
+		  PPP header.
+		</p></dd><dt><a name="id2717919"></a><span class="term"><tt>DLT_FDDI</tt></span></dt><dd><p>FDDI</p></dd><dt><a name="id2717938"></a><span class="term"><tt>DLT_ATM_RFC1483</tt></span></dt><dd><p>
+		  RFC 1483
+		  LLC/SNAP&#8211;encapsulated
+		  ATM; the packet begins with an
+		  IEEE 802.2 LLC
+		  header.
+		</p></dd><dt><a name="id2717976"></a><span class="term"><tt>DLT_RAW</tt></span></dt><dd><p>
+		  Raw IP; the packet begins with an
+		  IP header.
+		</p></dd><dt><a name="id2718002"></a><span class="term"><tt>DLT_PPP_SERIAL</tt></span></dt><dd><p>
+		  PPP in
+		  HDLC&#8211;like framing, as per
+		  RFC 1662, or Cisco
+		  PPP with HDLC
+		  framing, as per section �4.3.1 of
+		  RFC 1547; the first byte will be
+		  <tt>0xFF</tt> for PPP
+		  in HDLC&#8211;like framing, and
+		  will be <tt>0x0F</tt> or
+		  <tt>0x8F</tt> for Cisco
+		  PPP with HDLC
+		  framing.
+		</p></dd><dt><a name="id2718179"></a><span class="term"><tt>DLT_PPP_ETHER</tt></span></dt><dd><p>
+		  PPPoE; the packet begins with a
+		  PPPoE header, as per
+		  RFC 2516.
+		</p></dd><dt><a name="id2718208"></a><span class="term"><tt>DLT_C_HDLC</tt></span></dt><dd><p>
+		  Cisco PPP with
+		  HDLC framing, as per section
+		  � 4.3.1 of RFC 1547.
+		</p></dd><dt><a name="id2718045"></a><span class="term"><tt>DLT_IEEE802_11</tt></span></dt><dd><p>
+		  IEEE 802.11 wireless
+		  LAN.
+		</p></dd><dt><a name="id2718071"></a><span class="term"><tt>DLT_LOOP</tt></span></dt><dd><p>
+		  OpenBSD loopback encapsulation; the link layer
+		  header is a 4&#8211;byte field, in network byte
+		  order, containing a <tt>PF_</tt> value
+		  from OpenBSD's <tt>socket.h</tt> for the
+		  network&#8211;layer protocol of the packet.
+		</p><div class="note" style="margin-left: 0.5in; margin-right: 0.5in;"><h3 class="title"><a name="id2718249"></a>Note</h3><p>
+		    Note that, if a <i>savefile</i> is being read, those
+		    <tt>PF_</tt> values are
+		    <i>not</i> necessarily those of the
+		    machine reading the capture file.
+		  </p></div></dd><dt><a name="id2718273"></a><span class="term"><tt>DLT_LINUX_SLL</tt></span></dt><dd><p><a name="id2718281"></a>
+		  Linux cooked capture encapsulation; the link layer
+		  header contains, in order:
+
+		  <div class="itemizedlist"><ul><li><p><a name="id2718292"></a>
+			a 2&#8211;byte &quot;packet  type&quot;,  in  network
+			byte order, which is one of:
+
+			<div class="itemizedlist"><ul><li><a name="id2718303"></a><p>
+			      <tt>0</tt>; packet was sent to
+			      us by somebody else.
+			    </p></li><li><a name="id2718320"></a><p>
+			      <tt>1</tt>; packet was
+			      broadcast by somebody else.
+			    </p></li><li><a name="id2718336"></a><p>
+			      <tt>2</tt>; packet was
+			      multicast, but not broadcast, by
+			      somebody else.
+			    </p></li><li><a name="id2718353"></a><p>
+			      <tt>3</tt>; packet was sent by
+			      somebody else to somebody else.
+			    </p></li><li><a name="id2718369"></a><p>
+			      <tt>4</tt>; packet was sent by
+			      us.
+			    </p></li></ul></div>
+		      </p></li><li><a name="id2718388"></a><p>
+			a 2&#8211;byte field, in network byte order,
+			containing a Linux
+			<tt>ARPHRD_</tt> value for the
+			link layer device type.
+		      </p></li><li><a name="id2718403"></a><p>
+			a 2&#8211;byte field, in network byte order,
+			containing the length of the link layer
+			address of the sender of the packet (which
+			could be 0).
+		      </p></li><li><a name="id2718414"></a><p>
+			an 8&#8211;byte field containing that number
+			of bytes of the link layer header (if there
+			are more than 8 bytes, only the first 8 are
+			present).
+		      </p></li><li><a name="id2718426"></a><p>
+			a 2&#8211;byte field containing an Ethernet
+			protocol type, in network byte order, or
+			containing <tt>1</tt> for Novell
+			802.3 frames without an 802.2
+			LLC header or
+			<tt>4</tt> for frames beginning with
+			an 802.2 LLC header.
+		      </p></li></ul></div>
+		</p></dd><dt><a name="id2718463"></a><span class="term"><tt>DLT_LTALK</tt></span></dt><dd><p>
+		  Apple LocalTalk; the packet begins with an AppleTalk
+		  LLAP header.
+		</p></dd></dl></div>
+	</p></div></div><div class="refentry"><h1 class="title"><a name="id2718490"></a>getnonblock</h1><div class="refnamediv"><a name="id2718494"></a><h2>Name</h2>getnonblock, setnonblock &#8212; Manipulate the
+	  <i>non&#8211;blocking</i> flag</div><div class="refsynopsisdiv"><a name="id2718514"></a><h2>Synopsis</h2><div class="funcsynopsis" id="id2718516"><a name="id2718516"></a><p><code><code class="funcdef">int <b class="fsfunc">getnonblock</b></code>();</code></p></div><div class="funcsynopsis" id="id2718538"><a name="id2718538"></a><p><code><code class="funcdef"><b class="fsfunc">setnonblock</b></code>(<var class="pdparam">state</var>);<br>int <var class="pdparam">state</var>;</code></p></div></div><div class="refsect1"><a name="id2718567"></a><h2><a name="id2718567"></a>DESCRIPTION</h2><p>
+	  <tt>getnonblock</tt> returns the current
+	  non&#8211;blocking state of the capture descriptor; it
+	  always returns 0 on <i>savefile</i>s.
+	</p></div><div class="refsect1"><a name="id2718596"></a><h2><a name="id2718596"></a>DESCRIPTION</h2><p>
+	  <tt>setnonblock</tt> puts a capture descriptor,
+	  opened with <tt>open_live</tt>, into
+	  non&#8211;blocking mode, or takes it out of
+	  non&#8211;blocking mode, depending on whether the
+	  <i><tt>state</tt></i> argument is non&#8211;zero or
+	  zero. It has no effect on <i>savefile</i>s. In non&#8211;blocking
+	  mode, an attempt to read from the capture descriptor with
+	  <tt>dispatch</tt> will, if no packets are
+	  currently available to be read, return
+	  0 immediately rather than
+	  blocking waiting for packets to arrive.
+	  <tt>loop</tt> and <tt>next</tt> will
+	  not work in non&#8211;blocking mode.
+	</p></div></div><div class="refentry"><h1 class="title"><a name="id2718128"></a>dump_open</h1><div class="refnamediv"><a name="id2718622"></a><h2>Name</h2>dump_open &#8212; Create a Dumper object</div><div class="refsynopsisdiv"><a name="id2718635"></a><h2>Synopsis</h2><div class="funcsynopsis" id="id2718639"><a name="id2718639"></a><p><code><code class="funcdef">Dumper <b class="fsfunc">dump_open</b></code>(<var class="pdparam">filename</var>);<br>string <var class="pdparam">filename</var>;</code></p></div></div><div class="refsect1"><a name="id2718669"></a><h2><a name="id2718669"></a>DESCRIPTION</h2><p>
+	  <tt>dump_open</tt> is called to open a <i>savefile</i>
+	  for writing and associate it to a newly created
+	  <tt>Dumper</tt> instance. The name
+	  <tt>-</tt> is a synonym for <tt>stdout</tt>.
+	  <i><tt>filename</tt></i> specifies the name of the
+	  file to open.
+	</p></div></div></div><div class="reference"><div class="titlepage"><div><h1 class="title"><a name="id2718727"></a>Dumper Object Reference</h1></div><hr></div><div class="toc"><p><b>Table of Contents</b></p><dl><dt><a href="#id2718732">dump</a></dt></dl></div><div class="refentry"><h1 class="title"><a name="id2718732"></a>dump</h1><div class="refnamediv"><a name="id2718735"></a><h2>Name</h2>dump &#8212; Dump a packet to a <i>savefile</i></div><div class="refsynopsisdiv"><a name="id2718751"></a><h2>Synopsis</h2><div class="funcsynopsis" id="id2718755"><a name="id2718755"></a><p><code><code class="funcdef"><b class="fsfunc">dump</b></code>(<var class="pdparam">header</var>, <var class="pdparam">data</var>);<br>Pkthdr <var class="pdparam">header</var>;<br>string <var class="pdparam">data</var>;</code></p></div></div><div class="refsect1"><a name="id2718793"></a><h2><a name="id2718793"></a>DESCRIPTION</h2><p>
+	  <tt>dump</tt> outputs a packet to the <i>savefile</i>
+	  opened with <tt>dump_open</tt> from type
+	  <tt>Reader</tt>.
+	</p></div></div></div><div class="reference"><div class="titlepage"><div><h1 class="title"><a name="id2718829"></a>Pkthdr Object Reference</h1></div><hr></div><div class="toc"><p><b>Table of Contents</b></p><dl><dt><a href="#id2718835">getts</a></dt></dl></div><div class="refentry"><h1 class="title"><a name="id2718835"></a>getts</h1><div class="refnamediv"><a name="id2718838"></a><h2>Name</h2>getts, getcaplen, getlen &#8212; Obtain packet header information</div><div class="refsynopsisdiv"><a name="id2780956"></a><h2>Synopsis</h2><div class="funcsynopsis" id="id2780959"><a name="id2780959"></a><p><code><code class="funcdef">(long, long) <b class="fsfunc">getts</b></code>();</code></p></div><div class="funcsynopsis" id="id2780980"><a name="id2780980"></a><p><code><code class="funcdef">long <b class="fsfunc">getcaplen</b></code>();</code></p></div><div class="funcsynopsis" id="id2781001"><a name="id2781001"></a><p><code><code class="funcdef">long <b class="fsfunc">getlen</b></code>();</code></p></div></div><div class="refsect1"><a name="id2781024"></a><h2><a name="id2781024"></a>DESCRIPTION</h2><p>
+	  <tt>getts</tt>, <tt>getcaplen</tt>
+	  and <tt>getlen</tt> return the timestamp,
+	  capture length and total length fields of the packet header,
+	  respectively.
+	</p><p>
+	  Timestamp is a tuple with two elements: the number of
+	  seconds since the Epoch, and the amount of microseconds past
+	  the current second. The capture length is the number of
+	  bytes of the packet that are available from the capture.
+	  Finally, total length gives 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).
+	</p></div></div></div><div class="reference"><div class="titlepage"><div><h1 class="title"><a name="id2781073"></a>Bpf Object Reference</h1></div><hr></div><div class="toc"><p><b>Table of Contents</b></p><dl><dt><a href="#id2781080">filter</a></dt></dl></div><div class="refentry"><h1 class="title"><a name="id2781080"></a>filter</h1><div class="refnamediv"><a name="id2781083"></a><h2>Name</h2>filter &#8212; Test a packet against a compiled filter</div><div class="refsynopsisdiv"><a name="id2781096"></a><h2>Synopsis</h2><div class="funcsynopsis" id="id2781099"><a name="id2781099"></a><p><code><code class="funcdef">int <b class="fsfunc">filter</b></code>(<var class="pdparam">packet</var>);<br>string <var class="pdparam">packet</var>;</code></p></div></div><div class="refsect1"><a name="id2781129"></a><h2><a name="id2781129"></a>DESCRIPTION</h2><p>
+	  <tt>filter</tt> tests a packet against a
+	  compiled filter as returned by
+	  <tt>pcapy</tt>'s <tt>compile</tt>.
+	  If the packet is allowed to pass through
+	  -1 is returned, otherwise
+	  <tt>filter</tt> returns
+	  0.
+	</p></div></div></div><div id="id2781178" class="bibliography"><div class="titlepage"><div><h2 class="title"><a name="id2781178"></a>Bibliography</h2></div></div><div class="bibliodiv"><h3 class="title"><a name="id2781186">Sources</a></h3><div id="id2781192" class="biblioentry"><a name="id2781192"></a><p><span class="bibliomisc">
+	  Portions of this work based on
+	  pcap(3) by the Lawrence
+	  Berkeley National Laboratory, University of California,
+	  Berkeley, CA.
+	. </span></p></div></div></div></div></body></html>
+<?xml version='1.0'?>
+<!DOCTYPE part PUBLIC "-//OASIS//DTD DocBook XML V4.1.2//EN"
+               "docbook/dtd/xml/4.1.2/docbookx.dtd" [
+<!ENTITY corest "CORE SECURITY TECHNOLOGIES">
+]>
+<!-- $Id: pcapy.xml,v 1.2 2003/10/23 17:24:27 jkohen Exp $ -->
+<part>
+  <partinfo>
+    <copyright>
+      <year>2003</year>
+      <holder>&corest;</holder>
+    </copyright>
+    <corpauthor>&corest;</corpauthor>
+    <keywordset>
+      <keyword>pcap</keyword>
+      <keyword>packet</keyword>
+      <keyword>capture</keyword>
+      <keyword>python</keyword>
+    </keywordset>
+    <revhistory>
+      <revision>
+	<revnumber>$Revision: 1.2 $</revnumber>
+	<date>$Date: 2003/10/23 17:24:27 $</date>
+	<authorinitials>$Author: jkohen $</authorinitials>
+	<revremark>Initial revision</revremark>
+      </revision>
+    </revhistory>
+  </partinfo>
+  <title>Pcapy Reference</title>
+
+  <reference><title>Pcapy Module Reference</title>
+    <refentry>
+      <refnamediv>
+	<refname>open_live</refname>
+	<refpurpose>Obtain a packet capture descriptor to look at packets on the network</refpurpose>
+      </refnamediv>
+
+      <refsynopsisdiv>
+	<funcsynopsis>
+	  <funcprototype>
+	    <funcdef>Reader <function>open_live</function></funcdef>
+	    <paramdef>string <parameter>device</parameter></paramdef>
+	    <paramdef>int <parameter>snaplen</parameter></paramdef>
+	    <paramdef>int <parameter>promisc</parameter></paramdef>
+	    <paramdef>int <parameter>to_ms</parameter></paramdef>
+	  </funcprototype>
+	</funcsynopsis>
+      </refsynopsisdiv>
+
+      <refsect1>
+	<title>DESCRIPTION</title>
+	<para>
+	  <function>open_live</function> is used to obtain a packet
+	  capture descriptor to look at packets on the network.
+	  <parameter>device</parameter> is a string that specifies the
+	  network device to open; on Linux systems with 2.2 or later
+	  kernels, a device argument of <literal>any</literal> or
+	  <constant>NULL</constant> can be used to capture packets
+	  from all interfaces. <parameter>snaplen</parameter>
+	  specifies the maximum number of bytes to capture.
+	  <parameter>promisc</parameter> specifies if the interface is
+	  to be put into promiscuous mode. (Note that even if this
+	  parameter is false, the interface could well be in
+	  promiscuous mode for some other reason.) For now, this
+	  doesn't work on the <literal>any</literal> device; if an
+	  argument of <literal>any</literal> or
+	  <constant>NULL</constant> is supplied, the
+	  <parameter>promisc</parameter> flag is ignored.
+	  <parameter>to_ms</parameter> specifies the read timeout in
+	  milliseconds. The read timeout is used to arrange that the
+	  read not necessarily return immediately when a packet is
+	  seen, but that it wait for some amount of time to allow more
+	  packets to arrive and to read multiple packets from the OS
+	  kernel in one operation. Not all platforms support a read
+	  timeout; on platforms that don't, the read timeout is
+	  ignored.
+	</para>
+      </refsect1>
+    </refentry>
+
+    <refentry>
+      <refnamediv>
+	<refname>open_offline</refname>
+	<refpurpose>Obtain a packet capture descriptor to look at packets on a <glossterm>savefile</glossterm></refpurpose>
+      </refnamediv>
+
+      <refsynopsisdiv>
+	<funcsynopsis>
+	  <funcprototype>
+	    <funcdef>Reader <function>open_offline</function></funcdef>
+	    <paramdef>string <parameter>filename</parameter></paramdef>
+	  </funcprototype>
+	</funcsynopsis>
+      </refsynopsisdiv>
+
+      <refsect1>
+	<title>DESCRIPTION</title>
+	<para>
+	  <function>open_offline</function> is called to open a
+	  <glossterm>savefile</glossterm> for reading. <parameter>filename</parameter>
+	  specifies the name of the file to open. The file has the
+	  same format as those used by
+	  <citerefentry><refentrytitle>tcpdump</refentrytitle>
+	    <manvolnum>8</manvolnum></citerefentry> and
+	  <citerefentry><refentrytitle>tcpslice</refentrytitle>
+	    <manvolnum>8</manvolnum></citerefentry>. The name
+	  <filename>-</filename> is a synonym for
+	  <filename class="devicefile">stdin</filename>.
+	</para>
+      </refsect1>
+    </refentry>
+
+    <refentry>
+      <refnamediv>
+	<refname>lookupdev</refname>
+	<refpurpose>Return a network device suitable for use with
+	  <function>open_live</function></refpurpose>
+      </refnamediv>
+
+      <refsynopsisdiv>
+	<funcsynopsis>
+	  <funcprototype>
+	    <funcdef>string <function>lookupdev</function></funcdef>
+	    <void/>
+	  </funcprototype>
+	</funcsynopsis>
+      </refsynopsisdiv>
+
+      <refsect1>
+	<title>DESCRIPTION</title>
+	<para>
+	  <function>lookupdev</function> returns the name of a network
+	  device suitable for use with <function>open_live</function>.
+	</para>
+      </refsect1>
+    </refentry>
+
+    <refentry>
+      <refnamediv>
+	<refname>findalldevs</refname>
+	<refpurpose>Obtain the list of available network devices</refpurpose>
+      </refnamediv>
+
+      <refsynopsisdiv>
+	<funcsynopsis>
+	  <funcprototype>
+	    <funcdef>string[] <function>findalldevs</function></funcdef>
+	    <void/>
+	  </funcprototype>
+	</funcsynopsis>
+      </refsynopsisdiv>
+
+      <refsect1>
+	<title>DESCRIPTION</title>
+	<para>
+	  <function>findalldevs</function> constructs a list of
+	  network devices that can be opened with
+	  <function>open_live</function>. (Note that there may be
+	  network devices that cannot be opened with
+	  <function>open_live</function>, because, for example, that
+	  process might not have sufficient privileges to open them
+	  for capturing; if so, those devices will not appear on the
+	  list.)
+	</para>
+      </refsect1>
+    </refentry>
+
+    <refentry>
+      <refnamediv>
+	<refname>compile</refname>
+	<refpurpose>Compile a BPF filter</refpurpose>
+      </refnamediv>
+
+      <refsynopsisdiv>
+	<funcsynopsis>
+	  <funcprototype>
+	    <funcdef>Bpf <function>compile</function></funcdef>
+	    <paramdef>int <parameter>linktype</parameter></paramdef>
+	    <paramdef>int <parameter>snaplen</parameter></paramdef>
+	    <paramdef>string <parameter>filter</parameter></paramdef>
+	    <paramdef>int <parameter>optimize</parameter></paramdef>
+	    <paramdef>int32 <parameter>netmask</parameter></paramdef>
+	  </funcprototype>
+	</funcsynopsis>
+      </refsynopsisdiv>
+
+      <refsect1>
+	<title>DESCRIPTION</title>
+	<para>
+	  <function>compile</function> is used to compile the
+	  <parameter>filter</parameter> into a filter program.
+	  <function>snaplen</function> specifies the maximum number of
+	  bytes to capture. <parameter>optimize</parameter> controls
+	  whether optimization on the resulting code is performed.
+	  <parameter>netmask</parameter> specifies the netmask of the
+	  local network.
+	</para>
+      </refsect1>
+    </refentry>
+  </reference>
+
+  <reference><title>Reader Object Reference</title>
+    <refentry>
+      <refnamediv>
+	<refname>dispatch</refname>
+	<refname>loop</refname>
+	<refpurpose>Collect and process packets</refpurpose>
+      </refnamediv>
+
+      <refsynopsisdiv>
+	<funcsynopsis>
+	  <funcprototype>
+	    <funcdef>int <function>dispatch</function></funcdef>
+	    <paramdef>int <parameter>maxcant</parameter></paramdef>
+	    <paramdef>void <parameter>(* callback)</parameter>
+	      <funcparams>Pkthdr, string</funcparams></paramdef>
+	  </funcprototype>
+
+	  <funcprototype>
+	    <funcdef>int <function>loop</function></funcdef>
+	    <paramdef>int <parameter>maxcant</parameter></paramdef>
+	    <paramdef>void <parameter>(* callback)</parameter>
+	      <funcparams>Pkthdr, string</funcparams></paramdef>
+	  </funcprototype>
+	</funcsynopsis>
+      </refsynopsisdiv>
+
+      <refsect1>
+	<title>DESCRIPTION</title>
+	<para>
+	  <function>dispatch</function> is used to collect and process
+	  packets. <parameter>maxcant</parameter> specifies the
+	  maximum number of packets to process before returning. This
+	  is not a minimum number; when reading a live capture, only
+	  one bufferful of packets is read at a time, so fewer than
+	  <parameter>maxcant</parameter> packets may be processed. A
+	  <parameter>cnt</parameter> of <literal>-1</literal>
+	  processes all the packets received in one buffer when
+	  reading a live capture, or all the packets in the file when
+	  reading a <glossterm>savefile</glossterm>. <parameter>callback</parameter>
+	  specifies a routine to be called with two arguments: a
+	  <classname>Pkthdr</classname> instance describing the data
+	  passed and the data itself.
+	</para>
+	<para>
+	  The number of packets read is returned.
+	  <returnvalue>0</returnvalue> is returned if no packets were
+	  read from a live capture (if, for example, they were
+	  discarded because they didn't pass the packet filter, or if,
+	  on platforms that support a read timeout that starts before
+	  any packets arrive, the timeout expires before any  packets
+	  arrive, or if the file descriptor for the capture device is
+	  in non&ndash;blocking mode and no packets were available to be
+	  read) or if no more packets are available in a <glossterm>savefile</glossterm>.
+	</para>
+	<note>
+	  <para>
+	    When reading a live capture, <function>dispatch</function>
+	    will not necessarily return when the read times out; on
+	    some platforms, the read timeout isn't supported, and, on
+	    other platforms, the timer doesn't start until at least
+	    one packet arrives. This means that the read timeout
+	    should <emphasis>not</emphasis> be used in, for example,
+	    an interactive application, to allow the packet capture
+	    loop to poll for user input periodically, as there's no
+	    guarantee that <function>dispatch</function> will return
+	    after the timeout expires.
+	  </para>
+	</note>
+	<para>
+	  <function>loop</function> is similar to
+	  <function>dispatch</function> except it keeps reading
+	  packets until <parameter>maxcant</parameter> packets are
+	  processed or an error occurs. It does
+	  <emphasis>not</emphasis> return when live read timeouts
+	  occur. Rather, specifying a non&ndash;zero read timeout to
+	  <function>open_live</function> and then calling
+	  <function>dispatch</function> allows the reception and
+	  processing of any packets that arrive when the timeout
+	  occurs. A negative <parameter>maxcant</parameter> causes
+	  <function>loop</function> to loop forever (or at least until
+	  an error occurs). <returnvalue>0</returnvalue> is returned
+	  if <parameter>maxcant</parameter> is exhausted.
+	</para>
+      </refsect1>
+    </refentry>
+
+    <refentry>
+      <refnamediv>
+	<refname>next</refname>
+	<refpurpose>Collect the next packet</refpurpose>
+      </refnamediv>
+
+      <refsynopsisdiv>
+	<funcsynopsis>
+	  <funcprototype>
+	    <funcdef>(Pkthdr, string) <function>next</function></funcdef>
+	    <void/>
+	  </funcprototype>
+	</funcsynopsis>
+      </refsynopsisdiv>
+
+      <refsect1>
+	<title>DESCRIPTION</title>
+	<para>
+	  <function>next</function> reads the next packet (by calling
+	  <function>dispatch</function> with a
+	  <parameter>maxcant</parameter> of <constant>1</constant>)
+	  and returns a tuple (header, data) where
+	  <parameter>header</parameter> is a
+	  <classname>Pkthdr</classname> instance describing the data
+	  passed and <parameter>data</parameter> is the data itself.
+	</para>
+      </refsect1>
+    </refentry>
+
+    <refentry>
+      <refnamediv>
+	<refname>setfilter</refname>
+	<refpurpose>Specify a filter</refpurpose>
+      </refnamediv>
+
+      <refsynopsisdiv>
+	<funcsynopsis>
+	  <funcprototype>
+	    <funcdef><function>setfilter</function></funcdef>
+	    <paramdef>string <parameter>filter</parameter></paramdef>
+	  </funcprototype>
+	</funcsynopsis>
+      </refsynopsisdiv>
+
+      <refsect1>
+	<title>DESCRIPTION</title>
+	<para>
+	  <function>setfilter</function> is used to specify a filter
+	  for this object.
+	</para>
+      </refsect1>
+    </refentry>
+
+    <refentry>
+      <refnamediv>
+	<refname>getnet</refname>
+	<refname>getmask</refname>
+	<refpurpose>Get the associated network number and mask</refpurpose>
+      </refnamediv>
+
+      <refsynopsisdiv>
+	<funcsynopsis>
+	  <funcprototype>
+	    <funcdef>int32 <function>getnet</function></funcdef>
+	    <void/>
+	  </funcprototype>
+	</funcsynopsis>
+
+	<funcsynopsis>
+	  <funcprototype>
+	    <funcdef>int32 <function>getmask</function></funcdef>
+	    <void/>
+	  </funcprototype>
+	</funcsynopsis>
+      </refsynopsisdiv>
+
+      <refsect1>
+	<title>DESCRIPTION</title>
+	<para>
+	  <function>getnet</function> and <function>getmask</function>
+	  are used to determine the network number and mask associated
+	  with the network device attached to this
+	  <classname>Reader</classname>.
+	</para>
+      </refsect1>
+    </refentry>
+
+    <refentry>
+      <refnamediv>
+	<refname>datalink</refname>
+	<refpurpose>Obtain the link layer type</refpurpose>
+      </refnamediv>
+
+      <refsynopsisdiv>
+	<funcsynopsis>
+	  <funcprototype>
+	    <funcdef>int <function>datalink</function></funcdef>
+	    <void/>
+	  </funcprototype>
+	</funcsynopsis>
+      </refsynopsisdiv>
+
+      <refsect1>
+	<title>DESCRIPTION</title>
+	<para>
+	  <function>datalink</function> returns the link layer type; link layer types it can return include:
+	  <variablelist>
+	    <varlistentry><term><constant>DLT_NULL</constant></term>
+	      <listitem>
+		<simpara>
+		  <acronym>BSD</acronym> loopback encapsulation; the
+		  link layer header is a 4&ndash;byte field, in host
+		  byte order, containing a <constant>PF_</constant>
+		  value from <filename
+		    class="headerfile">socket.h</filename> for the
+		  network&ndash;layer protocol of the packet.
+		</simpara>
+		<note>
+		  <simpara>
+		    <quote>host byte order</quote> is the byte order
+		    of the machine on which the packets are captured,
+		    and the <constant>PF_</constant> values are for
+		    the <acronym>OS</acronym> of the machine on which
+		    the packets are captured; if a live capture is
+		    being done, <quote>host byte order</quote> is the
+		    byte order of the machine capturing the packets,
+		    and the <constant>PF_</constant> values are those
+		    of the <acronym>OS</acronym> of the machine
+		    capturing the packets, but if a <glossterm>savefile</glossterm> is being
+		    read, the byte order and <constant>PF_</constant>
+		    values are <emphasis>not</emphasis> necessarily
+		    those of the machine reading the capture file.
+		  </simpara>
+		</note>
+	      </listitem>
+	    </varlistentry>
+
+	    <varlistentry><term><constant>DLT_EN10MB</constant></term>
+	      <listitem>
+		<simpara>Ethernet (10Mb, 100Mb, 1000Mb, and up)</simpara>
+	      </listitem>
+	    </varlistentry>
+
+	    <varlistentry><term><constant>DLT_IEEE802</constant></term>
+	      <listitem>
+		<simpara><acronym>IEEE</acronym> 802.5 Token Ring</simpara>
+	      </listitem>
+	    </varlistentry>
+
+	    <varlistentry><term><constant>DLT_ARCNET</constant></term>
+	      <listitem>
+		<simpara><acronym>ARCNET</acronym></simpara>
+	      </listitem>
+	    </varlistentry>
+
+	    <varlistentry><term><constant>DLT_SLIP</constant></term>
+	      <listitem>
+		<para>
+		  <acronym>SLIP</acronym>; the link layer header contains, in order:
+		  <itemizedlist>
+		    <listitem>
+		      <simpara>
+			a 1&ndash;byte flag, which is
+			<literal>0</literal> for packets received by
+			the machine and <literal>1</literal> for
+			packets sent by the machine.
+		      </simpara>
+		    </listitem>
+
+		    <listitem>
+		      <para>
+			a 1&ndash;byte field, the upper 4 bits of which indicate the type of packet, as per <acronym>RFC</acronym> 1144:
+
+			<itemizedlist>
+			  <listitem>
+			    <simpara>
+			      <literal>0x40</literal>; an unmodified
+			      <acronym>IP</acronym> datagram
+			      (<constant>TYPE_IP</constant>)
+			    </simpara>
+			  </listitem>
+
+			  <listitem>
+			    <simpara>
+			      <literal>0x70</literal>; an
+			      uncompressed&ndash;<acronym>TCP/IP</acronym>
+			      datagram
+			      (<constant>UNCOMPRESSED_TCP</constant>),
+			      with that byte being the first byte of
+			      the raw <acronym>IP</acronym> header on
+			      the wire, containing the connection
+			      number in the protocol field
+			    </simpara>
+			  </listitem>
+
+			  <listitem>
+			    <simpara>
+			      <literal>0x80</literal>; a
+			      compressed&ndash;<acronym>TCP/IP</acronym>
+			      datagram
+			      (<constant>COMPRESSED_TCP</constant>),
+			      with that byte being the first byte of
+			      the compressed <acronym>TCP/IP</acronym>
+			      datagram header
+			    </simpara>
+			  </listitem>
+			</itemizedlist>
+		      </para>
+		    </listitem>
+
+		    <listitem>
+		      <simpara>
+			for <constant>UNCOMPRESSED_TCP</constant>, the
+			rest of the modified <acronym>IP</acronym>
+			header, and for
+			<constant>COMPRESSED_TCP</constant>, the
+			compressed <acronym>TCP/IP</acronym> datagram
+			header
+		      </simpara>
+		    </listitem>
+
+		  </itemizedlist>
+		  for a total of 16 bytes; the uncompressed <acronym>IP</acronym> datagram follows the header.
+		</para>
+	      </listitem>
+	    </varlistentry>
+
+	    <varlistentry><term><constant>DLT_PPP</constant></term>
+	      <listitem>
+		<simpara>
+		  <acronym>PPP</acronym>; if the first 2 bytes are
+		  <literal>0xff</literal> and <literal>0x03</literal>,
+		  it's <acronym>PPP</acronym> in
+		  <acronym>HDLC</acronym>&ndash;like framing, with the
+		  <acronym>PPP</acronym> header following those two
+		  bytes, otherwise it's <acronym>PPP</acronym> without
+		  framing, and the packet begins with the
+		  <acronym>PPP</acronym> header.
+		</simpara>
+	      </listitem>
+	    </varlistentry>
+
+	    <varlistentry><term><constant>DLT_FDDI</constant></term>
+	      <listitem>
+		<simpara><acronym>FDDI</acronym></simpara>
+	      </listitem>
+	    </varlistentry>
+
+	    <varlistentry><term><constant>DLT_ATM_RFC1483</constant></term>
+	      <listitem>
+		<simpara>
+		  <acronym>RFC</acronym> 1483
+		  <acronym>LLC/SNAP</acronym>&ndash;encapsulated
+		  <acronym>ATM</acronym>; the packet begins with an
+		  <acronym>IEEE</acronym> 802.2 <acronym>LLC</acronym>
+		  header.
+		</simpara>
+	      </listitem>
+	    </varlistentry>
+
+	    <varlistentry><term><constant>DLT_RAW</constant></term>
+	      <listitem>
+		<simpara>
+		  Raw <acronym>IP</acronym>; the packet begins with an
+		  <acronym>IP</acronym> header.
+		</simpara>
+	      </listitem>
+	    </varlistentry>
+
+	    <varlistentry><term><constant>DLT_PPP_SERIAL</constant></term>
+	      <listitem>
+		<simpara>
+		  <acronym>PPP</acronym> in
+		  <acronym>HDLC</acronym>&ndash;like framing, as per
+		  <acronym>RFC</acronym> 1662, or Cisco
+		  <acronym>PPP</acronym> with <acronym>HDLC</acronym>
+		  framing, as per section &sect;4.3.1 of
+		  <acronym>RFC</acronym> 1547; the first byte will be
+		  <literal>0xFF</literal> for <acronym>PPP</acronym>
+		  in <acronym>HDLC</acronym>&ndash;like framing, and
+		  will be <literal>0x0F</literal> or
+		  <literal>0x8F</literal> for Cisco
+		  <acronym>PPP</acronym> with <acronym>HDLC</acronym>
+		  framing.
+		</simpara>
+	      </listitem>
+	    </varlistentry>
+
+	    <varlistentry><term><constant>DLT_PPP_ETHER</constant></term>
+	      <listitem>
+		<simpara>
+		  <acronym>PPPoE</acronym>; the packet begins with a
+		  <acronym>PPPoE</acronym> header, as per
+		  <acronym>RFC</acronym> 2516.
+		</simpara>
+	      </listitem>
+	    </varlistentry>
+
+	    <varlistentry><term><constant>DLT_C_HDLC</constant></term>
+	      <listitem>
+		<simpara>
+		  Cisco <acronym>PPP</acronym> with
+		  <acronym>HDLC</acronym> framing, as per section
+		  &sect; 4.3.1 of <acronym>RFC</acronym> 1547.
+		</simpara>
+	      </listitem>
+	    </varlistentry>
+
+	    <varlistentry><term><constant>DLT_IEEE802_11</constant></term>
+	      <listitem>
+		<simpara>
+		  <acronym>IEEE</acronym> 802.11 wireless
+		  <acronym>LAN</acronym>.
+		</simpara>
+	      </listitem>
+	    </varlistentry>
+
+	    <varlistentry><term><constant>DLT_LOOP</constant></term>
+	      <listitem>
+		<simpara>
+		  OpenBSD loopback encapsulation; the link layer
+		  header is a 4&ndash;byte field, in network byte
+		  order, containing a <constant>PF_</constant> value
+		  from OpenBSD's <filename
+		    class="headerfile">socket.h</filename> for the
+		  network&ndash;layer protocol of the packet.
+		</simpara>
+		<note>
+		  <simpara>
+		    Note that, if a <glossterm>savefile</glossterm> is being read, those
+		    <constant>PF_</constant> values are
+		    <emphasis>not</emphasis> necessarily those of the
+		    machine reading the capture file.
+		  </simpara>
+		</note>
+	      </listitem>