Skip to content
Snippets Groups Projects
Commit d5b2e6e5 authored by Pierre Lalet's avatar Pierre Lalet
Browse files

Merge pull request #1 from p-l-/feature-winpcap

Windows: use Winpcap, drop DNET dependency

self-merge since @guedou is OK and @n1nj4sec agrees.
parents 04462497 00d6c026
No related branches found
No related tags found
No related merge requests found
...@@ -16,8 +16,306 @@ from scapy.utils import warning ...@@ -16,8 +16,306 @@ from scapy.utils import warning
from scapy.supersocket import SuperSocket from scapy.supersocket import SuperSocket
from scapy.error import Scapy_Exception from scapy.error import Scapy_Exception
import scapy.arch import scapy.arch
import socket
if conf.use_winpcapy:
#mostly code from https://github.com/phaethon/scapy translated to python2.X
try:
from .winpcapy import *
def winpcapy_get_if_list():
err = create_string_buffer(PCAP_ERRBUF_SIZE)
devs = POINTER(pcap_if_t)()
ret = []
if pcap_findalldevs(byref(devs), err) < 0:
return ret
try:
p = devs
while p:
ret.append(p.contents.name.decode('ascii'))
p = p.contents.next
return ret
finally:
pcap_freealldevs(devs)
except OSError as e:
if conf.interactive:
log_loading.error("Unable to import libpcap library: %s" % e)
conf.use_winpcapy = False
else:
raise
# From BSD net/bpf.h
#BIOCIMMEDIATE=0x80044270
BIOCIMMEDIATE=-2147204496
class PcapTimeoutElapsed(Scapy_Exception):
pass
def get_if_raw_hwaddr(iff):
err = create_string_buffer(PCAP_ERRBUF_SIZE)
devs = POINTER(pcap_if_t)()
ret = "\0\0\0\0\0\0"
if pcap_findalldevs(byref(devs), err) < 0:
return ret
try:
p = devs
while p:
if p.contents.name.endswith(iff):
a = p.contents.addresses
while a:
if hasattr(socket, 'AF_LINK') and a.contents.addr.contents.sa_family == socket.AF_LINK:
ap = a.contents.addr
val = cast(ap, POINTER(sockaddr_dl))
ret = str(val.contents.sdl_data[ val.contents.sdl_nlen : val.contents.sdl_nlen + val.contents.sdl_alen ])
a = a.contents.next
break
p = p.contents.next
return ret
finally:
pcap_freealldevs(devs)
def get_if_raw_addr(iff):
err = create_string_buffer(PCAP_ERRBUF_SIZE)
devs = POINTER(pcap_if_t)()
ret = "\0\0\0\0"
if pcap_findalldevs(byref(devs), err) < 0:
return ret
try:
p = devs
while p:
if p.contents.name.endswith(iff):
a = p.contents.addresses
while a:
if a.contents.addr.contents.sa_family == socket.AF_INET:
ap = a.contents.addr
val = cast(ap, POINTER(sockaddr_in))
#ret = bytes(val.contents.sin_addr[:4])
ret = "".join([chr(x) for x in val.contents.sin_addr[:4]])
a = a.contents.next
break
p = p.contents.next
return ret
finally:
pcap_freealldevs(devs)
get_if_list = winpcapy_get_if_list
def in6_getifaddr():
err = create_string_buffer(PCAP_ERRBUF_SIZE)
devs = POINTER(pcap_if_t)()
ret = []
if pcap_findalldevs(byref(devs), err) < 0:
return ret
try:
p = devs
ret = []
while p:
a = p.contents.addresses
while a:
if a.contents.addr.contents.sa_family == socket.AF_INET6:
ap = a.contents.addr
val = cast(ap, POINTER(sockaddr_in6))
addr = socket.inet_ntop(socket.AF_INET6, str(val.contents.sin6_addr[:]))
scope = scapy.utils6.in6_getscope(addr)
ret.append((addr, scope, p.contents.name.decode('ascii')))
a = a.contents.next
p = p.contents.next
return ret
finally:
pcap_freealldevs(devs)
from ctypes import POINTER, byref, create_string_buffer
class _PcapWrapper_pypcap:
def __init__(self, device, snaplen, promisc, to_ms):
self.errbuf = create_string_buffer(PCAP_ERRBUF_SIZE)
self.iface = create_string_buffer(device)
self.pcap = pcap_open_live(self.iface, snaplen, promisc, to_ms, self.errbuf)
self.header = POINTER(pcap_pkthdr)()
self.pkt_data = POINTER(c_ubyte)()
self.bpf_program = bpf_program()
def next(self):
c = pcap_next_ex(self.pcap, byref(self.header), byref(self.pkt_data))
if not c > 0:
return
ts = self.header.contents.ts.tv_sec
pkt = "".join([ chr(i) for i in self.pkt_data[:self.header.contents.len] ])
#pkt = bytes(self.pkt_data[:self.header.contents.len])
return ts, pkt
def datalink(self):
return pcap_datalink(self.pcap)
def fileno(self):
if sys.platform.startswith("win"):
error("Cannot get selectable PCAP fd on Windows")
return 0
return pcap_get_selectable_fd(self.pcap)
def setfilter(self, f):
filter_exp = create_string_buffer(f)
if pcap_compile(self.pcap, byref(self.bpf_program), filter_exp, 0, -1) == -1:
error("Could not compile filter expression %s" % f)
return False
else:
if pcap_setfilter(self.pcap, byref(self.bpf_program)) == -1:
error("Could not install filter %s" % f)
return False
return True
def setnonblock(self, i):
pcap_setnonblock(self.pcap, i, self.errbuf)
def send(self, x):
pcap_sendpacket(self.pcap, x, len(x))
def close(self):
pcap_close(self.pcap)
open_pcap = lambda *args,**kargs: _PcapWrapper_pypcap(*args,**kargs)
class PcapTimeoutElapsed(Scapy_Exception):
pass
class L2pcapListenSocket(SuperSocket):
desc = "read packets at layer 2 using libpcap"
def __init__(self, iface = None, type = ETH_P_ALL, promisc=None, filter=None):
self.type = type
self.outs = None
self.iface = iface
if iface is None:
iface = conf.iface
if promisc is None:
promisc = conf.sniff_promisc
self.promisc = promisc
self.ins = open_pcap(iface, 1600, self.promisc, 100)
try:
ioctl(self.ins.fileno(),BIOCIMMEDIATE,struct.pack("I",1))
except:
pass
if type == ETH_P_ALL: # Do not apply any filter if Ethernet type is given
if conf.except_filter:
if filter:
filter = "(%s) and not (%s)" % (filter, conf.except_filter)
else:
filter = "not (%s)" % conf.except_filter
if filter:
self.ins.setfilter(filter)
def close(self):
self.ins.close()
def recv(self, x=MTU):
ll = self.ins.datalink()
if ll in conf.l2types:
cls = conf.l2types[ll]
else:
cls = conf.default_l2
warning("Unable to guess datalink type (interface=%s linktype=%i). Using %s" % (self.iface, ll, cls.name))
pkt = None
while pkt is None:
pkt = self.ins.next()
if pkt is not None:
ts,pkt = pkt
if scapy.arch.WINDOWS and pkt is None:
raise PcapTimeoutElapsed
try:
pkt = cls(pkt)
except KeyboardInterrupt:
raise
except:
if conf.debug_dissector:
raise
pkt = conf.raw_layer(pkt)
pkt.time = ts
return pkt
def send(self, x):
raise Scapy_Exception("Can't send anything with L2pcapListenSocket")
conf.L2listen = L2pcapListenSocket
class L2pcapSocket(SuperSocket):
desc = "read/write packets at layer 2 using only libpcap"
def __init__(self, iface = None, type = ETH_P_ALL, filter=None, nofilter=0):
if iface is None:
iface = conf.iface
self.iface = iface
self.ins = open_pcap(iface, 1600, 0, 100)
try:
ioctl(self.ins.fileno(),BIOCIMMEDIATE,struct.pack("I",1))
except:
pass
if nofilter:
if type != ETH_P_ALL: # PF_PACKET stuff. Need to emulate this for pcap
filter = "ether proto %i" % type
else:
filter = None
else:
if conf.except_filter:
if filter:
filter = "(%s) and not (%s)" % (filter, conf.except_filter)
else:
filter = "not (%s)" % conf.except_filter
if type != ETH_P_ALL: # PF_PACKET stuff. Need to emulate this for pcap
if filter:
filter = "(ether proto %i) and (%s)" % (type,filter)
else:
filter = "ether proto %i" % type
if filter:
self.ins.setfilter(filter)
def send(self, x):
sx = str(x)
if hasattr(x, "sent_time"):
x.sent_time = time.time()
return self.ins.send(sx)
def recv(self,x=MTU):
ll = self.ins.datalink()
if ll in conf.l2types:
cls = conf.l2types[ll]
else:
cls = conf.default_l2
warning("Unable to guess datalink type (interface=%s linktype=%i). Using %s" % (self.iface, ll, cls.name))
pkt = self.ins.next()
if pkt is not None:
ts,pkt = pkt
if pkt is None:
return
try:
pkt = cls(pkt)
except KeyboardInterrupt:
raise
except:
if conf.debug_dissector:
raise
pkt = conf.raw_layer(pkt)
pkt.time = ts
return pkt
def nonblock_recv(self):
self.ins.setnonblock(1)
p = self.recv(MTU)
self.ins.setnonblock(0)
return p
def close(self):
if hasattr(self, "ins"):
self.ins.close()
if hasattr(self, "outs"):
self.outs.close()
class L3pcapSocket(L2pcapSocket):
#def __init__(self, iface = None, type = ETH_P_ALL, filter=None, nofilter=0):
# L2pcapSocket.__init__(self, iface, type, filter, nofilter)
def recv(self, x = MTU):
r = L2pcapSocket.recv(self, x)
if r:
return r.payload
else:
return
def send(self, x):
cls = conf.l2types[1]
sx = str(cls()/x)
if hasattr(x, "sent_time"):
x.sent_time = time.time()
return self.ins.send(sx)
conf.L2socket=L2pcapSocket
conf.L3socket=L3pcapSocket
if conf.use_pcap: if conf.use_pcap:
......
...@@ -7,25 +7,129 @@ ...@@ -7,25 +7,129 @@
Customizations needed to support Microsoft Windows. Customizations needed to support Microsoft Windows.
""" """
import os,re,sys,socket,time from __future__ import with_statement
import os,re,sys,socket,time, itertools
import subprocess as sp
from glob import glob from glob import glob
import tempfile
from scapy.config import conf,ConfClass from scapy.config import conf,ConfClass
from scapy.error import Scapy_Exception,log_loading,log_runtime from scapy.error import Scapy_Exception,log_loading,log_runtime
from scapy.utils import atol, inet_aton, inet_ntoa, PcapReader from scapy.utils import atol, itom, inet_aton, inet_ntoa, PcapReader
from scapy.base_classes import Gen, Net, SetGen from scapy.base_classes import Gen, Net, SetGen
import scapy.plist as plist import scapy.plist as plist
from scapy.sendrecv import debug, srp1 from scapy.sendrecv import debug, srp1
from scapy.layers.l2 import Ether, ARP from scapy.layers.l2 import Ether, ARP
from scapy.data import MTU, ETHER_BROADCAST, ETH_P_ARP from scapy.data import MTU, ETHER_BROADCAST, ETH_P_ARP
conf.use_pcap = 1 conf.use_pcap = False
conf.use_dnet = 1 conf.use_dnet = False
conf.use_winpcapy = True
#hot-patching socket for missing variables on Windows
import socket
if not hasattr(socket, 'IPPROTO_IPIP'):
socket.IPPROTO_IPIP=4
if not hasattr(socket, 'IPPROTO_AH'):
socket.IPPROTO_AH=51
if not hasattr(socket, 'IPPROTO_ESP'):
socket.IPPROTO_ESP=50
from scapy.arch import pcapdnet from scapy.arch import pcapdnet
from scapy.arch.pcapdnet import * from scapy.arch.pcapdnet import *
LOOPBACK_NAME="lo0" LOOPBACK_NAME="lo0"
WINDOWS = True WINDOWS = True
def _exec_query_ps(cmd, fields):
"""Execute a PowerShell query"""
ps = sp.Popen([conf.prog.powershell] + cmd +
['|', 'select %s' % ', '.join(fields), '|', 'fl'],
stdout=sp.PIPE,
universal_newlines=True)
l=[]
for line in ps.stdout:
if not line.strip(): #skip empty lines
continue
l.append(line.split(':', 1)[1].strip())
if len(l) == len(fields):
yield l
l=[]
def _vbs_exec_code(code):
tmpfile = tempfile.NamedTemporaryFile(suffix=".vbs", delete=False)
tmpfile.write(code)
tmpfile.close()
ps = sp.Popen([conf.prog.cscript, tmpfile.name],
stdout=sp.PIPE, stderr=open(os.devnull),
universal_newlines=True)
for _ in xrange(3):
# skip 3 first lines
ps.stdout.readline()
for line in ps.stdout:
yield line
os.unlink(tmpfile.name)
def _vbs_get_iface_guid(devid):
try:
devid = str(int(devid) + 1)
guid = _vbs_exec_code("""WScript.Echo CreateObject("WScript.Shell").RegRead("HKEY_LOCAL_MACHINE\\SOFTWARE\\Microsoft\\Windows NT\\CurrentVersion\\NetworkCards\\%s\\ServiceName")
""" % devid).__iter__().next()
if guid.startswith('{') and guid.endswith('}\n'):
return guid[:-1]
except StopIteration:
pass
# Some names differ between VBS and PS
## None: field will not be returned under VBS
_VBS_WMI_FIELDS = {
"Win32_NetworkAdapter": {
"InterfaceIndex": "Index",
"InterfaceDescription": "Description",
"GUID": "DeviceID",
}
}
_VBS_WMI_OUTPUT = {
"Win32_NetworkAdapter": {
"DeviceID": _vbs_get_iface_guid,
}
}
def _exec_query_vbs(cmd, fields):
"""Execute a query using VBS. Currently Get-WmiObject queries are
supported.
"""
assert len(cmd) == 2 and cmd[0] == "Get-WmiObject"
fields = [_VBS_WMI_FIELDS.get(cmd[1], {}).get(fld, fld) for fld in fields]
values = _vbs_exec_code("""Set wmi = GetObject("winmgmts:")
Set lines = wmi.InstancesOf("%s")
On Error Resume Next
Err.clear
For Each line in lines
%s
Next
""" % (cmd[1], "\n ".join("WScript.Echo line.%s" % fld for fld in fields
if fld is not None))).__iter__()
while True:
yield [None if fld is None else
_VBS_WMI_OUTPUT.get(cmd[1], {}).get(fld, lambda x: x)(
values.next().strip()
)
for fld in fields]
def exec_query(cmd, fields):
"""Execute a system query using PowerShell if it is available, and
using VBS/cscript as a fallback.
"""
if conf.prog.powershell is None:
return _exec_query_vbs(cmd, fields)
return _exec_query_ps(cmd, fields)
def _where(filename, dirs=[], env="PATH"): def _where(filename, dirs=[], env="PATH"):
"""Find file in current dir or system path""" """Find file in current dir or system path"""
...@@ -66,253 +170,280 @@ class WinProgPath(ConfClass): ...@@ -66,253 +170,280 @@ class WinProgPath(ConfClass):
display = _default display = _default
hexedit = win_find_exe("hexer") hexedit = win_find_exe("hexer")
wireshark = win_find_exe("wireshark", "wireshark") wireshark = win_find_exe("wireshark", "wireshark")
powershell = win_find_exe(
"powershell",
installsubdir="System32\\WindowsPowerShell\\v1.0",
env="SystemRoot"
)
cscript = win_find_exe("cscript", installsubdir="System32",
env="SystemRoot")
conf.prog = WinProgPath() conf.prog = WinProgPath()
if conf.prog.powershell == "powershell":
conf.prog.powershell = None
import _winreg
class PcapNameNotFoundError(Scapy_Exception): class PcapNameNotFoundError(Scapy_Exception):
pass pass
import platform
def is_interface_valid(iface):
if "guid" in iface and iface["guid"]:
return True
return False
def get_windows_if_list():
if platform.release()=="post2008Server" or platform.release()=="8":
# This works only starting from Windows 8/2012 and up. For older Windows another solution is needed
query = exec_query(['Get-NetAdapter'],
['Name', 'InterfaceIndex', 'InterfaceDescription',
'InterfaceGuid', 'MacAddress'])
else:
query = exec_query(['Get-WmiObject', 'Win32_NetworkAdapter'],
['Name', 'InterfaceIndex', 'InterfaceDescription',
'GUID', 'MacAddress'])
return [
iface for iface in
(dict(zip(['name', 'win_index', 'description', 'guid', 'mac'], line))
for line in query)
if is_interface_valid(iface)
]
def get_ip_from_name(ifname, v6=False):
for descr, ipadrr in exec_query(['Get-WmiObject',
'Win32_NetworkAdapterConfiguration'],
['Description', 'IPAddress']):
if descr == ifname.strip():
return ipaddr.split(",", 1)[v6].strip('{}').strip()
class NetworkInterface(object): class NetworkInterface(object):
"""A network interface of your local host""" """A network interface of your local host"""
def __init__(self, dnetdict=None): def __init__(self, data=None):
self.name = None self.name = None
self.ip = None self.ip = None
self.mac = None self.mac = None
self.pcap_name = None self.pcap_name = None
self.win_name = None self.description = None
self.uuid = None self.data = data
self.dnetdict = dnetdict if data is not None:
if dnetdict is not None: self.update(data)
self.update(dnetdict)
def update(self, dnetdict): def update(self, data):
"""Update info about network interface according to given dnet dictionary""" """Update info about network interface according to given dnet dictionary"""
self.name = dnetdict["name"] self.name = data["name"]
self.description = data['description']
self.win_index = data['win_index']
self.guid = data['guid']
# Other attributes are optional # Other attributes are optional
self._update_pcapdata()
try: try:
self.ip = socket.inet_ntoa(dnetdict["addr"].ip) self.ip = socket.inet_ntoa(get_if_raw_addr(data['guid']))
except (KeyError, AttributeError, NameError): except (KeyError, AttributeError, NameError):
pass pass
try:
if not self.ip:
self.ip=get_ip_from_name(data['name'])
except (KeyError, AttributeError, NameError) as e:
print e
try: try:
self.mac = dnetdict["link_addr"] self.mac = data['mac']
except KeyError: except KeyError:
pass pass
self._update_pcapdata()
def _update_pcapdata(self): def _update_pcapdata(self):
"""Supplement more info from pypcap and the Windows registry""" for i in winpcapy_get_if_list():
if i.endswith(self.data['guid']):
# XXX: We try eth0 - eth29 by bruteforce and match by IP address, self.pcap_name = i
# because only the IP is available in both pypcap and dnet. return
# This may not work with unorthodox network configurations and is
# slow because we have to walk through the Windows registry.
for n in xrange(30):
guess = "eth%s" % n
win_name = pcapdnet.pcap.ex_name(guess)
if win_name.endswith("}"):
try:
uuid = win_name[win_name.index("{"):win_name.index("}")+1]
keyname = r"SYSTEM\CurrentControlSet\Services\Tcpip\Parameters\Interfaces\%s" % uuid
try:
key = _winreg.OpenKey(_winreg.HKEY_LOCAL_MACHINE, keyname)
except WindowsError:
log_loading.debug("Couldn't open 'HKEY_LOCAL_MACHINE\\%s' (for guessed pcap iface name '%s')." % (keyname, guess))
continue
try:
fixed_ip = _winreg.QueryValueEx(key, "IPAddress")[0][0].encode("utf-8")
except (WindowsError, UnicodeDecodeError, IndexError):
fixed_ip = None
try:
dhcp_ip = _winreg.QueryValueEx(key, "DhcpIPAddress")[0].encode("utf-8")
except (WindowsError, UnicodeDecodeError, IndexError):
dhcp_ip = None
# "0.0.0.0" or None means the value is not set (at least not correctly).
# If both fixed_ip and dhcp_ip are set, fixed_ip takes precedence
if fixed_ip is not None and fixed_ip != "0.0.0.0":
ip = fixed_ip
elif dhcp_ip is not None and dhcp_ip != "0.0.0.0":
ip = dhcp_ip
else:
continue
except IOError:
continue
else:
if ip == self.ip:
self.pcap_name = guess
self.win_name = win_name
self.uuid = uuid
break
else:
raise PcapNameNotFoundError raise PcapNameNotFoundError
def __repr__(self): def __repr__(self):
return "<%s: %s %s %s pcap_name=%s win_name=%s>" % (self.__class__.__name__, return "<%s %s %s>" % (self.__class__.__name__, self.name, self.guid)
self.name, self.ip, self.mac, self.pcap_name, self.win_name)
from UserDict import IterableUserDict from UserDict import UserDict
class NetworkInterfaceDict(IterableUserDict): class NetworkInterfaceDict(UserDict):
"""Store information about network interfaces and convert between names""" """Store information about network interfaces and convert between names"""
def load_from_powershell(self):
def load_from_dnet(self): for i in get_windows_if_list():
"""Populate interface table via dnet"""
for i in pcapdnet.dnet.intf():
try: try:
# XXX: Only Ethernet for the moment: localhost is not supported by dnet and pcap interface = NetworkInterface(i)
# We only take interfaces that have an IP address, because the IP self.data[interface.guid] = interface
# is used for the mapping between dnet and pcap interface names
# and this significantly improves Scapy's startup performance
if i["name"].startswith("eth") and "addr" in i:
self.data[i["name"]] = NetworkInterface(i)
except (KeyError, PcapNameNotFoundError): except (KeyError, PcapNameNotFoundError):
pass pass
if len(self.data) == 0: if len(self.data) == 0:
log_loading.warning("No match between your pcap and dnet network interfaces found. " log_loading.warning("No match between your pcap and windows network interfaces found. "
"You probably won't be able to send packets. " "You probably won't be able to send packets. "
"Deactivating unneeded interfaces and restarting Scapy might help.") "Deactivating unneeded interfaces and restarting Scapy might help."
"Check your winpcap and powershell installation, and access rights.")
def pcap_name(self, devname):
"""Return pypcap device name for given libdnet/Scapy device name
This mapping is necessary because pypcap numbers the devices differently."""
try:
pcap_name = self.data[devname].pcap_name
except KeyError:
raise ValueError("Unknown network interface %r" % devname)
else:
return pcap_name
def devname(self, pcap_name): def dev_from_name(self, name):
"""Return libdnet/Scapy device name for given pypcap device name """Return the first pcap device name for a given Windows
device name.
This mapping is necessary because pypcap numbers the devices differently.""" """
for iface in self.itervalues():
for devname, iface in self.items(): if iface.name == name:
return iface
raise ValueError("Unknown network interface %r" % name)
def dev_from_pcapname(self, pcap_name):
"""Return Windows device name for given pcap device name."""
for iface in self.itervalues():
if iface.pcap_name == pcap_name: if iface.pcap_name == pcap_name:
return iface.name return iface
raise ValueError("Unknown pypcap network interface %r" % pcap_name) raise ValueError("Unknown pypcap network interface %r" % pcap_name)
def dev_from_index(self, if_index):
"""Return interface name from interface index"""
for devname, iface in self.items():
if iface.win_index == str(if_index):
return iface
raise ValueError("Unknown network interface index %r" % if_index)
def show(self, resolve_mac=True): def show(self, resolve_mac=True):
"""Print list of available network interfaces in human readable form""" """Print list of available network interfaces in human readable form"""
print "%s %s %s" % ("IFACE".ljust(5), "IP".ljust(15), "MAC") print "%s %s %s %s" % ("INDEX".ljust(5), "IFACE".ljust(35), "IP".ljust(15), "MAC")
for iface_name in sorted(self.data.keys()): for iface_name in sorted(self.data.keys()):
dev = self.data[iface_name] dev = self.data[iface_name]
mac = str(dev.mac) mac = dev.mac
if resolve_mac: if resolve_mac:
mac = conf.manufdb._resolve_MAC(mac) mac = conf.manufdb._resolve_MAC(mac)
print "%s %s %s" % (str(dev.name).ljust(5), str(dev.ip).ljust(15), mac) print "%s %s %s %s" % (str(dev.win_index).ljust(5), str(dev.name).ljust(35), str(dev.ip).ljust(15), mac)
IFACES = NetworkInterfaceDict()
IFACES.load_from_powershell()
ifaces = NetworkInterfaceDict() def pcapname(dev):
ifaces.load_from_dnet() """Return pypcap device name for given interface or libdnet/Scapy
device name.
def pcap_name(devname): """
"""Return pypcap device name for given libdnet/Scapy device name""" if type(dev) is NetworkInterface:
return dev.pcap_name
try: try:
pcap_name = ifaces.pcap_name(devname) return IFACES.dev_from_name(dev).pcap_name
except ValueError: except ValueError:
# pcap.pcap() will choose a sensible default for sniffing if iface=None # pcap.pcap() will choose a sensible default for sniffing if
pcap_name = None # iface=None
return pcap_name return None
def devname(pcap_name): def dev_from_pcapname(pcap_name):
"""Return libdnet/Scapy device name for given pypcap device name""" """Return libdnet/Scapy device name for given pypcap device name"""
return ifaces.devname(pcap_name) return IFACES.dev_from_pcapname(pcap_name)
def dev_from_index(if_index):
"""Return Windows adapter name for given Windows interface index"""
return IFACES.dev_from_index(if_index)
def show_interfaces(resolve_mac=True): def show_interfaces(resolve_mac=True):
"""Print list of available network interfaces""" """Print list of available network interfaces"""
return ifaces.show(resolve_mac) return IFACES.show(resolve_mac)
_orig_open_pcap = pcapdnet.open_pcap _orig_open_pcap = pcapdnet.open_pcap
pcapdnet.open_pcap = lambda iface,*args,**kargs: _orig_open_pcap(pcap_name(iface),*args,**kargs) pcapdnet.open_pcap = lambda iface,*args,**kargs: _orig_open_pcap(pcapname(iface),*args,**kargs)
_orig_get_if_raw_hwaddr = pcapdnet.get_if_raw_hwaddr
pcapdnet.get_if_raw_hwaddr = lambda iface, *args, **kargs: (
ARPHDR_ETHER, IFACES.dev_from_pcapname(iface.pcap_name).mac.replace(':', '').decode('hex')
)
get_if_raw_hwaddr = pcapdnet.get_if_raw_hwaddr
def read_routes_xp():
# The InterfaceIndex in Win32_IP4RouteTable does not match the
# InterfaceIndex in Win32_NetworkAdapter under some platforms
# (namely Windows XP): let's try an IP association
routes = []
partial_routes = []
# map local IP addresses to interfaces
local_addresses = dict((iface.ip, iface)
for iface in IFACES.itervalues())
iface_indexes = {}
for line in exec_query(['Get-WmiObject', 'Win32_IP4RouteTable'],
['Name', 'Mask', 'NextHop', 'InterfaceIndex']):
if line[2] in local_addresses:
iface = local_addresses[line[2]]
# This gives us an association InterfaceIndex <-> interface
iface_indexes[line[3]] = iface
routes.append((atol(line[0]), atol(line[1]), "0.0.0.0", iface,
iface.ip))
else:
partial_routes.append((atol(line[0]), atol(line[1]), line[2],
line[3]))
for dst, mask, gw, ifidx in partial_routes:
if ifidx in iface_indexes:
iface = iface_indexes[ifidx]
routes.append((dst, mask, gw, iface, iface.ip))
return routes
def read_routes_7():
routes=[]
for line in exec_query(['Get-WmiObject', 'win32_IP4RouteTable'],
['Name', 'Mask', 'NextHop', 'InterfaceIndex']):
try:
iface = dev_from_index(line[3])
except ValueError:
continue
routes.append((atol(line[0]), atol(line[1]), line[2], iface, iface.ip))
return routes
def read_routes(): def read_routes():
ok = 0
routes = [] routes = []
ip = '(\d+\.\d+\.\d+\.\d+)' release = platform.release()
# On Vista and Windows 7 the gateway can be IP or 'On-link'. try:
# But the exact 'On-link' string depends on the locale, so we allow any text. if release in ["post2008Server", "8"]:
gw_pattern = '(.+)' routes = read_routes_post2008()
elif release == "XP":
routes = read_routes_xp()
else:
routes = read_routes_7()
except Exception as e:
log_loading.warning("Error building scapy routing table : %s"%str(e))
else:
if not routes:
log_loading.warning("No default IPv4 routes found. Your Windows release may no be supported and you have to enter your routes manually")
return routes
def read_routes_post2008():
# XXX TODO: FIX THIS XXX
routes = []
if_index = '(\d+)'
dest = '(\d+\.\d+\.\d+\.\d+)/(\d+)'
next_hop = '(\d+\.\d+\.\d+\.\d+)'
metric_pattern = "(\d+)" metric_pattern = "(\d+)"
delim = "\s+" # The columns are separated by whitespace delim = "\s+" # The columns are separated by whitespace
netstat_line = delim.join([ip, ip, gw_pattern, ip, metric_pattern]) netstat_line = delim.join([if_index, dest, next_hop, metric_pattern])
pattern = re.compile(netstat_line) pattern = re.compile(netstat_line)
f=os.popen("netstat -rn") # This works only starting from Windows 8/2012 and up. For older Windows another solution is needed
for l in f.readlines(): ps = sp.Popen([conf.prog.powershell, 'Get-NetRoute', '-AddressFamily IPV4', '|', 'select ifIndex, DestinationPrefix, NextHop, RouteMetric'], stdout = sp.PIPE, universal_newlines = True)
stdout, stdin = ps.communicate()
for l in stdout.split('\n'):
match = re.search(pattern,l) match = re.search(pattern,l)
if match: if match:
dest = match.group(1)
mask = match.group(2)
gw = match.group(3)
netif = match.group(4)
metric = match.group(5)
try: try:
intf = pcapdnet.dnet.intf().get_dst(pcapdnet.dnet.addr(type=2, addrtxt=dest)) iface = dev_from_index(match.group(1))
except OSError: except:
log_loading.warning("Building Scapy's routing table: Couldn't get outgoing interface for destination %s" % dest)
continue continue
if not intf.has_key("addr"): # try:
break # intf = pcapdnet.dnet.intf().get_dst(pcapdnet.dnet.addr(type=2, addrtxt=dest))
addr = str(intf["addr"]) # except OSError:
addr = addr.split("/")[0] # log_loading.warning("Building Scapy's routing table: Couldn't get outgoing interface for destination %s" % dest)
# continue
dest = atol(dest) routes.append((atol(match.group(2)), itom(int(match.group(3))),
mask = atol(mask) match.group(4), iface, iface.ip))
# If the gateway is no IP we assume it's on-link
gw_ipmatch = re.search('\d+\.\d+\.\d+\.\d+', gw)
if gw_ipmatch:
gw = gw_ipmatch.group(0)
else:
gw = netif
routes.append((dest,mask,gw, str(intf["name"]), addr))
f.close()
return routes return routes
def read_routes6(): def read_routes6():
return [] return []
def getmacbyip(ip, chainCC=0): if conf.interactive_shell != 'ipython':
"""Return MAC address corresponding to a given IP address""" try:
if isinstance(ip,Net): __IPYTHON__
ip = iter(ip).next() except NameError:
tmp = map(ord, inet_aton(ip))
if (tmp[0] & 0xf0) == 0xe0: # mcast @
return "01:00:5e:%.2x:%.2x:%.2x" % (tmp[1]&0x7f,tmp[2],tmp[3])
iff,a,gw = conf.route.route(ip)
if ( (iff == LOOPBACK_NAME) or (ip == conf.route.get_if_bcast(iff)) ):
return "ff:ff:ff:ff:ff:ff"
# Windows uses local IP instead of 0.0.0.0 to represent locally reachable addresses
ifip = str(pcapdnet.dnet.intf().get(iff)['addr'])
if gw != ifip.split('/')[0]:
ip = gw
mac = conf.netcache.arp_cache.get(ip)
if mac:
return mac
res = srp1(Ether(dst=ETHER_BROADCAST)/ARP(op="who-has", pdst=ip),
type=ETH_P_ARP,
iface = iff,
timeout=2,
verbose=0,
chainCC=chainCC,
nofilter=1)
if res is not None:
mac = res.payload.hwsrc
conf.netcache.arp_cache[ip] = mac
return mac
return None
import scapy.layers.l2
scapy.layers.l2.getmacbyip = getmacbyip
try: try:
import readline import readline
console = readline.GetOutputFile() console = readline.GetOutputFile()
...@@ -323,10 +454,6 @@ else: ...@@ -323,10 +454,6 @@ else:
orig_stdout = sys.stdout orig_stdout = sys.stdout
sys.stdout = console sys.stdout = console
def sndrcv(pks, pkt, timeout = 2, inter = 0, verbose=None, chainCC=0, retry=0, multi=0): def sndrcv(pks, pkt, timeout = 2, inter = 0, verbose=None, chainCC=0, retry=0, multi=0):
if not isinstance(pkt, Gen): if not isinstance(pkt, Gen):
pkt = SetGen(pkt) pkt = SetGen(pkt)
...@@ -395,7 +522,6 @@ def sndrcv(pks, pkt, timeout = 2, inter = 0, verbose=None, chainCC=0, retry=0, m ...@@ -395,7 +522,6 @@ def sndrcv(pks, pkt, timeout = 2, inter = 0, verbose=None, chainCC=0, retry=0, m
else: else:
stoptime = 0 stoptime = 0
remaintime = None remaintime = None
inmask = [pks.ins.fd]
try: try:
try: try:
while 1: while 1:
...@@ -442,9 +568,9 @@ def sndrcv(pks, pkt, timeout = 2, inter = 0, verbose=None, chainCC=0, retry=0, m ...@@ -442,9 +568,9 @@ def sndrcv(pks, pkt, timeout = 2, inter = 0, verbose=None, chainCC=0, retry=0, m
finally: finally:
pass pass
remain = reduce(list.__add__, hsent.values(), []) remain = list(itertools.chain(*[ i for i in hsent.values() ]))
if multi: if multi:
remain = filter(lambda p: not hasattr(p, '_answered'), remain); remain = [ p for p in remain if not hasattr(p, '_answered')]
if autostop and len(remain) > 0 and len(remain) != len(tobesent): if autostop and len(remain) > 0 and len(remain) != len(tobesent):
retry = autostop retry = autostop
...@@ -475,7 +601,7 @@ scapy.sendrecv.sndrcv = sndrcv ...@@ -475,7 +601,7 @@ scapy.sendrecv.sndrcv = sndrcv
def sniff(count=0, store=1, offline=None, prn = None, lfilter=None, L2socket=None, timeout=None, *arg, **karg): def sniff(count=0, store=1, offline=None, prn = None, lfilter=None, L2socket=None, timeout=None, *arg, **karg):
"""Sniff packets """Sniff packets
sniff([count=0,] [prn=None,] [store=1,] [offline=None,] [lfilter=None,] + L2ListenSocket args) -> list of packets sniff([count=0,] [prn=None,] [store=1,] [offline=None,] [lfilter=None,] + L2ListenSocket args) -> list of packets
Select interface to sniff by setting conf.iface. Use show_interfaces() to see interface names.
count: number of packets to capture. 0 means infinity count: number of packets to capture. 0 means infinity
store: wether to store sniffed packets or discard them store: wether to store sniffed packets or discard them
prn: function to apply to each packet. If something is returned, prn: function to apply to each packet. If something is returned,
...@@ -491,6 +617,7 @@ L2socket: use the provided L2socket ...@@ -491,6 +617,7 @@ L2socket: use the provided L2socket
c = 0 c = 0
if offline is None: if offline is None:
log_runtime.info('Sniffing on %s' % conf.iface)
if L2socket is None: if L2socket is None:
L2socket = conf.L2listen L2socket = conf.L2listen
s = L2socket(type=ETH_P_ALL, *arg, **karg) s = L2socket(type=ETH_P_ALL, *arg, **karg)
...@@ -533,11 +660,13 @@ L2socket: use the provided L2socket ...@@ -533,11 +660,13 @@ L2socket: use the provided L2socket
import scapy.sendrecv import scapy.sendrecv
scapy.sendrecv.sniff = sniff scapy.sendrecv.sniff = sniff
def get_if_list():
return sorted(ifaces.keys())
def get_working_if(): def get_working_if():
try: try:
return devname(pcap.lookupdev()) # return the interface associated with the route with smallest
except Exception: # mask (route by default if it exists)
return 'lo0' return min(read_routes(), key=lambda x: x[1])[3]
except ValueError:
# no route
return LOOPBACK_NAME
conf.iface = get_working_if()
#-------------------------------------------------------------------------------
# Name: winpcapy.py
#
# Author: Massimo Ciani
#
# Created: 01/09/2009
# Copyright: (c) Massimo Ciani 2009
#
#-------------------------------------------------------------------------------
from ctypes import *
from ctypes.util import find_library
import sys
WIN32=False
HAVE_REMOTE=False
if sys.platform.startswith('win'):
WIN32=True
HAVE_REMOTE=True
if WIN32:
SOCKET = c_uint
_lib=CDLL('wpcap.dll')
else:
SOCKET = c_int
_lib_name = find_library('pcap')
if not _lib_name:
raise OSError("Cannot fine libpcap.so library")
_lib=CDLL(_lib_name)
##
## misc
##
u_short = c_ushort
bpf_int32 = c_int
u_int = c_int
bpf_u_int32 = u_int
pcap = c_void_p
pcap_dumper = c_void_p
u_char = c_ubyte
FILE = c_void_p
STRING = c_char_p
class bpf_insn(Structure):
_fields_=[("code",c_ushort),
("jt",c_ubyte),
("jf",c_ubyte),
("k",bpf_u_int32)]
class bpf_program(Structure):
pass
bpf_program._fields_ = [('bf_len', u_int),
('bf_insns', POINTER(bpf_insn))]
class bpf_version(Structure):
_fields_=[("bv_major",c_ushort),
("bv_minor",c_ushort)]
class timeval(Structure):
pass
timeval._fields_ = [('tv_sec', c_long),
('tv_usec', c_long)]
## sockaddr is used by pcap_addr.
## For exapmle if sa_family==socket.AF_INET then we need cast
## with sockaddr_in
if WIN32:
class sockaddr(Structure):
_fields_ = [("sa_family", c_ushort),
("sa_data",c_ubyte * 14)]
class sockaddr_in(Structure):
_fields_ = [("sin_family", c_ushort),
("sin_port", c_uint16),
("sin_addr", 4 * c_ubyte)]
class sockaddr_in6(Structure):
_fields_ = [("sin6_family", c_ushort),
("sin6_port", c_uint16),
("sin6_flowinfo", c_uint32),
("sin6_addr", 16 * c_ubyte),
("sin6_scope", c_uint32)]
else:
class sockaddr(Structure):
_fields_ = [("sa_len", c_ubyte),
("sa_family",c_ubyte),
("sa_data",c_ubyte * 14)]
class sockaddr_in(Structure):
_fields_ = [("sin_len", c_ubyte),
("sin_family", c_ubyte),
("sin_port", c_uint16),
("sin_addr", 4 * c_ubyte),
("sin_zero", 8 * c_char)]
class sockaddr_in6(Structure):
_fields_ = [("sin6_len", c_ubyte),
("sin6_family", c_ubyte),
("sin6_port", c_uint16),
("sin6_flowinfo", c_uint32),
("sin6_addr", 16 * c_ubyte),
("sin6_scope", c_uint32)]
class sockaddr_dl(Structure):
_fields_ = [("sdl_len", c_ubyte),
("sdl_family", c_ubyte),
("sdl_index", c_ushort),
("sdl_type", c_ubyte),
("sdl_nlen", c_ubyte),
("sdl_alen", c_ubyte),
("sdl_slen", c_ubyte),
("sdl_data", 46 * c_ubyte)]
##
## END misc
##
##
## Data Structures
##
## struct pcap_file_header
## Header of a libpcap dump file.
class pcap_file_header(Structure):
_fields_ = [('magic', bpf_u_int32),
('version_major', u_short),
('version_minor', u_short),
('thiszone', bpf_int32),
('sigfigs', bpf_u_int32),
('snaplen', bpf_u_int32),
('linktype', bpf_u_int32)]
## struct pcap_pkthdr
## Header of a packet in the dump file.
class pcap_pkthdr(Structure):
_fields_ = [('ts', timeval),
('caplen', bpf_u_int32),
('len', bpf_u_int32)]
## struct pcap_stat
## Structure that keeps statistical values on an interface.
class pcap_stat(Structure):
pass
### _fields_ list in Structure is final.
### We need a temp list
_tmpList=[]
_tmpList.append(("ps_recv",c_uint))
_tmpList.append(("ps_drop",c_uint))
_tmpList.append(("ps_ifdrop",c_uint))
if HAVE_REMOTE:
_tmpList.append(("ps_capt",c_uint))
_tmpList.append(("ps_sent",c_uint))
_tmpList.append(("ps_netdrop",c_uint))
pcap_stat._fields_=_tmpList
## struct pcap_addr
## Representation of an interface address, used by pcap_findalldevs().
class pcap_addr(Structure):
pass
pcap_addr._fields_ = [('next', POINTER(pcap_addr)),
('addr', POINTER(sockaddr)),
('netmask', POINTER(sockaddr)),
('broadaddr', POINTER(sockaddr)),
('dstaddr', POINTER(sockaddr))]
## struct pcap_if
## Item in a list of interfaces, used by pcap_findalldevs().
class pcap_if(Structure):
pass
pcap_if._fields_ = [('next', POINTER(pcap_if)),
('name', STRING),
('description', STRING),
('addresses', POINTER(pcap_addr)),
('flags', bpf_u_int32)]
##
## END Data Structures
##
##
## Defines
##
##define PCAP_VERSION_MAJOR 2
# Major libpcap dump file version.
PCAP_VERSION_MAJOR = 2
##define PCAP_VERSION_MINOR 4
# Minor libpcap dump file version.
PCAP_VERSION_MINOR = 4
##define PCAP_ERRBUF_SIZE 256
# Size to use when allocating the buffer that contains the libpcap errors.
PCAP_ERRBUF_SIZE = 256
##define PCAP_IF_LOOPBACK 0x00000001
# interface is loopback
PCAP_IF_LOOPBACK = 1
##define MODE_CAPT 0
# Capture mode, to be used when calling pcap_setmode().
MODE_CAPT = 0
##define MODE_STAT 1
# Statistical mode, to be used when calling pcap_setmode().
MODE_STAT = 1
##
## END Defines
##
##
## Typedefs
##
#typedef int bpf_int32 (already defined)
# 32-bit integer
#typedef u_int bpf_u_int32 (already defined)
# 32-bit unsigned integer
#typedef struct pcap pcap_t
# Descriptor of an open capture instance. This structure is opaque to the user, that handles its content through the functions provided by wpcap.dll.
pcap_t = pcap
#typedef struct pcap_dumper pcap_dumper_t
# libpcap savefile descriptor.
pcap_dumper_t = pcap_dumper
#typedef struct pcap_if pcap_if_t
# Item in a list of interfaces, see pcap_if.
pcap_if_t = pcap_if
#typedef struct pcap_addr pcap_addr_t
# Representation of an interface address, see pcap_addr.
pcap_addr_t = pcap_addr
##
## END Typedefs
##
# values for enumeration 'pcap_direction_t'
#pcap_direction_t = c_int # enum
##
## Unix-compatible Functions
## These functions are part of the libpcap library, and therefore work both on Windows and on Linux.
##
#typedef void(* pcap_handler )(u_char *user, const struct pcap_pkthdr *pkt_header, const u_char *pkt_data)
# Prototype of the callback function that receives the packets.
## This one is defined from programmer
pcap_handler=CFUNCTYPE(None,POINTER(c_ubyte),POINTER(pcap_pkthdr),POINTER(c_ubyte))
#pcap_t * pcap_open_live (const char *device, int snaplen, int promisc, int to_ms, char *ebuf)
# Open a live capture from the network.
pcap_open_live = _lib.pcap_open_live
pcap_open_live.restype = POINTER(pcap_t)
pcap_open_live.argtypes = [STRING, c_int, c_int, c_int, STRING]
#pcap_t * pcap_open_dead (int linktype, int snaplen)
# Create a pcap_t structure without starting a capture.
pcap_open_dead = _lib.pcap_open_dead
pcap_open_dead.restype = POINTER(pcap_t)
pcap_open_dead.argtypes = [c_int, c_int]
#pcap_t * pcap_open_offline (const char *fname, char *errbuf)
# Open a savefile in the tcpdump/libpcap format to read packets.
pcap_open_offline = _lib.pcap_open_offline
pcap_open_offline.restype = POINTER(pcap_t)
pcap_open_offline.argtypes = [STRING, STRING]
#pcap_dumper_t * pcap_dump_open (pcap_t *p, const char *fname)
# Open a file to write packets.
pcap_dump_open = _lib.pcap_dump_open
pcap_dump_open.restype = POINTER(pcap_dumper_t)
pcap_dump_open.argtypes = [POINTER(pcap_t), STRING]
#int pcap_setnonblock (pcap_t *p, int nonblock, char *errbuf)
# Switch between blocking and nonblocking mode.
pcap_setnonblock = _lib.pcap_setnonblock
pcap_setnonblock.restype = c_int
pcap_setnonblock.argtypes = [POINTER(pcap_t), c_int, STRING]
#int pcap_getnonblock (pcap_t *p, char *errbuf)
# Get the "non-blocking" state of an interface.
pcap_getnonblock = _lib.pcap_getnonblock
pcap_getnonblock.restype = c_int
pcap_getnonblock.argtypes = [POINTER(pcap_t), STRING]
#int pcap_findalldevs (pcap_if_t **alldevsp, char *errbuf)
# Construct a list of network devices that can be opened with pcap_open_live().
pcap_findalldevs = _lib.pcap_findalldevs
pcap_findalldevs.restype = c_int
pcap_findalldevs.argtypes = [POINTER(POINTER(pcap_if_t)), STRING]
#void pcap_freealldevs (pcap_if_t *alldevsp)
# Free an interface list returned by pcap_findalldevs().
pcap_freealldevs = _lib.pcap_freealldevs
pcap_freealldevs.restype = None
pcap_freealldevs.argtypes = [POINTER(pcap_if_t)]
#char * pcap_lookupdev (char *errbuf)
# Return the first valid device in the system.
pcap_lookupdev = _lib.pcap_lookupdev
pcap_lookupdev.restype = STRING
pcap_lookupdev.argtypes = [STRING]
#int pcap_lookupnet (const char *device, bpf_u_int32 *netp, bpf_u_int32 *maskp, char *errbuf)
# Return the subnet and netmask of an interface.
pcap_lookupnet = _lib.pcap_lookupnet
pcap_lookupnet.restype = c_int
pcap_lookupnet.argtypes = [STRING, POINTER(bpf_u_int32), POINTER(bpf_u_int32), STRING]
#int pcap_dispatch (pcap_t *p, int cnt, pcap_handler callback, u_char *user)
# Collect a group of packets.
pcap_dispatch = _lib.pcap_dispatch
pcap_dispatch.restype = c_int
pcap_dispatch.argtypes = [POINTER(pcap_t), c_int, pcap_handler, POINTER(u_char)]
#int pcap_loop (pcap_t *p, int cnt, pcap_handler callback, u_char *user)
# Collect a group of packets.
pcap_loop = _lib.pcap_loop
pcap_loop.restype = c_int
pcap_loop.argtypes = [POINTER(pcap_t), c_int, pcap_handler, POINTER(u_char)]
#u_char * pcap_next (pcap_t *p, struct pcap_pkthdr *h)
# Return the next available packet.
pcap_next = _lib.pcap_next
pcap_next.restype = POINTER(u_char)
pcap_next.argtypes = [POINTER(pcap_t), POINTER(pcap_pkthdr)]
#int pcap_next_ex (pcap_t *p, struct pcap_pkthdr **pkt_header, const u_char **pkt_data)
# Read a packet from an interface or from an offline capture.
pcap_next_ex = _lib.pcap_next_ex
pcap_next_ex.restype = c_int
pcap_next_ex.argtypes = [POINTER(pcap_t), POINTER(POINTER(pcap_pkthdr)), POINTER(POINTER(u_char))]
#void pcap_breakloop (pcap_t *)
# set a flag that will force pcap_dispatch() or pcap_loop() to return rather than looping.
pcap_breakloop = _lib.pcap_breakloop
pcap_breakloop.restype = None
pcap_breakloop.argtypes = [POINTER(pcap_t)]
#int pcap_sendpacket (pcap_t *p, u_char *buf, int size)
# Send a raw packet.
pcap_sendpacket = _lib.pcap_sendpacket
pcap_sendpacket.restype = c_int
#pcap_sendpacket.argtypes = [POINTER(pcap_t), POINTER(u_char), c_int]
pcap_sendpacket.argtypes = [POINTER(pcap_t), c_void_p, c_int]
#void pcap_dump (u_char *user, const struct pcap_pkthdr *h, const u_char *sp)
# Save a packet to disk.
pcap_dump = _lib.pcap_dump
pcap_dump.restype = None
pcap_dump.argtypes = [POINTER(pcap_dumper_t), POINTER(pcap_pkthdr), POINTER(u_char)]
#long pcap_dump_ftell (pcap_dumper_t *)
# Return the file position for a "savefile".
pcap_dump_ftell = _lib.pcap_dump_ftell
pcap_dump_ftell.restype = c_long
pcap_dump_ftell.argtypes = [POINTER(pcap_dumper_t)]
#int pcap_compile (pcap_t *p, struct bpf_program *fp, char *str, int optimize, bpf_u_int32 netmask)
# Compile a packet filter, converting an high level filtering expression (see Filtering expression syntax) in a program that can be interpreted by the kernel-level filtering engine.
pcap_compile = _lib.pcap_compile
pcap_compile.restype = c_int
pcap_compile.argtypes = [POINTER(pcap_t), POINTER(bpf_program), STRING, c_int, bpf_u_int32]
#int pcap_compile_nopcap (int snaplen_arg, int linktype_arg, struct bpf_program *program, char *buf, int optimize, bpf_u_int32 mask)
# Compile a packet filter without the need of opening an adapter. This function converts an high level filtering expression (see Filtering expression syntax) in a program that can be interpreted by the kernel-level filtering engine.
pcap_compile_nopcap = _lib.pcap_compile_nopcap
pcap_compile_nopcap.restype = c_int
pcap_compile_nopcap.argtypes = [c_int, c_int, POINTER(bpf_program), STRING, c_int, bpf_u_int32]
#int pcap_setfilter (pcap_t *p, struct bpf_program *fp)
# Associate a filter to a capture.
pcap_setfilter = _lib.pcap_setfilter
pcap_setfilter.restype = c_int
pcap_setfilter.argtypes = [POINTER(pcap_t), POINTER(bpf_program)]
#void pcap_freecode (struct bpf_program *fp)
# Free a filter.
pcap_freecode = _lib.pcap_freecode
pcap_freecode.restype = None
pcap_freecode.argtypes = [POINTER(bpf_program)]
#int pcap_datalink (pcap_t *p)
# Return the link layer of an adapter.
pcap_datalink = _lib.pcap_datalink
pcap_datalink.restype = c_int
pcap_datalink.argtypes = [POINTER(pcap_t)]
#int pcap_list_datalinks (pcap_t *p, int **dlt_buf)
# list datalinks
pcap_list_datalinks = _lib.pcap_list_datalinks
pcap_list_datalinks.restype = c_int
#pcap_list_datalinks.argtypes = [POINTER(pcap_t), POINTER(POINTER(c_int))]
#int pcap_set_datalink (pcap_t *p, int dlt)
# Set the current data link type of the pcap descriptor to the type specified by dlt. -1 is returned on failure.
pcap_set_datalink = _lib.pcap_set_datalink
pcap_set_datalink.restype = c_int
pcap_set_datalink.argtypes = [POINTER(pcap_t), c_int]
#int pcap_datalink_name_to_val (const char *name)
# Translates a data link type name, which is a DLT_ name with the DLT_ removed, to the corresponding data link type value. The translation is case-insensitive. -1 is returned on failure.
pcap_datalink_name_to_val = _lib.pcap_datalink_name_to_val
pcap_datalink_name_to_val.restype = c_int
pcap_datalink_name_to_val.argtypes = [STRING]
#const char * pcap_datalink_val_to_name (int dlt)
# Translates a data link type value to the corresponding data link type name. NULL is returned on failure.
pcap_datalink_val_to_name = _lib.pcap_datalink_val_to_name
pcap_datalink_val_to_name.restype = STRING
pcap_datalink_val_to_name.argtypes = [c_int]
#const char * pcap_datalink_val_to_description (int dlt)
# Translates a data link type value to a short description of that data link type. NULL is returned on failure.
pcap_datalink_val_to_description = _lib.pcap_datalink_val_to_description
pcap_datalink_val_to_description.restype = STRING
pcap_datalink_val_to_description.argtypes = [c_int]
#int pcap_snapshot (pcap_t *p)
# Return the dimension of the packet portion (in bytes) that is delivered to the application.
pcap_snapshot = _lib.pcap_snapshot
pcap_snapshot.restype = c_int
pcap_snapshot.argtypes = [POINTER(pcap_t)]
#int pcap_is_swapped (pcap_t *p)
# returns true if the current savefile uses a different byte order than the current system.
pcap_is_swapped = _lib.pcap_is_swapped
pcap_is_swapped.restype = c_int
pcap_is_swapped.argtypes = [POINTER(pcap_t)]
#int pcap_major_version (pcap_t *p)
# return the major version number of the pcap library used to write the savefile.
pcap_major_version = _lib.pcap_major_version
pcap_major_version.restype = c_int
pcap_major_version.argtypes = [POINTER(pcap_t)]
#int pcap_minor_version (pcap_t *p)
# return the minor version number of the pcap library used to write the savefile.
pcap_minor_version = _lib.pcap_minor_version
pcap_minor_version.restype = c_int
pcap_minor_version.argtypes = [POINTER(pcap_t)]
#FILE * pcap_file (pcap_t *p)
# Return the standard stream of an offline capture.
pcap_file=_lib.pcap_file
pcap_file.restype = FILE
pcap_file.argtypes = [POINTER(pcap_t)]
#int pcap_stats (pcap_t *p, struct pcap_stat *ps)
# Return statistics on current capture.
pcap_stats = _lib.pcap_stats
pcap_stats.restype = c_int
pcap_stats.argtypes = [POINTER(pcap_t), POINTER(pcap_stat)]
#void pcap_perror (pcap_t *p, char *prefix)
# print the text of the last pcap library error on stderr, prefixed by prefix.
pcap_perror = _lib.pcap_perror
pcap_perror.restype = None
pcap_perror.argtypes = [POINTER(pcap_t), STRING]
#char * pcap_geterr (pcap_t *p)
# return the error text pertaining to the last pcap library error.
pcap_geterr = _lib.pcap_geterr
pcap_geterr.restype = STRING
pcap_geterr.argtypes = [POINTER(pcap_t)]
#char * pcap_strerror (int error)
# Provided in case strerror() isn't available.
pcap_strerror = _lib.pcap_strerror
pcap_strerror.restype = STRING
pcap_strerror.argtypes = [c_int]
#const char * pcap_lib_version (void)
# Returns a pointer to a string giving information about the version of the libpcap library being used; note that it contains more information than just a version number.
pcap_lib_version = _lib.pcap_lib_version
pcap_lib_version.restype = STRING
pcap_lib_version.argtypes = []
#void pcap_close (pcap_t *p)
# close the files associated with p and deallocates resources.
pcap_close = _lib.pcap_close
pcap_close.restype = None
pcap_close.argtypes = [POINTER(pcap_t)]
#FILE * pcap_dump_file (pcap_dumper_t *p)
# return the standard I/O stream of the 'savefile' opened by pcap_dump_open().
pcap_dump_file=_lib.pcap_dump_file
pcap_dump_file.restype=FILE
pcap_dump_file.argtypes= [POINTER(pcap_dumper_t)]
#int pcap_dump_flush (pcap_dumper_t *p)
# Flushes the output buffer to the ``savefile,'' so that any packets written with pcap_dump() but not yet written to the ``savefile'' will be written. -1 is returned on error, 0 on success.
pcap_dump_flush = _lib.pcap_dump_flush
pcap_dump_flush.restype = c_int
pcap_dump_flush.argtypes = [POINTER(pcap_dumper_t)]
#void pcap_dump_close (pcap_dumper_t *p)
# Closes a savefile.
pcap_dump_close = _lib.pcap_dump_close
pcap_dump_close.restype = None
pcap_dump_close.argtypes = [POINTER(pcap_dumper_t)]
if not WIN32:
pcap_get_selectable_fd = _lib.pcap_get_selectable_fd
pcap_get_selectable_fd.restype = c_int
pcap_get_selectable_fd.argtypes = [POINTER(pcap_t)]
###########################################
## Windows-specific Extensions
## The functions in this section extend libpcap to offer advanced functionalities
## (like remote packet capture, packet buffer size variation or high-precision packet injection).
## Howerver, at the moment they can be used only in Windows.
###########################################
if WIN32:
HANDLE = c_void_p
##############
## Identifiers related to the new source syntax
##############
#define PCAP_SRC_FILE 2
#define PCAP_SRC_IFLOCAL 3
#define PCAP_SRC_IFREMOTE 4
#Internal representation of the type of source in use (file, remote/local interface).
PCAP_SRC_FILE = 2
PCAP_SRC_IFLOCAL = 3
PCAP_SRC_IFREMOTE = 4
##############
## Strings related to the new source syntax
##############
#define PCAP_SRC_FILE_STRING "file://"
#define PCAP_SRC_IF_STRING "rpcap://"
#String that will be used to determine the type of source in use (file, remote/local interface).
PCAP_SRC_FILE_STRING="file://"
PCAP_SRC_IF_STRING="rpcap://"
##############
## Flags defined in the pcap_open() function
##############
# define PCAP_OPENFLAG_PROMISCUOUS 1
# Defines if the adapter has to go in promiscuous mode.
PCAP_OPENFLAG_PROMISCUOUS=1
# define PCAP_OPENFLAG_DATATX_UDP 2
# Defines if the data trasfer (in case of a remote capture) has to be done with UDP protocol.
PCAP_OPENFLAG_DATATX_UDP=2
# define PCAP_OPENFLAG_NOCAPTURE_RPCAP 4
PCAP_OPENFLAG_NOCAPTURE_RPCAP=4
# Defines if the remote probe will capture its own generated traffic.
# define PCAP_OPENFLAG_NOCAPTURE_LOCAL 8
PCAP_OPENFLAG_NOCAPTURE_LOCAL = 8
# define PCAP_OPENFLAG_MAX_RESPONSIVENESS 16
# This flag configures the adapter for maximum responsiveness.
PCAP_OPENFLAG_MAX_RESPONSIVENESS=16
##############
## Sampling methods defined in the pcap_setsampling() function
##############
# define PCAP_SAMP_NOSAMP 0
# No sampling has to be done on the current capture.
PCAP_SAMP_NOSAMP=0
# define PCAP_SAMP_1_EVERY_N 1
# It defines that only 1 out of N packets must be returned to the user.
PCAP_SAMP_1_EVERY_N=1
#define PCAP_SAMP_FIRST_AFTER_N_MS 2
# It defines that we have to return 1 packet every N milliseconds.
PCAP_SAMP_FIRST_AFTER_N_MS=2
##############
## Authentication methods supported by the RPCAP protocol
##############
# define RPCAP_RMTAUTH_NULL 0
# It defines the NULL authentication.
RPCAP_RMTAUTH_NULL=0
# define RPCAP_RMTAUTH_PWD 1
# It defines the username/password authentication.
RPCAP_RMTAUTH_PWD=1
##############
## Remote struct and defines
##############
# define PCAP_BUF_SIZE 1024
# Defines the maximum buffer size in which address, port, interface names are kept.
PCAP_BUF_SIZE = 1024
# define RPCAP_HOSTLIST_SIZE 1024
# Maximum lenght of an host name (needed for the RPCAP active mode).
RPCAP_HOSTLIST_SIZE = 1024
class pcap_send_queue(Structure):
_fields_=[("maxlen",c_uint),
("len",c_uint),
("buffer",c_char_p)]
## struct pcap_rmtauth
## This structure keeps the information needed to autheticate the user on a remote machine
class pcap_rmtauth(Structure):
_fields_=[("type",c_int),
("username",c_char_p),
("password",c_char_p)]
## struct pcap_samp
## This structure defines the information related to sampling
class pcap_samp(Structure):
_fields_=[("method",c_int),
("value",c_int)]
#PAirpcapHandle pcap_get_airpcap_handle (pcap_t *p)
# Returns the AirPcap handler associated with an adapter. This handler can be used to change the wireless-related settings of the CACE Technologies AirPcap wireless capture adapters.
#bool pcap_offline_filter (struct bpf_program *prog, const struct pcap_pkthdr *header, const u_char *pkt_data)
# Returns if a given filter applies to an offline packet.
pcap_offline_filter = _lib.pcap_offline_filter
pcap_offline_filter.restype = c_bool
pcap_offline_filter.argtypes = [POINTER(bpf_program),POINTER(pcap_pkthdr),POINTER(u_char)]
#int pcap_live_dump (pcap_t *p, char *filename, int maxsize, int maxpacks)
# Save a capture to file.
pcap_live_dump = _lib.pcap_live_dump
pcap_live_dump.restype = c_int
pcap_live_dump.argtypes = [POINTER(pcap_t), POINTER(c_char), c_int,c_int]
#int pcap_live_dump_ended (pcap_t *p, int sync)
# Return the status of the kernel dump process, i.e. tells if one of the limits defined with pcap_live_dump() has been reached.
pcap_live_dump_ended = _lib.pcap_live_dump_ended
pcap_live_dump_ended.restype = c_int
pcap_live_dump_ended.argtypes = [POINTER(pcap_t), c_int]
#struct pcap_stat * pcap_stats_ex (pcap_t *p, int *pcap_stat_size)
# Return statistics on current capture.
pcap_stats_ex = _lib.pcap_stats_ex
pcap_stats_ex.restype = POINTER(pcap_stat)
pcap_stats_ex.argtypes = [POINTER(pcap_t), POINTER(c_int)]
#int pcap_setbuff (pcap_t *p, int dim)
# Set the size of the kernel buffer associated with an adapter.
pcap_setbuff = _lib.pcap_setbuff
pcap_setbuff.restype = c_int
pcap_setbuff.argtypes = [POINTER(pcap_t), c_int]
#int pcap_setmode (pcap_t *p, int mode)
# Set the working mode of the interface p to mode.
pcap_setmode = _lib.pcap_setmode
pcap_setmode.restype = c_int
pcap_setmode.argtypes = [POINTER(pcap_t), c_int]
#int pcap_setmintocopy (pcap_t *p, int size)
# Set the minumum amount of data received by the kernel in a single call.
pcap_setmintocopy = _lib.pcap_setmintocopy
pcap_setmintocopy.restype = c_int
pcap_setmintocopy.argtype = [POINTER(pcap_t), c_int]
#HANDLE pcap_getevent (pcap_t *p)
# Return the handle of the event associated with the interface p.
pcap_getevent = _lib.pcap_getevent
pcap_getevent.restype = HANDLE
pcap_getevent.argtypes = [POINTER(pcap_t)]
#pcap_send_queue * pcap_sendqueue_alloc (u_int memsize)
# Allocate a send queue.
pcap_sendqueue_alloc = _lib.pcap_sendqueue_alloc
pcap_sendqueue_alloc.restype = POINTER(pcap_send_queue)
pcap_sendqueue_alloc.argtypes = [c_uint]
#void pcap_sendqueue_destroy (pcap_send_queue *queue)
# Destroy a send queue.
pcap_sendqueue_destroy = _lib.pcap_sendqueue_destroy
pcap_sendqueue_destroy.restype = None
pcap_sendqueue_destroy.argtypes = [POINTER(pcap_send_queue)]
#int pcap_sendqueue_queue (pcap_send_queue *queue, const struct pcap_pkthdr *pkt_header, const u_char *pkt_data)
# Add a packet to a send queue.
pcap_sendqueue_queue = _lib.pcap_sendqueue_queue
pcap_sendqueue_queue.restype = c_int
pcap_sendqueue_queue.argtypes = [POINTER(pcap_send_queue), POINTER(pcap_pkthdr), POINTER(u_char)]
#u_int pcap_sendqueue_transmit (pcap_t *p, pcap_send_queue *queue, int sync)
# Send a queue of raw packets to the network.
pcap_sendqueue_transmit = _lib.pcap_sendqueue_transmit
pcap_sendqueue_transmit.retype = u_int
pcap_sendqueue_transmit.argtypes = [POINTER(pcap_t), POINTER(pcap_send_queue), c_int]
#int pcap_findalldevs_ex (char *source, struct pcap_rmtauth *auth, pcap_if_t **alldevs, char *errbuf)
# Create a list of network devices that can be opened with pcap_open().
pcap_findalldevs_ex = _lib.pcap_findalldevs_ex
pcap_findalldevs_ex.retype = c_int
pcap_findalldevs_ex.argtypes = [STRING, POINTER(pcap_rmtauth), POINTER(POINTER(pcap_if_t)), STRING]
#int pcap_createsrcstr (char *source, int type, const char *host, const char *port, const char *name, char *errbuf)
# Accept a set of strings (host name, port, ...), and it returns the complete source string according to the new format (e.g. 'rpcap://1.2.3.4/eth0').
pcap_createsrcstr = _lib.pcap_createsrcstr
pcap_createsrcstr.restype = c_int
pcap_createsrcstr.argtypes = [STRING, c_int, STRING, STRING, STRING, STRING]
#int pcap_parsesrcstr (const char *source, int *type, char *host, char *port, char *name, char *errbuf)
# Parse the source string and returns the pieces in which the source can be split.
pcap_parsesrcstr = _lib.pcap_parsesrcstr
pcap_parsesrcstr.retype = c_int
pcap_parsesrcstr.argtypes = [STRING, POINTER(c_int), STRING, STRING, STRING, STRING]
#pcap_t * pcap_open (const char *source, int snaplen, int flags, int read_timeout, struct pcap_rmtauth *auth, char *errbuf)
# Open a generic source in order to capture / send (WinPcap only) traffic.
pcap_open = _lib.pcap_open
pcap_open.restype = POINTER(pcap_t)
pcap_open.argtypes = [STRING, c_int, c_int, c_int, POINTER(pcap_rmtauth), STRING]
#struct pcap_samp * pcap_setsampling (pcap_t *p)
# Define a sampling method for packet capture.
pcap_setsampling = _lib.pcap_setsampling
pcap_setsampling.restype = POINTER(pcap_samp)
pcap_setsampling.argtypes = [POINTER(pcap_t)]
#SOCKET pcap_remoteact_accept (const char *address, const char *port, const char *hostlist, char *connectinghost, struct pcap_rmtauth *auth, char *errbuf)
# Block until a network connection is accepted (active mode only).
pcap_remoteact_accept = _lib.pcap_remoteact_accept
pcap_remoteact_accept.restype = SOCKET
pcap_remoteact_accept.argtypes = [STRING, STRING, STRING, STRING, POINTER(pcap_rmtauth), STRING]
#int pcap_remoteact_close (const char *host, char *errbuf)
# Drop an active connection (active mode only).
pcap_remoteact_close = _lib.pcap_remoteact_close
pcap_remoteact_close.restypes = c_int
pcap_remoteact_close.argtypes = [STRING, STRING]
#void pcap_remoteact_cleanup ()
# Clean the socket that is currently used in waiting active connections.
pcap_remoteact_cleanup = _lib.pcap_remoteact_cleanup
pcap_remoteact_cleanup.restypes = None
pcap_remoteact_cleanup.argtypes = []
#int pcap_remoteact_list (char *hostlist, char sep, int size, char *errbuf)
# Return the hostname of the host that have an active connection with us (active mode only).
pcap_remoteact_list = _lib.pcap_remoteact_list
pcap_remoteact_list.restype = c_int
pcap_remoteact_list.argtypes = [STRING, c_char, c_int, STRING]
...@@ -360,6 +360,7 @@ extensions_paths: path or list of paths where extensions are to be looked for ...@@ -360,6 +360,7 @@ extensions_paths: path or list of paths where extensions are to be looked for
emph = Emphasize() emph = Emphasize()
use_pcap = False use_pcap = False
use_dnet = False use_dnet = False
use_winpcapy = False
ipv6_enabled = socket.has_ipv6 ipv6_enabled = socket.has_ipv6
ethertypes = ETHER_TYPES ethertypes = ETHER_TYPES
protocols = IP_PROTOS protocols = IP_PROTOS
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment