% Regression tests on Windows only for Scapy # More informations at http://www.secdev.org/projects/UTscapy/ ############ ############ + Mocked read_routes6() calls = Windows with fake IPv6 adapter route_add_loopback() import mock from scapy.arch.windows import _read_routes6_post2008 def check_mandatory_ipv6_routes(routes6): """Ensure that mandatory IPv6 routes are present.""" if len(filter(lambda r: r[0] == "::" and r[-1] == ["::1"], routes6)) < 1: return False if len(filter(lambda r: r[0] == "fe80::" and (r[1] == 64 or r[1] == 32), routes6)) < 1: return False if len(filter(lambda r: in6_islladdr(r[0]) and r[1] == 128, routes6)) < 1: return False return True def dev_from_index_custom(if_index): if_list = [{'mac': 'D0:50:99:56:DD:F9', 'win_index': '13', 'guid': '{C56DFFB3-992C-4964-B000-3E7C0F76E8BA}', 'name': 'Killer E2200 Gigabit Ethernet Controller', 'description': 'Ethernet'}, {'mac': '00:FF:0E:C7:25:37', 'win_index': '3', 'guid': '{0EC72537-B662-4F5D-B34E-48BFAE799BBE}', 'name': 'TAP-Windows Adapter V9', 'description': 'Ethernet 2'}] values = {} for i in if_list: try: interface = NetworkInterface(i) values[interface.guid] = interface except (KeyError, PcapNameNotFoundError): pass for devname, iface in values.items(): if iface.win_index == str(if_index): return iface raise ValueError("Unknown network interface index %r" % if_index) @mock.patch("scapy.utils6.construct_source_candidate_set") @mock.patch("scapy.arch.windows.winpcapy_get_if_list") @mock.patch("scapy.arch.windows.dev_from_index") @mock.patch("scapy.arch.windows.sp.Popen") def test_read_routes6_windows(mock_comm, mock_dev_from_index, mock_winpcapylist, mock_utils6cset): """Test read_routes6() on Windows""" # 'Get-NetRoute -AddressFamily IPV6 | select ifIndex, DestinationPrefix, NextHop' get_net_route_output = """ ifIndex DestinationPrefix NextHop ------- ----------------- ------- 3 ff00::/8 :: 16 ff00::/8 :: 13 ff00::/8 :: 1 ff00::/8 :: 13 fe80::dc1d:24e8:af00:125e/128 :: 3 fe80::9402:5804:cb16:fb3b/128 :: 16 fe80::100:7f:fffe/128 :: 3 fe80::/64 :: 16 fe80::/64 :: 13 fe80::/64 :: 13 2a01:e35:2f17:fe60:dc1d:24e8:af00:125e/128 :: 13 2a01:e35:2f17:fe60::/64 :: 1 ::1/128 :: 13 ::/0 fe80::224:d4ff:fea0:a6d7 """ mock_comm.return_value.communicate.return_value = (get_net_route_output, "") mock_winpcapylist.return_value = [u'\\Device\\NPF_{0EC72537-B662-4F5D-B34E-48BFAE799BBE}', u'\\Device\\NPF_{C56DFFB3-992C-4964-B000-3E7C0F76E8BA}'] # Mocked in6_getifaddr() output mock_dev_from_index.side_effect = dev_from_index_custom # Random mock_utils6cset.side_effect = lambda w,x,y,z: ["::1"] if w=="::" else ["fdbb:d995:ddd8:51fc::"] # Test the function routes = _read_routes6_post2008() for r in routes: print r print(len(routes)) assert(len(routes) == 9) assert(check_mandatory_ipv6_routes(routes)) test_read_routes6_windows() ############ ############ + Main.py emulator = Prepare readline patching functions from scapy.main import * import scapy.config as conf import sys import mock import readline index = 0 @mock.patch("pyreadline.console.console.Console.size") @mock.patch("scapy.config.conf.readfunc") def emulate_main_input(data, mock_readfunc, mock_pyr_size): # This fix when the windows doesn't have a size (run with a windows server) mock_pyr_size.return_value = (300, 300) global index index = 0 # reset var def readlineScapy(*args, **kargs): global index if len(data) == index: r_data = "exit(1 if hasattr(sys, 'last_value') and sys.last_value is not None else 0)" else: r_data = data[index] if r_data.startswith("#AUTOCOMPLETE"): send_text = re.match(r'#AUTOCOMPLETE{(.*)}', r_data).group(1) cmpl = readline.rl.get_completer() r_data = cmpl(send_text, 0) index +=1 print r_data return r_data mock_readfunc.side_effect = readlineScapy sys.argv = [''] def console_exit(code): raise SystemExit(code) exit_code = -1 try: interact(mydict={"exit": console_exit}) except SystemExit as e: exit_code = str(e) pass assert exit_code == "0" = Test basic running data = ["IP()", "assert _.name == 'IP'"] emulate_main_input(data) = Test function parsing data = ["def test():", " return True", "", "assert test() == True"] emulate_main_input(data) = Test auto-completion from ctypes import wintypes data = ["#AUTOCOMPLETE{scapy.config.conf.vers}", "assert _ == scapy.config.conf.version"] emulate_main_input(data) ############ ############ + Windows arch unit tests = Test PowerShell availability from scapy.config import conf assert conf.prog.powershell != None = Test all VBS fallback import mock from scapy.config import conf ps_ip = get_ip_from_name(conf.iface.name) ps_if_list = get_windows_if_list() ps_read_routes = read_routes() # Turn on VBS mode conf.prog.powershell = None # Test get_ip_from_name assert get_ip_from_name(conf.iface.name) == ps_ip # Test get_windows_if_list def is_in_if_list(i, list): for j in list: if j["guid"] == i["guid"] and j["name"] == i["name"]: return True return False vbs_if_list = get_windows_if_list() _correct = True for i in ps_if_list: if not is_in_if_list(i, vbs_if_list): _correct = False break assert _correct # Test read_routes def is_in_route_list(i, list): for j in list: #Ignore all empty IP if j[4] == '' or i[4] == '': return True if j[2] == i[2] and j[4] == i[4] and j[3].guid == i[3].guid: return True return False vbs_read_routes = read_routes() _correct = True for i in ps_read_routes: if not is_in_route_list(i, vbs_read_routes): _correct = False break assert _correct = show_interfaces from scapy.arch import show_interfaces from StringIO import StringIO @mock.patch('sys.stdout', new_callable=StringIO) def test_show_interfaces(mock_stdout): show_interfaces() lines = mock_stdout.getvalue().split("\n")[1:] for l in lines: if not l.strip(): continue try: int(l[:2]) except: sys.stderr.write(l) return False return True assert test_show_interfaces() = dev_from_pcapname from scapy.config import conf assert dev_from_pcapname(conf.iface.pcap_name).guid == conf.iface.guid