% Regression tests on Windows only for Scapy

# More information at http://www.secdev.org/projects/UTscapy/

+ Configuration

= Imports

from unittest import mock

############
############
+ Mechanics tests

= Automaton - Test select_objects edge cases

assert select_objects([ObjectPipe()], 0) == []
assert select_objects([ObjectPipe()], 1) == []

a = ObjectPipe()
a.send("test")
assert select_objects([a], 0) == [a]

############
############
+ Windows arch unit tests

= Test network_name

iface = conf.iface

assert network_name(iface.name) == iface.network_name
assert network_name(iface.description) == iface.network_name
assert network_name(iface.network_name) == iface.network_name

= dev_from_networkname

from scapy.config import conf

assert dev_from_networkname(conf.iface.network_name).guid == conf.iface.guid

= test pcap_service_status
~ npcap_service

from scapy.arch.windows import pcap_service_status

status = pcap_service_status()
assert status

= test get_if_list

from scapy.interfaces import get_if_list

print(get_if_list())
assert all(x.startswith(r"\Device\NPF_") for x in get_if_list())

= test pcap_service_stop
~ appveyor_only require_gui npcap_service

from scapy.arch.windows import pcap_service_stop

pcap_service_stop()
assert pcap_service_status() == False

= test pcap_service_start
~ appveyor_only require_gui npcap_service

from scapy.arch.windows import pcap_service_start

pcap_service_start()
assert pcap_service_status() == True

= Test auto-pcap start UI

@mock.patch("scapy.arch.windows.get_windows_if_list")
def _test_autostart_ui(mocked_getiflist):
    mocked_getiflist.side_effect = lambda: []
    conf.ifaces.reload()
    assert all(x.index < 0 for x in conf.ifaces.data.values())

try:
    old_ifaces = conf.ifaces.data.copy()
    _test_autostart_ui()
finally:
     conf.ifaces.data = old_ifaces

######### Native mode ###########

+ Test Windows Native sockets

= Set up native mode

conf.use_pcap = False
conf.route.resync()
conf.ifaces.reload()
assert conf.use_pcap == False

= Ping
~ netaccess needs_root

def _test():
    with conf.L3socket() as a:
        answer = a.sr1(IP(dst="1.1.1.1", ttl=128)/ICMP()/"abcdefghijklmnopqrstuvwabcdefghi", timeout=2)
        answer.show()
        assert ICMP in answer

retry_test(_test)

= DNS lookup
~ netaccess needs_root

def _test():
    answer = sr1(IP(dst="8.8.8.8")/UDP()/DNS(rd=1, qd=DNSQR(qname="www.google.com")), timeout=2)
    answer.show()
    assert DNS in answer
    assert answer.qd.qname == b'www.google.com.'

retry_test(_test)

= Leave native mode

conf.use_pcap = True
conf.route.resync()
conf.ifaces.reload()
assert conf.use_pcap == True
