1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
|
#!/usr/bin/python
from time import time
import logging
from ctypes import (cdll, c_char_p, create_string_buffer, Structure, byref
, c_int32, c_long, pointer, POINTER, c_char)
logger = logging.getLogger('mypcap')
pcap = cdll.LoadLibrary('libpcap.so')
PCAP_ERRBUF_SIZE = 1000 # bogus
DATA_SIZE = 2000000
for f in "pcap_next pcap_create pcap_set_snaplen pcap_set_buffer_size pcap_activate pcap_next_ex pcap_perror".split():
if len(f) > 0:
globals()[f] = getattr(pcap, f)
time_t = c_long
class timeval(Structure):
_fields_ = [('tv_sec', time_t),
('tv_usec', c_long)]
class pcap_pkthdr(Structure):
_fields_ = [('ts', timeval), # time stamp
('caplen', c_int32), # length of portion present
('len', c_int32)] # length this packet (off wire)
PCAP_ERROR = -1 # generic error code
PCAP_ERROR_BREAK = -2 # loop terminated by pcap_breakloop
PCAP_ERROR_NOT_ACTIVATED = -3 # the capture needs to be activated
PCAP_ERROR_ACTIVATED = -4 # the operation can't be performed on already activated captures
PCAP_ERROR_NO_SUCH_DEVICE = -5 # no such device exists
PCAP_ERROR_RFMON_NOTSUP = -6 # this device doesn't support rfmon (monitor) mode
PCAP_ERROR_NOT_RFMON = -7 # operation supported only in monitor mode
PCAP_ERROR_PERM_DENIED = -8 # no permission to open the device
PCAP_ERROR_IFACE_NOT_UP = -9 # interface isn't up
PCAP_WARNING = 1 # generic warning code
PCAP_WARNING_PROMISC_NOTSUP = 2 # this device doesn't support promiscuous mode
pcap_errors = [PCAP_ERROR_ACTIVATED
,PCAP_ERROR_NO_SUCH_DEVICE
,PCAP_ERROR_PERM_DENIED
,PCAP_ERROR_RFMON_NOTSUP
,PCAP_ERROR_IFACE_NOT_UP
,PCAP_ERROR]
pcap_next.restype = POINTER(c_char)
class PCAPError(Exception):
pass
class PCAP(object):
def __init__(self, dev):
self.errbuf = create_string_buffer(PCAP_ERRBUF_SIZE)
self.hdr = pcap_pkthdr()
self.hdrp = pointer(self.hdr)
self.pcap = pcap_create(dev, self.errbuf)
if self.pcap == 0:
raise PCAPError("error: %s" % self.errbuf.value)
if pcap_set_snaplen(self.pcap, 65536) != 0:
raise PCAPError("error: set snaplen failed")
if pcap_set_buffer_size(self.pcap, DATA_SIZE) != 0:
raise PCAPError("error: set buffer size failed")
ret = pcap_activate(self.pcap)
if ret in [PCAP_WARNING_PROMISC_NOTSUP, PCAP_WARNING]:
logger.warning("pcap_activate returned a warning - %d" % ret)
elif ret in pcap_errors:
pcap_perror(self.pcap, "")
raise PCAPError('pcap_activate failed')
def __iter__(self):
i_pkt = 0
hdr = self.hdr
total = 0
while True:
data = pcap_next(self.pcap, self.hdrp)
#ret = pcap_next_ex(self.pcap, byref(hdrp), byref(data));
ret = 1
if ret == 1:
total += hdr.len
i_pkt += 1
secs = float(hdr.ts.tv_sec) + float(hdr.ts.tv_usec)/1000000
logger.debug("%3d: %5.3f, %d, %d| %d" % (
i_pkt, secs, hdr.caplen, hdr.len, total))
yield secs, data[:hdr.len] # if data is NULL?
elif ret == 0:
logger.debug("%3d: timeout" % i_pkt)
elif ret == -1:
pcap_perror(self.pcap, "")
raise PCAPError("pcap_next errored")
else:
raise PCAPError("error: unexpected return %d" % ret)
pcap = PCAP
def main():
cap_2 = 10
cap = 2*cap_2
total = 0
start = time()
for secs, data in pcap('lo'):
if len(data) > cap:
r = data[:cap_2] + ('...%s...' % (len(data) - cap)) + data[-cap_2:]
else:
r = data
total += len(data)
print '%7.3f %12d %10d %s' % (secs, total, len(data), repr(r))
if __name__ == '__main__':
import sys
sys.exit(main())
|