blob: 86e015ae09f327b61a3458fb999d2dc038207e59 [file]
% Regression tests for Linux only
# More information at http://www.secdev.org/projects/UTscapy/
############
############
+ Linux only test
= L3RawSocket
~ netaccess IP ICMP linux needs_root
old_l3socket = conf.L3socket
old_debug_dissector = conf.debug_dissector
conf.debug_dissector = False
conf.L3socket = L3RawSocket
x = sr1(IP(dst="www.google.com")/ICMP(),timeout=3)
conf.debug_dissector = old_debug_dissector
conf.L3socket = old_l3socket
x
assert x[IP].ottl() in [32, 64, 128, 255]
assert 0 <= x[IP].hops() <= 126
x is not None and ICMP in x and x[ICMP].type == 0
# TODO: fix this test (randomly stuck)
# ex: https://travis-ci.org/secdev/scapy/jobs/247473497
#= Supersocket _flush_fd
#~ needs_root linux
#
#import select
#
#from scapy.arch.linux import _flush_fd
#socket = conf.L2listen()
#select.select([socket],[],[],2)
#_flush_fd(socket.ins)
= Interface aliases & sub-interfaces
~ linux needs_root
import os
exit_status = os.system("ip link add name scapy0 type dummy")
exit_status = os.system("ip addr add 192.0.2.1/24 dev scapy0")
exit_status = os.system("ip link set scapy0 up")
exit_status = os.system("ifconfig scapy0:0 inet 198.51.100.1/24 up")
if exit_status == 0:
exit_status = os.system("ip addr show scapy0")
print(get_if_list())
conf.route.resync()
print(conf.route.routes)
assert(conf.route.route("198.51.100.254") == ("scapy0", "198.51.100.1", "0.0.0.0"))
route_alias = (3325256704, 4294967040, "0.0.0.0", "scapy0", "198.51.100.1", 0)
assert(route_alias in conf.route.routes)
exit_status = os.system("ip link add link scapy0 name scapy0.42 type vlan id 42")
exit_status = os.system("ip addr add 203.0.113.42/24 dev scapy0.42")
exit_status = os.system("ip link set scapy0.42 up")
exit_status = os.system("ip route add 192.0.2.43/32 via 203.0.113.41")
print(get_if_list())
conf.route.resync()
print(conf.route.routes)
assert(conf.route.route("192.0.2.43") == ("scapy0.42", "203.0.113.42", "203.0.113.41"))
route_specific = (3221226027, 4294967295, "203.0.113.41", "scapy0.42", "203.0.113.42", 0)
assert(route_specific in conf.route.routes)
exit_status = os.system("ip link del name dev scapy0")
else:
assert True
= catch loopback device missing
~ linux needs_root
from mock import patch
# can't remove the lo device (or its address without causing trouble) - use some pseudo dummy instead
with patch('scapy.arch.linux.conf.loopback_name', 'scapy_lo_x'):
routes = read_routes()
= catch loopback device no address assigned
~ linux needs_root
import os, socket
from mock import patch
exit_status = os.system("ip link add name scapy_lo type dummy")
assert(exit_status == 0)
exit_status = os.system("ip link set dev scapy_lo up")
assert(exit_status == 0)
with patch('scapy.arch.linux.conf.loopback_name', 'scapy_lo'):
routes = read_routes()
exit_status = os.system("ip addr add dev scapy_lo 10.10.0.1/24")
assert(exit_status == 0)
with patch('scapy.arch.linux.conf.loopback_name', 'scapy_lo'):
routes = read_routes()
got_lo_device = False
for route in routes:
dst_int, msk_int, gw_str, if_name, if_addr, metric = route
if if_name == 'scapy_lo':
got_lo_device = True
assert(if_addr == '10.10.0.1')
dst_addr = socket.inet_ntoa(struct.pack("!I", dst_int))
assert(dst_addr == '10.10.0.0')
msk = socket.inet_ntoa(struct.pack("!I", msk_int))
assert (msk == '255.255.255.0')
break
assert(got_lo_device)
exit_status = os.system("ip link del dev scapy_lo")
assert(exit_status == 0)
= IPv6 link-local address selection
IFACES._add_fake_iface("scapy0")
from mock import patch
conf.route6.routes = [('fe80::', 64, '::', 'scapy0', ['fe80::e039:91ff:fe79:1910'], 256)]
conf.route6.ipv6_ifaces = set(['scapy0'])
bck_conf_iface = conf.iface
conf.iface = "scapy0"
with patch("scapy.layers.l2.get_if_hwaddr") as mgih:
mgih.return_value = 'e2:39:91:79:19:10'
p = Ether()/IPv6(dst="ff02::1")/ICMPv6NIQueryName(data="ff02::1")
print(p.sprintf("%Ether.src% > %Ether.dst%\n%IPv6.src% > %IPv6.dst%"))
ip6_ll_address = 'fe80::e039:91ff:fe79:1910'
print(p[IPv6].src, ip6_ll_address)
assert p[IPv6].src == ip6_ll_address
mac_address = 'e2:39:91:79:19:10'
print(p[Ether].src, mac_address)
assert p[Ether].src == mac_address
conf.iface = bck_conf_iface
conf.route6.resync()
= IPv6
~ linux
addrs = in6_getifaddr()
if len(addrs) == 0:
assert True
else:
assert all([in6_isvalid(addr[0]) for addr in in6_getifaddr()])
assert set([addr[2] for addr in in6_getifaddr()]) == conf.route6.ipv6_ifaces
= veth interface error handling
~ linux needs_root veth
try:
veth = VEthPair('this_IF_name_is_to_long_and_will_cause_an_error', 'veth_scapy_1')
veth.setup()
assert False
except subprocess.CalledProcessError:
pass
except Exception:
assert False
= veth interface usage - ctx manager
~ linux needs_root veth
from threading import Condition
cond_started = Condition()
def _sniffer_started():
global cond_started
cond_started.acquire()
cond_started.notify()
cond_started.release()
cond_started.acquire()
try:
with VEthPair('veth_scapy_0', 'veth_scapy_1') as veth:
if_list = get_if_list()
assert ('veth_scapy_0' in if_list)
assert ('veth_scapy_1' in if_list)
frm_count = 0
def _sniffer():
sniffed = sniff(iface='veth_scapy_1',
store=True,
count=2,
lfilter=lambda p: Ether in p and p[Ether].type == 0xbeef,
started_callback=_sniffer_started)
global frm_count
frm_count = 2
t_sniffer = Thread(target=_sniffer)
t_sniffer.start()
cond_started.wait()
sendp(Ether(type=0xbeef)/Raw(b'0123456789'),
iface='veth_scapy_0',
count=2)
t_sniffer.join(1)
assert(frm_count == 2)
if_list = get_if_list()
assert ('veth_scapy_0' not in if_list)
assert ('veth_scapy_1' not in if_list)
except subprocess.CalledProcessError:
assert False
except Exception:
assert False
= veth interface usage - manual interface handling
~ linux needs_root veth
from threading import Condition
cond_started = Condition()
def _sniffer_started():
global cond_started
cond_started.acquire()
cond_started.notify()
cond_started.release()
cond_started.acquire()
veth = VEthPair('veth_scapy_0', 'veth_scapy_1')
try:
veth.setup()
veth.up()
except subprocess.CalledProcessError:
assert False
except Exception:
assert False
conf.ifaces.reload()
if_list = get_if_list()
assert ('veth_scapy_0' in if_list)
assert ('veth_scapy_1' in if_list)
frm_count = 0
def _sniffer():
sniffed = sniff(iface='veth_scapy_1',
store=True,
count=2,
lfilter=lambda p: Ether in p and p[Ether].type == 0xbeef,
started_callback=_sniffer_started)
global frm_count
frm_count = 2
t_sniffer = Thread(target=_sniffer)
t_sniffer.start()
cond_started.wait()
sendp(Ether(type=0xbeef)/Raw(b'0123456789'),
iface='veth_scapy_0',
count=2)
t_sniffer.join(1)
assert(frm_count == 2)
try:
veth.down()
veth.destroy()
conf.ifaces.reload()
if_list = get_if_list()
assert ('veth_scapy_0' not in if_list)
assert ('veth_scapy_1' not in if_list)
except subprocess.CalledProcessError:
assert False
except Exception:
assert False
= Routing table, interface with no names
~ linux
from mock import patch
@patch("scapy.arch.linux.ioctl")
def test_read_routes(mock_ioctl):
def raise_ioerror(*args, **kwargs):
if args[1] == 0x8912:
return args[2]
raise IOError
mock_ioctl.side_effect = raise_ioerror
read_routes()
test_read_routes()
= L3PacketSocket sendto exception
~ linux needs_root
if six.PY3:
import mock, six, socket
@mock.patch("scapy.arch.linux.socket.socket.sendto")
def test_L3PacketSocket_sendto_python3(mock_sendto):
mock_sendto.side_effect = OSError(22, 2807)
l3ps = L3PacketSocket()
l3ps.send(IP(dst="8.8.8.8")/ICMP())
return True
assert test_L3PacketSocket_sendto_python3()
= Test _interface_selection
~ netaccess linux needs_root
import os
from scapy.sendrecv import _interface_selection
assert _interface_selection(None, IP(dst="8.8.8.8")/UDP()) == conf.iface
exit_status = os.system("ip link add name scapy0 type dummy")
exit_status = os.system("ip addr add 192.0.2.1/24 dev scapy0")
exit_status = os.system("ip link set scapy0 up")
assert _interface_selection(None, IP(dst="192.0.2.42")/UDP()) == "scapy0"
exit_status = os.system("ip link del name dev scapy0")
= Test 802.Q sniffing
~ linux needs_root python3_only
from threading import Thread, Condition
veth = VEthPair("left0", "right0")
veth.setup()
veth.up()
exit_status = os.system("ip link add link right0 name vlanright0 type vlan id 42")
exit_status = os.system("ip link add link left0 name vlanleft0 type vlan id 42")
exit_status = os.system("ip link set vlanright0 up")
exit_status = os.system("ip link set vlanleft0 up")
exit_status = os.system("ip addr add 198.51.100.1/24 dev vlanleft0")
exit_status = os.system("ip addr add 198.51.100.2/24 dev vlanright0")
cond_started = Condition()
def _sniffer_started():
global cond_started
cond_started.acquire()
cond_started.notify()
cond_started.release()
cond_started.acquire()
dot1q_count = 0
def _sniffer():
sniffed = sniff(iface="right0",
lfilter=lambda p: Dot1Q in p,
count=2,
timeout=5,
started_callback=_sniffer_started)
global dot1q_count
dot1q_count = len(sniffed)
t_sniffer = Thread(target=_sniffer)
t_sniffer.start()
cond_started.wait()
sendp(Ether()/IP(dst="198.51.100.2")/ICMP(), iface='vlanleft0', count=2)
t_sniffer.join(1)
assert(dot1q_count == 2)
veth.destroy()
= Reload interfaces & routes
conf.ifaces.reload()
conf.route.resync()
conf.route6.resync()