#!/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())