class PCap(object): @staticmethod def get_devices(): def ip(addr): if addr is None: return None return IPAddr(addr, networkOrder=True) def link(addr): if addr is None: return None if len(addr) != 6: return None return EthAddr(addr) devs = pcapc.findalldevs() out = {} for d in devs: addrs = {} n = {'desc': d[1], 'addrs': addrs} out[d[0]] = n for a in d[2]: if a[0] == 'AF_INET': na = {} addrs[a[0]] = na na['addr'] = ip(a[1]) na['netmask'] = ip(a[2]) na['broadaddr'] = ip(a[3]) na['dstaddr'] = ip(a[4]) elif a[0] == 'AF_LINK': na = {} addrs[a[0]] = na na['addr'] = link(a[1]) na['netmask'] = link(a[2]) na['broadaddr'] = link(a[3]) na['dstaddr'] = link(a[4]) elif a[0] == 'AF_PACKET': addrs[a[0]] = {'addr': link(a[1])} elif a[0] == 'ethernet': addrs[a[0]] = {'addr': link(a[1])} return out @staticmethod def get_device_names(): return [d[0] for d in pcapc.findalldevs()] def __init__(self, device=None, promiscuous=True, period=10, start=True, callback=None, filter=None, use_bytearray=False, **kw): """ Initialize this instance use_bytearray: specifies capturing to bytearray buffers instead of bytes """ if filter is not None: self.deferred_filter = (filter, ) else: self.deferred_filter = None self.packets_received = 0 self.packets_dropped = 0 self._thread = None self.pcap = None self.promiscuous = promiscuous self.device = None self.use_bytearray = use_bytearray self.period = period self.netmask = IPAddr("0.0.0.0") self._quitting = False self.addresses = {} if callback is None: self.callback = self.__class__._handle_rx else: self.callback = callback for k, v in kw.items(): assert not hasattr(self, k) setattr(self, k, v) if device is not None: self.open(device) if self.pcap is not None: if start: self.start() def _handle_rx(self, data, sec, usec, length): pass def open(self, device, promiscuous=None, period=None, incoming=True, outgoing=False): assert self.device is None self.addresses = self.get_devices()[device]['addrs'] if 'AF_INET' in self.addresses: self.netmask = self.addresses['AF_INET'].get('netmask') if self.netmask is None: self.netmask = IPAddr("0.0.0.0") #print "NM:",self.netmask #print self.addresses['AF_LINK']['addr'] self.device = device if period is not None: self.period = period if promiscuous is not None: self.promiscuous = promiscuous self.pcap = pcapc.open_live(device, 65535, 1 if self.promiscuous else 0, self.period) pcapc.setdirection(self.pcap, incoming, outgoing) self.packets_received = 0 self.packets_dropped = 0 if self.deferred_filter is not None: self.set_filter(*self.deferred_filter) self.deferred_filter = None def set_direction(self, incoming, outgoing): pcapc.setdirection(self.pcap, incoming, outgoing) def _thread_func(self): while not self._quitting: pcapc.dispatch(self.pcap, 100, self.callback, self, bool(self.use_bytearray)) self.packets_received, self.packets_dropped = pcapc.stats( self.pcap) self._quitting = False self._thread = None def _handle_GoingDownEvent(self, event): self.close() def start(self): assert self._thread is None from pox.core import core core.addListeners(self, weak=True) self._thread = Thread(target=self._thread_func) #self._thread.daemon = True self._thread.start() def stop(self): t = self._thread if t is not None: self._quitting = True pcapc.breakloop(self.pcap) t.join() def close(self): if self.pcap is None: return self.stop() pcapc.close(self.pcap) self.pcap = None def __del__(self): self.close() def inject(self, data): if isinstance(data, pkt.ethernet): data = data.pack() if not isinstance(data, (bytes, bytearray)): data = bytes(data) # Give it a try... return pcapc.inject(self.pcap, data) def set_filter(self, filter, optimize=True): if self.pcap is None: self.deferred_filter = (filter, optimize) return if isinstance(filter, str): filter = Filter(filter, optimize, self.netmask.toSignedN(), pcap_obj=self) elif isinstance(filter, Filter): pass else: raise RuntimeError("Filter must be string or Filter object") pcapc.setfilter(self.pcap, filter._pprogram)
class PCap(object): use_select = False # Falls back to non-select @staticmethod def get_devices(): def ip(addr): if addr is None: return None return IPAddr(addr, networkOrder=True) def ip6(addr): if addr is None: return None return IPAddr6.from_raw(addr) def link(addr): if addr is None: return None if len(addr) != 6: return None return EthAddr(addr) devs = pcapc.findalldevs() out = {} for d in devs: addrs = {} n = {"desc": d[1], "addrs": addrs} out[d[0]] = n for a in d[2]: if a[0] == "AF_INET": na = {} addrs[a[0]] = na na["addr"] = ip(a[1]) na["netmask"] = ip(a[2]) na["broadaddr"] = ip(a[3]) na["dstaddr"] = ip(a[4]) elif a[0] == "AF_INET6": na = {} addrs[a[0]] = na na["addr"] = ip6(a[1]) na["netmask"] = ip6(a[2]) na["broadaddr"] = ip6(a[3]) na["dstaddr"] = ip6(a[4]) elif a[0] == "AF_LINK": na = {} addrs[a[0]] = na na["addr"] = link(a[1]) na["netmask"] = link(a[2]) na["broadaddr"] = link(a[3]) na["dstaddr"] = link(a[4]) elif a[0] == "AF_PACKET": addrs[a[0]] = {"addr": link(a[1])} elif a[0] == "ethernet": addrs[a[0]] = {"addr": link(a[1])} return out @staticmethod def get_device_names(): return [d[0] for d in pcapc.findalldevs()] def __init__( self, device=None, promiscuous=True, period=10, start=True, callback=None, filter=None, use_bytearray=False, **kw ): """ Initialize this instance use_bytearray: specifies capturing to bytearray buffers instead of bytes """ if filter is not None: self.deferred_filter = (filter,) else: self.deferred_filter = None self.packets_received = 0 self.packets_dropped = 0 self._thread = None self.pcap = None self.promiscuous = promiscuous self.device = None self.use_bytearray = use_bytearray self.period = period self.netmask = IPAddr("0.0.0.0") self._quitting = False self.addresses = {} if callback is None: self.callback = self.__class__._handle_rx else: self.callback = callback for k, v in kw.items(): assert not hasattr(self, k) setattr(self, k, v) if device is not None: self.open(device) if self.pcap is not None: if start: self.start() def _handle_rx(self, data, sec, usec, length): pass def open(self, device, promiscuous=None, period=None, incoming=True, outgoing=False): assert self.device is None self.addresses = self.get_devices()[device]["addrs"] if "AF_INET" in self.addresses: self.netmask = self.addresses["AF_INET"].get("netmask") if self.netmask is None: self.netmask = IPAddr("0.0.0.0") # print "NM:",self.netmask # print self.addresses['AF_LINK']['addr'] self.device = device if period is not None: self.period = period if promiscuous is not None: self.promiscuous = promiscuous self.pcap = pcapc.open_live(device, 65535, 1 if self.promiscuous else 0, self.period) pcapc.setdirection(self.pcap, incoming, outgoing) self.packets_received = 0 self.packets_dropped = 0 if self.deferred_filter is not None: self.set_filter(*self.deferred_filter) self.deferred_filter = None def set_direction(self, incoming, outgoing): pcapc.setdirection(self._pcap, incoming, outgoing) def set_nonblocking(self, nonblocking=True): pcapc.setnonblock(self._pcap, 1 if nonblocking else 0) def set_blocking(self, blocking=True): self.set_nonblocking(nonblocking=not blocking) @property def blocking(self): return False if pcapc.getnonblock(self._pcap) else True @blocking.setter def blocking(self, value): self.set_blocking(value) def next_packet(self, allow_threads=True): """ Get next packet Returns tuple with: data, timestamp_seconds, timestamp_useconds, total length, and the pcap_next_ex return value -- 1 is success """ return pcapc.next_ex(self._pcap, bool(self.use_bytearray), allow_threads) def _select_thread_func(self): try: import select fd = [self.fileno()] except: # Fall back self._thread_func() return self.blocking = False while not self._quitting: rr, ww, xx = select.select(fd, [], fd, 2) if xx: # Apparently we're done here. break if rr: r = self.next_packet(allow_threads=False) if r[-1] == 0: continue if r[-1] == 1: self.callback(self, r[0], r[1], r[2], r[3]) else: break self._quitting = False self._thread = None def _thread_func(self): while not self._quitting: pcapc.dispatch(self.pcap, 100, self.callback, self, bool(self.use_bytearray), True) self.packets_received, self.packets_dropped = pcapc.stats(self.pcap) self._quitting = False self._thread = None def _handle_GoingDownEvent(self, event): self.close() def start(self): assert self._thread is None from pox.core import core core.addListeners(self, weak=True) if self.use_select: self._thread = Thread(target=self._select_thread_func) else: self._thread = Thread(target=self._thread_func) # self._thread.daemon = True self._thread.start() def stop(self): t = self._thread if t is not None: self._quitting = True pcapc.breakloop(self.pcap) t.join() def close(self): if self.pcap is None: return self.stop() pcapc.close(self.pcap) self.pcap = None def __del__(self): self.close() @property def _pcap(self): if self.pcap is None: raise RuntimeError("PCap object not open") return self.pcap def inject(self, data): if isinstance(data, pkt.ethernet): data = data.pack() if not isinstance(data, (bytes, bytearray)): data = bytes(data) # Give it a try... return pcapc.inject(self.pcap, data) def set_filter(self, filter, optimize=True): if self.pcap is None: self.deferred_filter = (filter, optimize) return if isinstance(filter, str): filter = Filter(filter, optimize, self.netmask.toSignedN(), pcap_obj=self) elif isinstance(filter, Filter): pass else: raise RuntimeError("Filter must be string or Filter object") pcapc.setfilter(self.pcap, filter._pprogram) def fileno(self): if self.pcap is None: raise RuntimeError("PCap object not open") r = pcapc.get_selectable_fd(self.pcap) if r == -1: raise RuntimeError("Selectable FD not available") return r def __str__(self): return "PCap(device=%s)" % (self.device)
class PCap (object): @staticmethod def get_devices (): def ip (addr): if addr is None: return None return IPAddr(addr, networkOrder=True) def link (addr): if addr is None: return None if len(addr) != 6: return None return EthAddr(addr) devs = pcapc.findalldevs() out = {} for d in devs: addrs = {} n = {'desc':d[1],'addrs':addrs} out[d[0]] = n for a in d[2]: if a[0] == 'AF_INET': na = {} addrs[a[0]] = na na['addr'] = ip(a[1]) na['netmask'] = ip(a[2]) na['broadaddr'] = ip(a[3]) na['dstaddr'] = ip(a[4]) elif a[0] == 'AF_LINK': na = {} addrs[a[0]] = na na['addr'] = link(a[1]) na['netmask'] = link(a[2]) na['broadaddr'] = link(a[3]) na['dstaddr'] = link(a[4]) elif a[0] == 'AF_PACKET': addrs[a[0]] = {'addr':link(a[1])} elif a[0] == 'ethernet': addrs[a[0]] = {'addr':link(a[1])} return out @staticmethod def get_device_names (): return [d[0] for d in pcapc.findalldevs()] def __init__ (self, device = None, promiscuous = True, period = 10, start = True, callback = None, filter = None): if filter is not None: self.deferred_filter = (filter,) else: self.deferred_filter = None self.packets_received = 0 self.packets_dropped = 0 self._thread = None self.pcap = None self.promiscuous = promiscuous self.device = None self.period = period self.netmask = IPAddr("0.0.0.0") self._quitting = False self.addresses = {} if callback is None: self.callback = self.__class__._handle_rx else: self.callback = callback if device is not None: self.open(device) if self.pcap is not None: if start: self.start() def _handle_rx (self, data, sec, usec, length): pass def open (self, device, promiscuous = None, period = None, incoming = True, outgoing = False): assert self.device is None self.addresses = self.get_devices()[device]['addrs'] if 'AF_INET' in self.addresses: self.netmask = self.addresses['AF_INET'].get('netmask') if self.netmask is None: self.netmask = IPAddr("0.0.0.0") #print "NM:",self.netmask #print self.addresses['AF_LINK']['addr'] self.device = device if period is not None: self.period = period if promiscuous is not None: self.promiscuous = promiscuous self.pcap = pcapc.open_live(device, 65535, 1 if self.promiscuous else 0, self.period) pcapc.setdirection(self.pcap, incoming, outgoing) self.packets_received = 0 self.packets_dropped = 0 if self.deferred_filter is not None: self.set_filter(*self.deferred_filter) self.deferred_filter = None def set_direction (self, incoming, outgoing): pcapc.setdirection(self.pcap, incoming, outgoing) def _thread_func (self): while not self._quitting: pcapc.dispatch(self.pcap,100,self.callback,self) self.packets_received,self.packets_dropped = pcapc.stats(self.pcap) self._quitting = False self._thread = None def _handle_GoingDownEvent (self, event): self.close() def start (self): assert self._thread is None from pox.core import core core.addListeners(self, weak=True) self._thread = Thread(target=self._thread_func) #self._thread.daemon = True self._thread.start() def stop (self): t = self._thread if t is not None: self._quitting = True pcapc.breakloop(self.pcap) t.join() def close (self): if self.pcap is None: return self.stop() pcapc.close(self.pcap) self.pcap = None def __del__ (self): self.close() def inject (self, data): if isinstance(data, pkt.ethernet): data = data.pack() if not isinstance(data, bytes): data = bytes(data) # Give it a try... return pcapc.inject(self.pcap, data) def set_filter (self, filter, optimize = True): if self.pcap is None: self.deferred_filter = (filter, optimize) return if isinstance(filter, str): filter = Filter(filter, optimize, self.netmask.toSignedN(), pcap_obj=self) elif isinstance(filter, Filter): pass else: raise RuntimeError("Filter must be string or Filter object") pcapc.setfilter(self.pcap, filter._pprogram)
class PCap(object): use_select = True # Falls back to non-select @staticmethod def get_devices(): def ip(addr): if addr is None: return None return IPAddr(addr, networkOrder=True) def ip6(addr): if addr is None: return None return IPAddr6.from_raw(addr) def link(addr): if addr is None: return None if len(addr) != 6: return None return EthAddr(addr) devs = pcapc.findalldevs() out = {} for d in devs: addrs = {} n = {'desc': d[1], 'addrs': addrs} out[d[0]] = n for a in d[2]: if a[0] == 'AF_INET': na = {} addrs[a[0]] = na na['addr'] = ip(a[1]) na['netmask'] = ip(a[2]) na['broadaddr'] = ip(a[3]) na['dstaddr'] = ip(a[4]) elif a[0] == 'AF_INET6': na = {} addrs[a[0]] = na na['addr'] = ip6(a[1]) na['netmask'] = ip6(a[2]) na['broadaddr'] = ip6(a[3]) na['dstaddr'] = ip6(a[4]) elif a[0] == 'AF_LINK': na = {} addrs[a[0]] = na na['addr'] = link(a[1]) na['netmask'] = link(a[2]) na['broadaddr'] = link(a[3]) na['dstaddr'] = link(a[4]) elif a[0] == 'AF_PACKET': addrs[a[0]] = {'addr': link(a[1])} elif a[0] == 'ethernet': addrs[a[0]] = {'addr': link(a[1])} return out @staticmethod def get_device_names(): return [d[0] for d in pcapc.findalldevs()] def __init__(self, device=None, promiscuous=True, period=10, start=True, callback=None, filter=None, use_bytearray=False, **kw): """ Initialize this instance use_bytearray: specifies capturing to bytearray buffers instead of bytes """ if filter is not None: self.deferred_filter = (filter, ) else: self.deferred_filter = None self.packets_received = 0 self.packets_dropped = 0 self._thread = None self._stop_semaphore = None # Used when use_select=True self.pcap = None self.promiscuous = promiscuous self.device = None self.use_bytearray = use_bytearray self.period = period self.netmask = IPAddr("0.0.0.0") self._quitting = False self.addresses = {} if callback is None: self.callback = self.__class__._handle_rx else: self.callback = callback for k, v in kw.items(): assert not hasattr(self, k) setattr(self, k, v) if device is not None: self.open(device) if self.pcap is not None: if start: self.start() def _handle_rx(self, data, sec, usec, length): pass def open(self, device, promiscuous=None, period=None, incoming=True, outgoing=False): assert self.device is None self.addresses = self.get_devices()[device]['addrs'] if 'AF_INET' in self.addresses: self.netmask = self.addresses['AF_INET'].get('netmask') if self.netmask is None: self.netmask = IPAddr("0.0.0.0") #print "NM:",self.netmask #print self.addresses['AF_LINK']['addr'] self.device = device if period is not None: self.period = period if promiscuous is not None: self.promiscuous = promiscuous self.pcap = pcapc.open_live(device, 65535, 1 if self.promiscuous else 0, self.period) pcapc.setdirection(self.pcap, incoming, outgoing) self.packets_received = 0 self.packets_dropped = 0 if self.deferred_filter is not None: self.set_filter(*self.deferred_filter) self.deferred_filter = None def set_direction(self, incoming, outgoing): pcapc.setdirection(self._pcap, incoming, outgoing) def set_nonblocking(self, nonblocking=True): pcapc.setnonblock(self._pcap, 1 if nonblocking else 0) def set_blocking(self, blocking=True): self.set_nonblocking(nonblocking=not blocking) @property def blocking(self): return False if pcapc.getnonblock(self._pcap) else True @blocking.setter def blocking(self, value): self.set_blocking(value) def next_packet(self, allow_threads=True): """ Get next packet Returns tuple with: data, timestamp_seconds, timestamp_useconds, total length, and the pcap_next_ex return value -- 1 is success """ return pcapc.next_ex(self._pcap, bool(self.use_bytearray), allow_threads) def _thread_func(self): while not self._quitting: pcapc.dispatch(self.pcap, 100, self.callback, self, bool(self.use_bytearray), True) self.packets_received, self.packets_dropped = pcapc.stats( self.pcap) self._quitting = False self._thread = None def _handle_GoingDownEvent(self, event): self.close() def start(self): assert self._thread is None from pox.core import core core.addListeners(self, weak=True) if self.use_select: try: import select except: # Fall back self.use_select = False # Log warning? if self.use_select: self.blocking = False self._thread = pcap_select_loop.add(self) else: self._thread = Thread(target=self._thread_func) self._thread.start() def stop(self): t = self._thread if t is not None: if self.use_select: self._quitting = True self._stop_semaphore = Semaphore(0) pcap_select_loop.remove(self) pcapc.breakloop(self.pcap) self._stop_semaphore.acquire() self._stop_semaphore = None else: self._quitting = True pcapc.breakloop(self.pcap) t.join() self._thread = None def _notify_quit(self): if self._stop_semaphore: self._stop_semaphore.release() def close(self): if self.pcap is None: return self.stop() pcapc.close(self.pcap) self.pcap = None def __del__(self): self.close() @property def _pcap(self): if self.pcap is None: raise RuntimeError("PCap object not open") return self.pcap def inject(self, data): if isinstance(data, pkt.ethernet): data = data.pack() if not isinstance(data, (bytes, bytearray)): data = bytes(data) # Give it a try... return pcapc.inject(self.pcap, data) def set_filter(self, filter, optimize=True): if self.pcap is None: self.deferred_filter = (filter, optimize) return if isinstance(filter, str): filter = Filter(filter, optimize, self.netmask.toSignedN(), pcap_obj=self) elif isinstance(filter, Filter): pass else: raise RuntimeError("Filter must be string or Filter object") pcapc.setfilter(self.pcap, filter._pprogram) def fileno(self): if self.pcap is None: raise RuntimeError("PCap object not open") r = pcapc.get_selectable_fd(self.pcap) if r == -1: raise RuntimeError("Selectable FD not available") return r def __str__(self): return "PCap(device=%s)" % (self.device)