1 /*
2 * Copyright (c) 2014 CORE Security Technologies
3 *
4 * This software is provided under under a slightly modified version
5 * of the Apache Software License. See the accompanying LICENSE file
6 * for more information.
7 *
8 */
9
10 #include <pcap.h>
11 #include <Python.h>
12
13 #include "pcapy.h"
14 #include "pcapobj.h"
15 #include "bpfobj.h"
16 #include "pcapdumper.h"
17 #include "pcap_pkthdr.h"
18
19
20 PyObject *PcapError;
21
22
23
24 // module methods
25
26 static PyObject*
lookupdev(PyObject * self,PyObject * args)27 lookupdev(PyObject* self, PyObject* args)
28 {
29 char errbuff[PCAP_ERRBUF_SIZE];
30 char* dev;
31
32 dev = pcap_lookupdev(errbuff);
33 if(!dev)
34 {
35 PyErr_SetString(PcapError, errbuff);
36 return NULL;
37 }
38
39 return Py_BuildValue("u", dev);
40 }
41
42 static PyObject*
findalldevs(PyObject * self,PyObject * args)43 findalldevs(PyObject *self, PyObject *args)
44 {
45 char errbuff[PCAP_ERRBUF_SIZE];
46 pcap_if_t *devs;
47
48 int status = pcap_findalldevs(&devs, errbuff);
49 if(status)
50 {
51 PyErr_SetString(PcapError, errbuff);
52 return NULL;
53 }
54
55 if(devs==NULL)
56 {
57 PyErr_SetString(PcapError, "No valid interfaces to open");
58 return NULL;
59 }
60
61 pcap_if_t *cursor = devs;
62 PyObject* list = PyList_New(0);
63 while(cursor)
64 {
65 PyList_Append(list, Py_BuildValue("s", cursor->name));
66 cursor = cursor->next;
67 }
68
69 pcap_freealldevs(devs);
70
71 return list;
72 }
73
74 static PyObject*
open_live(PyObject * self,PyObject * args)75 open_live(PyObject *self, PyObject *args)
76 {
77 char errbuff[PCAP_ERRBUF_SIZE];
78 char * device;
79 int snaplen;
80 int promisc;
81 int to_ms;
82
83 bpf_u_int32 net, mask;
84
85
86 if(!PyArg_ParseTuple(args,"siii:open_live",&device,&snaplen,&promisc,&to_ms))
87 return NULL;
88
89 int status = pcap_lookupnet(device, &net, &mask, errbuff);
90 if(status)
91 {
92 net = 0;
93 mask = 0;
94 }
95
96 pcap_t* pt;
97
98 pt = pcap_open_live(device, snaplen, promisc!=0, to_ms, errbuff);
99 if(!pt)
100 {
101 PyErr_SetString(PcapError, errbuff);
102 return NULL;
103 }
104 #ifdef WIN32
105 pcap_setmintocopy(pt, 0);
106 #endif
107
108 return new_pcapobject( pt, net, mask );
109 }
110
111 static PyObject*
open_offline(PyObject * self,PyObject * args)112 open_offline(PyObject *self, PyObject *args)
113 {
114 char errbuff[PCAP_ERRBUF_SIZE];
115 char * filename;
116
117
118 if(!PyArg_ParseTuple(args,"s",&filename))
119 return NULL;
120
121 pcap_t* pt;
122
123 pt = pcap_open_offline(filename, errbuff);
124 if(!pt)
125 {
126 PyErr_SetString(PcapError, errbuff);
127 return NULL;
128 }
129 #ifdef WIN32
130 pcap_setmintocopy(pt, 0);
131 #endif
132
133 return new_pcapobject( pt );
134 }
135
136
137 static PyObject*
bpf_compile(PyObject * self,PyObject * args)138 bpf_compile(PyObject* self, PyObject* args)
139 {
140 int linktype;
141 int snaplen;
142 char *filter;
143 int optimize;
144 unsigned int netmask;
145
146 if(!PyArg_ParseTuple(args,
147 "iisiI:compile",
148 &linktype,
149 &snaplen,
150 &filter,
151 &optimize,
152 &netmask))
153 return NULL;
154
155 pcap_t *pp;
156
157 pp = pcap_open_dead(linktype, snaplen);
158 if(pp == NULL)
159 return NULL;
160
161 struct bpf_program bpf;
162 int status = pcap_compile(pp, &bpf, filter, optimize, netmask);
163 pcap_close(pp);
164
165 if(status)
166 {
167 PyErr_SetString(PcapError, pcap_geterr(pp));
168 return NULL;
169 }
170
171 return new_bpfobject( bpf );
172 }
173
174
175 static PyMethodDef pcap_methods[] = {
176 {"open_live", open_live, METH_VARARGS, "open_live(device, snaplen, promisc, to_ms) opens a pcap device"},
177 {"open_offline", open_offline, METH_VARARGS, "open_offline(filename) opens a pcap formated file"},
178 {"lookupdev", lookupdev, METH_VARARGS, "lookupdev() looks up a pcap device"},
179 {"findalldevs", findalldevs, METH_VARARGS, "findalldevs() lists all available interfaces"},
180 {"compile", bpf_compile, METH_VARARGS, "compile(linktype, snaplen, filter, optimize, netmask) creates a bpfprogram object"},
181 {NULL, NULL}
182 };
183
184 #if PY_MAJOR_VERSION >= 3
185 PyDoc_STRVAR(pcap_doc,
186 "A wrapper for the Packet Capture (PCAP) library");
187
188 static struct PyModuleDef pcapy_module = {
189 PyModuleDef_HEAD_INIT,
190 "pcapy", /* m_name */
191 pcap_doc, /* m_doc */
192 -1, /* m_size */
193 pcap_methods, /* m_methods */
194 NULL, /* m_reload */
195 NULL, /* m_traverse */
196 NULL, /* m_clear */
197 NULL, /* m_free */
198 };
199 #else
200
201 static char *pcap_doc =
202 "\nA wrapper for the Packet Capture (PCAP) library\n";
203 #endif //PY_MAJOR_VERSION >= 3
204
205
206 #if PY_MAJOR_VERSION >= 3
207 PyMODINIT_FUNC
PyInit_pcapy(void)208 PyInit_pcapy(void)
209 #else
210 void
211 initpcapy(void)
212 #endif //PY_MAJOR_VERSION >= 3
213
214
215 {
216 PyObject *m, *d;
217
218
219 #if PY_MAJOR_VERSION < 3
220 Pcaptype.ob_type = &PyType_Type;
221 Pkthdr_type.ob_type = &PyType_Type;
222 Pdumpertype.ob_type = &PyType_Type;
223 #endif
224
225
226 #if PY_MAJOR_VERSION >= 3
227 m = PyModule_Create(&pcapy_module);
228 #else
229 m = Py_InitModule3("pcapy", pcap_methods, pcap_doc);
230 #endif
231
232 if (PyType_Ready(&BPFProgramType) < 0) {
233 #if PY_MAJOR_VERSION >= 3
234 return NULL;
235 #else
236 return;
237 #endif //PY_MAJOR_VERSION >= 3
238 }
239
240 PyModule_AddObject(m, "BPFProgram", (PyObject *) &BPFProgramType);
241
242 /* Direct from pcap's net/bpf.h. */
243 PyModule_AddIntConstant(m, "DLT_NULL", 0);
244 PyModule_AddIntConstant(m, "DLT_EN10MB", 1);
245 PyModule_AddIntConstant(m, "DLT_IEEE802", 6);
246 PyModule_AddIntConstant(m, "DLT_ARCNET", 7);
247 PyModule_AddIntConstant(m, "DLT_SLIP", 8);
248 PyModule_AddIntConstant(m, "DLT_PPP", 9);
249 PyModule_AddIntConstant(m, "DLT_FDDI", 10);
250 PyModule_AddIntConstant(m, "DLT_ATM_RFC1483", 11);
251 PyModule_AddIntConstant(m, "DLT_RAW", 12);
252 PyModule_AddIntConstant(m, "DLT_PPP_SERIAL", 50);
253 PyModule_AddIntConstant(m, "DLT_PPP_ETHER", 51);
254 PyModule_AddIntConstant(m, "DLT_C_HDLC", 104);
255 PyModule_AddIntConstant(m, "DLT_IEEE802_11", 105);
256 PyModule_AddIntConstant(m, "DLT_LOOP", 108);
257 PyModule_AddIntConstant(m, "DLT_LINUX_SLL", 113);
258 PyModule_AddIntConstant(m, "DLT_LTALK", 114);
259
260 d = PyModule_GetDict(m);
261 PcapError = PyErr_NewException("pcapy.PcapError", NULL, NULL );
262 BPFError = PyErr_NewException("pcapy.BPFError", NULL, NULL );
263 if( PcapError )
264 {
265 PyDict_SetItemString( d, "PcapError", PcapError );
266 }
267
268 if ( BPFError )
269 {
270 PyDict_SetItemString( d, "BPFError", BPFError );
271 }
272 #if PY_MAJOR_VERSION >= 3
273 return m;
274 #endif //PY_MAJOR_VERSION >= 3
275 }
276 /* vim: set tabstop=2 shiftwidth=2 expandtab: */
277