summaryrefslogtreecommitdiffstats
path: root/scripts/external_libs/scapy-2.3.1/python2/scapy/arch/windows/__init__.py
diff options
context:
space:
mode:
Diffstat (limited to 'scripts/external_libs/scapy-2.3.1/python2/scapy/arch/windows/__init__.py')
-rw-r--r--scripts/external_libs/scapy-2.3.1/python2/scapy/arch/windows/__init__.py545
1 files changed, 545 insertions, 0 deletions
diff --git a/scripts/external_libs/scapy-2.3.1/python2/scapy/arch/windows/__init__.py b/scripts/external_libs/scapy-2.3.1/python2/scapy/arch/windows/__init__.py
new file mode 100644
index 00000000..e604266b
--- /dev/null
+++ b/scripts/external_libs/scapy-2.3.1/python2/scapy/arch/windows/__init__.py
@@ -0,0 +1,545 @@
+## This file is part of Scapy
+## See http://www.secdev.org/projects/scapy for more informations
+## Copyright (C) Philippe Biondi <phil@secdev.org>
+## This program is published under a GPLv2 license
+
+"""
+Customizations needed to support Microsoft Windows.
+"""
+
+import os,re,sys,socket,time
+from glob import glob
+from scapy.config import conf,ConfClass
+from scapy.error import Scapy_Exception,log_loading,log_runtime
+from scapy.utils import atol, inet_aton, inet_ntoa, PcapReader
+from scapy.base_classes import Gen, Net, SetGen
+import scapy.plist as plist
+from scapy.sendrecv import debug, srp1
+from scapy.layers.l2 import Ether, ARP
+from scapy.data import MTU, ETHER_BROADCAST, ETH_P_ARP
+
+conf.use_pcap = 1
+conf.use_dnet = 1
+#from scapy.arch import pcapdnet
+#from scapy.arch.pcapdnet import *
+
+LOOPBACK_NAME="lo0"
+WINDOWS = True
+IPPROTO_IPIP = 4
+
+
+def _where(filename, dirs=[], env="PATH"):
+ """Find file in current dir or system path"""
+ if not isinstance(dirs, list):
+ dirs = [dirs]
+ if glob(filename):
+ return filename
+ paths = [os.curdir] + os.environ[env].split(os.path.pathsep) + dirs
+ for path in paths:
+ for match in glob(os.path.join(path, filename)):
+ if match:
+ return os.path.normpath(match)
+ raise IOError("File not found: %s" % filename)
+
+def win_find_exe(filename, installsubdir=None, env="ProgramFiles"):
+ """Find executable in current dir, system path or given ProgramFiles subdir"""
+ for fn in [filename, filename+".exe"]:
+ try:
+ if installsubdir is None:
+ path = _where(fn)
+ else:
+ path = _where(fn, dirs=[os.path.join(os.environ[env], installsubdir)])
+ except IOError:
+ path = filename
+ else:
+ break
+ return path
+
+
+class WinProgPath(ConfClass):
+ _default = "<System default>"
+ # We try some magic to find the appropriate executables
+ pdfreader = win_find_exe("AcroRd32")
+ psreader = win_find_exe("gsview32.exe", "Ghostgum/gsview")
+ dot = win_find_exe("dot", "ATT/Graphviz/bin")
+ tcpdump = win_find_exe("windump")
+ tcpreplay = win_find_exe("tcpreplay")
+ display = _default
+ hexedit = win_find_exe("hexer")
+ wireshark = win_find_exe("wireshark", "wireshark")
+
+conf.prog = WinProgPath()
+
+
+
+import _winreg
+
+
+
+class PcapNameNotFoundError(Scapy_Exception):
+ pass
+
+class NetworkInterface(object):
+ """A network interface of your local host"""
+
+ def __init__(self, dnetdict=None):
+ self.name = None
+ self.ip = None
+ self.mac = None
+ self.pcap_name = None
+ self.win_name = None
+ self.uuid = None
+ self.dnetdict = dnetdict
+ if dnetdict is not None:
+ self.update(dnetdict)
+
+ def update(self, dnetdict):
+ """Update info about network interface according to given dnet dictionary"""
+ self.name = dnetdict["name"]
+ # Other attributes are optional
+ try:
+ self.ip = socket.inet_ntoa(dnetdict["addr"].ip)
+ except (KeyError, AttributeError, NameError):
+ pass
+ try:
+ self.mac = dnetdict["link_addr"]
+ except KeyError:
+ pass
+ self._update_pcapdata()
+
+ def _update_pcapdata(self):
+ """Supplement more info from pypcap and the Windows registry"""
+
+ # XXX: We try eth0 - eth29 by bruteforce and match by IP address,
+ # because only the IP is available in both pypcap and dnet.
+ # This may not work with unorthodox network configurations and is
+ # slow because we have to walk through the Windows registry.
+ for n in range(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
+
+ def __repr__(self):
+ return "<%s: %s %s %s pcap_name=%s win_name=%s>" % (self.__class__.__name__,
+ self.name, self.ip, self.mac, self.pcap_name, self.win_name)
+
+from UserDict import IterableUserDict
+
+class NetworkInterfaceDict(IterableUserDict):
+ """Store information about network interfaces and convert between names"""
+
+ def load_from_dnet(self):
+ """Populate interface table via dnet"""
+ #for i in pcapdnet.dnet.intf():
+ # try:
+ # XXX: Only Ethernet for the moment: localhost is not supported by dnet and pcap
+ # We only take interfaces that have an IP address, because the IP
+ # 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):
+ # pass
+ #if len(self.data) == 0:
+ # log_loading.warning("No match between your pcap and dnet network interfaces found. "
+ # "You probably won't be able to send packets. "
+ # "Deactivating unneeded interfaces and restarting Scapy might help.")
+
+ 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):
+ """Return libdnet/Scapy device name for given pypcap device name
+
+ This mapping is necessary because pypcap numbers the devices differently."""
+
+ for devname, iface in self.items():
+ if iface.pcap_name == pcap_name:
+ return iface.name
+ raise ValueError("Unknown pypcap network interface %r" % pcap_name)
+
+ def show(self, resolve_mac=True):
+ """Print list of available network interfaces in human readable form"""
+ print "%s %s %s" % ("IFACE".ljust(5), "IP".ljust(15), "MAC")
+ for iface_name in sorted(self.data.keys()):
+ dev = self.data[iface_name]
+ mac = str(dev.mac)
+ if resolve_mac:
+ mac = conf.manufdb._resolve_MAC(mac)
+ print "%s %s %s" % (str(dev.name).ljust(5), str(dev.ip).ljust(15), mac)
+
+ifaces = NetworkInterfaceDict()
+#ifaces.load_from_dnet()
+
+def pcap_name(devname):
+ """Return pypcap device name for given libdnet/Scapy device name"""
+ try:
+ pcap_name = ifaces.pcap_name(devname)
+ except ValueError:
+ # pcap.pcap() will choose a sensible default for sniffing if iface=None
+ pcap_name = None
+ return pcap_name
+
+def devname(pcap_name):
+ """Return libdnet/Scapy device name for given pypcap device name"""
+ return ifaces.devname(pcap_name)
+
+def show_interfaces(resolve_mac=True):
+ """Print list of available network interfaces"""
+ return ifaces.show(resolve_mac)
+
+#orig_open_pcap = pcapdnet.open_pcap
+#pcapdnet.open_pcap = lambda iface,*args,**kargs: _orig_open_pcap(pcap_name(iface),*args,**kargs)
+
+def read_routes():
+ ok = 0
+ routes = []
+ ip = '(\d+\.\d+\.\d+\.\d+)'
+ # On Vista and Windows 7 the gateway can be IP or 'On-link'.
+ # But the exact 'On-link' string depends on the locale, so we allow any text.
+ gw_pattern = '(.+)'
+ metric_pattern = "(\d+)"
+ delim = "\s+" # The columns are separated by whitespace
+ netstat_line = delim.join([ip, ip, gw_pattern, ip, metric_pattern])
+ pattern = re.compile(netstat_line)
+ f=os.popen("netstat -rn")
+ for l in f.readlines():
+ match = re.search(pattern,l)
+ if match:
+ dest = match.group(1)
+ mask = match.group(2)
+ gw = match.group(3)
+ netif = match.group(4)
+ metric = match.group(5)
+ try:
+ #intf = pcapdnet.dnet.intf().get_dst(pcapdnet.dnet.addr(type=2, addrtxt=dest))
+ intf={};
+ except OSError:
+ log_loading.warning("Building Scapy's routing table: Couldn't get outgoing interface for destination %s" % dest)
+ continue
+ if not intf.has_key("addr"):
+ break
+ addr = str(intf["addr"])
+ addr = addr.split("/")[0]
+
+ dest = atol(dest)
+ mask = atol(mask)
+ # 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
+
+def read_routes6():
+ return []
+
+def getmacbyip(ip, chainCC=0):
+ """Return MAC address corresponding to a given IP address"""
+ if isinstance(ip,Net):
+ ip = iter(ip).next()
+ 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:
+ import readline
+ console = readline.GetOutputFile()
+except (ImportError, AttributeError):
+ log_loading.info("Could not get readline console. Will not interpret ANSI color codes.")
+else:
+ conf.readfunc = readline.rl.readline
+ orig_stdout = sys.stdout
+ sys.stdout = console
+
+
+
+
+
+def sndrcv(pks, pkt, timeout = 2, inter = 0, verbose=None, chainCC=0, retry=0, multi=0):
+ if not isinstance(pkt, Gen):
+ pkt = SetGen(pkt)
+
+ if verbose is None:
+ verbose = conf.verb
+ debug.recv = plist.PacketList([],"Unanswered")
+ debug.sent = plist.PacketList([],"Sent")
+ debug.match = plist.SndRcvList([])
+ nbrecv=0
+ ans = []
+ # do it here to fix random fields, so that parent and child have the same
+ all_stimuli = tobesent = [p for p in pkt]
+ notans = len(tobesent)
+
+ hsent={}
+ for i in tobesent:
+ h = i.hashret()
+ if h in hsent:
+ hsent[h].append(i)
+ else:
+ hsent[h] = [i]
+ if retry < 0:
+ retry = -retry
+ autostop=retry
+ else:
+ autostop=0
+
+
+ while retry >= 0:
+ found=0
+
+ if timeout < 0:
+ timeout = None
+
+ pid=1
+ try:
+ if WINDOWS or pid == 0:
+ try:
+ try:
+ i = 0
+ if verbose:
+ print "Begin emission:"
+ for p in tobesent:
+ pks.send(p)
+ i += 1
+ time.sleep(inter)
+ if verbose:
+ print "Finished to send %i packets." % i
+ except SystemExit:
+ pass
+ except KeyboardInterrupt:
+ pass
+ except:
+ log_runtime.exception("--- Error sending packets")
+ log_runtime.info("--- Error sending packets")
+ finally:
+ try:
+ sent_times = [p.sent_time for p in all_stimuli if p.sent_time]
+ except:
+ pass
+ if WINDOWS or pid > 0:
+ # Timeout starts after last packet is sent (as in Unix version)
+ if timeout:
+ stoptime = time.time()+timeout
+ else:
+ stoptime = 0
+ remaintime = None
+ inmask = [pks.ins.fd]
+ try:
+ try:
+ while 1:
+ if stoptime:
+ remaintime = stoptime-time.time()
+ if remaintime <= 0:
+ break
+ r = pks.recv(MTU)
+ if r is None:
+ continue
+ ok = 0
+ h = r.hashret()
+ if h in hsent:
+ hlst = hsent[h]
+ for i in range(len(hlst)):
+ if r.answers(hlst[i]):
+ ans.append((hlst[i],r))
+ if verbose > 1:
+ os.write(1, "*")
+ ok = 1
+ if not multi:
+ del(hlst[i])
+ notans -= 1;
+ else:
+ if not hasattr(hlst[i], '_answered'):
+ notans -= 1;
+ hlst[i]._answered = 1;
+ break
+ if notans == 0 and not multi:
+ break
+ if not ok:
+ if verbose > 1:
+ os.write(1, ".")
+ nbrecv += 1
+ if conf.debug_match:
+ debug.recv.append(r)
+ except KeyboardInterrupt:
+ if chainCC:
+ raise
+ finally:
+ if WINDOWS:
+ for p,t in zip(all_stimuli, sent_times):
+ p.sent_time = t
+ finally:
+ pass
+
+ remain = reduce(list.__add__, hsent.values(), [])
+ if multi:
+ remain = filter(lambda p: not hasattr(p, '_answered'), remain);
+
+ if autostop and len(remain) > 0 and len(remain) != len(tobesent):
+ retry = autostop
+
+ tobesent = remain
+ if len(tobesent) == 0:
+ break
+ retry -= 1
+
+ if conf.debug_match:
+ debug.sent=plist.PacketList(remain[:],"Sent")
+ debug.match=plist.SndRcvList(ans[:])
+
+ #clean the ans list to delete the field _answered
+ if (multi):
+ for s,r in ans:
+ if hasattr(s, '_answered'):
+ del(s._answered)
+
+ if verbose:
+ print "\nReceived %i packets, got %i answers, remaining %i packets" % (nbrecv+len(ans), len(ans), notans)
+ return plist.SndRcvList(ans),plist.PacketList(remain,"Unanswered")
+
+
+import scapy.sendrecv
+scapy.sendrecv.sndrcv = sndrcv
+
+def sniff(count=0, store=1, offline=None, prn = None, lfilter=None, L2socket=None, timeout=None, *arg, **karg):
+ """Sniff packets
+sniff([count=0,] [prn=None,] [store=1,] [offline=None,] [lfilter=None,] + L2ListenSocket args) -> list of packets
+
+ count: number of packets to capture. 0 means infinity
+ store: wether to store sniffed packets or discard them
+ prn: function to apply to each packet. If something is returned,
+ it is displayed. Ex:
+ ex: prn = lambda x: x.summary()
+lfilter: python function applied to each packet to determine
+ if further action may be done
+ ex: lfilter = lambda x: x.haslayer(Padding)
+offline: pcap file to read packets from, instead of sniffing them
+timeout: stop sniffing after a given time (default: None)
+L2socket: use the provided L2socket
+ """
+ c = 0
+
+ if offline is None:
+ if L2socket is None:
+ L2socket = conf.L2listen
+ s = L2socket(type=ETH_P_ALL, *arg, **karg)
+ else:
+ s = PcapReader(offline)
+
+ lst = []
+ if timeout is not None:
+ stoptime = time.time()+timeout
+ remain = None
+ while 1:
+ try:
+ if timeout is not None:
+ remain = stoptime-time.time()
+ if remain <= 0:
+ break
+
+ try:
+ p = s.recv(MTU)
+ except PcapTimeoutElapsed:
+ continue
+ if p is None:
+ break
+ if lfilter and not lfilter(p):
+ continue
+ if store:
+ lst.append(p)
+ c += 1
+ if prn:
+ r = prn(p)
+ if r is not None:
+ print r
+ if count > 0 and c >= count:
+ break
+ except KeyboardInterrupt:
+ break
+ s.close()
+ return plist.PacketList(lst,"Sniffed")
+
+import scapy.sendrecv
+scapy.sendrecv.sniff = sniff
+
+def get_if_list():
+ return sorted(ifaces.keys())
+
+def get_working_if():
+ try:
+ return devname(pcap.lookupdev())
+ except Exception:
+ return 'lo0'