% Regression tests for Scapy

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

############
############
+ Information on Scapy

= Get conf
~ conf command
* Dump the current configuration
conf

IP().src
scapy.consts.LOOPBACK_INTERFACE

= Test module version detection
~ conf

class FakeModule(object):
    __version__ = "v1.12"

class FakeModule2(object):
    __version__ = "5.143.3.12"

from scapy.config import _version_checker

assert _version_checker(FakeModule, (1,11,5))
assert not _version_checker(FakeModule, (1,13))

assert _version_checker(FakeModule2, (5, 1))
assert not _version_checker(FakeModule2, (5, 143, 4))

= List layers
~ conf command
ls()

= List layers - advanced
~ conf command

with ContextManagerCaptureOutput() as cmco:
    ls("IP", case_sensitive=True)
    result_ls = cmco.get_output().split("\n")

assert all("IP" in x for x in result_ls if x.strip())
assert len(result_ls) >= 3

= List commands
~ conf command
lsc()

= List contribs
~ command
def test_list_contrib():
    with ContextManagerCaptureOutput() as cmco:
        list_contrib()
        result_list_contrib = cmco.get_output()
    assert("http2               : HTTP/2 (RFC 7540, RFC 7541)              status=loads" in result_list_contrib)
    assert(len(result_list_contrib.split('\n')) > 40)

test_list_contrib()

= Configuration
~ conf
conf.debug_dissector = True


###########
###########
= UTscapy route check
* Check that UTscapy has correctly replaced the routes. Many tests won't work otherwise

p = IP().src
p
assert p == "127.0.0.1"

############
############
+ Scapy functions tests

= Interface related functions

conf.iface

get_if_raw_hwaddr(conf.iface)

bytes_hex(get_if_raw_addr(conf.iface))

def get_dummy_interface():
    """Returns a dummy network interface"""
    if WINDOWS:
        data = {}
        data["name"] = "dummy0"
        data["description"] = "Does not exist"
        data["win_index"] = -1
        data["guid"] = "{1XX00000-X000-0X0X-X00X-00XXXX000XXX}"
        data["invalid"] = True
        dummy_int = NetworkInterface(data)
        dummy_int.pcap_name = "\\Device\\NPF_" + data["guid"]
        conf.cache_ipaddrs[dummy_int.pcap_name] = b'\x7f\x00\x00\x01'
        return dummy_int
    else:
        return "dummy0"

get_if_raw_addr(get_dummy_interface())

get_if_list()

get_if_raw_addr6(conf.iface6)

= Test read_routes6() - default output

routes6 = read_routes6()
if WINDOWS:
    route_add_loopback(routes6, True)

routes6

# Expected results:
# - one route if there is only the loopback interface
# - three routes if there is a network interface

if routes6:
    iflist = get_if_list()
    if WINDOWS:
        route_add_loopback(ipv6=True, iflist=iflist)
    if iflist == [LOOPBACK_NAME]:
        len(routes6) == 1
    elif len(iflist) >= 2:
        len(routes6) >= 3
    else:
        False
else:
    # IPv6 seems disabled. Force a route to ::1
    conf.route6.routes.append(("::1", 128, "::", LOOPBACK_NAME, ["::1"], 1))
    True

= Test read_routes6() - check mandatory routes

if len(routes6):
    assert(len([r for r in routes6 if r[0] == "::1" and r[4] == ["::1"]]) >= 1)
    if len(iflist) >= 2:
        assert len([r for r in routes6 if r[0] == "fe80::" and r[1] == 64]) >= 1
        try:
            assert len([r for r in routes6 if in6_islladdr(r[0]) and r[1] == 128 and r[4] == ["::1"]]) >= 1
        except:
            # IPv6 is not available, but we still check the loopback
            assert conf.route6.route("::/0") == (scapy.consts.LOOPBACK_NAME, "::", "::")
            assert len([r for r in routes6 if r[1] == 128 and r[4] == ["::1"]]) >= 1
else:
    True

= Test ifchange()
conf.route6.ifchange(LOOPBACK_NAME, "::1/128")
if WINDOWS:
    conf.netcache.in6_neighbor["::1"] = "ff:ff:ff:ff:ff:ff"  # Restore fake cache

True


############
############
+ Main.py tests

= Pickle and unpickle a packet

import scapy.modules.six as six

a = IP(dst="192.168.0.1")/UDP()

b = six.moves.cPickle.dumps(a)
c = six.moves.cPickle.loads(b)

assert c[IP].dst == "192.168.0.1"
assert raw(c) == raw(a)

= Usage test

from scapy.main import _usage
try:
    _usage()
    assert False
except SystemExit:
    assert True

= Session test

# This is automatic when using the console
def get_var(var):
    return six.moves.builtins.__dict__["scapy_session"][var]

def set_var(var, value):
    six.moves.builtins.__dict__["scapy_session"][var] = value

def del_var(var):
    del(six.moves.builtins.__dict__["scapy_session"][var])

init_session(None, {"init_value": 123})
set_var("test_value", "8.8.8.8") # test_value = "8.8.8.8"
save_session()
del_var("test_value")
load_session()
update_session()
assert get_var("test_value") == "8.8.8.8" #test_value == "8.8.8.8"
assert get_var("init_value") == 123
 
= Session test with fname

session_name = tempfile.mktemp()
init_session(session_name)
set_var("test_value", IP(dst="192.168.0.1")) # test_value = IP(dst="192.168.0.1")
save_session(fname="%s.dat" % session_name)
del_var("test_value")

set_var("z", True) #z = True
load_session(fname="%s.dat" % session_name)
try:
    get_var("z")
    assert False
except:
    pass

set_var("z", False) #z = False
update_session(fname="%s.dat" % session_name)
assert get_var("test_value").dst == "192.168.0.1" #test_value.dst == "192.168.0.1"
assert not get_var("z")

= Clear session files

os.remove("%s.dat" % session_name)

= Test temporary file creation
~ appveyor_only

scapy_delete_temp_files()

tmpfile = get_temp_file(autoext=".ut")
tmpfile
if WINDOWS:
    assert("scapy" in tmpfile and tmpfile.lower().startswith('c:\\users\\appveyor\\appdata\\local\\temp'))
else:
    import platform
    BYPASS_TMP = platform.python_implementation().lower() == "pypy" or DARWIN
    assert("scapy" in tmpfile and (BYPASS_TMP == True or "/tmp/" in tmpfile))

assert(conf.temp_files[0].endswith(".ut"))
scapy_delete_temp_files()
assert(len(conf.temp_files) == 0)

= Emulate interact()
import mock, sys
from scapy.main import interact
# Detect IPython
try:
    import IPython
except:
    code_interact_import = "scapy.main.code.interact"
else:
    code_interact_import = "IPython.start_ipython"

@mock.patch(code_interact_import)
def interact_emulator(code_int, extra_args=[]):
    try:
        code_int.side_effect = lambda *args, **kwargs: lambda *args, **kwargs: None
        interact(argv=["-s scapy1"] + extra_args, mybanner="What a test")
        return True
    except:
        return False
    finally:
        sys.ps1 = ">>> "

assert interact_emulator()  # Default
assert not interact_emulator(extra_args=["-?"])  # Failing
assert interact_emulator(extra_args=["-d"])  # Extended

= Test explore() with GUI mode
~ command

import mock
from scapy.tools.UTscapy import Bunch

def test_explore_gui(is_layer, layer):
    prompt_toolkit_mocked_module = Bunch(
                                       shortcuts=Bunch(
                                           dialogs=Bunch(
                                               radiolist_dialog=(lambda *args, **kargs: layer),
                                               yes_no_dialog=(lambda *args, **kargs: is_layer)
                                           )
                                       ),
                                       formatted_text=Bunch(HTML=lambda x: x),
                                       __version__="2.0.0"
                                   )
    # a mock.patch isn't enough to mock a module. Let's roll sys.modules
    modules_patched = {
        "prompt_toolkit": prompt_toolkit_mocked_module,
        "prompt_toolkit.shortcuts": prompt_toolkit_mocked_module.shortcuts,
        "prompt_toolkit.shortcuts.dialogs": prompt_toolkit_mocked_module.shortcuts.dialogs,
        "prompt_toolkit.formatted_text": prompt_toolkit_mocked_module.formatted_text,
    }
    with mock.patch.dict("sys.modules", modules_patched):
        with ContextManagerCaptureOutput() as cmco:
            explore()
            result_explore = cmco.get_output()
        return result_explore

explore_dns = test_explore_gui(True, "scapy.layers.dns")
assert "DNS" in explore_dns
assert "DNS Question Record" in explore_dns
assert "DNSRRNSEC3" in explore_dns
assert "DNS TSIG Resource Record" in explore_dns

explore_avs = test_explore_gui(False, "avs")
assert "AVSWLANHeader" in explore_avs
assert "AVS WLAN Monitor Header" in explore_avs

= Test explore() with non-GUI mode
~ command

def test_explore_non_gui(layer):
    with ContextManagerCaptureOutput() as cmco:
        explore(layer)
        result_explore = cmco.get_output()
    return result_explore

explore_dns = test_explore_non_gui("scapy.layers.dns")
assert "DNS" in explore_dns
assert "DNS Question Record" in explore_dns
assert "DNSRRNSEC3" in explore_dns
assert "DNS TSIG Resource Record" in explore_dns

explore_avs = test_explore_non_gui("avs")
assert "AVSWLANHeader" in explore_avs
assert "AVS WLAN Monitor Header" in explore_avs

assert test_explore_non_gui("scapy.layers.dns") == test_explore_non_gui("dns")
assert test_explore_non_gui("scapy.contrib.avs") == test_explore_non_gui("avs")

try:
    explore("unknown_module")
    assert False  # The previous should have raised an exception
except Scapy_Exception:
    pass

= Test load_contrib overwrite
load_contrib("gtp")
assert GTPHeader.__module__ == "scapy.contrib.gtp"

load_contrib("gtp_v2")
assert GTPHeader.__module__ == "scapy.contrib.gtp_v2"

load_contrib("gtp")
assert GTPHeader.__module__ == "scapy.contrib.gtp"

= Test sane function
sane("A\x00\xFFB") == "A..B"

= Test lhex function
assert(lhex(42) == "0x2a")
assert(lhex((28,7)) == "(0x1c, 0x7)")
assert(lhex([28,7]) == "[0x1c, 0x7]")

= Test restart function
import mock
conf.interactive = True

try:
    from scapy.utils import restart
    import os
    @mock.patch("os.execv")
    @mock.patch("subprocess.call")
    @mock.patch("os._exit")
    def _test(e, m, m2):
        def check(x, y=[]):
            z = [x] + y if not isinstance(x, list) else x + y
            assert os.path.isfile(z[0])
            assert os.path.isfile(z[1])
            return 0
        m2.side_effect = check
        m.side_effect = check
        e.side_effect = lambda x: None
        restart()
    _test()
finally:
    conf.interactive = False

= Test linehexdump function
conf_color_theme = conf.color_theme
conf.color_theme = BlackAndWhite()
assert linehexdump(Ether(src="00:01:02:03:04:05"), dump=True) == 'FF FF FF FF FF FF 00 01 02 03 04 05 90 00  ..............'
conf.color_theme = conf_color_theme

= Test chexdump function
chexdump(Ether(src="00:01:02:02:04:05"), dump=True) == "0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x00, 0x01, 0x02, 0x02, 0x04, 0x05, 0x90, 0x00"

= Test repr_hex function
repr_hex("scapy") == "7363617079"

= Test hexstr function
hexstr(b"A\x00\xFFB") == "41 00 FF 42  A..B"

= Test fletcher16 functions
assert(fletcher16_checksum(b"\x28\x07") == 22319)
assert(fletcher16_checkbytes(b"\x28\x07", 1) == b"\xaf(")

= Test hexdiff function
~ not_pypy
def test_hexdiff():
    conf_color_theme = conf.color_theme
    conf.color_theme = BlackAndWhite()
    with ContextManagerCaptureOutput() as cmco:
        hexdiff("abcde", "abCde")
        result_hexdiff = cmco.get_output()
    conf.interactive = True
    conf.color_theme = conf_color_theme
    expected  = "0000        61 62 63 64 65                                     abcde\n"
    expected += "     0000   61 62 43 64 65                                     abCde\n"
    assert(result_hexdiff == expected)

test_hexdiff()

= Test mysummary functions - Ether

p = Ether(dst="ff:ff:ff:ff:ff:ff", src="ff:ff:ff:ff:ff:ff", type=0x9000)
p
assert p.mysummary() in ['ff:ff:ff:ff:ff:ff > ff:ff:ff:ff:ff:ff (%s)' % loop
                         for loop in ['0x9000', 'LOOP']]

= Test zerofree_randstring function
random.seed(0x2807)
zerofree_randstring(4) in [b"\xd2\x12\xe4\x5b", b'\xd3\x8b\x13\x12']

= Test export_object and import_object functions
import mock
def test_export_import_object():
    with ContextManagerCaptureOutput() as cmco:
        export_object(2807)
        result_export_object = cmco.get_output(eval_bytes=True)
    assert(result_export_object.startswith("eNprYPL9zqUHAAdrAf8="))
    assert(import_object(result_export_object) == 2807)

test_export_import_object()

= Test tex_escape function
tex_escape("$#_") == "\\$\\#\\_"

= Test colgen function
f = colgen(range(3))
assert(len([next(f) for i in range(2)]) == 2)

= Test incremental_label function
f = incremental_label()
assert([next(f) for i in range(2)] == ["tag00000", "tag00001"])

= Test corrupt_* functions
import random
random.seed(0x2807)
assert(corrupt_bytes("ABCDE") in [b"ABCDW", b"ABCDX"])
assert(sane(corrupt_bytes("ABCDE", n=3)) in ["A.8D4", ".2.DE"])

assert(corrupt_bits("ABCDE") in [b"EBCDE", b"ABCDG"])
assert(sane(corrupt_bits("ABCDE", n=3)) in ["AF.EE", "QB.TE"])

= Test save_object and load_object functions
import tempfile
fd, fname = tempfile.mkstemp()
save_object(fname, 2807)
assert(load_object(fname) == 2807)

= Test whois function
if not WINDOWS:
    result = whois("193.0.6.139")
    assert(b"inetnum" in result and b"Amsterdam" in result)

= Test manuf DB methods
~ manufdb
assert(conf.manufdb._resolve_MAC("00:00:0F:01:02:03") == "Next:01:02:03")
assert(conf.manufdb._get_short_manuf("00:00:0F:01:02:03") == "Next")
assert(in6_addrtovendor("fe80::0200:0fff:fe01:0203").lower().startswith("next"))

= Test utility functions - network related
~ netaccess

atol("www.secdev.org") == 3642339845

= Test autorun functions

ret = autorun_get_text_interactive_session("IP().src")
assert(ret == (">>> IP().src\n'127.0.0.1'\n", '127.0.0.1'))

ret = autorun_get_html_interactive_session("IP().src")
assert(ret == ("<span class=prompt>&gt;&gt;&gt; </span>IP().src\n'127.0.0.1'\n", '127.0.0.1'))

ret = autorun_get_latex_interactive_session("IP().src")
assert(ret == ("\\textcolor{blue}{{\\tt\\char62}{\\tt\\char62}{\\tt\\char62} }IP().src\n'127.0.0.1'\n", '127.0.0.1'))

= Test utility TEX functions

assert tex_escape("{scapy}\\^$~#_&%|><") == "{\\tt\\char123}scapy{\\tt\\char125}{\\tt\\char92}\\^{}\\${\\tt\\char126}\\#\\_\\&\\%{\\tt\\char124}{\\tt\\char62}{\\tt\\char60}"

a = colgen(1, 2, 3)
assert next(a) == (1, 2, 2)
assert next(a) == (1, 3, 3)
assert next(a) == (2, 2, 1)
assert next(a) == (2, 3, 2)
assert next(a) == (2, 1, 3)
assert next(a) == (3, 3, 1)
assert next(a) == (3, 1, 2)
assert next(a) == (3, 2, 3)

= Test config file functions

saved_conf_verb = conf.verb
fd, fname = tempfile.mkstemp()
os.write(fd, b"conf.verb = 42\n")
os.close(fd)
from scapy.main import _read_config_file
_read_config_file(fname, globals(), locals())
assert(conf.verb == 42)
conf.verb = saved_conf_verb

= Test CacheInstance repr

conf.netcache


############
############
+ Basic tests

* Those test are here mainly to check nothing has been broken
* and to catch Exceptions

= Packet class methods
p = IP()/ICMP()
ret = p.do_build_ps()                                                                                                                             
assert(ret[0] == b"@\x00\x00\x00\x00\x01\x00\x00@\x01\x00\x00\x7f\x00\x00\x01\x7f\x00\x00\x01\x08\x00\x00\x00\x00\x00\x00\x00")
assert(len(ret[1]) == 2)

assert(p[ICMP].firstlayer() == p)

assert(p.command() == "IP()/ICMP()")

p.decode_payload_as(UDP)
assert(p.sport == 2048 and p.dport == 63487)

= hide_defaults
conf_color_theme = conf.color_theme
conf.color_theme = BlackAndWhite()
p = IP(ttl=64)/ICMP()
assert(repr(p) in ["<IP  frag=0 ttl=64 proto=icmp |<ICMP  |>>", "<IP  frag=0 ttl=64 proto=1 |<ICMP  |>>"])
p.hide_defaults()
assert(repr(p) in ["<IP  frag=0 proto=icmp |<ICMP  |>>", "<IP  frag=0 proto=1 |<ICMP  |>>"])
conf.color_theme = conf_color_theme

= split_layers
p = IP()/ICMP()
s = raw(p)
split_layers(IP, ICMP, proto=1)
assert(Raw in IP(s))
bind_layers(IP, ICMP, frag=0, proto=1)

= fuzz
~ not_pypy random_weird_py3
random.seed(0x2807)
r = raw(fuzz(IP()/ICMP()))
r
assert r in [
    b'u\x14\x00\x1c\xc2\xf6\x80\x00\xde\x01k\xd3\x7f\x00\x00\x01\x7f\x00\x00\x01y\xc9>\xa6\x84\xd8\xc2\xb7',
    b'E\xa7\x00\x1c\xb0c\xc0\x00\xf6\x01U\xd3\x7f\x00\x00\x01\x7f\x00\x00\x01\xfex\xb3\x92B<\x0b\xb8',
]

= fuzz on packets with advanced RandNum

x = IP(dst="8.8.8.8")/fuzz(UDP()/NTP(version=4))
x.show2()
x = IP(raw(x))
assert NTP in x

= fuzz on packets with FlagsField
assert isinstance(fuzz(TCP()).flags, VolatileValue)

= Building some packets
~ basic IP TCP UDP NTP LLC SNAP Dot11
IP()/TCP()
Ether()/IP()/UDP()/NTP()
Dot11()/LLC()/SNAP()/IP()/TCP()/"XXX"
IP(ttl=25)/TCP(sport=12, dport=42)
IP().summary()

= Manipulating some packets
~ basic IP TCP
a=IP(ttl=4)/TCP()
a.ttl
a.ttl=10
del(a.ttl)
a.ttl
TCP in a
a[TCP]
a[TCP].dport=[80,443]
a
assert(a.copy().time == a.time)
a=3


= Checking overloads
~ basic IP TCP Ether
a=Ether()/IP()/TCP()
r = a.proto
r
r == 6


= sprintf() function
~ basic sprintf Ether IP UDP NTP
a=Ether()/IP()/IP(ttl=4)/UDP()/NTP()
r = a.sprintf("%type% %IP.ttl% %#05xr,UDP.sport% %IP:2.ttl%")
r
r in ['0x800 64 0x07b 4', 'IPv4 64 0x07b 4']


= sprintf() function 
~ basic sprintf IP TCP SNAP LLC Dot11
* This test is on the conditionnal substring feature of <tt>sprintf()</tt>
a=Dot11()/LLC()/SNAP()/IP()/TCP()
r = a.sprintf("{IP:{TCP:flags=%TCP.flags%}{UDP:port=%UDP.ports%} %IP.src%}")
r
r == 'flags=S 127.0.0.1'


= haslayer function
~ basic haslayer IP TCP ICMP ISAKMP
x=IP(id=1)/ISAKMP_payload_SA(prop=ISAKMP_payload_SA(prop=IP()/ICMP()))/TCP()
r = (TCP in x, ICMP in x, IP in x, UDP in x)
r
r == (True,True,True,False)

= getlayer function
~ basic getlayer IP ISAKMP UDP
x=IP(id=1)/ISAKMP_payload_SA(prop=IP(id=2)/UDP(dport=1))/IP(id=3)/UDP(dport=2)
x[IP]
x[IP:2]
x[IP:3]
x.getlayer(IP,3)
x.getlayer(IP,4)
x[UDP]
x[UDP:1]
x[UDP:2]
assert(x[IP].id == 1 and x[IP:2].id == 2 and x[IP:3].id == 3 and 
       x.getlayer(IP).id == 1 and x.getlayer(IP,3).id == 3 and
       x.getlayer(IP,4) == None and
       x[UDP].dport == 1 and x[UDP:2].dport == 2)
try:
    x[IP:4]
except IndexError:
    True
else:
    False

= getlayer / haslayer with name
~ basic getlayer IP ICMP IPerror TCPerror
x = IP() / ICMP() / IPerror()
assert x.getlayer(ICMP) is not None
assert x.getlayer(IPerror) is not None
assert x.getlayer("IP in ICMP") is not None
assert x.getlayer(TCPerror) is None
assert x.getlayer("TCP in ICMP") is None
assert x.haslayer(ICMP)
assert x.haslayer(IPerror)
assert x.haslayer("IP in ICMP")
assert not x.haslayer(TCPerror)
assert not x.haslayer("TCP in ICMP")

= getlayer with a filter
~ getlayer IP
pkt = IP() / IP(ttl=3) / IP()
assert pkt[IP::{"ttl":3}].ttl == 3
assert pkt.getlayer(IP, ttl=3).ttl == 3
assert IPv6ExtHdrHopByHop(options=[HBHOptUnknown()]).getlayer(HBHOptUnknown, otype=42) is None

= specific haslayer and getlayer implementations for NTP
~ haslayer getlayer NTP
pkt = IP() / UDP() / NTPHeader()
assert NTP in pkt
assert pkt.haslayer(NTP)
assert isinstance(pkt[NTP], NTPHeader)
assert isinstance(pkt.getlayer(NTP), NTPHeader)

= specific haslayer and getlayer implementations for EAP
~ haslayer getlayer EAP
pkt = Ether() / EAPOL() / EAP_MD5()
assert EAP in pkt
assert pkt.haslayer(EAP)
assert isinstance(pkt[EAP], EAP_MD5)
assert isinstance(pkt.getlayer(EAP), EAP_MD5)

= specific haslayer and getlayer implementations for RadiusAttribute
~ haslayer getlayer RadiusAttribute
pkt = RadiusAttr_EAP_Message()
assert RadiusAttribute in pkt
assert pkt.haslayer(RadiusAttribute)
assert isinstance(pkt[RadiusAttribute], RadiusAttr_EAP_Message)
assert isinstance(pkt.getlayer(RadiusAttribute), RadiusAttr_EAP_Message)


= equality
~ basic
w=Ether()/IP()/UDP(dport=53)
x=Ether()/IP(version=4)/UDP()
y=Ether()/IP()/UDP(dport=4)
z=Ether()/IP()/UDP()/NTP()
t=Ether()/IP()/TCP()
assert x != y and x != z and x != t and y != z and y != t and z != t and w == x

= answers
~ basic
a1, a2 = "1.2.3.4", "5.6.7.8"
p1 = IP(src=a1, dst=a2)/ICMP(type=8)
p2 = IP(src=a2, dst=a1)/ICMP(type=0)
assert p1.hashret() == p2.hashret()
assert not p1.answers(p2)
assert p2.answers(p1)
assert p1 > p2
assert p2 < p1
assert p1 == p1
conf_back = conf.checkIPinIP
conf.checkIPinIP = True
px = [IP()/p1, IPv6()/p1]
assert not any(p.hashret() == p2.hashret() for p in px)
assert not any(p.answers(p2) for p in px)
assert not any(p2.answers(p) for p in px)
conf.checkIPinIP = False
assert all(p.hashret() == p2.hashret() for p in px)
assert not any(p.answers(p2) for p in px)
assert all(p2.answers(p) for p in px)
conf.checkIPinIP = conf_back

a1, a2 = Net("www.google.com"), Net("www.secdev.org")
prt1, prt2 = 12345, 54321
s1, s2 = 2767216324, 3845532842
p1 = IP(src=a1, dst=a2)/TCP(flags='SA', seq=s1, ack=s2, sport=prt1, dport=prt2)
p2 = IP(src=a2, dst=a1)/TCP(flags='R', seq=s2, ack=0, sport=prt2, dport=prt1)
assert p2.answers(p1)
assert not p1.answers(p2)
# Not available yet because of IPv6
# a1, a2 = Net6("www.google.com"), Net6("www.secdev.org")
p1 = IP(src=a1, dst=a2)/TCP(flags='S', seq=s1, ack=0, sport=prt1, dport=prt2)
p2 = IP(src=a2, dst=a1)/TCP(flags='RA', seq=0, ack=s1+1, sport=prt2, dport=prt1)
assert p2.answers(p1)
assert not p1.answers(p2)
p1 = IP(src=a1, dst=a2)/TCP(flags='S', seq=s1, ack=0, sport=prt1, dport=prt2)
p2 = IP(src=a2, dst=a1)/TCP(flags='SA', seq=s2, ack=s1+1, sport=prt2, dport=prt1)
assert p2.answers(p1)
assert not p1.answers(p2)
p1 = IP(src=a1, dst=a2)/TCP(flags='A', seq=s1, ack=s2+1, sport=prt1, dport=prt2)
assert not p2.answers(p1)
assert p1.answers(p2)
p1 = IP(src=a1, dst=a2)/TCP(flags='S', seq=s1, ack=0, sport=prt1, dport=prt2)
p2 = IP(src=a2, dst=a1)/TCP(flags='SA', seq=s2, ack=s1+10, sport=prt2, dport=prt1)
assert not p2.answers(p1)
assert not p1.answers(p2)
p1 = IP(src=a1, dst=a2)/TCP(flags='A', seq=s1, ack=s2+1, sport=prt1, dport=prt2)
assert not p2.answers(p1)
assert not p1.answers(p2)
p1 = IP(src=a1, dst=a2)/TCP(flags='A', seq=s1+9, ack=s2+10, sport=prt1, dport=prt2)
assert not p2.answers(p1)
assert not p1.answers(p2)


############
############
+ Tests on padding

= Padding assembly
r = raw(Padding("abc"))
r
assert(r == b"abc" )
r = raw(Padding("abc")/Padding("def"))
r
assert(r == b"abcdef" )
r = raw(Raw("ABC")/Padding("abc")/Padding("def"))
r
assert(r == b"ABCabcdef" )
r = raw(Raw("ABC")/Padding("abc")/Raw("DEF")/Padding("def"))
r
assert(r == b"ABCDEFabcdef")

= Padding and length computation
p = IP(raw(IP()/Padding("abc")))
p
assert(p.len == 20 and len(p) == 23)
p = IP(raw(IP()/Raw("ABC")/Padding("abc")))
p
assert(p.len == 23 and len(p) == 26)
p = IP(raw(IP()/Raw("ABC")/Padding("abc")/Padding("def")))
p
assert(p.len == 23 and len(p) == 29)

= PadField test
~ PadField padding

class TestPad(Packet):
    fields_desc = [ PadField(StrNullField("st", b""),4), StrField("id", b"")]

TestPad() == TestPad(raw(TestPad()))

= ReversePadField
~ PadField padding

class TestReversePad(Packet):
    fields_desc = [ ByteField("a", 0),
                    ReversePadField(IntField("b", 0), 4)]

assert raw(TestReversePad(a=1, b=0xffffffff)) == b'\x01\x00\x00\x00\xff\xff\xff\xff'
assert TestReversePad(raw(TestReversePad(a=1, b=0xffffffff))).b == 0xffffffff

############
############
+ Tests on default value changes mechanism

= Creation of an IPv3 class from IP class with different default values
class IPv3(IP):
    version = 3
    ttl = 32

= Test of IPv3 class
a = IPv3()
v,t = a.version, a.ttl
v,t
assert((v,t) == (3,32))
r = raw(a)
r
assert(r == b'5\x00\x00\x14\x00\x01\x00\x00 \x00\xac\xe7\x7f\x00\x00\x01\x7f\x00\x00\x01')


############
############
+ ISAKMP transforms test

= ISAKMP creation
~ IP UDP ISAKMP 
p=IP(src='192.168.8.14',dst='10.0.0.1')/UDP()/ISAKMP()/ISAKMP_payload_SA(prop=ISAKMP_payload_Proposal(trans=ISAKMP_payload_Transform(transforms=[('Encryption', 'AES-CBC'), ('Hash', 'MD5'), ('Authentication', 'PSK'), ('GroupDesc', '1536MODPgr'), ('KeyLength', 256), ('LifeType', 'Seconds'), ('LifeDuration', 86400)])/ISAKMP_payload_Transform(res2=12345,transforms=[('Encryption', '3DES-CBC'), ('Hash', 'SHA'), ('Authentication', 'PSK'), ('GroupDesc', '1024MODPgr'), ('LifeType', 'Seconds'), ('LifeDuration', 86400)])))
p.show()
p


= ISAKMP manipulation
~ ISAKMP
r = p[ISAKMP_payload_Transform:2]
r
r.res2 == 12345

= ISAKMP assembly
~ ISAKMP 
hexdump(p)
raw(p) == b"E\x00\x00\x96\x00\x01\x00\x00@\x11\xa7\x9f\xc0\xa8\x08\x0e\n\x00\x00\x01\x01\xf4\x01\xf4\x00\x82\xbf\x1e\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01\x10\x00\x00\x00\x00\x00\x00\x00\x00\x00z\x00\x00\x00^\x00\x00\x00\x01\x00\x00\x00\x01\x00\x00\x00R\x01\x01\x00\x00\x03\x00\x00'\x00\x01\x00\x00\x80\x01\x00\x07\x80\x02\x00\x01\x80\x03\x00\x01\x80\x04\x00\x05\x80\x0e\x01\x00\x80\x0b\x00\x01\x00\x0c\x00\x03\x01Q\x80\x00\x00\x00#\x00\x0109\x80\x01\x00\x05\x80\x02\x00\x02\x80\x03\x00\x01\x80\x04\x00\x02\x80\x0b\x00\x01\x00\x0c\x00\x03\x01Q\x80"


= ISAKMP disassembly
~ ISAKMP
q=IP(raw(p))
q.show()
r = q[ISAKMP_payload_Transform:2]
r
r.res2 == 12345


############
############
+ TFTP tests

= TFTP Options
x=IP()/UDP(sport=12345)/TFTP()/TFTP_RRQ(filename="fname")/TFTP_Options(options=[TFTP_Option(oname="blksize", value="8192"),TFTP_Option(oname="other", value="othervalue")])
assert( raw(x) == b'E\x00\x00H\x00\x01\x00\x00@\x11|\xa2\x7f\x00\x00\x01\x7f\x00\x00\x0109\x00E\x004B6\x00\x01fname\x00octet\x00blksize\x008192\x00other\x00othervalue\x00' )
y=IP(raw(x))
y[TFTP_Option].oname
y[TFTP_Option:2].oname
assert(len(y[TFTP_Options].options) == 2 and y[TFTP_Option].oname == b"blksize")


############
############
+ Dot11 tests


= WEP tests
~ wifi crypto Dot11 LLC SNAP IP TCP
conf.wepkey = "Fobar"
r = raw(Dot11WEP()/LLC()/SNAP()/IP()/TCP(seq=12345678))
r
assert(r == b'\x00\x00\x00\x00\xe3OjYLw\xc3x_%\xd0\xcf\xdeu-\xc3pH#\x1eK\xae\xf5\xde\xe7\xb8\x1d,\xa1\xfe\xe83\xca\xe1\xfe\xbd\xfe\xec\x00)T`\xde.\x93Td\x95C\x0f\x07\xdd')
p = Dot11WEP(r)
p
assert(TCP in p and p[TCP].seq == 12345678)

= RadioTap - dissection & build
data = b'\x00\x008\x00k\x084\x00oo\x0f\x98\x00\x00\x00\x00\x10\x00\x99\x16@\x01\xc5\xa1\x01\x00\x00\x00@\x01\x02\x00\x99\x16\x9d"\x05\x0b\x00\x00\x00\x00\x00\x00\xff\x01\x16\x01\x82\x00\x00\x00\x01\x00\x00\x00\x88\x020\x00\xb8\xe8VB_\xb2\x82*\xa8Uq\x15\xf0\x9f\xc2\x11\x16dP\xb0\x00\x00\xaa\xaa\x03\x00\x00\x00\x08\x00E\x00\x00GC\xad@\x007\x11\x97;\xd0C\xde{\xac\x10\r\xee\x005\xed\xec\x003\xd5/\xfc\\\x81\x80\x00\x01\x00\x01\x00\x00\x00\x00\tlocalhost\x00\x00\x01\x00\x01\xc0\x0c\x00\x01\x00\x01\x00\t:\x80\x00\x04\x7f\x00\x00\x01\xcdj\x88]'
r = RadioTap(data)
r = RadioTap(raw(r))
assert r.dBm_AntSignal == -59
assert r.ChannelFrequency == 5785
assert r.present == 3410027
assert r.A_MPDU_ref == 2821
assert r.KnownVHT == 511
assert r.PresentVHT == 22
assert r.notdecoded == b''

= RadioTap Big-Small endian dissection
data = b'\x00\x00\x1a\x00/H\x00\x00\xe1\xd3\xcb\x05\x00\x00\x00\x00@0x\x14@\x01\xac\x00\x00\x00'
r = RadioTap(data)
r.show()
assert r.present == 18479

= RadioTap - Dissection - guess_payload_class() test
data = b'\x00\x00\r\x00\x04\x80\x02\x00\x02\x00\x00\x00\x00@\x00\x00\x00\xff\xff\xff\xff\xff\xff\xe8\x94\xf6\x1c\xdf\x8b\xff\xff\xff\xff\xff\xff\xa0\x01\x00\x10ciscosb-wpa2-eap\x01\x08\x02\x04\x0b\x16\x0c\x12\x18$2\x040H`l\x03\x01\x01-\x1an\x11\x1b\xff\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00'
radiotap = RadioTap(data)
assert radiotap.present.Rate
assert radiotap.present.b16
assert radiotap.present.b18
assert radiotap.present == 163844
assert radiotap.guess_payload_class("")

= RadioTap - Dissection with Extended presence mask
data = b"\x00\x00 \x00\xae@\x00\xa0 \x08\x00\xa0 \x08\x00\x00\x10\x02\x9e\t\xa0\x00\xa2\x00d\x00\x00\x00\x00\x00\x00\x01\x80\x00\x00\x00\xff\xff\xff\xff\xff\xff\x94S0\xe8\x93\xb2\x94S0\xe8\x93\xb2\xf0u\x85\xe1H\x9c\x08\x00\x00\x00d\x00\x11\x14\x00\x08Why Fye?\x01\x08\x82\x84\x8b\x96$0Hl\x03\x01\x0b\x05\x04\x00\x01\x00\x00*\x01\x04/\x01\x040\x14\x01\x00\x00\x0f\xac\x04\x01\x00\x00\x0f\xac\x04\x01\x00\x00\x0f\xac\x02\x0c\x002\x04\x0c\x12\x18`\x0b\x05\x07\x00;\x00\x00-\x1a\xad\x19\x17\xff\xff\xff\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00=\x16\x0b\x08\x04\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x7f\x08\x04\x00\x08\x00\x00\x00\x00@\xdd1\x00P\xf2\x04\x10J\x00\x01\x10\x10D\x00\x01\x02\x10G\x00\x10\xef\xda]\xd2#\xe8\xa7\xf0\xb2/\xa4\x98\xbf\x0cv\xe7\x10<\x00\x01\x03\x10I\x00\x06\x007*\x00\x01 \xdd\t\x00\x10\x18\x02\x07\x00\x1c\x00\x00\xdd\x18\x00P\xf2\x02\x01\x01\x80\x00\x03\xa4\x00\x00'\xa4\x00\x00BC^\x00b2/\x00F\x05r\x08\x01\x00\x00\xdd\x1e\x00\x90L\x04\x08\xbf\x0c\xb2Y\x82\x0f\xea\xff\x00\x00\xea\xff\x00\x00\xc0\x05\x00\x0b\x00\x00\x00\xc3\x02\x00\x02\x08I\xc0\xdb"
radiotap = RadioTap(data)

assert radiotap.present.Ext
assert len(radiotap.Ext) == 2
assert radiotap.Ext[0].present.b5
assert radiotap.Ext[0].present.b11
assert radiotap.Ext[0].present.b29
assert radiotap.Ext[0].present.Ext
assert radiotap.Ext[1].present.b37
assert radiotap.Ext[1].present.b43
assert not radiotap.Ext[1].present.Ext

assert radiotap.present.Flags
assert radiotap.Flags.FCS
assert Dot11FCS in radiotap
assert radiotap.fcs == 0xdbc04908

assert Dot11EltRates in radiotap
assert radiotap[Dot11EltRates].rates == [0x82, 0x84, 0x8b, 0x96, 0x24, 0x30, 0x48, 0x6c]

= RadioTap - Build with Extended presence mask

a = RadioTapExtendedPresenceMask(present="b0+b12+b29+Ext")
b = RadioTapExtendedPresenceMask(index=1, present="b32+b45+b59+b62")
pkt = RadioTap(present="Ext", Ext=[a, b])
assert raw(pkt) == b'\x00\x00\x10\x00\x00\x00\x00\x80\x01\x10\x00\xa0\x01 \x00H'

= fuzz() calls for Dot11Elt()
for i in range(10):
    assert isinstance(raw(fuzz(Dot11Elt())), bytes)


############
############
+ SNMP tests

= SNMP assembling
~ SNMP ASN1
r = raw(SNMP())
r
assert(r == b'0\x18\x02\x01\x01\x04\x06public\xa0\x0b\x02\x01\x00\x02\x01\x00\x02\x01\x000\x00')
p = SNMP(version="v2c", community="ABC", PDU=SNMPbulk(id=4,varbindlist=[SNMPvarbind(oid="1.2.3.4",value=ASN1_INTEGER(7)),SNMPvarbind(oid="4.3.2.1.2.3",value=ASN1_IA5_STRING("testing123"))]))
p
r = raw(p)
r
assert(r == b'05\x02\x01\x01\x04\x03ABC\xa5+\x02\x01\x04\x02\x01\x00\x02\x01\x000 0\x08\x06\x03*\x03\x04\x02\x01\x070\x14\x06\x06\x81#\x02\x01\x02\x03\x16\ntesting123')

= SNMP disassembling
~ SNMP ASN1
x=SNMP(b'0y\x02\x01\x00\x04\x06public\xa2l\x02\x01)\x02\x01\x00\x02\x01\x000a0!\x06\x12+\x06\x01\x04\x01\x81}\x08@\x04\x02\x01\x07\n\x86\xde\xb78\x04\x0b172.31.19.20#\x06\x12+\x06\x01\x04\x01\x81}\x08@\x04\x02\x01\x07\n\x86\xde\xb76\x04\r255.255.255.00\x17\x06\x12+\x06\x01\x04\x01\x81}\x08@\x04\x02\x01\x05\n\x86\xde\xb9`\x02\x01\x01')
x.show()
assert(x.community==b"public" and x.version == 0)
assert(x.PDU.id == 41 and len(x.PDU.varbindlist) == 3)
assert(x.PDU.varbindlist[0].oid == "1.3.6.1.4.1.253.8.64.4.2.1.7.10.14130104")
assert(x.PDU.varbindlist[0].value == b"172.31.19.2")
assert(x.PDU.varbindlist[2].oid == "1.3.6.1.4.1.253.8.64.4.2.1.5.10.14130400")
assert(x.PDU.varbindlist[2].value == 1)

= Basic UDP/SNMP bindings
~ SNMP ASN1
z = UDP()/x
z = UDP(raw(z))
assert SNMP in z

x = UDP()/SNMP()
assert x.sport == x.dport == 161

= ASN1 - ASN1_Object
assert ASN1_Object(1) == ASN1_Object(1)
assert ASN1_Object(1) > ASN1_Object(0)
assert ASN1_Object(1) >= ASN1_Object(1)
assert ASN1_Object(0) < ASN1_Object(1)
assert ASN1_Object(1) <= ASN1_Object(2)
assert ASN1_Object(1) != ASN1_Object(2)
ASN1_Object(2).show()

= ASN1 - RandASN1Object
~ random_weird_py3
a = RandASN1Object()
random.seed(0x2807)
assert raw(a) in [b'A\x02\x07q', b'C\x02\xfe\x92', b'\x1e\x023V']

= ASN1 - ASN1_BIT_STRING
a = ASN1_BIT_STRING("test", "value")
a
assert raw(a) == b'test'

a = ASN1_BIT_STRING(b"\xff"*16, "value")
a
assert raw(a) == b'\xff'*16

= ASN1 - ASN1_SEQUENCE
a = ASN1_SEQUENCE([ASN1_Object(1), ASN1_Object(0)])
assert a.strshow() == '# ASN1_SEQUENCE:\n  <ASN1_Object[1]>\n  <ASN1_Object[0]>\n'

= ASN1 - ASN1_DECODING_ERROR
a = ASN1_DECODING_ERROR("error", exc=OSError(1))
assert repr(a) == "<ASN1_DECODING_ERROR['error']{{1}}>"
b = ASN1_DECODING_ERROR("error", exc=OSError(ASN1_BIT_STRING("0")))
assert repr(b) == "<ASN1_DECODING_ERROR['error']{{<ASN1_BIT_STRING[0] (7 unused bits)>}}>"

= ASN1 - ASN1_INTEGER
a = ASN1_INTEGER(int("1"*23))
assert repr(a) in ["0x25a55a46e5da99c71c7 <ASN1_INTEGER[1111111111...1111111111]>",
                   "0x25a55a46e5da99c71c7 <ASN1_INTEGER[1111111111...111111111L]>"]

= ASN1 - ASN1_OID
assert raw(ASN1_OID("")) == b"\x06\x00"

= RandASN1Object(), specific crashes

import random

# ASN1F_NUMERIC_STRING
random.seed(1514315682)
raw(RandASN1Object())

# ASN1F_VIDEOTEX_STRING
random.seed(1240186058)
raw(RandASN1Object())

# ASN1F_UTC_TIME & ASN1F_GENERALIZED_TIME
random.seed(1873503288)
raw(RandASN1Object())


############
############
+ Network tests

* Those tests need network access

= Import retry_test()
from scapy.tools.UTscapy import retry_test

= Sending and receiving an ICMP
~ netaccess IP ICMP
def _test():
    old_debug_dissector = conf.debug_dissector
    conf.debug_dissector = False
    x = sr1(IP(dst="www.google.com")/ICMP(),timeout=3)
    conf.debug_dissector = old_debug_dissector
    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

retry_test(_test)

= Sending an ICMP message at layer 2 and layer 3
~ netaccess IP ICMP
def _test():
    tmp = send(IP(dst="8.8.8.8")/ICMP(), return_packets=True, realtime=True)
    assert(len(tmp) == 1)
    
    tmp = sendp(Ether()/IP(dst="8.8.8.8")/ICMP(), return_packets=True, realtime=True)
    assert(len(tmp) == 1)

retry_test(_test)

= Sending an ICMP message 'forever' at layer 2 and layer 3
~ netaccess IP ICMP
def _test():
    tmp = srloop(IP(dst="8.8.8.8")/ICMP(), count=1)
    assert(type(tmp) == tuple and len(tmp[0]) == 1)
    
    tmp = srploop(Ether()/IP(dst="8.8.8.8")/ICMP(), count=1)
    assert(type(tmp) == tuple and len(tmp[0]) == 1)

retry_test(_test)

= Sending and receiving an ICMP with flooding methods
~ netaccess IP ICMP
from functools import partial
# flooding methods do not support timeout. Packing the test for security
def _test_flood(flood_function, add_ether=False):
    old_debug_dissector = conf.debug_dissector
    conf.debug_dissector = False
    p = IP(dst="www.google.com")/ICMP()
    if add_ether:
        p = Ether()/p
    x = flood_function(p, timeout=2)
    conf.debug_dissector = old_debug_dissector
    if type(x) == tuple:
        x = x[0][0][1]
    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

_test_srflood = partial(_test_flood, srflood)
retry_test(_test_srflood)

_test_sr1flood = partial(_test_flood, sr1flood)
retry_test(_test_sr1flood)

_test_srpflood = partial(_test_flood, srpflood, True)
retry_test(_test_srpflood)

_test_srp1flood = partial(_test_flood, srp1flood, True)
retry_test(_test_srp1flood)

= Sending and receiving an ICMPv6EchoRequest
~ netaccess ipv6
def _test():
    old_debug_dissector = conf.debug_dissector
    conf.debug_dissector = False
    x = sr1(IPv6(dst="www.google.com")/ICMPv6EchoRequest(),timeout=3)
    conf.debug_dissector = old_debug_dissector
    x
    assert x[IPv6].ottl() in [32, 64, 128, 255]
    assert 0 <= x[IPv6].hops() <= 126
    x is not None and ICMPv6EchoReply in x and x[ICMPv6EchoReply].type == 129

retry_test(_test)

= DNS request
~ netaccess IP UDP DNS
* A possible cause of failure could be that the open DNS (resolver1.opendns.com)
* is not reachable or down.
def _test():
    old_debug_dissector = conf.debug_dissector
    conf.debug_dissector = False
    dns_ans = sr1(IP(dst="resolver1.opendns.com")/UDP()/DNS(rd=1,qd=DNSQR(qname="www.slashdot.com")),timeout=5)
    conf.debug_dissector = old_debug_dissector
    DNS in dns_ans
    return dns_ans

dns_ans = retry_test(_test)

= Whois request
~ netaccess IP
* This test retries on failure because it often fails
def _test():
    IP(src="8.8.8.8").whois()

retry_test(_test)

= AS resolvers
~ netaccess IP
* This test retries on failure because it often fails

def _test():
    ret = conf.AS_resolver.resolve("8.8.8.8", "8.8.4.4")
    assert (len(ret) == 2)
    all(x[1] == "AS15169" for x in ret)

retry_test(_test)

def _test():
    ret = AS_resolver_riswhois().resolve("8.8.8.8")
    assert (len(ret) == 1)
    assert all(x[1] == "AS15169" for x in ret)

retry_test(_test)

# This test is too buggy, and is simulated below
#def _test():
#    ret = AS_resolver_cymru().resolve("8.8.8.8")
#    assert (len(ret) == 1)
#    all(x[1] == "AS15169" for x in ret)
#
#retry_test(_test)

cymru_bulk_data = """
Bulk mode; whois.cymru.com [2017-10-03 08:38:08 +0000]
24776   | 217.25.178.5     | INFOCLIP-AS, FR
36459   | 192.30.253.112   | GITHUB - GitHub, Inc., US
26496   | 68.178.213.61    | AS-26496-GO-DADDY-COM-LLC - GoDaddy.com, LLC, US
"""
tmp = AS_resolver_cymru().parse(cymru_bulk_data)
assert(len(tmp) == 3)
assert([l[1] for l in tmp] == ['AS24776', 'AS36459', 'AS26496'])

= AS resolver - IPv6
~ netaccess IP
* This test retries on failure because it often fails

def _test():
    as_resolver6 = AS_resolver6()
    ret = as_resolver6.resolve("2001:4860:4860::8888", "2001:4860:4860::4444")
    assert (len(ret) == 2)
    assert all(x[1] == 15169 for x in ret)

retry_test(_test)

= sendpfast

old_interactive = conf.interactive
conf.interactive = False
try:
    sendpfast([])
    assert False
except Exception:
    assert True

conf.interactive = old_interactive
assert True

############
############
+ More complex tests

= Implicit logic 1
~ IP TCP
a = Ether() / IP(ttl=(5, 10)) / TCP(dport=[80, 443])
ls(a)
ls(a, verbose=True)
l = [p for p in a]
len(l) == 12

= Implicit logic 2
~ IP
a = IP(ttl=[1,2,(5,9)])
ls(a)
ls(a, verbose=True)
l = [p for p in a]
len(l) == 7


############
############
+ Real usages

= Port scan
~ netaccess IP TCP
def _test():
    old_debug_dissector = conf.debug_dissector
    conf.debug_dissector = False
    ans,unans=sr(IP(dst="www.google.com/30")/TCP(dport=[80,443]),timeout=2)
    conf.debug_dissector = old_debug_dissector
    
    # Backward compatibility: Python 2 only
    if six.PY2:
        exec("""ans.make_table(lambda (s, r): (s.dst, s.dport, r.sprintf("{TCP:%TCP.flags%}{ICMP:%ICMP.code%}")))""")
    
    # New format: all Python versions
    ans.make_table(lambda s, r: (s.dst, s.dport, r.sprintf("{TCP:%TCP.flags%}{ICMP:%ICMP.code%}")))

retry_test(_test)

= Send & receive with retry
~ netaccess IP ICMP
def _test():
    old_debug_dissector = conf.debug_dissector
    conf.debug_dissector = False
    ans, unans = sr(IP(dst=["8.8.8.8", "1.2.3.4"]) / ICMP(), timeout=2, retry=1)
    conf.debug_dissector = old_debug_dissector
    len(ans) == 1 and len(unans) == 1

retry_test(_test)

= Send & receive with process
~ netaccess IP ICMP
def _test():
    old_debug_dissector = conf.debug_dissector
    conf.debug_dissector = False
    ans, unans = sr(IP(dst=["www.google.fr", "www.google.com", "www.google.co.uk"])/ICMP(), process=lambda x, y: (x[IP].dst, y[IP].src), timeout=2)
    conf.debug_dissector = old_debug_dissector
    assert all(x == y for x, y in ans)
    assert isinstance(unans, list)

retry_test(_test)

= Send & receive with store_unanswered=False
~ netaccess IP ICMP
def _test():
    old_debug_dissector = conf.debug_dissector
    conf.debug_dissector = False
    ans, unans = sr(IP(dst=["www.google.fr", "www.google.com", "www.google.co.uk"])/ICMP(), store_unanswered=False, timeout=2)
    conf.debug_dissector = old_debug_dissector
    assert isinstance(ans, PacketList)
    assert unans == None

retry_test(_test)

= Traceroute function
~ netaccess
* Let's test traceroute
ans, unans = traceroute("www.slashdot.org")

= Result manipulation
~ netaccess
ans.nsummary()
s,r=ans[0]
s.show()
s.show(2)

= DNS packet manipulation
~ netaccess IP UDP DNS
dns_ans.show()
dns_ans.show2()
dns_ans[DNS].an.show()
dns_ans2 = IP(raw(dns_ans))
DNS in dns_ans2
assert(raw(dns_ans2) == raw(dns_ans))
dns_ans2.qd.qname = "www.secdev.org."
* We need to recalculate these values
del(dns_ans2[IP].len)
del(dns_ans2[IP].chksum)
del(dns_ans2[UDP].len)
del(dns_ans2[UDP].chksum)
assert(b"\x03www\x06secdev\x03org\x00" in raw(dns_ans2))
assert(DNS in IP(raw(dns_ans2)))
assert raw(DNSRR(type='A', rdata='1.2.3.4')) == b'\x00\x00\x01\x00\x01\x00\x00\x00\x00\x00\x04\x01\x02\x03\x04'

= Arping
~ netaccess
* This test assumes the local network is a /24. This is bad.
def _test():
    ip_address = conf.route.route("0.0.0.0")[2]
    ip_address
    arping(ip_address+"/24")

retry_test(_test)

= send() and sniff()
~ netaccess
import time
import os

from scapy.modules.six.moves.queue import Queue

def _send_or_sniff(pkt, timeout, flt, pid, fork, t_other=None, opened_socket=None):
    assert pid != -1
    if pid == 0:
        time.sleep(1)
        (sendp if isinstance(pkt, (Ether, Dot3)) else send)(pkt)
        if fork:
            os._exit(0)
        else:
            return
    else:
        spkt = raw(pkt)
        # We do not want to crash when a packet cannot be parsed
        old_debug_dissector = conf.debug_dissector
        conf.debug_dissector = False
        pkts = sniff(
            timeout=timeout, filter=flt, opened_socket=opened_socket,
            stop_filter=lambda p: pkt.__class__ in p and raw(p[pkt.__class__]) == spkt
        )
        conf.debug_dissector = old_debug_dissector
        if fork:
            os.waitpid(pid, 0)
        else:
            t_other.join()
    assert raw(pkt) in (raw(p[pkt.__class__]) for p in pkts if pkt.__class__ in p)

def send_and_sniff(pkt, timeout=2, flt=None, opened_socket=None):
    """Send a packet, sniff, and check the packet has been seen"""
    if hasattr(os, "fork"):
        _send_or_sniff(pkt, timeout, flt, os.fork(), True)
    else:
        from threading import Thread
        def run_function(pkt, timeout, flt, pid, thread, results, opened_socket):
            _send_or_sniff(pkt, timeout, flt, pid, False, t_other=thread, opened_socket=opened_socket)
            results.put(True)
        results = Queue()
        t_parent = Thread(target=run_function, args=(pkt, timeout, flt, 0, None, results, None))
        t_child = Thread(target=run_function, args=(pkt, timeout, flt, 1, t_parent, results, opened_socket))
        t_parent.start()
        t_child.start()
        t_parent.join()
        t_child.join()
        assert results.qsize() >= 2
        while not results.empty():
            assert results.get()

retry_test(lambda: send_and_sniff(IP(dst="secdev.org")/ICMP()))
retry_test(lambda: send_and_sniff(IP(dst="secdev.org")/ICMP(), flt="icmp"))
retry_test(lambda: send_and_sniff(Ether()/IP(dst="secdev.org")/ICMP()))

= Test L2ListenTcpdump socket
~ netaccess FIXME_py3

# Needs to be fixed. Fails randomly
#import time
#for i in range(10):
#    read_s = L2ListenTcpdump(iface=conf.iface)
#    out_s = conf.L2socket(iface=conf.iface)
#    time.sleep(5)  # wait for read_s to be ready
#    icmp_r = Ether()/IP(dst="secdev.org")/ICMP()
#    res = sndrcv(out_s, icmp_r, timeout=5, rcv_pks=read_s)[0]
#    read_s.close()
#    out_s.close()
#    time.sleep(5)
#    if res:
#        break
#
#response = res[0][1]
#assert response[ICMP].type == 0

True

= Test set of sent_time by sr
~ netaccess IP ICMP
def _test():
    packet = IP(dst="8.8.8.8")/ICMP()
    r = sr(packet, timeout=2)
    assert packet.sent_time is not None

retry_test(_test)

= Test set of sent_time by sr (multiple packets)
~ netaccess IP ICMP
def _test():
    packet1 = IP(dst="8.8.8.8")/ICMP()
    packet2 = IP(dst="8.8.4.4")/ICMP()
    r = sr([packet1, packet2], timeout=2)
    assert packet1.sent_time is not None
    assert packet2.sent_time is not None

retry_test(_test)

= Test set of sent_time by srflood
~ netaccess IP ICMP
def _test():
    packet = IP(dst="8.8.8.8")/ICMP()
    r = srflood(packet, timeout=2)
    assert packet.sent_time is not None

retry_test(_test)

= Test set of sent_time by srflood (multiple packets)
~ netaccess IP ICMP
def _test():
    packet1 = IP(dst="8.8.8.8")/ICMP()
    packet2 = IP(dst="8.8.4.4")/ICMP()
    r = srflood([packet1, packet2], timeout=2)
    assert packet1.sent_time is not None
    assert packet2.sent_time is not None

retry_test(_test)

############
############
+ ManuFDB tests

= __repr__

if conf.manufdb:
    len(conf.manufdb)
else:
    True

= check _resolve_MAC

if conf.manufdb:
    assert conf.manufdb._resolve_MAC("00:00:17") == "Oracle"
else:
    True

############
############
+ Automaton tests

= Simple automaton
~ automaton
class ATMT1(Automaton):
    def parse_args(self, init, *args, **kargs):
        Automaton.parse_args(self, *args, **kargs)
        self.init = init
    @ATMT.state(initial=1)
    def BEGIN(self):
        raise self.MAIN(self.init)
    @ATMT.state()
    def MAIN(self, s):
        return s
    @ATMT.condition(MAIN, prio=-1)
    def go_to_END(self, s):
        if len(s) > 20:
            raise self.END(s).action_parameters(s)
    @ATMT.condition(MAIN)
    def trA(self, s):
        if s.endswith("b"):
            raise self.MAIN(s+"a")
    @ATMT.condition(MAIN)
    def trB(self, s):
        if s.endswith("a"):
            raise self.MAIN(s*2+"b")
    @ATMT.state(final=1)
    def END(self, s):
        return s
    @ATMT.action(go_to_END)
    def action_test(self, s):
        self.result = s
    
= Simple automaton Tests
~ automaton

a=ATMT1(init="a", ll=lambda: None, recvsock=lambda: None)
r = a.run()
r
assert(r == 'aabaaababaaabaaababab')
r = a.result
r
assert(r == 'aabaaababaaabaaababab')
a = ATMT1(init="b", ll=lambda: None, recvsock=lambda: None)
r = a.run()
r
assert(r == 'babababababababababababababab')
r = a.result
assert(r == 'babababababababababababababab')

= Simple automaton stuck test
~ automaton

try:    
    ATMT1(init="", ll=lambda: None, recvsock=lambda: None).run()
except Automaton.Stuck:
    True
else:
    False


= Automaton state overloading
~ automaton
class ATMT2(ATMT1):
    @ATMT.state()
    def MAIN(self, s):
        return "c"+ATMT1.MAIN(self, s).run()

a=ATMT2(init="a", ll=lambda: None, recvsock=lambda: None)
r = a.run()
r
assert(r == 'ccccccacabacccacababacccccacabacccacababab')


r = a.result
r
assert(r == 'ccccccacabacccacababacccccacabacccacababab')
a=ATMT2(init="b", ll=lambda: None, recvsock=lambda: None)
r = a.run()
r
assert(r == 'cccccbaccbabaccccbaccbabab')
r = a.result
r
assert(r == 'cccccbaccbabaccccbaccbabab')


= Automaton condition overloading
~ automaton
class ATMT3(ATMT2):
    @ATMT.condition(ATMT1.MAIN)
    def trA(self, s):
        if s.endswith("b"):
            raise self.MAIN(s+"da")


a=ATMT3(init="a", debug=2, ll=lambda: None, recvsock=lambda: None)
r = a.run()
r
assert(r == 'cccccacabdacccacabdabda')
r = a.result
r
assert(r == 'cccccacabdacccacabdabda')
a=ATMT3(init="b", ll=lambda: None, recvsock=lambda: None)
r = a.run()
r
assert(r == 'cccccbdaccbdabdaccccbdaccbdabdab')

r = a.result
r
assert(r == 'cccccbdaccbdabdaccccbdaccbdabdab')


= Automaton action overloading
~ automaton
class ATMT4(ATMT3):
    @ATMT.action(ATMT1.go_to_END)
    def action_test(self, s):
        self.result = "e"+s+"e"

a=ATMT4(init="a", ll=lambda: None, recvsock=lambda: None)
r = a.run()
r
assert(r == 'cccccacabdacccacabdabda')
r = a.result
r
assert(r == 'ecccccacabdacccacabdabdae')
a=ATMT4(init="b", ll=lambda: None, recvsock=lambda: None)
r = a.run()
r
assert(r == 'cccccbdaccbdabdaccccbdaccbdabdab')
r = a.result
r
assert(r == 'ecccccbdaccbdabdaccccbdaccbdabdabe')


= Automaton priorities
~ automaton
class ATMT5(Automaton):
    @ATMT.state(initial=1)
    def BEGIN(self):
        self.res = "J"
    @ATMT.condition(BEGIN, prio=1)
    def tr1(self):
        self.res += "i"
        raise self.END()
    @ATMT.condition(BEGIN)
    def tr2(self):
        self.res += "p"
    @ATMT.condition(BEGIN, prio=-1)
    def tr3(self):
        self.res += "u"
    
    @ATMT.action(tr1)
    def ac1(self):
        self.res += "e"
    @ATMT.action(tr1, prio=-1)
    def ac2(self):
        self.res += "t"
    @ATMT.action(tr1, prio=1)
    def ac3(self):
        self.res += "r"
   
    @ATMT.state(final=1)
    def END(self):
        return self.res

a=ATMT5(ll=lambda: None, recvsock=lambda: None)
r = a.run()
r
assert(r == 'Jupiter')

= Automaton test same action for many conditions
~ automaton
class ATMT6(Automaton):
    @ATMT.state(initial=1)
    def BEGIN(self):
        self.res="M"
    @ATMT.condition(BEGIN)
    def tr1(self):
        raise self.MIDDLE()
    @ATMT.action(tr1) # default prio=0
    def add_e(self):
        self.res += "e"
    @ATMT.action(tr1, prio=2)
    def add_c(self):
        self.res += "c"
    @ATMT.state()
    def MIDDLE(self):
        self.res += "u"
    @ATMT.condition(MIDDLE)
    def tr2(self):
        raise self.END()
    @ATMT.action(tr2, prio=2)
    def add_y(self):
        self.res += "y"
    @ATMT.action(tr1, prio=1)
    @ATMT.action(tr2)
    def add_r(self):
        self.res += "r"
    @ATMT.state(final=1)
    def END(self):
        return self.res

a=ATMT6(ll=lambda: None, recvsock=lambda: None)
r = a.run()
assert(r == 'Mercury')

a.restart()
r = a.run()
r
assert(r == 'Mercury')

= Automaton test io event
~ automaton

class ATMT7(Automaton):
    @ATMT.state(initial=1)
    def BEGIN(self):
        self.res = "S"
    @ATMT.ioevent(BEGIN, name="tst")
    def tr1(self, fd):
        self.res += fd.recv()
        raise self.NEXT_STATE()
    @ATMT.state()
    def NEXT_STATE(self):
        self.oi.tst.send("ur")
    @ATMT.ioevent(NEXT_STATE, name="tst")
    def tr2(self, fd):
        self.res += fd.recv()
        raise self.END()
    @ATMT.state(final=1)
    def END(self):
        self.res += "n"
        return self.res

a=ATMT7(ll=lambda: None, recvsock=lambda: None)
a.run(wait=False)
a.io.tst.send("at")
r = a.io.tst.recv()
r
a.io.tst.send(r)
r = a.run()
r
assert(r == "Saturn")

a.restart()
a.run(wait=False)
a.io.tst.send("at")
r = a.io.tst.recv()
r
a.io.tst.send(r)
r = a.run()
r
assert(r == "Saturn")

= Automaton test io event from external fd
~ automaton
import os

class ATMT8(Automaton):
    @ATMT.state(initial=1)
    def BEGIN(self):
        self.res = b"U"
    @ATMT.ioevent(BEGIN, name="extfd")
    def tr1(self, fd):
        self.res += fd.read(2)
        raise self.NEXT_STATE()
    @ATMT.state()
    def NEXT_STATE(self):
        pass
    @ATMT.ioevent(NEXT_STATE, name="extfd")
    def tr2(self, fd):
        self.res += fd.read(2)
        raise self.END()
    @ATMT.state(final=1)
    def END(self):
        self.res += b"s"
        return self.res

if WINDOWS:
    r = w = ObjectPipe()
else:
    r,w = os.pipe()

def writeOn(w, msg):
    if WINDOWS:
        w.write(msg)
    else:
        os.write(w, msg)

a=ATMT8(external_fd={"extfd":r}, ll=lambda: None, recvsock=lambda: None)
a.run(wait=False)
writeOn(w, b"ra")
writeOn(w, b"nu")

r = a.run()
r
assert(r == b"Uranus")

a.restart()
a.run(wait=False)
writeOn(w, b"ra")
writeOn(w, b"nu")
r = a.run()
r
assert(r == b"Uranus")

= Automaton test interception_points, and restart
~ automaton
class ATMT9(Automaton):
    def my_send(self, x):
        self.io.loop.send(x)
    @ATMT.state(initial=1)
    def BEGIN(self):
        self.res = "V"
        self.send(Raw("ENU"))
    @ATMT.ioevent(BEGIN, name="loop")
    def received_sth(self, fd):
        self.res += plain_str(fd.recv().load)
        raise self.END()
    @ATMT.state(final=1)
    def END(self):
        self.res += "s"
        return self.res

a=ATMT9(debug=5, ll=lambda: None, recvsock=lambda: None)
r = a.run()
r
assert(r == "VENUs")

a.restart()
r = a.run()
r
assert(r == "VENUs")

a.restart()
a.BEGIN.intercepts()
while True:
    try:
        x = a.run()
    except Automaton.InterceptionPoint as p:
        a.accept_packet(Raw(p.packet.load.lower()), wait=False)
    else:
        break

r = x
r
assert(r == "Venus")


############
############
+ Test IP options

= IP options individual assembly
~ IP options
r = raw(IPOption())
r
assert(r == b'\x00\x02')
r = raw(IPOption_NOP())
r
assert(r == b'\x01')
r = raw(IPOption_EOL())
r
assert(r == b'\x00')
r = raw(IPOption_LSRR(routers=["1.2.3.4","5.6.7.8"]))
r
assert(r == b'\x83\x0b\x04\x01\x02\x03\x04\x05\x06\x07\x08')

= IP options individual dissection
~ IP options
io = IPOption(b"\x00")
io
assert(io.option == 0 and isinstance(io, IPOption_EOL))
io = IPOption(b"\x01")
io
assert(io.option == 1 and isinstance(io, IPOption_NOP))
lsrr=b'\x83\x0b\x04\x01\x02\x03\x04\x05\x06\x07\x08'
p=IPOption_LSRR(lsrr)
p
q=IPOption(lsrr)
q
assert(p == q)

= IP assembly and dissection with options
~ IP options
p = IP(src="9.10.11.12",dst="13.14.15.16",options=IPOption_SDBM(addresses=["1.2.3.4","5.6.7.8"]))/TCP()
r = raw(p)
r
assert(r == b'H\x00\x004\x00\x01\x00\x00@\x06\xa2q\t\n\x0b\x0c\r\x0e\x0f\x10\x95\n\x01\x02\x03\x04\x05\x06\x07\x08\x00\x00\x00\x14\x00P\x00\x00\x00\x00\x00\x00\x00\x00P\x02 \x00_K\x00\x00')
q=IP(r)
q
assert( isinstance(q.options[0],IPOption_SDBM) )
assert( q[IPOption_SDBM].addresses[1] == "5.6.7.8" )
p.options[0].addresses[0] = '5.6.7.8'
assert( IP(raw(p)).options[0].addresses[0] == '5.6.7.8' )
p = IP(src="9.10.11.12", dst="13.14.15.16", options=[IPOption_NOP(),IPOption_LSRR(routers=["1.2.3.4","5.6.7.8"]),IPOption_Security(transmission_control_code="XYZ")])/TCP()
p
r = raw(p)
r
assert(r == b'K\x00\x00@\x00\x01\x00\x00@\x06\xf3\x83\t\n\x0b\x0c\r\x0e\x0f\x10\x01\x83\x0b\x04\x01\x02\x03\x04\x05\x06\x07\x08\x82\x0b\x00\x00\x00\x00\x00\x00XYZ\x00\x00\x14\x00P\x00\x00\x00\x00\x00\x00\x00\x00P\x02 \x00_K\x00\x00')
q = IP(r)
q
assert(q[IPOption_LSRR].get_current_router() == "1.2.3.4")
assert(q[IPOption_Security].transmission_control_code == b"XYZ")
assert(q[TCP].flags == 2)


############
############
+ Test PPP

= PPP/HDLC
~ ppp hdlc
p = HDLC()/PPP()/PPP_IPCP()
p
s = raw(p)
s
assert(s == b'\xff\x03\x80!\x01\x00\x00\x04')
p = PPP(s)
p
assert(HDLC in p)
assert(p[HDLC].control==3)
assert(p[PPP].proto==0x8021)
q = PPP(s[2:])
q
assert(HDLC not in q)
assert(q[PPP].proto==0x8021)


= PPP IPCP
~ ppp ipcp
p = PPP(b'\x80!\x01\x01\x00\x10\x03\x06\xc0\xa8\x01\x01\x02\x06\x00-\x0f\x01')
p
assert(p[PPP_IPCP].code == 1)
assert(p[PPP_IPCP_Option_IPAddress].data=="192.168.1.1")
assert(p[PPP_IPCP_Option].data == b'\x00-\x0f\x01')
p=PPP()/PPP_IPCP(options=[PPP_IPCP_Option_DNS1(data="1.2.3.4"),PPP_IPCP_Option_DNS2(data="5.6.7.8"),PPP_IPCP_Option_NBNS2(data="9.10.11.12")])
r = raw(p)
r
assert(r == b'\x80!\x01\x00\x00\x16\x81\x06\x01\x02\x03\x04\x83\x06\x05\x06\x07\x08\x84\x06\t\n\x0b\x0c')
q = PPP(r)
q
assert(raw(p) == raw(q))
assert(PPP(raw(q))==q)
p = PPP()/PPP_IPCP(options=[PPP_IPCP_Option_DNS1(data="1.2.3.4"),PPP_IPCP_Option_DNS2(data="5.6.7.8"),PPP_IPCP_Option(type=123,data="ABCDEFG"),PPP_IPCP_Option_NBNS2(data="9.10.11.12")])
p
r = raw(p)
r
assert(r == b'\x80!\x01\x00\x00\x1f\x81\x06\x01\x02\x03\x04\x83\x06\x05\x06\x07\x08{\tABCDEFG\x84\x06\t\n\x0b\x0c')
q = PPP(r)
q
assert( q[PPP_IPCP_Option].type == 123 )
assert( q[PPP_IPCP_Option].data == b"ABCDEFG" )
assert( q[PPP_IPCP_Option_NBNS2].data == '9.10.11.12' )


= PPP ECP
~ ppp ecp

p = PPP()/PPP_ECP(options=[PPP_ECP_Option_OUI(oui="XYZ")])
p
r = raw(p)
r
assert(r == b'\x80S\x01\x00\x00\n\x00\x06XYZ\x00')
q = PPP(r)
q
assert(raw(p) == raw(q))
p = PPP()/PPP_ECP(options=[PPP_ECP_Option_OUI(oui="XYZ"),PPP_ECP_Option(type=1,data="ABCDEFG")])
p
r = raw(p)
r
assert(r == b'\x80S\x01\x00\x00\x13\x00\x06XYZ\x00\x01\tABCDEFG')
q = PPP(r)
q
assert( raw(p) == raw(q) )
assert( q[PPP_ECP_Option].data == b"ABCDEFG" )


= PPP_ (PPP with only one byte for protocol)
~ ppp

assert(len(raw(PPP_() / IP())) == 21)

p = PPP(b'!E\x00\x00<\x00\x00@\x008\x06\xa5\xce\x85wP)\xc0\xa8Va\x01\xbbd\x8a\xe2}r\xb8O\x95\xb5\x84\xa0\x12q \xc8\x08\x00\x00\x02\x04\x02\x18\x04\x02\x08\nQ\xdf\xd6\xb0\x00\x07LH\x01\x03\x03\x07Ao')
assert(IP in p)
assert(TCP in p)

# Scapy6 Regression Test Campaign 

############
############
+ Test IPv6 Class 
= IPv6 Class basic Instantiation
a=IPv6() 

= IPv6 Class basic build (default values)
raw(IPv6()) == b'`\x00\x00\x00\x00\x00;@\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01'

= IPv6 Class basic dissection (default values)
a=IPv6(raw(IPv6())) 
a.version == 6 and a.tc == 0 and a.fl == 0 and a.plen == 0 and a.nh == 59 and a.hlim ==64 and a.src == "::1" and a.dst == "::1"

= IPv6 Class with basic TCP stacked - build
raw(IPv6()/TCP()) == b'`\x00\x00\x00\x00\x14\x06@\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01\x00\x14\x00P\x00\x00\x00\x00\x00\x00\x00\x00P\x02 \x00\x8f}\x00\x00'

= IPv6 Class with basic TCP stacked - dissection
a=IPv6(raw(IPv6()/TCP()))
a.nh == 6 and a.plen == 20 and isinstance(a.payload, TCP) and a.payload.chksum == 0x8f7d

= IPv6 Class with TCP and TCP data - build
raw(IPv6()/TCP()/Raw(load="somedata")) == b'`\x00\x00\x00\x00\x1c\x06@\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01\x00\x14\x00P\x00\x00\x00\x00\x00\x00\x00\x00P\x02 \x00\xd5\xdd\x00\x00somedata'

= IPv6 Class with TCP and TCP data - dissection
a=IPv6(raw(IPv6()/TCP()/Raw(load="somedata")))
a.nh == 6 and a.plen == 28 and isinstance(a.payload, TCP) and a.payload.chksum == 0xd5dd and isinstance(a.payload.payload, Raw) and a[Raw].load == b"somedata"

= IPv6 Class binding with Ethernet - build
raw(Ether(src="00:00:00:00:00:00", dst="ff:ff:ff:ff:ff:ff")/IPv6()/TCP()) == b'\xff\xff\xff\xff\xff\xff\x00\x00\x00\x00\x00\x00\x86\xdd`\x00\x00\x00\x00\x14\x06@\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01\x00\x14\x00P\x00\x00\x00\x00\x00\x00\x00\x00P\x02 \x00\x8f}\x00\x00'

= IPv6 Class binding with Ethernet - dissection
a=Ether(raw(Ether()/IPv6()/TCP()))
a.type == 0x86dd

= IPv6 Class - summary
a = Ether(src="aa:aa:aa:aa:aa:aa", dst="bb:bb:bb:bb:bb:bb")/IPv6(src='c266:a92d:0ed8:dc54:7d6f:9667:3743:a32f', dst='6406:c31f:d0b5:72fc:1700:2081:62e7:fae9')
assert a.summary() == 'Ether / c266:a92d:ed8:dc54:7d6f:9667:3743:a32f > 6406:c31f:d0b5:72fc:1700:2081:62e7:fae9 (59)'

= IPv6 Class binding with GRE - build
s = raw(IP(src="127.0.0.1")/GRE()/Ether(dst="ff:ff:ff:ff:ff:ff", src="00:00:00:00:00:00")/IP()/GRE()/IPv6(src="::1"))
s == b'E\x00\x00f\x00\x01\x00\x00@/|f\x7f\x00\x00\x01\x7f\x00\x00\x01\x00\x00eX\xff\xff\xff\xff\xff\xff\x00\x00\x00\x00\x00\x00\x08\x00E\x00\x00@\x00\x01\x00\x00@/|\x8c\x7f\x00\x00\x01\x7f\x00\x00\x01\x00\x00\x86\xdd`\x00\x00\x00\x00\x00;@\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01'

= IPv6 Class binding with GRE - dissection
p = IP(s)
GRE in p and p[GRE:1].proto == 0x6558 and p[GRE:2].proto == 0x86DD and IPv6 in p


########### IPv6ExtHdrRouting Class ###########################

= IPv6ExtHdrRouting Class - No address - build
raw(IPv6(src="2048::deca", dst="2047::cafe")/IPv6ExtHdrRouting(addresses=[])/TCP(dport=80)) ==b'`\x00\x00\x00\x00\x1c+@ H\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xde\xca G\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xca\xfe\x06\x00\x00\x00\x00\x00\x00\x00\x00\x14\x00P\x00\x00\x00\x00\x00\x00\x00\x00P\x02 \x00\xa5&\x00\x00' 

= IPv6ExtHdrRouting Class - One address - build
raw(IPv6(src="2048::deca", dst="2047::cafe")/IPv6ExtHdrRouting(addresses=["2022::deca"])/TCP(dport=80)) == b'`\x00\x00\x00\x00,+@ H\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xde\xca G\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xca\xfe\x06\x02\x00\x01\x00\x00\x00\x00 "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xde\xca\x00\x14\x00P\x00\x00\x00\x00\x00\x00\x00\x00P\x02 \x00\x91\x7f\x00\x00'

= IPv6ExtHdrRouting Class - Multiple Addresses - build
raw(IPv6(src="2048::deca", dst="2047::cafe")/IPv6ExtHdrRouting(addresses=["2001::deca", "2022::deca"])/TCP(dport=80)) == b'`\x00\x00\x00\x00<+@ H\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xde\xca G\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xca\xfe\x06\x04\x00\x02\x00\x00\x00\x00 \x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xde\xca "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xde\xca\x00\x14\x00P\x00\x00\x00\x00\x00\x00\x00\x00P\x02 \x00\x91\x7f\x00\x00'

= IPv6ExtHdrRouting Class - Specific segleft (2->1) - build
raw(IPv6(src="2048::deca", dst="2047::cafe")/IPv6ExtHdrRouting(addresses=["2001::deca", "2022::deca"], segleft=1)/TCP(dport=80)) == b'`\x00\x00\x00\x00<+@ H\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xde\xca G\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xca\xfe\x06\x04\x00\x01\x00\x00\x00\x00 \x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xde\xca "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xde\xca\x00\x14\x00P\x00\x00\x00\x00\x00\x00\x00\x00P\x02 \x00\x91\x7f\x00\x00'

= IPv6ExtHdrRouting Class - Specific segleft (2->0) - build
raw(IPv6(src="2048::deca", dst="2047::cafe")/IPv6ExtHdrRouting(addresses=["2001::deca", "2022::deca"], segleft=0)/TCP(dport=80)) == b'`\x00\x00\x00\x00<+@ H\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xde\xca G\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xca\xfe\x06\x04\x00\x00\x00\x00\x00\x00 \x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xde\xca "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xde\xca\x00\x14\x00P\x00\x00\x00\x00\x00\x00\x00\x00P\x02 \x00\xa5&\x00\x00'

########### IPv6ExtHdrSegmentRouting Class ###########################

= IPv6ExtHdrSegmentRouting Class - default - build & dissect
s = raw(IPv6()/IPv6ExtHdrSegmentRouting()/UDP())
assert(s == b'`\x00\x00\x00\x00 +@\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01\x11\x02\x04\x00\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01\x005\x005\x00\x08\xffr')

p = IPv6(s)
assert(UDP in p and IPv6ExtHdrSegmentRouting in p)
assert(len(p[IPv6ExtHdrSegmentRouting].addresses) == 1 and len(p[IPv6ExtHdrSegmentRouting].tlv_objects) == 0)

= IPv6ExtHdrSegmentRouting Class - empty lists - build & dissect

s = raw(IPv6()/IPv6ExtHdrSegmentRouting(addresses=[], tlv_objects=[])/UDP())
assert(s == b'`\x00\x00\x00\x00\x10+@\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01\x11\x00\x04\x00\x00\x00\x00\x00\x005\x005\x00\x08\xffr')

p = IPv6(s)
assert(UDP in p and IPv6ExtHdrSegmentRouting in p)
assert(len(p[IPv6ExtHdrSegmentRouting].addresses) == 0 and len(p[IPv6ExtHdrSegmentRouting].tlv_objects) == 0)

= IPv6ExtHdrSegmentRouting Class - addresses list - build & dissect

s = raw(IPv6()/IPv6ExtHdrSegmentRouting(addresses=["::1", "::2", "::3"])/UDP())
assert(s == b'`\x00\x00\x00\x00@+@\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01\x11\x06\x04\x02\x03\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x02\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x03\x005\x005\x00\x08\xffr')

p = IPv6(s)
assert(UDP in p and IPv6ExtHdrSegmentRouting in p)
assert(len(p[IPv6ExtHdrSegmentRouting].addresses) == 3 and len(p[IPv6ExtHdrSegmentRouting].tlv_objects) == 0)

= IPv6ExtHdrSegmentRouting Class - TLVs list - build & dissect

s = raw(IPv6()/IPv6ExtHdrSegmentRouting(addresses=[], tlv_objects=[IPv6ExtHdrSegmentRoutingTLV()])/TCP())
assert(s == b'`\x00\x00\x00\x00$+@\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01\x06\x01\x04\x00\x00\x00\x00\x00\x00\x00\x00\x00\x04\x02\x00\x00\x00\x14\x00P\x00\x00\x00\x00\x00\x00\x00\x00P\x02 \x00\x8f}\x00\x00')

p = IPv6(s)
assert(TCP in p and IPv6ExtHdrSegmentRouting in p)
assert(len(p[IPv6ExtHdrSegmentRouting].addresses) == 0 and len(p[IPv6ExtHdrSegmentRouting].tlv_objects) == 2)
assert(isinstance(p[IPv6ExtHdrSegmentRouting].tlv_objects[1], IPv6ExtHdrSegmentRoutingTLVPadding))

= IPv6ExtHdrSegmentRouting Class - both lists - build & dissect

s = raw(IPv6()/IPv6ExtHdrSegmentRouting(addresses=["::1", "::2", "::3"], tlv_objects=[IPv6ExtHdrSegmentRoutingTLVIngressNode(),IPv6ExtHdrSegmentRoutingTLVEgressNode()])/ICMPv6EchoRequest())
assert(s == b'`\x00\x00\x00\x00h+@\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01:\x0b\x04\x02\x03\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x02\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x03\x01\x12\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01\x02\x12\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01\x80\x00\x7f\xbb\x00\x00\x00\x00')

p = IPv6(s)
assert(ICMPv6EchoRequest in p and IPv6ExtHdrSegmentRouting in p)
assert(len(p[IPv6ExtHdrSegmentRouting].addresses) == 3 and len(p[IPv6ExtHdrSegmentRouting].tlv_objects) == 2)

= IPv6ExtHdrSegmentRouting Class - UDP pseudo-header checksum - build & dissect

s= raw(IPv6(src="fc00::1", dst="fd00::42")/IPv6ExtHdrSegmentRouting(addresses=["fd00::42", "fc13::1337"][::-1], segleft=1, lastentry=1) / UDP(sport=11000, dport=4242) / Raw('foobar'))
assert(s == b'`\x00\x00\x00\x006+@\xfc\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01\xfd\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00B\x11\x04\x04\x01\x01\x00\x00\x00\xfc\x13\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x137\xfd\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00B*\xf8\x10\x92\x00\x0e\x81\xb7foobar')


############
############
+ Test in6_get6to4Prefix()

= Test in6_get6to4Prefix() - 0.0.0.0 address
in6_get6to4Prefix("0.0.0.0") == "2002::"

= Test in6_get6to4Prefix() - 255.255.255.255 address
in6_get6to4Prefix("255.255.255.255") == "2002:ffff:ffff::"

= Test in6_get6to4Prefix() - 1.1.1.1 address
in6_get6to4Prefix("1.1.1.1") == "2002:101:101::"

= Test in6_get6to4Prefix() - invalid address
in6_get6to4Prefix("somebadrawing") is None


############
############
+ Test in6_6to4ExtractAddr()

= Test in6_6to4ExtractAddr() - 2002:: address
in6_6to4ExtractAddr("2002::") == "0.0.0.0"

= Test in6_6to4ExtractAddr() - 255.255.255.255 address
in6_6to4ExtractAddr("2002:ffff:ffff::") == "255.255.255.255"

= Test in6_6to4ExtractAddr() - "2002:101:101::" address
in6_6to4ExtractAddr("2002:101:101::") == "1.1.1.1"

= Test in6_6to4ExtractAddr() - invalid address
in6_6to4ExtractAddr("somebadrawing") is None


########### RFC 4489 - Link-Scoped IPv6 Multicast address ###########

= in6_getLinkScopedMcastAddr() : default generation
a = in6_getLinkScopedMcastAddr(addr="FE80::") 
a == 'ff32:ff::'

= in6_getLinkScopedMcastAddr() : different valid scope values
a = in6_getLinkScopedMcastAddr(addr="FE80::", scope=0) 
b = in6_getLinkScopedMcastAddr(addr="FE80::", scope=1) 
c = in6_getLinkScopedMcastAddr(addr="FE80::", scope=2) 
d = in6_getLinkScopedMcastAddr(addr="FE80::", scope=3) 
a == 'ff30:ff::' and b == 'ff31:ff::' and c == 'ff32:ff::' and d is None

= in6_getLinkScopedMcastAddr() : grpid in different formats
a = in6_getLinkScopedMcastAddr(addr="FE80::A12:34FF:FE56:7890", grpid=b"\x12\x34\x56\x78") 
b = in6_getLinkScopedMcastAddr(addr="FE80::A12:34FF:FE56:7890", grpid="12345678")
c = in6_getLinkScopedMcastAddr(addr="FE80::A12:34FF:FE56:7890", grpid=305419896)
a == b and b == c 


########### ethernet address to iface ID conversion #################

= in6_mactoifaceid() conversion function (test 1)
in6_mactoifaceid("FD:00:00:00:00:00", ulbit=0) == 'FD00:00FF:FE00:0000'

= in6_mactoifaceid() conversion function (test 2)
in6_mactoifaceid("FD:00:00:00:00:00", ulbit=1) == 'FF00:00FF:FE00:0000'

= in6_mactoifaceid() conversion function (test 3)
in6_mactoifaceid("FD:00:00:00:00:00") == 'FF00:00FF:FE00:0000'

= in6_mactoifaceid() conversion function (test 4)
in6_mactoifaceid("FF:00:00:00:00:00") == 'FD00:00FF:FE00:0000'

= in6_mactoifaceid() conversion function (test 5)
in6_mactoifaceid("FF:00:00:00:00:00", ulbit=1) == 'FF00:00FF:FE00:0000'

= in6_mactoifaceid() conversion function (test 6)
in6_mactoifaceid("FF:00:00:00:00:00", ulbit=0) == 'FD00:00FF:FE00:0000'

########### iface ID conversion #################

= in6_mactoifaceid() conversion function (test 1)
in6_ifaceidtomac(in6_mactoifaceid("FD:00:00:00:00:00", ulbit=0)) == 'ff:00:00:00:00:00'

= in6_mactoifaceid() conversion function (test 2)
in6_ifaceidtomac(in6_mactoifaceid("FD:00:00:00:00:00", ulbit=1)) == 'fd:00:00:00:00:00'

= in6_mactoifaceid() conversion function (test 3)
in6_ifaceidtomac(in6_mactoifaceid("FD:00:00:00:00:00")) == 'fd:00:00:00:00:00'

= in6_mactoifaceid() conversion function (test 4)
in6_ifaceidtomac(in6_mactoifaceid("FF:00:00:00:00:00")) == 'ff:00:00:00:00:00'

= in6_mactoifaceid() conversion function (test 5)
in6_ifaceidtomac(in6_mactoifaceid("FF:00:00:00:00:00", ulbit=1)) == 'fd:00:00:00:00:00'

= in6_mactoifaceid() conversion function (test 6)
in6_ifaceidtomac(in6_mactoifaceid("FF:00:00:00:00:00", ulbit=0)) == 'ff:00:00:00:00:00'


= in6_addrtomac() conversion function (test 1)
in6_addrtomac("FE80::" + in6_mactoifaceid("FD:00:00:00:00:00", ulbit=0)) == 'ff:00:00:00:00:00'

= in6_addrtomac() conversion function (test 2)
in6_addrtomac("FE80::" + in6_mactoifaceid("FD:00:00:00:00:00", ulbit=1)) == 'fd:00:00:00:00:00'

= in6_addrtomac() conversion function (test 3)
in6_addrtomac("FE80::" + in6_mactoifaceid("FD:00:00:00:00:00")) == 'fd:00:00:00:00:00'

= in6_addrtomac() conversion function (test 4)
in6_addrtomac("FE80::" + in6_mactoifaceid("FF:00:00:00:00:00")) == 'ff:00:00:00:00:00'

= in6_addrtomac() conversion function (test 5)
in6_addrtomac("FE80::" + in6_mactoifaceid("FF:00:00:00:00:00", ulbit=1)) == 'fd:00:00:00:00:00'

= in6_addrtomac() conversion function (test 6)
in6_addrtomac("FE80::" + in6_mactoifaceid("FF:00:00:00:00:00", ulbit=0)) == 'ff:00:00:00:00:00'

########### RFC 3041 related function ###############################
= Test in6_getRandomizedIfaceId
import socket

res=True
for a in six.moves.range(10):
    s1,s2 = in6_getRandomizedIfaceId('20b:93ff:feeb:2d3')
    inet_pton(socket.AF_INET6, '::'+s1)
    tmp2 = inet_pton(socket.AF_INET6, '::'+s2)
    res = res and ((orb(s1[0]) & 0x04) == 0x04)
    s1,s2 = in6_getRandomizedIfaceId('20b:93ff:feeb:2d3', previous=tmp2)
    tmp = inet_pton(socket.AF_INET6, '::'+s1)
    inet_pton(socket.AF_INET6, '::'+s2)
    res = res and ((orb(s1[0]) & 0x04) == 0x04)

########### RFC 1924 related function ###############################
= Test RFC 1924 function - in6_ctop() basic test
in6_ctop("4)+k&C#VzJ4br>0wv%Yp") == '1080::8:800:200c:417a'

= Test RFC 1924 function - in6_ctop() with character outside charset
in6_ctop("4)+k&C#VzJ4br>0wv%Y'") == None

= Test RFC 1924 function - in6_ctop() with bad length address
in6_ctop("4)+k&C#VzJ4br>0wv%Y") == None

= Test RFC 1924 function - in6_ptoc() basic test
in6_ptoc('1080::8:800:200c:417a') == '4)+k&C#VzJ4br>0wv%Yp'

= Test RFC 1924 function - in6_ptoc() basic test
in6_ptoc('1080::8:800:200c:417a') == '4)+k&C#VzJ4br>0wv%Yp'

= Test RFC 1924 function - in6_ptoc() with bad input
in6_ptoc('1080:::8:800:200c:417a') == None

########### in6_getAddrType #########################################

= in6_getAddrType - 6to4 addresses
in6_getAddrType("2002::1") == (IPV6_ADDR_UNICAST | IPV6_ADDR_GLOBAL | IPV6_ADDR_6TO4)

= in6_getAddrType - Assignable Unicast global address
in6_getAddrType("2001:db8::1") == (IPV6_ADDR_UNICAST | IPV6_ADDR_GLOBAL)

= in6_getAddrType - Multicast global address
in6_getAddrType("FF0E::1") == (IPV6_ADDR_GLOBAL | IPV6_ADDR_MULTICAST)

= in6_getAddrType - Multicast local address
in6_getAddrType("FF02::1") == (IPV6_ADDR_LINKLOCAL | IPV6_ADDR_MULTICAST)

= in6_getAddrType - Unicast Link-Local address
in6_getAddrType("FE80::") == (IPV6_ADDR_UNICAST | IPV6_ADDR_LINKLOCAL)

= in6_getAddrType - Loopback address
in6_getAddrType("::1") == IPV6_ADDR_LOOPBACK

= in6_getAddrType - Unspecified address
in6_getAddrType("::") == IPV6_ADDR_UNSPECIFIED

= in6_getAddrType - Unassigned Global Unicast address
in6_getAddrType("4000::") == (IPV6_ADDR_GLOBAL | IPV6_ADDR_UNICAST)

= in6_getAddrType - Weird address (FE::1)
in6_getAddrType("FE::") == (IPV6_ADDR_GLOBAL | IPV6_ADDR_UNICAST)

= in6_getAddrType - Weird address (FE8::1)
in6_getAddrType("FE8::1") == (IPV6_ADDR_GLOBAL | IPV6_ADDR_UNICAST)

= in6_getAddrType - Weird address (1::1)
in6_getAddrType("1::1") == (IPV6_ADDR_GLOBAL | IPV6_ADDR_UNICAST)

= in6_getAddrType - Weird address (1000::1)
in6_getAddrType("1000::1") == (IPV6_ADDR_GLOBAL | IPV6_ADDR_UNICAST)

########### ICMPv6DestUnreach Class #################################

= ICMPv6DestUnreach Class - Basic Build (no argument)
raw(ICMPv6DestUnreach()) == b'\x01\x00\x00\x00\x00\x00\x00\x00'

= ICMPv6DestUnreach Class - Basic Build over IPv6 (for cksum and overload)
raw(IPv6(src="2048::deca", dst="2047::cafe")/ICMPv6DestUnreach()) == b'`\x00\x00\x00\x00\x08:@ H\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xde\xca G\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xca\xfe\x01\x00\x14e\x00\x00\x00\x00'

= ICMPv6DestUnreach Class - Basic Build over IPv6 with some payload
raw(IPv6(src="2048::deca", dst="2047::cafe")/ICMPv6DestUnreach()/IPv6(src="2047::cafe", dst="2048::deca")) == b'`\x00\x00\x00\x000:@ H\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xde\xca G\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xca\xfe\x01\x00\x8e\xa3\x00\x00\x00\x00`\x00\x00\x00\x00\x00;@ G\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xca\xfe H\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xde\xca'

= ICMPv6DestUnreach Class - Dissection with default values and some payload
a = IPv6(raw(IPv6(src="2048::deca", dst="2047::cafe")/ICMPv6DestUnreach()/IPv6(src="2047::cafe", dst="2048::deca")))
a.plen == 48 and a.nh == 58 and ICMPv6DestUnreach in a and a[ICMPv6DestUnreach].type == 1 and a[ICMPv6DestUnreach].code == 0 and a[ICMPv6DestUnreach].cksum == 0x8ea3 and a[ICMPv6DestUnreach].unused == 0 and IPerror6 in a

= ICMPv6DestUnreach Class - Dissection with specific values
a=IPv6(raw(IPv6(src="2048::deca", dst="2047::cafe")/ICMPv6DestUnreach(code=1, cksum=0x6666, unused=0x7777)/IPv6(src="2047::cafe", dst="2048::deca")))
a.plen == 48 and a.nh == 58 and ICMPv6DestUnreach in a and a[ICMPv6DestUnreach].type == 1 and a[ICMPv6DestUnreach].cksum == 0x6666 and a[ICMPv6DestUnreach].unused == 0x7777 and IPerror6 in a[ICMPv6DestUnreach]

= ICMPv6DestUnreach Class - checksum computation related stuff
a=IPv6(raw(IPv6(src="2048::deca", dst="2047::cafe")/ICMPv6DestUnreach(code=1, cksum=0x6666, unused=0x7777)/IPv6(src="2047::cafe", dst="2048::deca")/TCP()))
b=IPv6(raw(IPv6(src="2047::cafe", dst="2048::deca")/TCP()))
a[ICMPv6DestUnreach][TCPerror].chksum == b.chksum


########### ICMPv6PacketTooBig Class ################################

= ICMPv6PacketTooBig Class - Basic Build (no argument)
raw(ICMPv6PacketTooBig()) == b'\x02\x00\x00\x00\x00\x00\x05\x00'

= ICMPv6PacketTooBig Class - Basic Build over IPv6 (for cksum and overload)
raw(IPv6(src="2048::deca", dst="2047::cafe")/ICMPv6PacketTooBig()) == b'`\x00\x00\x00\x00\x08:@ H\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xde\xca G\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xca\xfe\x02\x00\x0ee\x00\x00\x05\x00'

= ICMPv6PacketTooBig Class - Basic Build over IPv6 with some payload
raw(IPv6(src="2048::deca", dst="2047::cafe")/ICMPv6PacketTooBig()/IPv6(src="2047::cafe", dst="2048::deca")) == b'`\x00\x00\x00\x000:@ H\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xde\xca G\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xca\xfe\x02\x00\x88\xa3\x00\x00\x05\x00`\x00\x00\x00\x00\x00;@ G\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xca\xfe H\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xde\xca'

= ICMPv6PacketTooBig Class - Dissection with default values and some payload
a = IPv6(raw(IPv6(src="2048::deca", dst="2047::cafe")/ICMPv6PacketTooBig()/IPv6(src="2047::cafe", dst="2048::deca")))
a.plen == 48 and a.nh == 58 and ICMPv6PacketTooBig in a and a[ICMPv6PacketTooBig].type == 2 and a[ICMPv6PacketTooBig].code == 0 and a[ICMPv6PacketTooBig].cksum == 0x88a3 and a[ICMPv6PacketTooBig].mtu == 1280 and IPerror6 in a
True

= ICMPv6PacketTooBig Class - Dissection with specific values
a=IPv6(raw(IPv6(src="2048::deca", dst="2047::cafe")/ICMPv6PacketTooBig(code=2, cksum=0x6666, mtu=1460)/IPv6(src="2047::cafe", dst="2048::deca")))
a.plen == 48 and a.nh == 58 and ICMPv6PacketTooBig in a and a[ICMPv6PacketTooBig].type == 2 and a[ICMPv6PacketTooBig].code == 2 and a[ICMPv6PacketTooBig].cksum == 0x6666 and a[ICMPv6PacketTooBig].mtu == 1460 and IPerror6 in a

= ICMPv6PacketTooBig Class - checksum computation related stuff
a=IPv6(raw(IPv6(src="2048::deca", dst="2047::cafe")/ICMPv6PacketTooBig(code=1, cksum=0x6666, mtu=0x7777)/IPv6(src="2047::cafe", dst="2048::deca")/TCP()))
b=IPv6(raw(IPv6(src="2047::cafe", dst="2048::deca")/TCP()))
a[ICMPv6PacketTooBig][TCPerror].chksum == b.chksum


########### ICMPv6TimeExceeded Class ################################
# To be done but not critical. Same mechanisms and format as 
# previous ones.

########### ICMPv6ParamProblem Class ################################
# See previous note

############
############
+ Test ICMPv6EchoRequest Class

= ICMPv6EchoRequest - Basic Instantiation
raw(ICMPv6EchoRequest()) == b'\x80\x00\x00\x00\x00\x00\x00\x00'

= ICMPv6EchoRequest - Instantiation with specific values
raw(ICMPv6EchoRequest(code=0xff, cksum=0x1111, id=0x2222, seq=0x3333, data="thisissomestring")) == b'\x80\xff\x11\x11""33thisissomestring'

= ICMPv6EchoRequest - Basic dissection
a=ICMPv6EchoRequest(b'\x80\x00\x00\x00\x00\x00\x00\x00')
a.type == 128 and a.code == 0 and a.cksum == 0 and a.id == 0 and a.seq == 0 and a.data == b""

= ICMPv6EchoRequest - Dissection with specific values 
a=ICMPv6EchoRequest(b'\x80\xff\x11\x11""33thisissomerawing')
a.type == 128 and a.code == 0xff and a.cksum == 0x1111 and a.id == 0x2222 and a.seq == 0x3333 and a.data == b"thisissomerawing"

= ICMPv6EchoRequest - Automatic checksum computation and field overloading (build)
raw(IPv6(dst="2001::cafe", src="2001::deca", hlim=64)/ICMPv6EchoRequest()) == b'`\x00\x00\x00\x00\x08:@ \x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xde\xca \x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xca\xfe\x80\x00\x95\xf1\x00\x00\x00\x00'

= ICMPv6EchoRequest - Automatic checksum computation and field overloading (dissection)
a=IPv6(b'`\x00\x00\x00\x00\x08:@ \x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xde\xca \x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xca\xfe\x80\x00\x95\xf1\x00\x00\x00\x00')
isinstance(a, IPv6) and a.nh == 58 and isinstance(a.payload, ICMPv6EchoRequest) and a.payload.cksum == 0x95f1


############
############
+ Test ICMPv6EchoReply Class

= ICMPv6EchoReply - Basic Instantiation
raw(ICMPv6EchoReply()) == b'\x81\x00\x00\x00\x00\x00\x00\x00'

= ICMPv6EchoReply - Instantiation with specific values
raw(ICMPv6EchoReply(code=0xff, cksum=0x1111, id=0x2222, seq=0x3333, data="thisissomestring")) == b'\x81\xff\x11\x11""33thisissomestring'

= ICMPv6EchoReply - Basic dissection
a=ICMPv6EchoReply(b'\x80\x00\x00\x00\x00\x00\x00\x00')
a.type == 128 and a.code == 0 and a.cksum == 0 and a.id == 0 and a.seq == 0 and a.data == b""

= ICMPv6EchoReply - Dissection with specific values 
a=ICMPv6EchoReply(b'\x80\xff\x11\x11""33thisissomerawing')
a.type == 128 and a.code == 0xff and a.cksum == 0x1111 and a.id == 0x2222 and a.seq == 0x3333 and a.data == b"thisissomerawing"

= ICMPv6EchoReply - Automatic checksum computation and field overloading (build)
raw(IPv6(dst="2001::cafe", src="2001::deca", hlim=64)/ICMPv6EchoReply()) == b'`\x00\x00\x00\x00\x08:@ \x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xde\xca \x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xca\xfe\x81\x00\x94\xf1\x00\x00\x00\x00'

= ICMPv6EchoReply - Automatic checksum computation and field overloading (dissection)
a=IPv6(b'`\x00\x00\x00\x00\x08:@ \x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xde\xca \x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xca\xfe\x80\x00\x95\xf1\x00\x00\x00\x00')
isinstance(a, IPv6) and a.nh == 58 and isinstance(a.payload, ICMPv6EchoRequest) and a.payload.cksum == 0x95f1

########### ICMPv6EchoReply/Request answers() and hashret() #########

= ICMPv6EchoRequest and ICMPv6EchoReply - hashret() test 1
b=IPv6(src="2047::deca", dst="2048::cafe")/ICMPv6EchoReply(data="somedata")
a=IPv6(src="2048::cafe", dst="2047::deca")/ICMPv6EchoRequest(data="somedata")
b.hashret() == a.hashret()

# data are not taken into account for hashret
= ICMPv6EchoRequest and ICMPv6EchoReply - hashret() test 2
b=IPv6(src="2047::deca", dst="2048::cafe")/ICMPv6EchoReply(data="somedata")
a=IPv6(src="2048::cafe", dst="2047::deca")/ICMPv6EchoRequest(data="otherdata")
b.hashret() == a.hashret()

= ICMPv6EchoRequest and ICMPv6EchoReply - hashret() test 3
b=IPv6(src="2047::deca", dst="2048::cafe")/ICMPv6EchoReply(id=0x6666, seq=0x7777,data="somedata")
a=IPv6(src="2048::cafe", dst="2047::deca")/ICMPv6EchoRequest(id=0x6666, seq=0x8888, data="somedata")
b.hashret() != a.hashret()

= ICMPv6EchoRequest and ICMPv6EchoReply - hashret() test 4
b=IPv6(src="2047::deca", dst="2048::cafe")/ICMPv6EchoReply(id=0x6666, seq=0x7777,data="somedata")
a=IPv6(src="2048::cafe", dst="2047::deca")/ICMPv6EchoRequest(id=0x8888, seq=0x7777, data="somedata")
b.hashret() != a.hashret()

= ICMPv6EchoRequest and ICMPv6EchoReply - answers() test 5
b=IPv6(src="2047::deca", dst="2048::cafe")/ICMPv6EchoReply(data="somedata")
a=IPv6(src="2048::cafe", dst="2047::deca")/ICMPv6EchoRequest(data="somedata")
(a > b) == True

= ICMPv6EchoRequest and ICMPv6EchoReply - answers() test 6
b=IPv6(src="2047::deca", dst="2048::cafe")/ICMPv6EchoReply(id=0x6666, seq=0x7777, data="somedata")
a=IPv6(src="2048::cafe", dst="2047::deca")/ICMPv6EchoRequest(id=0x6666, seq=0x7777, data="somedata")
(a > b) == True

= ICMPv6EchoRequest and ICMPv6EchoReply - live answers() use Net6
~ netaccess ipv6

a = IPv6(dst="www.google.com")/ICMPv6EchoRequest()
b = IPv6(src="www.google.com", dst=a.src)/ICMPv6EchoReply()
assert b.answers(a)
assert (a > b)


########### ICMPv6MRD* Classes ######################################

= ICMPv6MRD_Advertisement - Basic instantiation
raw(ICMPv6MRD_Advertisement()) == b'\x97\x14\x00\x00\x00\x00\x00\x00'

= ICMPv6MRD_Advertisement - Instantiation with specific values
raw(ICMPv6MRD_Advertisement(advinter=0xdd, queryint=0xeeee, robustness=0xffff)) == b'\x97\xdd\x00\x00\xee\xee\xff\xff'

= ICMPv6MRD_Advertisement - Basic Dissection and overloading mechanisms
a=Ether(raw(Ether()/IPv6()/ICMPv6MRD_Advertisement()))
a.dst == "33:33:00:00:00:02" and IPv6 in a and a[IPv6].plen == 8 and a[IPv6].nh == 58 and a[IPv6].hlim == 1 and a[IPv6].dst == "ff02::2" and ICMPv6MRD_Advertisement in a and a[ICMPv6MRD_Advertisement].type == 151 and a[ICMPv6MRD_Advertisement].advinter == 20 and a[ICMPv6MRD_Advertisement].queryint == 0 and a[ICMPv6MRD_Advertisement].robustness == 0


= ICMPv6MRD_Solicitation - Basic dissection
raw(ICMPv6MRD_Solicitation()) == b'\x98\x00\x00\x00'

= ICMPv6MRD_Solicitation - Instantiation with specific values 
raw(ICMPv6MRD_Solicitation(res=0xbb)) == b'\x98\xbb\x00\x00'

= ICMPv6MRD_Solicitation - Basic Dissection and overloading mechanisms
a=Ether(raw(Ether()/IPv6()/ICMPv6MRD_Solicitation()))
a.dst == "33:33:00:00:00:02" and IPv6 in a and a[IPv6].plen == 4 and a[IPv6].nh == 58 and a[IPv6].hlim == 1 and a[IPv6].dst == "ff02::2" and ICMPv6MRD_Solicitation in a and a[ICMPv6MRD_Solicitation].type == 152 and a[ICMPv6MRD_Solicitation].res == 0


= ICMPv6MRD_Termination Basic instantiation
raw(ICMPv6MRD_Termination()) == b'\x99\x00\x00\x00'

= ICMPv6MRD_Termination - Instantiation with specific values 
raw(ICMPv6MRD_Termination(res=0xbb)) == b'\x99\xbb\x00\x00'

= ICMPv6MRD_Termination - Basic Dissection and overloading mechanisms
a=Ether(raw(Ether()/IPv6()/ICMPv6MRD_Termination()))
a.dst == "33:33:00:00:00:6a" and IPv6 in a and a[IPv6].plen == 4 and a[IPv6].nh == 58 and a[IPv6].hlim == 1 and a[IPv6].dst == "ff02::6a" and ICMPv6MRD_Termination in a and a[ICMPv6MRD_Termination].type == 153 and a[ICMPv6MRD_Termination].res == 0


############
############
+ Test HBHOptUnknown Class

= HBHOptUnknown - Basic Instantiation 
raw(HBHOptUnknown()) == b'\x01\x00'

= HBHOptUnknown - Basic Dissection 
a=HBHOptUnknown(b'\x01\x00')
a.otype == 0x01 and a.optlen == 0 and a.optdata == b""

= HBHOptUnknown - Automatic optlen computation
raw(HBHOptUnknown(optdata="B"*10)) == b'\x01\nBBBBBBBBBB'

= HBHOptUnknown - Instantiation with specific values
raw(HBHOptUnknown(optlen=9, optdata="B"*10)) == b'\x01\tBBBBBBBBBB'

= HBHOptUnknown - Dissection with specific values 
a=HBHOptUnknown(b'\x01\tBBBBBBBBBB')
a.otype == 0x01 and a.optlen == 9 and a.optdata == b"B"*9 and isinstance(a.payload, Raw) and a.payload.load == b"B"


############
############
+ Test Pad1 Class

= Pad1 - Basic Instantiation
raw(Pad1()) == b'\x00'

= Pad1 - Basic Dissection
raw(Pad1(b'\x00')) == b'\x00'


############
############
+ Test PadN Class

= PadN - Basic Instantiation
raw(PadN()) == b'\x01\x00'

= PadN - Optlen Automatic computation
raw(PadN(optdata="B"*10)) == b'\x01\nBBBBBBBBBB'

= PadN - Basic Dissection
a=PadN(b'\x01\x00')
a.otype == 1 and a.optlen == 0 and a.optdata == b""

= PadN - Dissection with specific values 
a=PadN(b'\x01\x0cBBBBBBBBBB')
a.otype == 1 and a.optlen == 12 and a.optdata == b'BBBBBBBBBB'

= PadN - Instantiation with forced optlen 
raw(PadN(optdata="B"*10, optlen=9)) == b'\x01\x09BBBBBBBBBB'


############
############
+ Test RouterAlert Class (RFC 2711)

= RouterAlert - Basic Instantiation 
raw(RouterAlert()) == b'\x05\x02\x00\x00'

= RouterAlert - Basic Dissection 
a=RouterAlert(b'\x05\x02\x00\x00')
a.otype == 0x05 and a.optlen == 2 and a.value == 00

= RouterAlert - Instantiation with specific values 
raw(RouterAlert(optlen=3, value=0xffff)) == b'\x05\x03\xff\xff' 

= RouterAlert - Instantiation with specific values
a=RouterAlert(b'\x05\x03\xff\xff')
a.otype == 0x05 and a.optlen == 3 and a.value == 0xffff


############
############
+ Test Jumbo Class (RFC 2675)

= Jumbo - Basic Instantiation 
raw(Jumbo()) == b'\xc2\x04\x00\x00\x00\x00'

= Jumbo - Basic Dissection 
a=Jumbo(b'\xc2\x04\x00\x00\x00\x00')
a.otype == 0xC2 and a.optlen == 4 and a.jumboplen == 0

= Jumbo - Instantiation with specific values
raw(Jumbo(optlen=6, jumboplen=0xffffffff)) == b'\xc2\x06\xff\xff\xff\xff'

= Jumbo - Dissection with specific values 
a=Jumbo(b'\xc2\x06\xff\xff\xff\xff')
a.otype == 0xc2 and a.optlen == 6 and a.jumboplen == 0xffffffff


############
############
+ Test HAO Class (RFC 3775)

= HAO - Basic Instantiation 
raw(HAO()) == b'\xc9\x10\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00'

= HAO - Basic Dissection 
a=HAO(b'\xc9\x10\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00')
a.otype == 0xC9 and a.optlen == 16 and a.hoa == "::"

= HAO - Instantiation with specific values
raw(HAO(optlen=9, hoa="2001::ffff")) == b'\xc9\t \x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xff\xff'

= HAO - Dissection with specific values 
a=HAO(b'\xc9\t \x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xff\xff')
a.otype == 0xC9 and a.optlen == 9 and a.hoa == "2001::ffff"

= HAO - hashret

p = IPv6()/IPv6ExtHdrDestOpt(options=HAO(hoa="2001:db8::1"))/ICMPv6EchoRequest()
p.hashret() == b"\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00:\x00\x00\x00\x00"


############
############
+ Test IPv6ExtHdrHopByHop()

= IPv6ExtHdrHopByHop - Basic Instantiation 
raw(IPv6ExtHdrHopByHop()) ==  b';\x00\x01\x04\x00\x00\x00\x00'

= IPv6ExtHdrHopByHop - Instantiation with HAO option
raw(IPv6ExtHdrHopByHop(options=[HAO()])) == b';\x02\x01\x02\x00\x00\xc9\x10\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00'

= IPv6ExtHdrHopByHop - Instantiation with RouterAlert option
raw(IPv6ExtHdrHopByHop(options=[RouterAlert()])) == b';\x00\x05\x02\x00\x00\x01\x00'
 
= IPv6ExtHdrHopByHop - Instantiation with Jumbo option
raw(IPv6ExtHdrHopByHop(options=[Jumbo()])) == b';\x00\xc2\x04\x00\x00\x00\x00'

= IPv6ExtHdrHopByHop - Complete dissection with Jumbo option
s = b'`\x00\x00\x00\x00\x00\x00@\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01:\x00\xc2\x04\x00\x00\x00\x10\x80\x00\x7f\xbb\x00\x00\x00\x00'
p = IPv6(s)
assert IPv6ExtHdrHopByHop in p and Jumbo in p and ICMPv6EchoRequest in p

s = b'`\x00\x00\x00\x00\x00\x00@\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01:\x01\x01\x06\x00\x00\x00\x00\x00\x00\xc2\x04\x00\x00\x00\x18\x80\x00\x7f\xbb\x00\x00\x00\x00'
p = IPv6(s)
assert IPv6ExtHdrHopByHop in p and PadN in p and Jumbo in p and ICMPv6EchoRequest in p

= IPv6ExtHdrHopByHop - Instantiation with Pad1 option
raw(IPv6ExtHdrHopByHop(options=[Pad1()])) == b';\x00\x00\x01\x03\x00\x00\x00'

= IPv6ExtHdrHopByHop - Instantiation with PadN option
raw(IPv6ExtHdrHopByHop(options=[Pad1()])) == b';\x00\x00\x01\x03\x00\x00\x00'

= IPv6ExtHdrHopByHop - Instantiation with Jumbo, RouterAlert, HAO
raw(IPv6ExtHdrHopByHop(options=[Jumbo(), RouterAlert(), HAO()])) == b';\x03\xc2\x04\x00\x00\x00\x00\x05\x02\x00\x00\x01\x00\xc9\x10\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00'

= IPv6ExtHdrHopByHop - Instantiation with HAO, Jumbo, RouterAlert
raw(IPv6ExtHdrHopByHop(options=[HAO(), Jumbo(), RouterAlert()])) == b';\x04\x01\x02\x00\x00\xc9\x10\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01\x00\xc2\x04\x00\x00\x00\x00\x05\x02\x00\x00\x01\x02\x00\x00'

= IPv6ExtHdrHopByHop - Instantiation with RouterAlert, HAO, Jumbo
raw(IPv6ExtHdrHopByHop(options=[RouterAlert(), HAO(), Jumbo()])) == b';\x03\x05\x02\x00\x00\xc9\x10\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01\x00\xc2\x04\x00\x00\x00\x00'

= IPv6ExtHdrHopByHop - Basic Dissection
a=IPv6ExtHdrHopByHop(b';\x00\x01\x04\x00\x00\x00\x00')
a.nh == 59 and a.len == 0 and len(a.options) == 1 and isinstance(a.options[0], PadN) and a.options[0].otype == 1 and a.options[0].optlen == 4 and a.options[0].optdata == b'\x00'*4

#= IPv6ExtHdrHopByHop - Automatic length computation
#raw(IPv6ExtHdrHopByHop(options=["toto"])) == b'\x00\x00toto'
#= IPv6ExtHdrHopByHop - Automatic length computation
#raw(IPv6ExtHdrHopByHop(options=["toto"])) == b'\x00\x00tototo'


############
############
+ Test ICMPv6ND_RS() class - ICMPv6 Type 133 Code 0

= ICMPv6ND_RS - Basic instantiation
raw(ICMPv6ND_RS()) == b'\x85\x00\x00\x00\x00\x00\x00\x00'

= ICMPv6ND_RS - Basic instantiation with empty dst in IPv6 underlayer
raw(IPv6(src="2001:db8::1")/ICMPv6ND_RS()) == b'`\x00\x00\x00\x00\x08:\xff \x01\r\xb8\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01\xff\x02\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x02\x85\x00M\xfe\x00\x00\x00\x00'

= ICMPv6ND_RS - Basic dissection
a=ICMPv6ND_RS(b'\x85\x00\x00\x00\x00\x00\x00\x00')
a.type == 133 and a.code == 0 and a.cksum == 0 and a.res == 0 

= ICMPv6ND_RS - Basic instantiation with empty dst in IPv6 underlayer
a=IPv6(b'`\x00\x00\x00\x00\x08:\xff \x01\r\xb8\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01\xff\x02\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x02\x85\x00M\xfe\x00\x00\x00\x00')
isinstance(a, IPv6) and a.nh == 58 and a.hlim == 255 and isinstance(a.payload, ICMPv6ND_RS) and a.payload.type == 133 and a.payload.code == 0 and a.payload.cksum == 0x4dfe and a.payload.res == 0


############
############
+ Test ICMPv6ND_RA() class - ICMPv6 Type 134 Code 0

= ICMPv6ND_RA - Basic Instantiation 
raw(ICMPv6ND_RA()) == b'\x86\x00\x00\x00\x00\x08\x07\x08\x00\x00\x00\x00\x00\x00\x00\x00'

= ICMPv6ND_RA - Basic instantiation with empty dst in IPv6 underlayer
raw(IPv6(src="2001:db8::1")/ICMPv6ND_RA()) == b'`\x00\x00\x00\x00\x10:\xff \x01\r\xb8\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01\xff\x02\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01\x86\x00E\xe7\x00\x08\x07\x08\x00\x00\x00\x00\x00\x00\x00\x00'

= ICMPv6ND_RA - Basic dissection
a=ICMPv6ND_RA(b'\x86\x00\x00\x00\x00\x08\x07\x08\x00\x00\x00\x00\x00\x00\x00\x00')
a.type == 134 and a.code == 0 and a.cksum == 0 and a.chlim == 0 and a.M == 0 and a.O == 0 and a.H == 0 and a.prf == 1 and a.res == 0 and a.routerlifetime == 1800 and a.reachabletime == 0 and a.retranstimer == 0

= ICMPv6ND_RA - Basic instantiation with empty dst in IPv6 underlayer
a=IPv6(b'`\x00\x00\x00\x00\x10:\xff \x01\r\xb8\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01\xff\x02\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01\x86\x00E\xe7\x00\x08\x07\x08\x00\x00\x00\x00\x00\x00\x00\x00')
isinstance(a, IPv6) and a.nh == 58 and a.hlim == 255 and isinstance(a.payload, ICMPv6ND_RA) and a.payload.type == 134 and a.code == 0 and a.cksum == 0x45e7 and a.chlim == 0 and a.M == 0 and a.O == 0 and a.H == 0 and a.prf == 1 and a.res == 0 and a.routerlifetime == 1800 and a.reachabletime == 0 and a.retranstimer == 0 

= ICMPv6ND_RA - Answers
assert ICMPv6ND_RA().answers(ICMPv6ND_RS())
a=IPv6(b'`\x00\x00\x00\x00\x10:\xff \x01\r\xb8\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01\xff\x02\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01\x86\x00E\xe7\x00\x08\x07\x08\x00\x00\x00\x00\x00\x00\x00\x00')
b = IPv6(b"`\x00\x00\x00\x00\x10:\xff\xff\x02\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01 \x01\r\xb8\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01\x85\x00M\xff\x00\x00\x00\x00")
assert a.answers(b)

= ICMPv6ND_RA - Summary Output
ICMPv6ND_RA(chlim=42, M=0, O=1, H=0, prf=1, P=0, routerlifetime=300).mysummary() == "ICMPv6 Neighbor Discovery - Router Advertisement Lifetime 300 Hop Limit 42 Preference High Managed 0 Other 1 Home 0"

############
############
+ ICMPv6ND_NS Class Test

= ICMPv6ND_NS - Basic Instantiation
raw(ICMPv6ND_NS()) == b'\x87\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00'

= ICMPv6ND_NS - Instantiation with specific values
raw(ICMPv6ND_NS(code=0x11, res=3758096385, tgt="ffff::1111")) == b'\x87\x11\x00\x00\xe0\x00\x00\x01\xff\xff\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x11\x11'

= ICMPv6ND_NS - Basic Dissection
a=ICMPv6ND_NS(b'\x87\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00')
a.code==0 and a.res==0 and a.tgt=="::"

= ICMPv6ND_NS - Dissection with specific values
a=ICMPv6ND_NS(b'\x87\x11\x00\x00\xe0\x00\x00\x01\xff\xff\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x11\x11')
a.code==0x11 and a.res==3758096385 and a.tgt=="ffff::1111"

= ICMPv6ND_NS - IPv6 layer fields overloading
a=IPv6(raw(IPv6()/ICMPv6ND_NS()))
a.nh == 58 and a.dst=="ff02::1" and a.hlim==255

############
############
+ ICMPv6ND_NA Class Test

= ICMPv6ND_NA - Basic Instantiation
raw(ICMPv6ND_NA()) == b'\x88\x00\x00\x00\xa0\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00'

= ICMPv6ND_NA - Instantiation with specific values
raw(ICMPv6ND_NA(code=0x11, R=0, S=1, O=0, res=1, tgt="ffff::1111")) == b'\x88\x11\x00\x00@\x00\x00\x01\xff\xff\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x11\x11'

= ICMPv6ND_NA - Basic Dissection
a=ICMPv6ND_NA(b'\x88\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00')
a.code==0 and a.R==0 and a.S==0 and a.O==0 and a.res==0 and a.tgt=="::"

= ICMPv6ND_NA - Dissection with specific values
a=ICMPv6ND_NA(b'\x88\x11\x00\x00@\x00\x00\x01\xff\xff\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x11\x11')
a.code==0x11 and a.R==0 and a.S==1 and a.O==0 and a.res==1 and a.tgt=="ffff::1111"
assert a.hashret() == b'ffff::1111'

= ICMPv6ND_NS - IPv6 layer fields overloading
a=IPv6(raw(IPv6()/ICMPv6ND_NS()))
a.nh == 58 and a.dst=="ff02::1" and a.hlim==255


############
############
+ ICMPv6ND_ND/ICMPv6ND_ND matching test

=  ICMPv6ND_ND/ICMPv6ND_ND matching - test 1
# Sent NS 
a=IPv6(b'`\x00\x00\x00\x00\x18:\xff\xfe\x80\x00\x00\x00\x00\x00\x00\x02\x0f\x1f\xff\xfe\xcaFP\xff\x02\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01\x87\x00UC\x00\x00\x00\x00\xfe\x80\x00\x00\x00\x00\x00\x00\x02\x0f4\xff\xfe\x8a\x8a\xa1')
# Received NA 
b=IPv6(b'n\x00\x00\x00\x00 :\xff\xfe\x80\x00\x00\x00\x00\x00\x00\x02\x0f4\xff\xfe\x8a\x8a\xa1\xfe\x80\x00\x00\x00\x00\x00\x00\x02\x0f\x1f\xff\xfe\xcaFP\x88\x00\xf3F\xe0\x00\x00\x00\xfe\x80\x00\x00\x00\x00\x00\x00\x02\x0f4\xff\xfe\x8a\x8a\xa1\x02\x01\x00\x0f4\x8a\x8a\xa1')
b.answers(a)


############
############
+ ICMPv6NDOptUnknown Class Test

= ICMPv6NDOptUnknown - Basic Instantiation
raw(ICMPv6NDOptUnknown()) == b'\x00\x02'

= ICMPv6NDOptUnknown - Instantiation with specific values
raw(ICMPv6NDOptUnknown(len=4, data="somestring")) == b'\x00\x04somestring'

= ICMPv6NDOptUnknown - Basic Dissection
a=ICMPv6NDOptUnknown(b'\x00\x02')
a.type == 0 and a.len == 2

= ICMPv6NDOptUnknown - Dissection with specific values 
a=ICMPv6NDOptUnknown(b'\x00\x04somerawing')
a.type == 0 and a.len==4 and a.data == b"so" and isinstance(a.payload, Raw) and a.payload.load == b"merawing"


############
############
+ ICMPv6NDOptSrcLLAddr Class Test

= ICMPv6NDOptSrcLLAddr - Basic Instantiation
raw(ICMPv6NDOptSrcLLAddr()) == b'\x01\x01\x00\x00\x00\x00\x00\x00'

= ICMPv6NDOptSrcLLAddr - Instantiation with specific values
raw(ICMPv6NDOptSrcLLAddr(len=2, lladdr="11:11:11:11:11:11")) == b'\x01\x02\x11\x11\x11\x11\x11\x11'

= ICMPv6NDOptSrcLLAddr - Basic Dissection
a=ICMPv6NDOptSrcLLAddr(b'\x01\x01\x00\x00\x00\x00\x00\x00')
a.type == 1 and a.len == 1 and a.lladdr == "00:00:00:00:00:00"

= ICMPv6NDOptSrcLLAddr - Instantiation with specific values
a=ICMPv6NDOptSrcLLAddr(b'\x01\x02\x11\x11\x11\x11\x11\x11') 
a.type == 1 and a.len == 2 and a.lladdr == "11:11:11:11:11:11"


############
############
+ ICMPv6NDOptDstLLAddr Class Test

= ICMPv6NDOptDstLLAddr - Basic Instantiation
raw(ICMPv6NDOptDstLLAddr()) == b'\x02\x01\x00\x00\x00\x00\x00\x00'

= ICMPv6NDOptDstLLAddr - Instantiation with specific values
raw(ICMPv6NDOptDstLLAddr(len=2, lladdr="11:11:11:11:11:11")) == b'\x02\x02\x11\x11\x11\x11\x11\x11'

= ICMPv6NDOptDstLLAddr - Basic Dissection
a=ICMPv6NDOptDstLLAddr(b'\x02\x01\x00\x00\x00\x00\x00\x00')
a.type == 2 and a.len == 1 and a.lladdr == "00:00:00:00:00:00"

= ICMPv6NDOptDstLLAddr - Instantiation with specific values
a=ICMPv6NDOptDstLLAddr(b'\x02\x02\x11\x11\x11\x11\x11\x11') 
a.type == 2 and a.len == 2 and a.lladdr == "11:11:11:11:11:11"


############
############
+ ICMPv6NDOptPrefixInfo Class Test

= ICMPv6NDOptPrefixInfo - Basic Instantiation
raw(ICMPv6NDOptPrefixInfo()) == b'\x03\x04\x00\xc0\xff\xff\xff\xff\xff\xff\xff\xff\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00'

= ICMPv6NDOptPrefixInfo - Instantiation with specific values
raw(ICMPv6NDOptPrefixInfo(len=5, prefixlen=64, L=0, A=0, R=1, res1=1, validlifetime=0x11111111, preferredlifetime=0x22222222, res2=0x33333333, prefix="2001:db8::1")) == b'\x03\x05@!\x11\x11\x11\x11""""3333 \x01\r\xb8\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01'

= ICMPv6NDOptPrefixInfo - Basic Dissection
a=ICMPv6NDOptPrefixInfo(b'\x03\x04\x00\xc0\xff\xff\xff\xff\xff\xff\xff\xff\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00')
a.type == 3 and a.len == 4 and a.prefixlen == 0 and a.L == 1 and a.A == 1 and a.R == 0 and a.res1 == 0 and a.validlifetime == 0xffffffff and a.preferredlifetime == 0xffffffff and a.res2 == 0 and a.prefix == "::"

= ICMPv6NDOptPrefixInfo - Instantiation with specific values
a=ICMPv6NDOptPrefixInfo(b'\x03\x05@!\x11\x11\x11\x11""""3333 \x01\r\xb8\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01')
a.type == 3 and a.len == 5 and a.prefixlen == 64 and a.L == 0 and a.A == 0 and a.R == 1 and a.res1 == 1 and a.validlifetime == 0x11111111 and a.preferredlifetime == 0x22222222 and a.res2 == 0x33333333 and a.prefix == "2001:db8::1"


############
############
+ ICMPv6NDOptRedirectedHdr Class Test 

= ICMPv6NDOptRedirectedHdr - Basic Instantiation
~ ICMPv6NDOptRedirectedHdr
raw(ICMPv6NDOptRedirectedHdr()) == b'\x04\x01\x00\x00\x00\x00\x00\x00'

= ICMPv6NDOptRedirectedHdr - Instantiation with specific values 
~ ICMPv6NDOptRedirectedHdr
raw(ICMPv6NDOptRedirectedHdr(len=0xff, res="abcdef", pkt="somestringthatisnotanipv6packet")) == b'\x04\xffabcdefsomestringthatisnotanipv'

= ICMPv6NDOptRedirectedHdr - Instantiation with simple IPv6 packet (no upper layer)
~ ICMPv6NDOptRedirectedHdr
raw(ICMPv6NDOptRedirectedHdr(pkt=IPv6())) == b'\x04\x06\x00\x00\x00\x00\x00\x00`\x00\x00\x00\x00\x00;@\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01'

= ICMPv6NDOptRedirectedHdr - Basic Dissection
~ ICMPv6NDOptRedirectedHdr
a=ICMPv6NDOptRedirectedHdr(b'\x04\x00\x00\x00')
assert(a.type == 4)
assert(a.len == 0)
assert(a.res == b"\x00\x00")
assert(a.pkt == b"")

= ICMPv6NDOptRedirectedHdr - Disssection with specific values
~ ICMPv6NDOptRedirectedHdr
a=ICMPv6NDOptRedirectedHdr(b'\x04\xff\x11\x11\x00\x00\x00\x00somerawingthatisnotanipv6pac')
a.type == 4 and a.len == 255 and a.res == b'\x11\x11\x00\x00\x00\x00' and isinstance(a.pkt, Raw) and a.pkt.load == b"somerawingthatisnotanipv6pac"

= ICMPv6NDOptRedirectedHdr - Dissection with cut IPv6 Header
~ ICMPv6NDOptRedirectedHdr
a=ICMPv6NDOptRedirectedHdr(b'\x04\x06\x00\x00\x00\x00\x00\x00`\x00\x00\x00\x00\x00;@\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00')
a.type == 4 and a.len == 6 and a.res == b"\x00\x00\x00\x00\x00\x00" and isinstance(a.pkt, Raw) and a.pkt.load == b'`\x00\x00\x00\x00\x00;@\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00'

= ICMPv6NDOptRedirectedHdr - Complete dissection
~ ICMPv6NDOptRedirectedHdr
x=ICMPv6NDOptRedirectedHdr(b'\x04\x06\x00\x00\x00\x00\x00\x00`\x00\x00\x00\x00\x00;@\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01')
y=x.copy()
del(y.len)
x == ICMPv6NDOptRedirectedHdr(raw(y))

# Add more tests


############
############
+ ICMPv6NDOptMTU Class Test 

= ICMPv6NDOptMTU - Basic Instantiation
raw(ICMPv6NDOptMTU()) == b'\x05\x01\x00\x00\x00\x00\x05\x00'

= ICMPv6NDOptMTU - Instantiation with specific values
raw(ICMPv6NDOptMTU(len=2, res=0x1111, mtu=1500)) == b'\x05\x02\x11\x11\x00\x00\x05\xdc'
 
= ICMPv6NDOptMTU - Basic dissection
a=ICMPv6NDOptMTU(b'\x05\x01\x00\x00\x00\x00\x05\x00')
a.type == 5 and a.len == 1 and a.res == 0 and a.mtu == 1280

= ICMPv6NDOptMTU - Dissection with specific values
a=ICMPv6NDOptMTU(b'\x05\x02\x11\x11\x00\x00\x05\xdc')
a.type == 5 and a.len == 2 and a.res == 0x1111 and a.mtu == 1500

= ICMPv6NDOptMTU - Summary Output
ICMPv6NDOptMTU(b'\x05\x02\x11\x11\x00\x00\x05\xdc').mysummary() == "ICMPv6 Neighbor Discovery Option - MTU 1500"


############
############
+ ICMPv6NDOptShortcutLimit Class Test (RFC2491)

= ICMPv6NDOptShortcutLimit - Basic Instantiation
raw(ICMPv6NDOptShortcutLimit()) == b'\x06\x01(\x00\x00\x00\x00\x00'

= ICMPv6NDOptShortcutLimit - Instantiation with specific values
raw(ICMPv6NDOptShortcutLimit(len=2, shortcutlim=0x11, res1=0xee, res2=0xaaaaaaaa)) == b'\x06\x02\x11\xee\xaa\xaa\xaa\xaa'

= ICMPv6NDOptShortcutLimit - Basic Dissection
a=ICMPv6NDOptShortcutLimit(b'\x06\x01(\x00\x00\x00\x00\x00')
a.type == 6 and a.len == 1 and a.shortcutlim == 40 and a.res1 == 0 and a.res2 == 0

= ICMPv6NDOptShortcutLimit - Dissection with specific values
a=ICMPv6NDOptShortcutLimit(b'\x06\x02\x11\xee\xaa\xaa\xaa\xaa')
a.len==2 and a.shortcutlim==0x11 and a.res1==0xee and a.res2==0xaaaaaaaa


############
############
+ ICMPv6NDOptAdvInterval Class Test 

= ICMPv6NDOptAdvInterval - Basic Instantiation
raw(ICMPv6NDOptAdvInterval()) == b'\x07\x01\x00\x00\x00\x00\x00\x00'

= ICMPv6NDOptAdvInterval - Instantiation with specific values
raw(ICMPv6NDOptAdvInterval(len=2, res=0x1111, advint=0xffffffff)) == b'\x07\x02\x11\x11\xff\xff\xff\xff'
 
= ICMPv6NDOptAdvInterval - Basic dissection
a=ICMPv6NDOptAdvInterval(b'\x07\x01\x00\x00\x00\x00\x00\x00')
a.type == 7 and a.len == 1 and a.res == 0 and a.advint == 0

= ICMPv6NDOptAdvInterval - Dissection with specific values
a=ICMPv6NDOptAdvInterval(b'\x07\x02\x11\x11\xff\xff\xff\xff')
a.type == 7 and a.len == 2 and a.res == 0x1111 and a.advint == 0xffffffff


############
############
+ ICMPv6NDOptHAInfo Class Test

= ICMPv6NDOptHAInfo - Basic Instantiation
raw(ICMPv6NDOptHAInfo()) == b'\x08\x01\x00\x00\x00\x00\x00\x01'

= ICMPv6NDOptHAInfo - Instantiation with specific values
raw(ICMPv6NDOptHAInfo(len=2, res=0x1111, pref=0x2222, lifetime=0x3333)) == b'\x08\x02\x11\x11""33'
 
= ICMPv6NDOptHAInfo - Basic dissection
a=ICMPv6NDOptHAInfo(b'\x08\x01\x00\x00\x00\x00\x00\x01')
a.type == 8 and a.len == 1 and a.res == 0 and a.pref == 0 and a.lifetime == 1

= ICMPv6NDOptHAInfo - Dissection with specific values
a=ICMPv6NDOptHAInfo(b'\x08\x02\x11\x11""33')
a.type == 8 and a.len == 2 and a.res == 0x1111 and a.pref == 0x2222 and a.lifetime == 0x3333


############
############
+ ICMPv6NDOptSrcAddrList Class Test 

= ICMPv6NDOptSrcAddrList - Basic Instantiation
raw(ICMPv6NDOptSrcAddrList()) == b'\t\x01\x00\x00\x00\x00\x00\x00'

= ICMPv6NDOptSrcAddrList - Instantiation with specific values (auto len)
raw(ICMPv6NDOptSrcAddrList(res="BBBBBB", addrlist=["ffff::ffff", "1111::1111"])) == b'\t\x05BBBBBB\xff\xff\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xff\xff\x11\x11\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x11\x11'

= ICMPv6NDOptSrcAddrList - Instantiation with specific values 
raw(ICMPv6NDOptSrcAddrList(len=3, res="BBBBBB", addrlist=["ffff::ffff", "1111::1111"])) == b'\t\x03BBBBBB\xff\xff\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xff\xff\x11\x11\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x11\x11'

= ICMPv6NDOptSrcAddrList - Basic Dissection
a=ICMPv6NDOptSrcAddrList(b'\t\x01\x00\x00\x00\x00\x00\x00')
a.type == 9 and a.len == 1 and a.res == b'\x00\x00\x00\x00\x00\x00' and not a.addrlist

= ICMPv6NDOptSrcAddrList - Dissection with specific values (auto len)
a=ICMPv6NDOptSrcAddrList(b'\t\x05BBBBBB\xff\xff\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xff\xff\x11\x11\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x11\x11')
a.type == 9 and a.len == 5 and a.res == b'BBBBBB' and len(a.addrlist) == 2 and a.addrlist[0] == "ffff::ffff" and a.addrlist[1] == "1111::1111"

= ICMPv6NDOptSrcAddrList - Dissection with specific values 
conf.debug_dissector = False
a=ICMPv6NDOptSrcAddrList(b'\t\x03BBBBBB\xff\xff\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xff\xff\x11\x11\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x11\x11')
conf.debug_dissector = True
a.type == 9 and a.len == 3 and a.res == b'BBBBBB' and len(a.addrlist) == 1 and a.addrlist[0] == "ffff::ffff" and isinstance(a.payload, Raw) and a.payload.load == b'\x11\x11\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x11\x11'


############
############
+ ICMPv6NDOptTgtAddrList Class Test 

= ICMPv6NDOptTgtAddrList - Basic Instantiation
raw(ICMPv6NDOptTgtAddrList()) == b'\n\x01\x00\x00\x00\x00\x00\x00'

= ICMPv6NDOptTgtAddrList - Instantiation with specific values (auto len)
raw(ICMPv6NDOptTgtAddrList(res="BBBBBB", addrlist=["ffff::ffff", "1111::1111"])) == b'\n\x05BBBBBB\xff\xff\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xff\xff\x11\x11\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x11\x11'

= ICMPv6NDOptTgtAddrList - Instantiation with specific values 
raw(ICMPv6NDOptTgtAddrList(len=3, res="BBBBBB", addrlist=["ffff::ffff", "1111::1111"])) == b'\n\x03BBBBBB\xff\xff\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xff\xff\x11\x11\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x11\x11'

= ICMPv6NDOptTgtAddrList - Basic Dissection
a=ICMPv6NDOptTgtAddrList(b'\n\x01\x00\x00\x00\x00\x00\x00')
a.type == 10 and a.len == 1 and a.res == b'\x00\x00\x00\x00\x00\x00' and not a.addrlist

= ICMPv6NDOptTgtAddrList - Dissection with specific values (auto len)
a=ICMPv6NDOptTgtAddrList(b'\n\x05BBBBBB\xff\xff\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xff\xff\x11\x11\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x11\x11')
a.type == 10 and a.len == 5 and a.res == b'BBBBBB' and len(a.addrlist) == 2 and a.addrlist[0] == "ffff::ffff" and a.addrlist[1] == "1111::1111"

= ICMPv6NDOptTgtAddrList - Instantiation with specific values 
conf.debug_dissector = False
a=ICMPv6NDOptTgtAddrList(b'\n\x03BBBBBB\xff\xff\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xff\xff\x11\x11\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x11\x11')
conf.debug_dissector = True
a.type == 10 and a.len == 3 and a.res == b'BBBBBB' and len(a.addrlist) == 1 and a.addrlist[0] == "ffff::ffff" and isinstance(a.payload, Raw) and a.payload.load == b'\x11\x11\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x11\x11'


############
############
+ ICMPv6NDOptIPAddr Class Test (RFC 4068)

= ICMPv6NDOptIPAddr - Basic Instantiation 
raw(ICMPv6NDOptIPAddr()) == b'\x11\x03\x01@\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00'

= ICMPv6NDOptIPAddr - Instantiation with specific values
raw(ICMPv6NDOptIPAddr(len=5, optcode=0xff, plen=40, res=0xeeeeeeee, addr="ffff::1111")) == b'\x11\x05\xff(\xee\xee\xee\xee\xff\xff\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x11\x11'

= ICMPv6NDOptIPAddr - Basic Dissection 
a=ICMPv6NDOptIPAddr(b'\x11\x03\x01@\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00')
a.type == 17 and a.len == 3 and a.optcode == 1 and a.plen == 64 and a.res == 0 and a.addr == "::"

= ICMPv6NDOptIPAddr - Dissection with specific values
a=ICMPv6NDOptIPAddr(b'\x11\x05\xff(\xee\xee\xee\xee\xff\xff\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x11\x11')
a.type == 17 and a.len == 5 and a.optcode == 0xff and a.plen == 40 and a.res == 0xeeeeeeee and a.addr == "ffff::1111"


############
############
+ ICMPv6NDOptNewRtrPrefix Class Test (RFC 4068)

= ICMPv6NDOptNewRtrPrefix - Basic Instantiation 
raw(ICMPv6NDOptNewRtrPrefix()) == b'\x12\x03\x00@\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00'

= ICMPv6NDOptNewRtrPrefix - Instantiation with specific values
raw(ICMPv6NDOptNewRtrPrefix(len=5, optcode=0xff, plen=40, res=0xeeeeeeee, prefix="ffff::1111")) == b'\x12\x05\xff(\xee\xee\xee\xee\xff\xff\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x11\x11'

= ICMPv6NDOptNewRtrPrefix - Basic Dissection 
a=ICMPv6NDOptNewRtrPrefix(b'\x12\x03\x00@\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00')
a.type == 18 and a.len == 3 and a.optcode == 0 and a.plen == 64 and a.res == 0 and a.prefix == "::"

= ICMPv6NDOptNewRtrPrefix - Dissection with specific values
a=ICMPv6NDOptNewRtrPrefix(b'\x12\x05\xff(\xee\xee\xee\xee\xff\xff\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x11\x11')
a.type == 18 and a.len == 5 and a.optcode == 0xff and a.plen == 40 and a.res == 0xeeeeeeee and a.prefix == "ffff::1111"


############
############
+ ICMPv6NDOptLLA Class Test (RFC 4068)

= ICMPv6NDOptLLA - Basic Instantiation 
raw(ICMPv6NDOptLLA()) == b'\x13\x01\x00\x00\x00\x00\x00\x00\x00'

= ICMPv6NDOptLLA - Instantiation with specific values
raw(ICMPv6NDOptLLA(len=2, optcode=3, lla="ff:11:ff:11:ff:11")) == b'\x13\x02\x03\xff\x11\xff\x11\xff\x11'

= ICMPv6NDOptLLA - Basic Dissection 
a=ICMPv6NDOptLLA(b'\x13\x01\x00\x00\x00\x00\x00\x00\x00')
a.type == 19 and a.len == 1 and a.optcode == 0 and a.lla == "00:00:00:00:00:00"

= ICMPv6NDOptLLA - Dissection with specific values
a=ICMPv6NDOptLLA(b'\x13\x02\x03\xff\x11\xff\x11\xff\x11')
a.type == 19 and a.len == 2 and a.optcode == 3 and a.lla == "ff:11:ff:11:ff:11"


############
############
+ ICMPv6NDOptRouteInfo Class Test

= ICMPv6NDOptRouteInfo - Basic Instantiation
raw(ICMPv6NDOptRouteInfo()) == b'\x18\x01\x00\x00\xff\xff\xff\xff'

= ICMPv6NDOptRouteInfo - Instantiation with forced prefix but no length
raw(ICMPv6NDOptRouteInfo(prefix="2001:db8:1:1:1:1:1:1")) == b'\x18\x03\x00\x00\xff\xff\xff\xff \x01\r\xb8\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01'

= ICMPv6NDOptRouteInfo - Instantiation with forced length values (1/4)
raw(ICMPv6NDOptRouteInfo(len=1, prefix="2001:db8:1:1:1:1:1:1")) == b'\x18\x01\x00\x00\xff\xff\xff\xff'

= ICMPv6NDOptRouteInfo - Instantiation with forced length values (2/4)
raw(ICMPv6NDOptRouteInfo(len=2, prefix="2001:db8:1:1:1:1:1:1")) == b'\x18\x02\x00\x00\xff\xff\xff\xff \x01\r\xb8\x00\x01\x00\x01'

= ICMPv6NDOptRouteInfo - Instantiation with forced length values (3/4)
raw(ICMPv6NDOptRouteInfo(len=3, prefix="2001:db8:1:1:1:1:1:1")) == b'\x18\x03\x00\x00\xff\xff\xff\xff \x01\r\xb8\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01'

= ICMPv6NDOptRouteInfo - Instantiation with forced length values (4/4)
raw(ICMPv6NDOptRouteInfo(len=4, prefix="2001:db8:1:1:1:1:1:1")) == b'\x18\x04\x00\x00\xff\xff\xff\xff \x01\r\xb8\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x00\x00\x00\x00\x00\x00\x00'

= ICMPv6NDOptRouteInfo - Instantiation with specific values 
raw(ICMPv6NDOptRouteInfo(len=6, plen=0x11, res1=1, prf=3, res2=1, rtlifetime=0x22222222, prefix="2001:db8::1")) == b'\x18\x06\x119"""" \x01\r\xb8\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00'

= ICMPv6NDOptRouteInfo - Basic dissection
a=ICMPv6NDOptRouteInfo(b'\x18\x03\x00\x00\xff\xff\xff\xff\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00')
a.type == 24 and a.len == 3 and a.plen == 0 and a.res1 == 0 and a.prf == 0 and a.res2 == 0 and a.rtlifetime == 0xffffffff and a. prefix == "::"

= ICMPv6NDOptRouteInfo - Dissection with specific values 
a=ICMPv6NDOptRouteInfo(b'\x18\x04\x119"""" \x01\r\xb8\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01')
a.plen == 0x11 and a.res1 == 1 and a.prf == 3 and a.res2 == 1 and a.rtlifetime == 0x22222222 and a.prefix == "2001:db8::1" 

= ICMPv6NDOptRouteInfo - Summary Output
ICMPv6NDOptRouteInfo(b'\x18\x04\x119"""" \x01\r\xb8\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01').mysummary() == "ICMPv6 Neighbor Discovery Option - Route Information Option 2001:db8::1/17 Preference Low"


############
############
+ ICMPv6NDOptMAP Class Test

= ICMPv6NDOptMAP - Basic Instantiation
raw(ICMPv6NDOptMAP()) == b'\x17\x03\x1f\x80\xff\xff\xff\xff\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00'

= ICMPv6NDOptMAP - Instantiation with specific values
raw(ICMPv6NDOptMAP(len=5, dist=3, pref=10, R=0, res=1, validlifetime=0x11111111, addr="ffff::1111")) == b'\x17\x05:\x01\x11\x11\x11\x11\xff\xff\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x11\x11'

= ICMPv6NDOptMAP - Basic Dissection
a=ICMPv6NDOptMAP(b'\x17\x03\x1f\x80\xff\xff\xff\xff\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00')
a.type==23 and a.len==3 and a.dist==1 and a.pref==15 and a.R==1 and a.res==0 and a.validlifetime==0xffffffff and a.addr=="::"

= ICMPv6NDOptMAP - Dissection with specific values
a=ICMPv6NDOptMAP(b'\x17\x05:\x01\x11\x11\x11\x11\xff\xff\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x11\x11')
a.type==23 and a.len==5 and a.dist==3 and a.pref==10 and a.R==0 and a.res==1 and a.validlifetime==0x11111111 and a.addr=="ffff::1111"


############
############
+ ICMPv6NDOptRDNSS Class Test

= ICMPv6NDOptRDNSS - Basic Instantiation
raw(ICMPv6NDOptRDNSS()) == b'\x19\x01\x00\x00\xff\xff\xff\xff'

= ICMPv6NDOptRDNSS - Basic instantiation with 1 DNS address
raw(ICMPv6NDOptRDNSS(dns=["2001:db8::1"])) == b'\x19\x03\x00\x00\xff\xff\xff\xff \x01\r\xb8\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01'

= ICMPv6NDOptRDNSS - Basic instantiation with 2 DNS addresses
raw(ICMPv6NDOptRDNSS(dns=["2001:db8::1", "2001:db8::2"])) == b'\x19\x05\x00\x00\xff\xff\xff\xff \x01\r\xb8\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01 \x01\r\xb8\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x02'

= ICMPv6NDOptRDNSS - Instantiation with specific values
raw(ICMPv6NDOptRDNSS(len=43, res=0xaaee, lifetime=0x11111111, dns=["2001:db8::2"])) == b'\x19+\xaa\xee\x11\x11\x11\x11 \x01\r\xb8\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x02'

= ICMPv6NDOptRDNSS - Basic Dissection
a=ICMPv6NDOptRDNSS(b'\x19\x01\x00\x00\xff\xff\xff\xff')
a.type==25 and a.len==1 and a.res == 0 and a.dns==[]

= ICMPv6NDOptRDNSS - Dissection (with 1 DNS address)
a=ICMPv6NDOptRDNSS(b'\x19\x03\x00\x00\xff\xff\xff\xff \x01\r\xb8\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01')
a.type==25 and a.len==3 and a.res ==0 and len(a.dns) == 1 and a.dns[0] == "2001:db8::1"

= ICMPv6NDOptRDNSS - Dissection (with 2 DNS addresses)
a=ICMPv6NDOptRDNSS(b'\x19\x05\xaa\xee\xff\xff\xff\xff \x01\r\xb8\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01 \x01\r\xb8\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x02')
a.type==25 and a.len==5 and a.res == 0xaaee and len(a.dns) == 2 and a.dns[0] == "2001:db8::1" and a.dns[1] == "2001:db8::2"

= ICMPv6NDOptRDNSS - Summary Output
a=ICMPv6NDOptRDNSS(b'\x19\x05\xaa\xee\xff\xff\xff\xff \x01\r\xb8\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01 \x01\r\xb8\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x02')
a.mysummary() == "ICMPv6 Neighbor Discovery Option - Recursive DNS Server Option 2001:db8::1, 2001:db8::2"


############
############
+ ICMPv6NDOptDNSSL Class Test

= ICMPv6NDOptDNSSL - Basic Instantiation
raw(ICMPv6NDOptDNSSL()) == b'\x1f\x01\x00\x00\xff\xff\xff\xff'

= ICMPv6NDOptDNSSL - Instantiation with 1 search domain, as seen in the wild
raw(ICMPv6NDOptDNSSL(lifetime=60, searchlist=["home."])) == b'\x1f\x02\x00\x00\x00\x00\x00<\x04home\x00\x00\x00'

= ICMPv6NDOptDNSSL - Basic instantiation with 2 search domains
raw(ICMPv6NDOptDNSSL(searchlist=["home.", "office."])) == b'\x1f\x03\x00\x00\xff\xff\xff\xff\x04home\x00\x06office\x00\x00\x00'

= ICMPv6NDOptDNSSL - Basic instantiation with 3 search domains
raw(ICMPv6NDOptDNSSL(searchlist=["home.", "office.", "here.there."])) == b'\x1f\x05\x00\x00\xff\xff\xff\xff\x04home\x00\x06office\x00\x04here\x05there\x00\x00\x00\x00\x00\x00\x00'

= ICMPv6NDOptDNSSL - Basic Dissection
p = ICMPv6NDOptDNSSL(b'\x1f\x01\x00\x00\xff\xff\xff\xff')
p.type == 31 and p.len == 1 and p.res == 0 and p.searchlist == []

= ICMPv6NDOptDNSSL - Basic Dissection with specific values
p = ICMPv6NDOptDNSSL(b'\x1f\x02\x00\x00\x00\x00\x00<\x04home\x00\x00\x00')
p.type == 31 and p.len == 2 and p.res == 0 and p.lifetime == 60 and p.searchlist == ["home."]

= ICMPv6NDOptDNSSL - Summary Output
ICMPv6NDOptDNSSL(searchlist=["home.", "office."]).mysummary() == "ICMPv6 Neighbor Discovery Option - DNS Search List Option home., office."


############
############
+ ICMPv6NDOptEFA Class Test

= ICMPv6NDOptEFA - Basic Instantiation
raw(ICMPv6NDOptEFA()) == b'\x1a\x01\x00\x00\x00\x00\x00\x00'

= ICMPv6NDOptEFA - Basic Dissection
a=ICMPv6NDOptEFA(b'\x1a\x01\x00\x00\x00\x00\x00\x00')
a.type==26 and a.len==1 and a.res == 0


############
############
+ Test Node Information Query - ICMPv6NIQueryNOOP

= ICMPv6NIQueryNOOP - Basic Instantiation
raw(ICMPv6NIQueryNOOP(nonce=b"\x00"*8)) == b'\x8b\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00'

= ICMPv6NIQueryNOOP - Basic Dissection
a = ICMPv6NIQueryNOOP(b'\x8b\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00')
a.type == 139 and a.code == 1 and a.cksum == 0 and a.qtype == 0 and a.unused == 0 and a.flags == 0 and a.nonce == b"\x00"*8 and a.data == b""


############
############
+ Test Node Information Query - ICMPv6NIQueryName

= ICMPv6NIQueryName - single label DNS name (internal)
a=ICMPv6NIQueryName(data="abricot").getfieldval("data")
type(a) is tuple and len(a) == 2 and a[0] == 1 and a[1] == b'\x07abricot\x00\x00'

= ICMPv6NIQueryName - single label DNS name
ICMPv6NIQueryName(data="abricot").data == b"abricot"

= ICMPv6NIQueryName - fqdn (internal)
a=ICMPv6NIQueryName(data="n.d.org").getfieldval("data")
type(a) is tuple and len(a) == 2 and a[0] == 1 and a[1] == b'\x01n\x01d\x03org\x00'

= ICMPv6NIQueryName - fqdn
ICMPv6NIQueryName(data="n.d.org").data == b"n.d.org"

= ICMPv6NIQueryName - IPv6 address (internal)
a=ICMPv6NIQueryName(data="2001:db8::1").getfieldval("data")
type(a) is tuple and len(a) == 2 and a[0] == 0 and a[1] == '2001:db8::1'

= ICMPv6NIQueryName - IPv6 address 
ICMPv6NIQueryName(data="2001:db8::1").data == "2001:db8::1"

= ICMPv6NIQueryName - IPv4 address (internal)
a=ICMPv6NIQueryName(data="169.254.253.252").getfieldval("data")
type(a) is tuple and len(a) == 2 and a[0] == 2 and a[1] == '169.254.253.252'

= ICMPv6NIQueryName - IPv4 address
ICMPv6NIQueryName(data="169.254.253.252").data == '169.254.253.252'

= ICMPv6NIQueryName - build & dissection
s = raw(IPv6()/ICMPv6NIQueryName(data="n.d.org"))
p = IPv6(s)
ICMPv6NIQueryName in p and p[ICMPv6NIQueryName].data == b"n.d.org"

= ICMPv6NIQueryName - dissection
s = b'\x8b\x00z^\x00\x02\x00\x00\x00\x03g\x90\xc7\xa3\xdd[\xff\x02\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01'
p = ICMPv6NIQueryName(s)
p.show()
assert ICMPv6NIQueryName in p and p.data == "ff02::1"


############
############
+ Test Node Information Query - ICMPv6NIQueryIPv6

= ICMPv6NIQueryIPv6 - single label DNS name (internal)
a = ICMPv6NIQueryIPv6(data="abricot")
ls(a)
a = a.getfieldval("data")
type(a) is tuple and len(a) == 2 and a[0] == 1 and a[1] == b'\x07abricot\x00\x00'

= ICMPv6NIQueryIPv6 - single label DNS name
ICMPv6NIQueryIPv6(data="abricot").data == b"abricot"

= ICMPv6NIQueryIPv6 - fqdn (internal)
a=ICMPv6NIQueryIPv6(data="n.d.org").getfieldval("data")
type(a) is tuple and len(a) == 2 and a[0] == 1 and a[1] == b'\x01n\x01d\x03org\x00'

= ICMPv6NIQueryIPv6 - fqdn
ICMPv6NIQueryIPv6(data="n.d.org").data == b"n.d.org"

= ICMPv6NIQueryIPv6 - IPv6 address (internal)
a=ICMPv6NIQueryIPv6(data="2001:db8::1").getfieldval("data")
type(a) is tuple and len(a) == 2 and a[0] == 0 and a[1] == '2001:db8::1'

= ICMPv6NIQueryIPv6 - IPv6 address 
ICMPv6NIQueryIPv6(data="2001:db8::1").data == "2001:db8::1"

= ICMPv6NIQueryIPv6 - IPv4 address (internal)
a=ICMPv6NIQueryIPv6(data="169.254.253.252").getfieldval("data")
type(a) is tuple and len(a) == 2 and a[0] == 2 and a[1] == '169.254.253.252'

= ICMPv6NIQueryIPv6 - IPv4 address
ICMPv6NIQueryIPv6(data="169.254.253.252").data == '169.254.253.252'


############
############
+ Test Node Information Query - ICMPv6NIQueryIPv4

= ICMPv6NIQueryIPv4 - single label DNS name (internal)
a=ICMPv6NIQueryIPv4(data="abricot").getfieldval("data")
type(a) is tuple and len(a) == 2 and a[0] == 1 and a[1] == b'\x07abricot\x00\x00'

= ICMPv6NIQueryIPv4 - single label DNS name
ICMPv6NIQueryIPv4(data="abricot").data == b"abricot"

= ICMPv6NIQueryIPv4 - fqdn (internal)
a=ICMPv6NIQueryIPv4(data="n.d.org").getfieldval("data")
type(a) is tuple and len(a) == 2 and a[0] == 1 and a[1] == b'\x01n\x01d\x03org\x00'

= ICMPv6NIQueryIPv4 - fqdn
ICMPv6NIQueryIPv4(data="n.d.org").data == b"n.d.org"

= ICMPv6NIQueryIPv4 - IPv6 address (internal)
a=ICMPv6NIQueryIPv4(data="2001:db8::1").getfieldval("data")
type(a) is tuple and len(a) == 2 and a[0] == 0 and a[1] == '2001:db8::1'

= ICMPv6NIQueryIPv4 - IPv6 address 
ICMPv6NIQueryIPv4(data="2001:db8::1").data == "2001:db8::1"

= ICMPv6NIQueryIPv4 - IPv4 address (internal)
a=ICMPv6NIQueryIPv4(data="169.254.253.252").getfieldval("data")
type(a) is tuple and len(a) == 2 and a[0] == 2 and a[1] == '169.254.253.252'

= ICMPv6NIQueryIPv4 - IPv4 address
ICMPv6NIQueryIPv4(data="169.254.253.252").data == '169.254.253.252'

= ICMPv6NIQueryIPv4 - dissection
s = b'\x8b\x01\x00\x00\x00\x04\x00\x00\xc2\xb9\xc2\x96\xc3\xa1.H\x07freebsd\x00\x00'
p = ICMPv6NIQueryIPv4(s)
p.show()
assert ICMPv6NIQueryIPv4 in p and p.data == b"freebsd"

= ICMPv6NIQueryIPv4 - hashret()
~ not_pypy random_weird_py3
random.seed(0x2807)
p = IPv6()/ICMPv6NIQueryIPv4(data="freebsd")
h_py2 = b'\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00:\xe10S7\x9d\x91\x84\xc9'
h_py3 = b'\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00:\xa8\x19uE\x01\xcf\xe3\x04'
assert p.hashret() in [h_py2, h_py3]


############
############
+ Test Node Information Query - Flags tests

= ICMPv6NIQuery* - flags handling (Test 1)
t = ICMPv6NIQueryIPv6(flags="T")
a = ICMPv6NIQueryIPv6(flags="A")
c = ICMPv6NIQueryIPv6(flags="C")
l = ICMPv6NIQueryIPv6(flags="L")
s = ICMPv6NIQueryIPv6(flags="S")
g = ICMPv6NIQueryIPv6(flags="G")
allflags = ICMPv6NIQueryIPv6(flags="TALCLSG")
t.flags == 1 and a.flags == 2 and c.flags == 4 and l.flags == 8 and s.flags == 16 and g.flags == 32 and allflags.flags == 63


= ICMPv6NIQuery* - flags handling (Test 2)
t = raw(ICMPv6NIQueryNOOP(flags="T", nonce="A"*8))[6:8]
a = raw(ICMPv6NIQueryNOOP(flags="A", nonce="A"*8))[6:8]
c = raw(ICMPv6NIQueryNOOP(flags="C", nonce="A"*8))[6:8]
l = raw(ICMPv6NIQueryNOOP(flags="L", nonce="A"*8))[6:8]
s = raw(ICMPv6NIQueryNOOP(flags="S", nonce="A"*8))[6:8]
g = raw(ICMPv6NIQueryNOOP(flags="G", nonce="A"*8))[6:8]
allflags = raw(ICMPv6NIQueryNOOP(flags="TALCLSG", nonce="A"*8))[6:8]
t == b'\x00\x01' and a == b'\x00\x02' and c == b'\x00\x04' and l == b'\x00\x08' and s == b'\x00\x10' and g == b'\x00\x20' and allflags == b'\x00\x3F'


= ICMPv6NIReply* - flags handling (Test 1)
t = ICMPv6NIReplyIPv6(flags="T")
a = ICMPv6NIReplyIPv6(flags="A")
c = ICMPv6NIReplyIPv6(flags="C")
l = ICMPv6NIReplyIPv6(flags="L")
s = ICMPv6NIReplyIPv6(flags="S")
g = ICMPv6NIReplyIPv6(flags="G")
allflags = ICMPv6NIReplyIPv6(flags="TALCLSG")
t.flags == 1 and a.flags == 2 and c.flags == 4 and l.flags == 8 and s.flags == 16 and g.flags == 32 and allflags.flags == 63


= ICMPv6NIReply* - flags handling (Test 2)
t = raw(ICMPv6NIReplyNOOP(flags="T", nonce="A"*8))[6:8]
a = raw(ICMPv6NIReplyNOOP(flags="A", nonce="A"*8))[6:8]
c = raw(ICMPv6NIReplyNOOP(flags="C", nonce="A"*8))[6:8]
l = raw(ICMPv6NIReplyNOOP(flags="L", nonce="A"*8))[6:8]
s = raw(ICMPv6NIReplyNOOP(flags="S", nonce="A"*8))[6:8]
g = raw(ICMPv6NIReplyNOOP(flags="G", nonce="A"*8))[6:8]
allflags = raw(ICMPv6NIReplyNOOP(flags="TALCLSG", nonce="A"*8))[6:8]
t == b'\x00\x01' and a == b'\x00\x02' and c == b'\x00\x04' and l == b'\x00\x08' and s == b'\x00\x10' and g == b'\x00\x20' and allflags == b'\x00\x3F'


= ICMPv6NIQuery* - Flags Default values
a = ICMPv6NIQueryNOOP()
b = ICMPv6NIQueryName()
c = ICMPv6NIQueryIPv4()
d = ICMPv6NIQueryIPv6()
a.flags == 0 and b.flags == 0 and c.flags == 0 and d.flags == 62

= ICMPv6NIReply* - Flags Default values
a = ICMPv6NIReplyIPv6()
b = ICMPv6NIReplyName()
c = ICMPv6NIReplyIPv6()
d = ICMPv6NIReplyIPv4()
e = ICMPv6NIReplyRefuse()
f = ICMPv6NIReplyUnknown()
a.flags == 0 and b.flags == 0 and c.flags == 0 and d.flags == 0 and e.flags == 0 and f.flags == 0



# Nonces 
# hashret and answers
# payload guess
# automatic destination address computation when integrated in scapy6
# at least computeNIGroupAddr


############
############
+ Test Node Information Query - Dispatching

= ICMPv6NIQueryIPv6 - dispatch with nothing in data
s = raw(IPv6(src="2001:db8::1", dst="2001:db8::2")/ICMPv6NIQueryIPv6())
p = IPv6(s)
isinstance(p.payload, ICMPv6NIQueryIPv6)

= ICMPv6NIQueryIPv6 - dispatch with IPv6 address in data
s = raw(IPv6(src="2001:db8::1", dst="2001:db8::2")/ICMPv6NIQueryIPv6(data="2001::db8::1"))
p = IPv6(s)
isinstance(p.payload, ICMPv6NIQueryIPv6)

= ICMPv6NIQueryIPv6 - dispatch with IPv4 address in data
s = raw(IPv6(src="2001:db8::1", dst="2001:db8::2")/ICMPv6NIQueryIPv6(data="192.168.0.1"))
p = IPv6(s)
isinstance(p.payload, ICMPv6NIQueryIPv6)

= ICMPv6NIQueryIPv6 - dispatch with name in data
s = raw(IPv6(src="2001:db8::1", dst="2001:db8::2")/ICMPv6NIQueryIPv6(data="alfred"))
p = IPv6(s)
isinstance(p.payload, ICMPv6NIQueryIPv6)

= ICMPv6NIQueryName - dispatch with nothing in data
s = raw(IPv6(src="2001:db8::1", dst="2001:db8::2")/ICMPv6NIQueryName())
p = IPv6(s)
isinstance(p.payload, ICMPv6NIQueryName)

= ICMPv6NIQueryName - dispatch with IPv6 address in data
s = raw(IPv6(src="2001:db8::1", dst="2001:db8::2")/ICMPv6NIQueryName(data="2001:db8::1"))
p = IPv6(s)
isinstance(p.payload, ICMPv6NIQueryName)

= ICMPv6NIQueryName - dispatch with IPv4 address in data
s = raw(IPv6(src="2001:db8::1", dst="2001:db8::2")/ICMPv6NIQueryName(data="192.168.0.1"))
p = IPv6(s)
isinstance(p.payload, ICMPv6NIQueryName)

= ICMPv6NIQueryName - dispatch with name in data
s = raw(IPv6(src="2001:db8::1", dst="2001:db8::2")/ICMPv6NIQueryName(data="alfred"))
p = IPv6(s)
isinstance(p.payload, ICMPv6NIQueryName)

= ICMPv6NIQueryIPv4 - dispatch with nothing in data
s = raw(IPv6(src="2001:db8::1", dst="2001:db8::2")/ICMPv6NIQueryIPv4())
p = IPv6(s)
isinstance(p.payload, ICMPv6NIQueryIPv4)

= ICMPv6NIQueryIPv4 - dispatch with IPv6 address in data
s = raw(IPv6(src="2001:db8::1", dst="2001:db8::2")/ICMPv6NIQueryIPv4(data="2001:db8::1"))
p = IPv6(s)
isinstance(p.payload, ICMPv6NIQueryIPv4)

= ICMPv6NIQueryIPv4 - dispatch with IPv6 address in data
s = raw(IPv6(src="2001:db8::1", dst="2001:db8::2")/ICMPv6NIQueryIPv4(data="192.168.0.1"))
p = IPv6(s)
isinstance(p.payload, ICMPv6NIQueryIPv4)

= ICMPv6NIQueryIPv4 - dispatch with name in data
s = raw(IPv6(src="2001:db8::1", dst="2001:db8::2")/ICMPv6NIQueryIPv4(data="alfred"))
p = IPv6(s)
isinstance(p.payload, ICMPv6NIQueryIPv4)

= ICMPv6NIReplyName - dispatch
s = raw(IPv6(src="2001:db8::1", dst="2001:db8::2")/ICMPv6NIReplyName())
p = IPv6(s)
isinstance(p.payload, ICMPv6NIReplyName)

= ICMPv6NIReplyIPv6 - dispatch
s = raw(IPv6(src="2001:db8::1", dst="2001:db8::2")/ICMPv6NIReplyIPv6())
p = IPv6(s)
isinstance(p.payload, ICMPv6NIReplyIPv6)

= ICMPv6NIReplyIPv4 - dispatch
s = raw(IPv6(src="2001:db8::1", dst="2001:db8::2")/ICMPv6NIReplyIPv4())
p = IPv6(s)
isinstance(p.payload, ICMPv6NIReplyIPv4)

= ICMPv6NIReplyRefuse - dispatch
s = raw(IPv6(src="2001:db8::1", dst="2001:db8::2")/ICMPv6NIReplyRefuse())
p = IPv6(s)
isinstance(p.payload, ICMPv6NIReplyRefuse)

= ICMPv6NIReplyUnknown - dispatch
s = raw(IPv6(src="2001:db8::1", dst="2001:db8::2")/ICMPv6NIReplyUnknown())
p = IPv6(s)
isinstance(p.payload, ICMPv6NIReplyUnknown)


############
############
+ Test Node Information Query - ICMPv6NIReplyNOOP

= ICMPv6NIReplyNOOP - single DNS name without hint => understood as string (internal)
a=ICMPv6NIReplyNOOP(data="abricot").getfieldval("data")
type(a) is tuple and len(a) == 2 and a[0] == 0 and a[1] == b"abricot"

= ICMPv6NIReplyNOOP - single DNS name without hint => understood as string
ICMPv6NIReplyNOOP(data="abricot").data == b"abricot"

= ICMPv6NIReplyNOOP - fqdn without hint => understood as string (internal)
a=ICMPv6NIReplyNOOP(data="n.d.tld").getfieldval("data")
type(a) is tuple and len(a) == 2 and a[0] == 0 and a[1] == b"n.d.tld"

= ICMPv6NIReplyNOOP - fqdn without hint => understood as string 
ICMPv6NIReplyNOOP(data="n.d.tld").data == b"n.d.tld"

= ICMPv6NIReplyNOOP - IPv6 address without hint => understood as string (internal)
a=ICMPv6NIReplyNOOP(data="2001:0db8::1").getfieldval("data")
type(a) is tuple and len(a) == 2 and a[0] == 0 and a[1] == b"2001:0db8::1"

= ICMPv6NIReplyNOOP - IPv6 address without hint => understood as string
ICMPv6NIReplyNOOP(data="2001:0db8::1").data == b"2001:0db8::1"

= ICMPv6NIReplyNOOP - IPv4 address without hint => understood as string (internal)
a=ICMPv6NIReplyNOOP(data="169.254.253.010").getfieldval("data")
type(a) is tuple and len(a) == 2 and a[0] == 0 and a[1] == b"169.254.253.010"

= ICMPv6NIReplyNOOP - IPv4 address without hint => understood as string
ICMPv6NIReplyNOOP(data="169.254.253.010").data == b"169.254.253.010"


############
############
+ Test Node Information Query - ICMPv6NIReplyName

= ICMPv6NIReplyName - single label DNS name as a rawing (without ttl) (internal)
a=ICMPv6NIReplyName(data="abricot").getfieldval("data")
type(a) is tuple and len(a) == 2 and a[0] == 2 and type(a[1]) is list and len(a[1]) == 2 and a[1][0] == 0 and a[1][1] == b'\x07abricot\x00\x00'

= ICMPv6NIReplyName - single label DNS name as a rawing (without ttl)
ICMPv6NIReplyName(data="abricot").data == [0, b"abricot"]

= ICMPv6NIReplyName - fqdn name as a rawing (without ttl) (internal)
a=ICMPv6NIReplyName(data="n.d.tld").getfieldval("data")
type(a) is tuple and len(a) == 2 and a[0] == 2 and type(a[1]) is list and len(a[1]) == 2 and a[1][0] == 0 and a[1][1] == b'\x01n\x01d\x03tld\x00'

= ICMPv6NIReplyName - fqdn name as a rawing (without ttl)
ICMPv6NIReplyName(data="n.d.tld").data == [0, b'n.d.tld']

= ICMPv6NIReplyName - list of 2 single label DNS names (without ttl) (internal)
a=ICMPv6NIReplyName(data=["abricot", "poire"]).getfieldval("data")
type(a) is tuple and len(a) == 2 and a[0] == 2 and type(a[1]) is list and len(a[1]) == 2 and a[1][0] == 0 and a[1][1] == b'\x07abricot\x00\x00\x05poire\x00\x00'

= ICMPv6NIReplyName - list of 2 single label DNS names (without ttl)
ICMPv6NIReplyName(data=["abricot", "poire"]).data == [0, b"abricot", b"poire"]

= ICMPv6NIReplyName - [ttl, single-label, single-label, fqdn] (internal)
a=ICMPv6NIReplyName(data=[42, "abricot", "poire", "n.d.tld"]).getfieldval("data")
type(a) is tuple and len(a) == 2 and a[0] == 2 and type(a[1]) is list and len(a[1]) == 2 and a[1][0] == 42 and a[1][1] == b'\x07abricot\x00\x00\x05poire\x00\x00\x01n\x01d\x03tld\x00'

= ICMPv6NIReplyName - [ttl, single-label, single-label, fqdn]
ICMPv6NIReplyName(data=[42, "abricot", "poire", "n.d.tld"]).data == [42, b"abricot", b"poire", b"n.d.tld"]

= ICMPv6NIReplyName - dissection

s = b'\x8c\x00\xd1\x0f\x00\x02\x00\x00\x00\x00\xd9$\x94\x8d\xc6%\x00\x00\x00\x00\x07freebsd\x00\x00'
p = ICMPv6NIReplyName(s)
p.show()
assert ICMPv6NIReplyName in p and p.data == [0, b'freebsd']


############
############
+ Test Node Information Query - ICMPv6NIReplyIPv6

= ICMPv6NIReplyIPv6 - one IPv6 address without TTL (internal)
a=ICMPv6NIReplyIPv6(data="2001:db8::1").getfieldval("data")
type(a) is tuple and len(a) == 2 and a[0] == 3 and type(a[1]) is list and len(a[1]) == 1 and type(a[1][0]) is tuple and len(a[1][0]) == 2 and a[1][0][0] == 0 and a[1][0][1] == "2001:db8::1" 

= ICMPv6NIReplyIPv6 - one IPv6 address without TTL
ICMPv6NIReplyIPv6(data="2001:db8::1").data == [(0, '2001:db8::1')]

= ICMPv6NIReplyIPv6 - one IPv6 address without TTL (as a list)  (internal)
a=ICMPv6NIReplyIPv6(data=["2001:db8::1"]).getfieldval("data")
type(a) is tuple and len(a) == 2 and a[0] == 3 and type(a[1]) is list and len(a[1]) == 1 and type(a[1][0]) is tuple and len(a[1][0]) == 2 and a[1][0][0] == 0 and a[1][0][1] == "2001:db8::1" 

= ICMPv6NIReplyIPv6 - one IPv6 address without TTL (as a list) 
ICMPv6NIReplyIPv6(data=["2001:db8::1"]).data == [(0, '2001:db8::1')]

= ICMPv6NIReplyIPv6 - one IPv6 address with TTL  (internal)
a=ICMPv6NIReplyIPv6(data=[(0, "2001:db8::1")]).getfieldval("data")
type(a) is tuple and len(a) == 2 and a[0] == 3 and type(a[1]) is list and len(a[1]) == 1 and type(a[1][0]) is tuple and len(a[1][0]) == 2 and a[1][0][0] == 0 and a[1][0][1] == "2001:db8::1" 

= ICMPv6NIReplyIPv6 - one IPv6 address with TTL
ICMPv6NIReplyIPv6(data=[(0, "2001:db8::1")]).data == [(0, '2001:db8::1')]

= ICMPv6NIReplyIPv6 - two IPv6 addresses as a list of rawings (without TTL) (internal)
a=ICMPv6NIReplyIPv6(data=["2001:db8::1", "2001:db8::2"]).getfieldval("data")
type(a) is tuple and len(a) == 2 and a[0] == 3 and type(a[1]) is list and len(a[1]) == 2 and type(a[1][0]) is tuple and len(a[1][0]) == 2 and a[1][0][0] == 0 and a[1][0][1] == "2001:db8::1" and len(a[1][1]) == 2 and a[1][1][0] == 0 and a[1][1][1] == "2001:db8::2" 

= ICMPv6NIReplyIPv6 - two IPv6 addresses as a list of rawings (without TTL)
ICMPv6NIReplyIPv6(data=["2001:db8::1", "2001:db8::2"]).data == [(0, '2001:db8::1'), (0, '2001:db8::2')]

= ICMPv6NIReplyIPv6 - two IPv6 addresses as a list (first with ttl, second without) (internal)
a=ICMPv6NIReplyIPv6(data=[(42, "2001:db8::1"), "2001:db8::2"]).getfieldval("data")
type(a) is tuple and len(a) == 2 and a[0] == 3 and type(a[1]) is list and len(a[1]) == 2 and type(a[1][0]) is tuple and len(a[1][0]) == 2 and a[1][0][0] == 42 and a[1][0][1] == "2001:db8::1" and len(a[1][1]) == 2 and a[1][1][0] == 0 and a[1][1][1] == "2001:db8::2" 

= ICMPv6NIReplyIPv6 - two IPv6 addresses as a list (first with ttl, second without)
ICMPv6NIReplyIPv6(data=[(42, "2001:db8::1"), "2001:db8::2"]).data == [(42, "2001:db8::1"), (0, "2001:db8::2")]

= ICMPv6NIReplyIPv6 - build & dissection

s = raw(IPv6()/ICMPv6NIReplyIPv6(data="2001:db8::1"))
p = IPv6(s)
ICMPv6NIReplyIPv6 in p and p.data == [(0, '2001:db8::1')]

############
############
+ Test Node Information Query - ICMPv6NIReplyIPv4

= ICMPv6NIReplyIPv4 - one IPv4 address without TTL (internal)
a=ICMPv6NIReplyIPv4(data="169.254.253.252").getfieldval("data")
type(a) is tuple and len(a) == 2 and a[0] == 4 and type(a[1]) is list and len(a[1]) == 1 and type(a[1][0]) is tuple and len(a[1][0]) == 2 and a[1][0][0] == 0 and a[1][0][1] == "169.254.253.252" 

= ICMPv6NIReplyIPv4 - one IPv4 address without TTL
ICMPv6NIReplyIPv4(data="169.254.253.252").data == [(0, '169.254.253.252')]

= ICMPv6NIReplyIPv4 - one IPv4 address without TTL (as a list) (internal)
a=ICMPv6NIReplyIPv4(data=["169.254.253.252"]).getfieldval("data")
type(a) is tuple and len(a) == 2 and a[0] == 4 and type(a[1]) is list and len(a[1]) == 1 and type(a[1][0]) is tuple and len(a[1][0]) == 2 and a[1][0][0] == 0 and a[1][0][1] == "169.254.253.252" 

= ICMPv6NIReplyIPv4 - one IPv4 address without TTL (as a list)
ICMPv6NIReplyIPv4(data=["169.254.253.252"]).data == [(0, '169.254.253.252')]

= ICMPv6NIReplyIPv4 - one IPv4 address with TTL (internal)
a=ICMPv6NIReplyIPv4(data=[(0, "169.254.253.252")]).getfieldval("data")
type(a) is tuple and len(a) == 2 and a[0] == 4 and type(a[1]) is list and len(a[1]) == 1 and type(a[1][0]) is tuple and len(a[1][0]) == 2 and a[1][0][0] == 0 and a[1][0][1] == "169.254.253.252" 

= ICMPv6NIReplyIPv4 - one IPv4 address with TTL (internal)
ICMPv6NIReplyIPv4(data=[(0, "169.254.253.252")]).data == [(0, '169.254.253.252')]

= ICMPv6NIReplyIPv4 - two IPv4 addresses as a list of rawings (without TTL)
a=ICMPv6NIReplyIPv4(data=["169.254.253.252", "169.254.253.253"]).getfieldval("data")
type(a) is tuple and len(a) == 2 and a[0] == 4 and type(a[1]) is list and len(a[1]) == 2 and type(a[1][0]) is tuple and len(a[1][0]) == 2 and a[1][0][0] == 0 and a[1][0][1] == "169.254.253.252" and len(a[1][1]) == 2 and a[1][1][0] == 0 and a[1][1][1] == "169.254.253.253" 

= ICMPv6NIReplyIPv4 - two IPv4 addresses as a list of rawings (without TTL) (internal)
ICMPv6NIReplyIPv4(data=["169.254.253.252", "169.254.253.253"]).data == [(0, '169.254.253.252'), (0, '169.254.253.253')]

= ICMPv6NIReplyIPv4 - two IPv4 addresses as a list (first with ttl, second without)
a=ICMPv6NIReplyIPv4(data=[(42, "169.254.253.252"), "169.254.253.253"]).getfieldval("data")
type(a) is tuple and len(a) == 2 and a[0] == 4 and type(a[1]) is list and len(a[1]) == 2 and type(a[1][0]) is tuple and len(a[1][0]) == 2 and a[1][0][0] == 42 and a[1][0][1] == "169.254.253.252" and len(a[1][1]) == 2 and a[1][1][0] == 0 and a[1][1][1] == "169.254.253.253" 

= ICMPv6NIReplyIPv4 - two IPv4 addresses as a list (first with ttl, second without) (internal)
ICMPv6NIReplyIPv4(data=[(42, "169.254.253.252"), "169.254.253.253"]).data == [(42, "169.254.253.252"), (0, "169.254.253.253")]

= ICMPv6NIReplyIPv4 - build & dissection

s = raw(IPv6()/ICMPv6NIReplyIPv4(data="192.168.0.1"))
p = IPv6(s)
ICMPv6NIReplyIPv4 in p and p.data == [(0, '192.168.0.1')]

s = raw(IPv6()/ICMPv6NIReplyIPv4(data=[(2807, "192.168.0.1")]))
p = IPv6(s)
ICMPv6NIReplyIPv4 in p and p.data == [(2807, "192.168.0.1")]


############
############
+ Test Node Information Query - ICMPv6NIReplyRefuse
= ICMPv6NIReplyRefuse - basic instantiation
raw(ICMPv6NIReplyRefuse())[:8] == b'\x8c\x01\x00\x00\x00\x00\x00\x00'

= ICMPv6NIReplyRefuse - basic dissection
a=ICMPv6NIReplyRefuse(b'\x8c\x01\x00\x00\x00\x00\x00\x00\xf1\xe9\xab\xc9\x8c\x0by\x18')
a.type == 140 and a.code == 1 and a.cksum == 0 and a.unused == 0 and a.flags == 0 and a.nonce == b'\xf1\xe9\xab\xc9\x8c\x0by\x18' and a.data ==  None


############
############
+ Test Node Information Query - ICMPv6NIReplyUnknown

= ICMPv6NIReplyUnknown - basic instantiation
raw(ICMPv6NIReplyUnknown(nonce=b'\x00'*8)) == b'\x8c\x02\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00'

= ICMPv6NIReplyRefuse - basic dissection
a=ICMPv6NIReplyRefuse(b'\x8c\x02\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00')
a.type == 140 and a.code == 2 and a.cksum == 0 and a.unused == 0 and a.flags == 0 and a.nonce == b'\x00'*8 and a.data ==  None


############
############
+ Test Node Information Query - utilities

= computeNIGroupAddr
computeNIGroupAddr("scapy") == "ff02::2:f886:2f66"


############
############
+ IPv6ExtHdrFragment Class Test

= IPv6ExtHdrFragment - Basic Instantiation
raw(IPv6ExtHdrFragment()) == b';\x00\x00\x00\x00\x00\x00\x00'

= IPv6ExtHdrFragment - Instantiation with specific values
raw(IPv6ExtHdrFragment(nh=0xff, res1=0xee, offset=0x1fff, res2=1, m=1, id=0x11111111)) == b'\xff\xee\xff\xfb\x11\x11\x11\x11'

= IPv6ExtHdrFragment - Basic Dissection 
a=IPv6ExtHdrFragment(b';\x00\x00\x00\x00\x00\x00\x00')
a.nh == 59 and a.res1 == 0 and a.offset == 0 and a.res2 == 0 and a.m == 0 and a.id == 0

= IPv6ExtHdrFragment - Instantiation with specific values
a=IPv6ExtHdrFragment(b'\xff\xee\xff\xfb\x11\x11\x11\x11')
a.nh == 0xff and a.res1 == 0xee and a.offset==0x1fff and a.res2==1 and a.m == 1 and a.id == 0x11111111


############
############
+ Test fragment6 function

= fragment6 - test against a long TCP packet with a 1280 MTU
l=fragment6(IPv6()/IPv6ExtHdrFragment()/TCP()/Raw(load="A"*40000), 1280) 
len(l) == 33 and len(raw(l[-1])) == 644


############
############
+ Test defragment6 function

= defragment6 - test against a long TCP packet fragmented with a 1280 MTU
l=fragment6(IPv6()/IPv6ExtHdrFragment()/TCP()/Raw(load="A"*40000), 1280) 
raw(defragment6(l)) == (b'`\x00\x00\x00\x9cT\x06@\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01\x00\x14\x00P\x00\x00\x00\x00\x00\x00\x00\x00P\x02 \x00\xe92\x00\x00' + b'A'*40000)


= defragment6 - test against a large TCP packet fragmented with a 1280 bytes MTU and missing fragments
l=fragment6(IPv6()/IPv6ExtHdrFragment()/TCP()/Raw(load="A"*40000), 1280) 
del(l[2])
del(l[4])
del(l[12])
del(l[18])
raw(defragment6(l)) == (b'`\x00\x00\x00\x9cT\x06@\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01\x00\x14\x00P\x00\x00\x00\x00\x00\x00\x00\x00P\x02 \x00\xe92\x00\x00' + 2444*b'A' + 1232*b'X' + 2464*b'A' + 1232*b'X' + 9856*b'A' + 1232*b'X' + 7392*b'A' + 1232*b'X' + 12916*b'A')


= defragment6 - test against a TCP packet fragmented with a 800 bytes MTU and missing fragments
l=fragment6(IPv6()/IPv6ExtHdrFragment()/TCP()/Raw(load="A"*4000), 800) 
del(l[4])
del(l[2])
raw(defragment6(l)) == b'`\x00\x00\x00\x0f\xb4\x06@\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01\x00\x14\x00P\x00\x00\x00\x00\x00\x00\x00\x00P\x02 \x00\xb2\x0f\x00\x00AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA'

= defragment6 - test the packet length
pkts = fragment6(IPv6()/IPv6ExtHdrFragment()/UDP(dport=42, sport=42)/Raw(load="A"*1500), 1280)
pkts = [IPv6(raw(p)) for p in pkts]
assert defragment6(pkts).plen == 1508


############
############
+ Test Route6 class

= Route6 - Route6 flushing
conf_iface = conf.iface
conf.iface = "eth0"
conf.route6.routes=[
(                               '::1', 128,                       '::',   'lo', ['::1'], 1), 
(          'fe80::20f:1fff:feca:4650', 128,                       '::',   'lo', ['::1'], 1)]
conf.route6.flush()
not conf.route6.routes

= Route6 - Route6.route
conf.route6.flush()
conf.route6.routes=[
(                               '::1', 128,                       '::',   'lo', ['::1'], 1), 
(          'fe80::20f:1fff:feca:4650', 128,                       '::',   'lo', ['::1'], 1), 
(                            'fe80::',  64,                       '::', 'eth0', ['fe80::20f:1fff:feca:4650'], 1),
('2001:db8:0:4444:20f:1fff:feca:4650', 128,                       '::',   'lo', ['::1'], 1), 
(                 '2001:db8:0:4444::',  64,                       '::', 'eth0', ['2001:db8:0:4444:20f:1fff:feca:4650'], 1), 
(                                '::',   0, 'fe80::20f:34ff:fe8a:8aa1', 'eth0', ['2001:db8:0:4444:20f:1fff:feca:4650', '2002:db8:0:4444:20f:1fff:feca:4650'], 1)
]
conf.route6.route("2002::1") == ('eth0', '2002:db8:0:4444:20f:1fff:feca:4650', 'fe80::20f:34ff:fe8a:8aa1') and conf.route6.route("2001::1") == ('eth0', '2001:db8:0:4444:20f:1fff:feca:4650', 'fe80::20f:34ff:fe8a:8aa1') and conf.route6.route("fe80::20f:1fff:feab:4870") == ('eth0', 'fe80::20f:1fff:feca:4650', '::') and conf.route6.route("::1") == ('lo', '::1', '::') and conf.route6.route("::") == ('eth0', '2001:db8:0:4444:20f:1fff:feca:4650', 'fe80::20f:34ff:fe8a:8aa1') and conf.route6.route('ff00::') == ('eth0', '2001:db8:0:4444:20f:1fff:feca:4650', 'fe80::20f:34ff:fe8a:8aa1')
conf.iface = conf_iface
conf.route6.resync()
if not len(conf.route6.routes):
    # IPv6 seems disabled. Force a route to ::1
    conf.route6.routes.append(("::1", 128, "::", LOOPBACK_NAME, ["::1"], 1))
    True

= Route6 - Route6.make_route

r6 = Route6()
r6.make_route("2001:db8::1", dev=LOOPBACK_NAME) == ("2001:db8::1", 128, "::", LOOPBACK_NAME, [], 1)
len_r6 = len(r6.routes)

= Route6 - Route6.add & Route6.delt

r6.add(dst="2001:db8:cafe:f000::/64", gw="2001:db8:cafe::1", dev="eth0")
assert(len(r6.routes) == len_r6 + 1)
r6.delt(dst="2001:db8:cafe:f000::/64", gw="2001:db8:cafe::1")
assert(len(r6.routes) == len_r6)

= Route6 - Route6.ifadd & Route6.ifdel
r6.ifadd("scapy0", "2001:bd8:cafe:1::1/64")
r6.ifdel("scapy0")

= IPv6 - utils

@mock.patch("scapy.layers.inet6.get_if_hwaddr")
@mock.patch("scapy.layers.inet6.srp1")
def test_neighsol(mock_srp1, mock_get_if_hwaddr):
    mock_srp1.return_value = Ether()/IPv6()/ICMPv6ND_NA()/ICMPv6NDOptDstLLAddr(lladdr="05:04:03:02:01:00")
    mock_get_if_hwaddr.return_value = "00:01:02:03:04:05"
    return neighsol("fe80::f6ce:46ff:fea9:e04b", "fe80::f6ce:46ff:fea9:e04b", "scapy0")

p = test_neighsol()
ICMPv6NDOptDstLLAddr in p and p[ICMPv6NDOptDstLLAddr].lladdr == "05:04:03:02:01:00"


@mock.patch("scapy.layers.inet6.neighsol")
@mock.patch("scapy.layers.inet6.conf.route6.route")
def test_getmacbyip6(mock_route6, mock_neighsol):
    mock_route6.return_value = ("scapy0", "fe80::baca:3aff:fe72:b08b", "::")
    mock_neighsol.return_value = test_neighsol()
    return getmacbyip6("fe80::704:3ff:fe2:100")

test_getmacbyip6() == "05:04:03:02:01:00"

= IPv6 - IPerror6 & UDPerror & _ICMPv6Error

query = IPv6(dst="2001:db8::1", src="2001:db8::2", hlim=1)/UDP()/DNS()
answer = IPv6(dst="2001:db8::2", src="2001:db8::1", hlim=1)/ICMPv6TimeExceeded()/IPerror6(dst="2001:db8::1", src="2001:db8::2", hlim=0)/UDPerror()/DNS()
answer.answers(query) == True

# Test _ICMPv6Error
from scapy.layers.inet6 import _ICMPv6Error
assert _ICMPv6Error().guess_payload_class(None) == IPerror6

############
############
+ ICMPv6ML

= ICMPv6MLQuery - build & dissection
s = raw(IPv6(src="fe80::1")/ICMPv6MLQuery())
assert s == b"`\x00\x00\x00\x00\x18:\x01\xfe\x80\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01\xff\x02\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01\x82\x00Y\x17'\x10\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"

p = IPv6(s)
assert ICMPv6MLQuery in p and p[IPv6].dst == "ff02::1"

= Check awnswers

q = IPv6()/IPv6ExtHdrHopByHop(options=[RouterAlert()])/ICMPv6MLQuery()
a = IPv6()/IPv6ExtHdrHopByHop(options=[RouterAlert()])/ICMPv6MLReport()

assert a.answers(q)

############
############
+ ICMPv6MLv2

= ICMPv6MLQuery2 - build & dissection
p = IPv6()/IPv6ExtHdrHopByHop(options=[RouterAlert()])/ICMPv6MLQuery2(sources=["::1"])
s = raw(p)
assert s == b"`\x00\x00\x00\x004\x00@\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01:\x00\x05\x02\x00\x00\x01\x00\x82\x00V\x85'\x10\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01"

p = IPv6(s)
assert ICMPv6MLQuery2 in p and p.sources_number == 1

= ICMPv6MLReport2 - build & dissection
p = IPv6()/IPv6ExtHdrHopByHop(options=[RouterAlert()])/ICMPv6MLReport2(records=[ICMPv6MLDMultAddrRec(), ICMPv6MLDMultAddrRec(sources=["::1"], auxdata="scapy")])
s = raw(p)
assert s == b'`\x00\x00\x00\x00M\x00@\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01:\x00\x05\x02\x00\x00\x01\x00\x8f\x00\x1a\xa1\x00\x00\x00\x02\x04\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x04\x05\x00\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01scapy'

p = IPv6(s)
assert ICMPv6MLReport2 in p and p.records_number == 2

= ICMPv6MLReport2 and ICMPv6MLDMultAddrRec - dissection

z = b'33\x00\x00\x00\x16\xd0P\x99V\xdd\xf9\x86\xdd`\x00\x00\x00\x00\x1c:\x01\xfe\x80\x00\x00\x00\x00\x00\x00q eX\x98\x86\xfa\x88\xff\x02\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x16\x8f\x00\x13\x4d\x00\x00\x00\x01\x04\x00\x00\x00\xff\x02\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01\xffR\xf3\xe1'
w = Ether(z)

assert len(w.records) == 1
assert isinstance(w.records[0], ICMPv6MLDMultAddrRec)
assert w.records[0].dst == "ff02::1:ff52:f3e1"

= Check answers

q = IPv6()/IPv6ExtHdrHopByHop(options=[RouterAlert()])/ICMPv6MLQuery2()
a = IPv6()/IPv6ExtHdrHopByHop(options=[RouterAlert()])/ICMPv6MLReport2()

assert a.answers(q)

############
############
+ Ether tests with IPv6

= Ether IPv6 checking for dst
~ netaccess ipv6

p = Ether()/IPv6(dst="www.google.com")/TCP()
assert p.dst != p[IPv6].dst
p.show()

############
############
+ TracerouteResult6

= get_trace()
ip6_hlim = [("2001:db8::%d" % i, i) for i in six.moves.range(1, 12)]

tr6_packets = [ (IPv6(dst="2001:db8::1", src="2001:db8::254", hlim=hlim)/UDP()/"scapy",
                 IPv6(dst="2001:db8::254", src=ip)/ICMPv6TimeExceeded()/IPerror6(dst="2001:db8::1", src="2001:db8::254", hlim=0)/UDPerror()/"scapy")
                   for (ip, hlim) in ip6_hlim ]

tr6 = TracerouteResult6(tr6_packets)
tr6.get_trace() == {'2001:db8::1': {1: ('2001:db8::1', False), 2: ('2001:db8::2', False), 3: ('2001:db8::3', False), 4: ('2001:db8::4', False), 5: ('2001:db8::5', False), 6: ('2001:db8::6', False), 7: ('2001:db8::7', False), 8: ('2001:db8::8', False), 9: ('2001:db8::9', False), 10: ('2001:db8::10', False), 11: ('2001:db8::11', False)}}

= show()
def test_show():
    with ContextManagerCaptureOutput() as cmco:
        tr6 = TracerouteResult6(tr6_packets)
        tr6.show()
        result = cmco.get_output()
    expected = "  2001:db8::1                               :udpdomain \n"
    expected += "1  2001:db8::1                                3         \n"
    expected += "2  2001:db8::2                                3         \n"
    expected += "3  2001:db8::3                                3         \n"
    expected += "4  2001:db8::4                                3         \n"
    expected += "5  2001:db8::5                                3         \n"
    expected += "6  2001:db8::6                                3         \n"
    expected += "7  2001:db8::7                                3         \n"
    expected += "8  2001:db8::8                                3         \n"
    expected += "9  2001:db8::9                                3         \n"
    expected += "10 2001:db8::10                               3         \n"
    expected += "11 2001:db8::11                               3         \n"
    index_result = result.index("\n1")
    index_expected = expected.index("\n1")
    assert(result[index_result:] == expected[index_expected:])

test_show()

= graph()
saved_AS_resolver = conf.AS_resolver
conf.AS_resolver = None
tr6.make_graph()
assert len(tr6.graphdef) == 530
assert tr6.graphdef.startswith("digraph trace {")
'"2001:db8::1 53/udp";' in tr6.graphdef
conf.AS_resolver = saved_AS_resolver 

############
############
+ IPv6 attacks

= Define test utilities

import mock

@mock.patch("scapy.layers.inet6.sniff")
@mock.patch("scapy.layers.inet6.sendp")
def test_attack(function, pktlist, sendp_mock, sniff_mock, options=()):
    pktlist = [Ether(raw(x)) for x in pktlist]
    ret_list = []
    def _fake_sniff(lfilter=None, prn=None, **kwargs):
        for p in pktlist:
            if lfilter and lfilter(p) and prn:
                prn(p)
    sniff_mock.side_effect = _fake_sniff
    def _fake_sendp(pkt, *args, **kwargs):
        ret_list.append(Ether(raw(pkt)))
    sendp_mock.side_effect = _fake_sendp
    function(*options)
    return ret_list

= Test NDP_Attack_DAD_DoS_via_NS

data = [Ether(src='aa:aa:aa:aa:aa:aa', dst='33:33:ff:00:11:11')/IPv6(src="::", dst="ff02::1:ff00:1111")/ICMPv6ND_NS(tgt="ffff::1111", code=17, res=3758096385),
        Ether(src='aa:aa:aa:aa:aa:aa', dst='33:33:ff:5d:c3:53')/IPv6(src="::", dst="ff02::1:ff5d:c353")/ICMPv6ND_NS(tgt="b643:44c3:f659:f8e6:31c0:6437:825d:c353"),
        Ether()/IP()/ICMP()]
results = test_attack(NDP_Attack_DAD_DoS_via_NS, data)
assert len(results) == 2

a = results[0][IPv6]
assert a[IPv6].src == "::"
assert a[IPv6].dst == "ff02::1:ff00:1111"
assert a[IPv6].hlim == 255
assert a[ICMPv6ND_NS].tgt == "ffff::1111"

b = results[1][IPv6]
assert b[IPv6].src == "::"
assert b[IPv6].dst == "ff02::1:ff5d:c353"
assert b[IPv6].hlim == 255
assert b[ICMPv6ND_NS].tgt == "b643:44c3:f659:f8e6:31c0:6437:825d:c353"

= Test NDP_Attack_DAD_DoS_via_NA

data = [Ether(src='aa:aa:aa:aa:aa:aa', dst='33:33:ff:00:11:11')/IPv6(src="::", dst="ff02::1:ff00:1111")/ICMPv6ND_NS(tgt="ffff::1111", code=17, res=3758096385),
        Ether(src='aa:aa:aa:aa:aa:aa', dst='33:33:ff:5d:c3:53')/IPv6(src="::", dst="ff02::1:ff5d:c353")/ICMPv6ND_NS(tgt="b643:44c3:f659:f8e6:31c0:6437:825d:c353"),
        Ether()/IP()/ICMP()]
results = test_attack(NDP_Attack_DAD_DoS_via_NA, data, options=(None, None, None, "ab:ab:ab:ab:ab:ab"))
assert len(results) == 2
results[0].dst = "ff:ff:ff:ff:ff:ff"
results[1].dst = "ff:ff:ff:ff:ff:ff"

a = results[0]
assert a[Ether].dst == "ff:ff:ff:ff:ff:ff"
assert a[Ether].src == "ab:ab:ab:ab:ab:ab"
assert a[IPv6].src == "ffff::1111"
assert a[IPv6].dst == "ff02::1:ff00:1111"
assert a[IPv6].hlim == 255
assert a[ICMPv6ND_NA].tgt == "ffff::1111"
assert a[ICMPv6NDOptDstLLAddr].lladdr == "ab:ab:ab:ab:ab:ab"

b = results[1]
assert b[Ether].dst == "ff:ff:ff:ff:ff:ff"
assert b[Ether].src == "ab:ab:ab:ab:ab:ab"
assert b[IPv6].src == "b643:44c3:f659:f8e6:31c0:6437:825d:c353"
assert b[IPv6].dst == "ff02::1:ff5d:c353"
assert b[IPv6].hlim == 255
assert b[ICMPv6ND_NA].tgt == "b643:44c3:f659:f8e6:31c0:6437:825d:c353"
assert b[ICMPv6NDOptDstLLAddr].lladdr == "ab:ab:ab:ab:ab:ab"

= Test NDP_Attack_NA_Spoofing

data = [Ether(src='aa:aa:aa:aa:aa:aa', dst='33:33:ff:d4:e5:f6')/IPv6(src="753a:727c:97b5:f71d:51ea:3901:ab52:e110", dst="ff02::1:ffd4:e5f6")/ICMPv6ND_NS(tgt="ff02::1:ffd4:e5f6", code=171, res=3758096),
        Ether(src='aa:aa:aa:aa:aa:aa', dst='33:33:e4:68:c9:4f')/IPv6(src="753a:727c:97b5:f71d:51ea:3901:ab52:e110", dst="fe9c:98b0:52b5:7033:5db0:394f:e468:c94f")/ICMPv6ND_NS(),
        Ether()/IP()/ICMP()]
results = test_attack(NDP_Attack_NA_Spoofing, data, options=(None, None, None, "ff:ff:ff:ff:ff:ff", None))
assert len(results) == 2

a = results[0]
assert a[Ether].dst == "aa:aa:aa:aa:aa:aa"
assert a[Ether].src == "ff:ff:ff:ff:ff:ff"
assert a[IPv6].src == "ff02::1:ffd4:e5f6"
assert a[IPv6].dst == "753a:727c:97b5:f71d:51ea:3901:ab52:e110"
assert a[IPv6].hlim == 255
assert a[ICMPv6ND_NA].R == 0
assert a[ICMPv6ND_NA].S == 1
assert a[ICMPv6ND_NA].O == 1
assert a[ICMPv6ND_NA].tgt == "ff02::1:ffd4:e5f6"
assert a[ICMPv6NDOptDstLLAddr].lladdr == "ff:ff:ff:ff:ff:ff"

b = results[1]
assert b[Ether].dst == "aa:aa:aa:aa:aa:aa"
assert b[Ether].src == "ff:ff:ff:ff:ff:ff"
assert b[IPv6].src == "::"
assert b[IPv6].dst == "753a:727c:97b5:f71d:51ea:3901:ab52:e110"
assert b[IPv6].hlim == 255
assert b[ICMPv6ND_NA].R == 0
assert b[ICMPv6ND_NA].S == 1
assert b[ICMPv6ND_NA].O == 1
assert b[ICMPv6ND_NA].tgt == "::"
assert b[ICMPv6NDOptDstLLAddr].lladdr == "ff:ff:ff:ff:ff:ff"

= Test NDP_Attack_Kill_Default_Router

data = [Ether(src='aa:aa:aa:aa:aa:aa', dst='33:33:ff:d4:e5:f6')/IPv6(src="753a:727c:97b5:f71d:51ea:3901:ab52:e110", dst="ff02::1:ffd4:e5f6")/ICMPv6ND_RA(routerlifetime=1),
        Ether(src='aa:aa:aa:aa:aa:aa', dst='33:33:ab:52:e1:10')/IPv6(src="fe9c:98b0:52b5:7033:5db0:394f:e468:c94f", dst="753a:727c:97b5:f71d:51ea:3901:ab52:e110")/ICMPv6ND_RA(routerlifetime=1),
        Ether()/IP()/"RANDOM"]
results = test_attack(NDP_Attack_Kill_Default_Router, data)
assert len(results) == 2

a = results[0][IPv6]
assert a[IPv6].src == "753a:727c:97b5:f71d:51ea:3901:ab52:e110"
assert a[IPv6].dst == "ff02::1"
assert a[IPv6].hlim == 255
assert a[ICMPv6ND_RA].M == 0
assert a[ICMPv6ND_RA].O == 0
assert a[ICMPv6ND_RA].H == 0
assert a[ICMPv6ND_RA].P == 0
assert a[ICMPv6ND_RA].routerlifetime == 0
assert a[ICMPv6ND_RA].reachabletime == 0
assert a[ICMPv6ND_RA].retranstimer == 0
assert a[ICMPv6NDOptSrcLLAddr].lladdr == "aa:aa:aa:aa:aa:aa"

b = results[1][IPv6]
assert b[IPv6].src == "fe9c:98b0:52b5:7033:5db0:394f:e468:c94f"
assert b[IPv6].dst == "ff02::1"
assert b[IPv6].hlim == 255
assert b[ICMPv6ND_RA].M == 0
assert b[ICMPv6ND_RA].O == 0
assert b[ICMPv6ND_RA].H == 0
assert b[ICMPv6ND_RA].P == 0
assert b[ICMPv6ND_RA].routerlifetime == 0
assert b[ICMPv6ND_RA].reachabletime == 0
assert b[ICMPv6ND_RA].retranstimer == 0
assert b[ICMPv6NDOptSrcLLAddr].lladdr == "aa:aa:aa:aa:aa:aa"

= Test NDP_Attack_Fake_Router

ra  = Ether()/IPv6()/ICMPv6ND_RA()
ra /= ICMPv6NDOptPrefixInfo(prefix="2001:db8:1::", prefixlen=64)
ra /= ICMPv6NDOptPrefixInfo(prefix="2001:db8:2::", prefixlen=64)
ra /= ICMPv6NDOptSrcLLAddr(lladdr="00:11:22:33:44:55")

rad = Ether(raw(ra))

data = [Ether(src='aa:aa:aa:aa:aa:aa', dst='33:33:ab:52:e1:10')/IPv6(src="753a:727c:97b5:f71d:51ea:3901:ab52:e110", dst="ff02::1:ffd4:e5f6")/ICMPv6ND_RS(code=11, res=3758096),
        Ether(src='aa:aa:aa:aa:aa:aa', dst='33:33:ab:52:e1:10')/IPv6(src="753a:727c:97b5:f71d:51ea:3901:ab52:e110", dst="fe9c:98b0:52b5:7033:5db0:394f:e468:c94f")/ICMPv6ND_RS(),
        Ether()/IP()/ICMP()]
results = test_attack(NDP_Attack_Fake_Router, data, options=(ra,))
assert len(results) == 2

assert results[0] == rad
assert results[1] == rad

= Test NDP_Attack_NS_Spoofing

r = test_attack(NDP_Attack_NS_Spoofing, [], options=("aa:aa:aa:aa:aa:aa", "753a:727c:97b5:f71d:51ea:3901:ab52:e110", "2001:db8::1", 'e4a0:654b:1a24:1b15:761d:2e5d:245d:ba83', "cc:cc:cc:cc:cc:cc", "dd:dd:dd:dd:dd:dd"))[0]

assert r[Ether].dst == "dd:dd:dd:dd:dd:dd"
assert r[Ether].src == "cc:cc:cc:cc:cc:cc"
assert r[IPv6].hlim == 255
assert r[IPv6].src == "753a:727c:97b5:f71d:51ea:3901:ab52:e110"
assert r[IPv6].dst == "e4a0:654b:1a24:1b15:761d:2e5d:245d:ba83"
assert r[ICMPv6ND_NS].tgt == "2001:db8::1"
assert r[ICMPv6NDOptSrcLLAddr].lladdr == "aa:aa:aa:aa:aa:aa"

# Below is our Homework : here is the mountain ...
#

########### ICMPv6MLReport Class ####################################
########### ICMPv6MLDone Class ######################################
########### ICMPv6ND_Redirect Class #################################
########### ICMPv6NDOptSrcAddrList Class ############################
########### ICMPv6NDOptTgtAddrList Class ############################
########### ICMPv6ND_INDSol Class ###################################
########### ICMPv6ND_INDAdv Class ###################################





#####################################################################
#####################################################################
##########################     DHCPv6      ##########################
#####################################################################
#####################################################################


############
############
+ Test DHCP6 DUID_LLT

= DUID_LLT basic instantiation
a=DUID_LLT() 

= DUID_LLT basic build
raw(DUID_LLT()) == b'\x00\x01\x00\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00'

= DUID_LLT build with specific values
raw(DUID_LLT(lladdr="ff:ff:ff:ff:ff:ff", timeval=0x11111111, hwtype=0x2222)) == b'\x00\x01""\x11\x11\x11\x11\xff\xff\xff\xff\xff\xff'

= DUID_LLT basic dissection 
a=DUID_LLT(raw(DUID_LLT()))
a.type == 1 and a.hwtype == 1 and a.timeval == 0 and a.lladdr == "00:00:00:00:00:00"

= DUID_LLT dissection with specific values
a=DUID_LLT(b'\x00\x01""\x11\x11\x11\x11\xff\xff\xff\xff\xff\xff') 
a.type == 1 and a.hwtype == 0x2222 and a.timeval == 0x11111111 and a.lladdr == "ff:ff:ff:ff:ff:ff"


############
############
+ Test DHCP6 DUID_EN

= DUID_EN basic instantiation
a=DUID_EN() 

= DUID_EN basic build
raw(DUID_EN()) == b'\x00\x02\x00\x00\x017'

= DUID_EN build with specific values
raw(DUID_EN(enterprisenum=0x11111111, id="iamastring")) == b'\x00\x02\x11\x11\x11\x11iamastring'

= DUID_EN basic dissection 
a=DUID_EN(b'\x00\x02\x00\x00\x017')
a.type == 2 and a.enterprisenum == 311 

= DUID_EN dissection with specific values 
a=DUID_EN(b'\x00\x02\x11\x11\x11\x11iamarawing')
a.type == 2 and a.enterprisenum == 0x11111111 and a.id == b"iamarawing"


############
############
+ Test DHCP6 DUID_LL

= DUID_LL basic instantiation
a=DUID_LL() 

= DUID_LL basic build
raw(DUID_LL()) == b'\x00\x03\x00\x01\x00\x00\x00\x00\x00\x00'

= DUID_LL build with specific values
raw(DUID_LL(hwtype=1, lladdr="ff:ff:ff:ff:ff:ff")) == b'\x00\x03\x00\x01\xff\xff\xff\xff\xff\xff'

= DUID_LL basic dissection
a=DUID_LL(raw(DUID_LL()))
a.type == 3 and a.hwtype == 1 and a.lladdr == "00:00:00:00:00:00"

= DUID_LL with specific values 
a=DUID_LL(b'\x00\x03\x00\x01\xff\xff\xff\xff\xff\xff')
a.hwtype == 1 and a.lladdr == "ff:ff:ff:ff:ff:ff"


############
############
+ Test DHCP6 Opt Unknown

= DHCP6 Opt Unknown basic instantiation 
a=DHCP6OptUnknown()

= DHCP6 Opt Unknown basic build (default values)
raw(DHCP6OptUnknown()) == b'\x00\x00\x00\x00'

= DHCP6 Opt Unknown - len computation test
raw(DHCP6OptUnknown(data="shouldbe9")) == b'\x00\x00\x00\tshouldbe9'


############
############
+ Test DHCP6 Client Identifier option

= DHCP6OptClientId basic instantiation
a=DHCP6OptClientId()

= DHCP6OptClientId basic build
raw(DHCP6OptClientId()) == b'\x00\x01\x00\x00'

= DHCP6OptClientId instantiation with specific values 
raw(DHCP6OptClientId(duid="toto")) == b'\x00\x01\x00\x04toto'

= DHCP6OptClientId instantiation with DUID_LL
raw(DHCP6OptClientId(duid=DUID_LL())) == b'\x00\x01\x00\n\x00\x03\x00\x01\x00\x00\x00\x00\x00\x00'

= DHCP6OptClientId instantiation with DUID_LLT
raw(DHCP6OptClientId(duid=DUID_LLT())) == b'\x00\x01\x00\x0e\x00\x01\x00\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00'

= DHCP6OptClientId instantiation with DUID_EN
raw(DHCP6OptClientId(duid=DUID_EN())) == b'\x00\x01\x00\x06\x00\x02\x00\x00\x017'

= DHCP6OptClientId instantiation with specified length
raw(DHCP6OptClientId(optlen=80, duid="somestring")) == b'\x00\x01\x00Psomestring'

= DHCP6OptClientId basic dissection
a=DHCP6OptClientId(b'\x00\x01\x00\x00') 
a.optcode == 1 and a.optlen == 0

= DHCP6OptClientId instantiation with specified length
raw(DHCP6OptClientId(optlen=80, duid="somestring")) == b'\x00\x01\x00Psomestring'

= DHCP6OptClientId basic dissection
a=DHCP6OptClientId(b'\x00\x01\x00\x00') 
a.optcode == 1 and a.optlen == 0

= DHCP6OptClientId dissection with specific duid value
a=DHCP6OptClientId(b'\x00\x01\x00\x04somerawing')
a.optcode == 1 and a.optlen == 4 and isinstance(a.duid, Raw) and a.duid.load == b'some' and isinstance(a.payload, DHCP6OptUnknown)

= DHCP6OptClientId dissection with specific DUID_LL as duid value
a=DHCP6OptClientId(b'\x00\x01\x00\n\x00\x03\x00\x01\x00\x00\x00\x00\x00\x00')
a.optcode == 1 and a.optlen == 10 and isinstance(a.duid, DUID_LL) and a.duid.type == 3 and a.duid.hwtype == 1 and a.duid.lladdr == "00:00:00:00:00:00"

= DHCP6OptClientId dissection with specific DUID_LLT as duid value
a=DHCP6OptClientId(b'\x00\x01\x00\x0e\x00\x01\x00\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00')
a.optcode == 1 and a.optlen == 14 and isinstance(a.duid, DUID_LLT) and a.duid.type == 1 and a.duid.hwtype == 1 and a.duid.timeval == 0 and a.duid.lladdr == "00:00:00:00:00:00"

= DHCP6OptClientId dissection with specific DUID_EN as duid value
a=DHCP6OptClientId(b'\x00\x01\x00\x06\x00\x02\x00\x00\x017')
a.optcode == 1 and a.optlen == 6 and isinstance(a.duid, DUID_EN) and a.duid.type == 2 and a.duid.enterprisenum == 311 and a.duid.id == b""


############
############
+ Test DHCP6 Server Identifier option

= DHCP6OptServerId basic instantiation
a=DHCP6OptServerId()

= DHCP6OptServerId basic build 
raw(DHCP6OptServerId()) == b'\x00\x02\x00\x00'

= DHCP6OptServerId basic build with specific values
raw(DHCP6OptServerId(duid="toto")) == b'\x00\x02\x00\x04toto'

= DHCP6OptServerId instantiation with DUID_LL
raw(DHCP6OptServerId(duid=DUID_LL())) == b'\x00\x02\x00\n\x00\x03\x00\x01\x00\x00\x00\x00\x00\x00'

= DHCP6OptServerId instantiation with DUID_LLT
raw(DHCP6OptServerId(duid=DUID_LLT())) == b'\x00\x02\x00\x0e\x00\x01\x00\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00'

= DHCP6OptServerId instantiation with DUID_EN
raw(DHCP6OptServerId(duid=DUID_EN())) == b'\x00\x02\x00\x06\x00\x02\x00\x00\x017'

= DHCP6OptServerId instantiation with specified length
raw(DHCP6OptServerId(optlen=80, duid="somestring")) == b'\x00\x02\x00Psomestring'

= DHCP6OptServerId basic dissection
a=DHCP6OptServerId(b'\x00\x02\x00\x00') 
a.optcode == 2 and a.optlen == 0

= DHCP6OptServerId dissection with specific duid value
a=DHCP6OptServerId(b'\x00\x02\x00\x04somerawing')
a.optcode == 2 and a.optlen == 4 and isinstance(a.duid, Raw) and a.duid.load == b'some' and isinstance(a.payload, DHCP6OptUnknown)

= DHCP6OptServerId dissection with specific DUID_LL as duid value
a=DHCP6OptServerId(b'\x00\x02\x00\n\x00\x03\x00\x01\x00\x00\x00\x00\x00\x00')
a.optcode == 2 and a.optlen == 10 and isinstance(a.duid, DUID_LL) and a.duid.type == 3 and a.duid.hwtype == 1 and a.duid.lladdr == "00:00:00:00:00:00"

= DHCP6OptServerId dissection with specific DUID_LLT as duid value
a=DHCP6OptServerId(b'\x00\x02\x00\x0e\x00\x01\x00\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00')
a.optcode == 2 and a.optlen == 14 and isinstance(a.duid, DUID_LLT) and a.duid.type == 1 and a.duid.hwtype == 1 and a.duid.timeval == 0 and a.duid.lladdr == "00:00:00:00:00:00"

= DHCP6OptServerId dissection with specific DUID_EN as duid value
a=DHCP6OptServerId(b'\x00\x02\x00\x06\x00\x02\x00\x00\x017')
a.optcode == 2 and a.optlen == 6 and isinstance(a.duid, DUID_EN) and a.duid.type == 2 and a.duid.enterprisenum == 311 and a.duid.id == b""


############
############
+ Test DHCP6 IA Address Option (IA_TA or IA_NA suboption)

= DHCP6OptIAAddress - Basic Instantiation
raw(DHCP6OptIAAddress()) == b'\x00\x05\x00\x18\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00'

= DHCP6OptIAAddress - Basic Dissection
a = DHCP6OptIAAddress(b'\x00\x05\x00\x18\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00')
a.optcode == 5 and a.optlen == 24 and a.addr == "::" and a.preflft == 0 and a. validlft == 0 and a.iaaddropts == b""

= DHCP6OptIAAddress - Instantiation with specific values
raw(DHCP6OptIAAddress(optlen=0x1111, addr="2222:3333::5555", preflft=0x66666666, validlft=0x77777777, iaaddropts="somestring")) == b'\x00\x05\x11\x11""33\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00UUffffwwwwsomestring'

= DHCP6OptIAAddress - Instantiation with specific values (default optlen computation)
raw(DHCP6OptIAAddress(addr="2222:3333::5555", preflft=0x66666666, validlft=0x77777777, iaaddropts="somestring")) == b'\x00\x05\x00"""33\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00UUffffwwwwsomestring'

= DHCP6OptIAAddress - Dissection with specific values 
a = DHCP6OptIAAddress(b'\x00\x05\x00"""33\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00UUffffwwwwsomerawing')
a.optcode == 5 and a.optlen == 34 and a.addr == "2222:3333::5555" and a.preflft == 0x66666666 and a. validlft == 0x77777777 and a.iaaddropts == b"somerawing"


############
############
+ Test DHCP6 Identity Association for Non-temporary Addresses Option

= DHCP6OptIA_NA - Basic Instantiation
raw(DHCP6OptIA_NA()) == b'\x00\x03\x00\x0c\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00'

= DHCP6OptIA_NA - Basic Dissection
a = DHCP6OptIA_NA(b'\x00\x03\x00\x0c\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00')
a.optcode == 3 and a.optlen == 12 and a.iaid == 0 and a.T1 == 0 and a.T2==0 and a.ianaopts == []

= DHCP6OptIA_NA - Instantiation with specific values (keep automatic length computation) 
raw(DHCP6OptIA_NA(iaid=0x22222222, T1=0x33333333, T2=0x44444444)) == b'\x00\x03\x00\x0c""""3333DDDD'

= DHCP6OptIA_NA - Instantiation with specific values (forced optlen)
raw(DHCP6OptIA_NA(optlen=0x1111, iaid=0x22222222, T1=0x33333333, T2=0x44444444)) == b'\x00\x03\x11\x11""""3333DDDD'

= DHCP6OptIA_NA - Instantiation with a list of IA Addresses (optlen automatic computation)
raw(DHCP6OptIA_NA(iaid=0x22222222, T1=0x33333333, T2=0x44444444, ianaopts=[DHCP6OptIAAddress(), DHCP6OptIAAddress()])) == b'\x00\x03\x00D""""3333DDDD\x00\x05\x00\x18\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x05\x00\x18\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00'

= DHCP6OptIA_NA - Dissection with specific values
a = DHCP6OptIA_NA(b'\x00\x03\x00L""""3333DDDD\x00\x05\x00\x18\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x05\x00\x18\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00')
a.optcode == 3 and a.optlen == 76 and a.iaid == 0x22222222 and a.T1 == 0x33333333 and a.T2==0x44444444 and len(a.ianaopts) == 2 and isinstance(a.ianaopts[0], DHCP6OptIAAddress) and isinstance(a.ianaopts[1], DHCP6OptIAAddress)


############
############
+ Test DHCP6 Identity Association for Temporary Addresses Option

= DHCP6OptIA_TA - Basic Instantiation
raw(DHCP6OptIA_TA()) == b'\x00\x04\x00\x04\x00\x00\x00\x00'

= DHCP6OptIA_TA - Basic Dissection
a = DHCP6OptIA_TA(b'\x00\x04\x00\x04\x00\x00\x00\x00')
a.optcode == 4 and a.optlen == 4 and a.iaid == 0 and a.iataopts == []

= DHCP6OptIA_TA - Instantiation with specific values
raw(DHCP6OptIA_TA(optlen=0x1111, iaid=0x22222222, iataopts=[DHCP6OptIAAddress(), DHCP6OptIAAddress()])) == b'\x00\x04\x11\x11""""\x00\x05\x00\x18\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x05\x00\x18\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00'

= DHCP6OptIA_TA - Dissection with specific values
a = DHCP6OptIA_TA(b'\x00\x04\x11\x11""""\x00\x05\x00\x18\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x05\x00\x18\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00')
a.optcode == 4 and a.optlen == 0x1111 and a.iaid == 0x22222222 and len(a.iataopts) == 2 and isinstance(a.iataopts[0], DHCP6OptIAAddress) and isinstance(a.iataopts[1], DHCP6OptIAAddress)


############
############
+ Test DHCP6 Option Request Option

= DHCP6OptOptReq - Basic Instantiation
raw(DHCP6OptOptReq()) ==  b'\x00\x06\x00\x04\x00\x17\x00\x18'

= DHCP6OptOptReq - optlen field computation
raw(DHCP6OptOptReq(reqopts=[1,2,3,4])) == b'\x00\x06\x00\x08\x00\x01\x00\x02\x00\x03\x00\x04'

= DHCP6OptOptReq - instantiation with empty list
raw(DHCP6OptOptReq(reqopts=[])) == b'\x00\x06\x00\x00'

= DHCP6OptOptReq - Basic dissection
a=DHCP6OptOptReq(b'\x00\x06\x00\x00')
a.optcode == 6 and a.optlen == 0 and a.reqopts == [23,24]

= DHCP6OptOptReq - Dissection with specific value
a=DHCP6OptOptReq(b'\x00\x06\x00\x08\x00\x01\x00\x02\x00\x03\x00\x04')
a.optcode == 6 and a.optlen == 8 and a.reqopts == [1,2,3,4]

= DHCP6OptOptReq - repr
a.show()


############
############
+ Test DHCP6 Option - Preference option

= DHCP6OptPref - Basic instantiation
raw(DHCP6OptPref()) == b'\x00\x07\x00\x01\xff'

= DHCP6OptPref - Instantiation with specific values 
raw(DHCP6OptPref(optlen=0xffff, prefval= 0x11)) == b'\x00\x07\xff\xff\x11'

= DHCP6OptPref - Basic Dissection
a=DHCP6OptPref(b'\x00\x07\x00\x01\xff')
a.optcode == 7 and a.optlen == 1 and a.prefval == 255

= DHCP6OptPref - Dissection with specific values
a=DHCP6OptPref(b'\x00\x07\xff\xff\x11')
a.optcode == 7 and a.optlen == 0xffff and a.prefval == 0x11


############
############
+ Test DHCP6 Option - Elapsed Time

= DHCP6OptElapsedTime - Basic Instantiation
raw(DHCP6OptElapsedTime()) == b'\x00\x08\x00\x02\x00\x00'

= DHCP6OptElapsedTime - Instantiation with specific elapsedtime value
raw(DHCP6OptElapsedTime(elapsedtime=421)) == b'\x00\x08\x00\x02\x01\xa5'

= DHCP6OptElapsedTime - Basic Dissection
a=DHCP6OptElapsedTime(b'\x00\x08\x00\x02\x00\x00') 
a.optcode == 8 and a.optlen == 2 and a.elapsedtime == 0

= DHCP6OptElapsedTime - Dissection with specific values
a=DHCP6OptElapsedTime(b'\x00\x08\x00\x02\x01\xa5')
a.optcode == 8 and a.optlen == 2 and a.elapsedtime == 421

= DHCP6OptElapsedTime - Repr
a.show()


############
############
+ Test DHCP6 Option - Server Unicast Address

= DHCP6OptServerUnicast - Basic Instantiation
raw(DHCP6OptServerUnicast()) == b'\x00\x0c\x00\x10\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00'

= DHCP6OptServerUnicast - Instantiation with specific values (test 1)
raw(DHCP6OptServerUnicast(srvaddr="2001::1")) == b'\x00\x0c\x00\x10 \x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01'

= DHCP6OptServerUnicast - Instantiation with specific values (test 2)
raw(DHCP6OptServerUnicast(srvaddr="2001::1", optlen=42)) == b'\x00\x0c\x00* \x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01'

= DHCP6OptServerUnicast - Dissection with default values
a=DHCP6OptServerUnicast(b'\x00\x0c\x00\x10\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00')
a.optcode == 12 and a.optlen == 16 and a.srvaddr == "::"

= DHCP6OptServerUnicast - Dissection with specific values (test 1)
a=DHCP6OptServerUnicast(b'\x00\x0c\x00\x10 \x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01')
a.optcode == 12 and a.optlen == 16 and a.srvaddr == "2001::1"

= DHCP6OptServerUnicast - Dissection with specific values (test 2)
a=DHCP6OptServerUnicast(b'\x00\x0c\x00* \x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01')
a.optcode == 12 and a.optlen == 42 and a.srvaddr == "2001::1"


############
############
+ Test DHCP6 Option - Status Code

= DHCP6OptStatusCode - Basic Instantiation
raw(DHCP6OptStatusCode()) == b'\x00\r\x00\x02\x00\x00' 

= DHCP6OptStatusCode - Instantiation with specific values
raw(DHCP6OptStatusCode(optlen=42, statuscode=0xff, statusmsg="Hello")) == b'\x00\r\x00*\x00\xffHello'

= DHCP6OptStatusCode - Automatic Length computation
raw(DHCP6OptStatusCode(statuscode=0xff, statusmsg="Hello")) == b'\x00\r\x00\x07\x00\xffHello'

# Add tests to verify Unicode behavior


############
############
+ Test DHCP6 Option - Rapid Commit

= DHCP6OptRapidCommit - Basic Instantiation
raw(DHCP6OptRapidCommit()) == b'\x00\x0e\x00\x00'

= DHCP6OptRapidCommit - Basic Dissection
a=DHCP6OptRapidCommit(b'\x00\x0e\x00\x00')
a.optcode == 14 and a.optlen == 0


############
############
+ Test DHCP6 Option - User class

= DHCP6OptUserClass - Basic Instantiation
raw(DHCP6OptUserClass()) == b'\x00\x0f\x00\x00'

= DHCP6OptUserClass - Basic Dissection
a = DHCP6OptUserClass(b'\x00\x0f\x00\x00')
a.optcode == 15 and a.optlen == 0 and a.userclassdata == []

= DHCP6OptUserClass - Instantiation with one user class data rawucture
raw(DHCP6OptUserClass(userclassdata=[USER_CLASS_DATA(data="something")])) == b'\x00\x0f\x00\x0b\x00\tsomething'

= DHCP6OptUserClass - Dissection with one user class data rawucture
a = DHCP6OptUserClass(b'\x00\x0f\x00\x0b\x00\tsomething')
a.optcode == 15 and a.optlen == 11 and len(a.userclassdata) == 1 and isinstance(a.userclassdata[0], USER_CLASS_DATA) and a.userclassdata[0].len == 9 and a.userclassdata[0].data == b'something'

= DHCP6OptUserClass - Instantiation with two user class data rawuctures
raw(DHCP6OptUserClass(userclassdata=[USER_CLASS_DATA(data="something"), USER_CLASS_DATA(data="somethingelse")])) == b'\x00\x0f\x00\x1a\x00\tsomething\x00\rsomethingelse'

= DHCP6OptUserClass - Dissection with two user class data rawuctures
a = DHCP6OptUserClass(b'\x00\x0f\x00\x1a\x00\tsomething\x00\rsomethingelse')
a.optcode == 15 and a.optlen == 26 and len(a.userclassdata) == 2 and isinstance(a.userclassdata[0], USER_CLASS_DATA) and isinstance(a.userclassdata[1], USER_CLASS_DATA) and a.userclassdata[0].len == 9 and a.userclassdata[0].data == b'something' and a.userclassdata[1].len == 13 and a.userclassdata[1].data == b'somethingelse'


############
############
+ Test DHCP6 Option - Vendor class

= DHCP6OptVendorClass - Basic Instantiation
raw(DHCP6OptVendorClass()) == b'\x00\x10\x00\x04\x00\x00\x00\x00'

= DHCP6OptVendorClass - Basic Dissection
a = DHCP6OptVendorClass(b'\x00\x10\x00\x04\x00\x00\x00\x00')
a.optcode == 16 and a.optlen == 4 and a.enterprisenum == 0 and a.vcdata == []

= DHCP6OptVendorClass - Instantiation with one vendor class data rawucture
raw(DHCP6OptVendorClass(vcdata=[VENDOR_CLASS_DATA(data="something")])) == b'\x00\x10\x00\x0f\x00\x00\x00\x00\x00\tsomething'

= DHCP6OptVendorClass - Dissection with one vendor class data rawucture
a = DHCP6OptVendorClass(b'\x00\x10\x00\x0f\x00\x00\x00\x00\x00\tsomething')
a.optcode == 16 and a.optlen == 15 and a.enterprisenum == 0 and len(a.vcdata) == 1 and isinstance(a.vcdata[0], VENDOR_CLASS_DATA) and a.vcdata[0].len == 9 and a.vcdata[0].data == b'something'

= DHCP6OptVendorClass - Instantiation with two vendor class data rawuctures
raw(DHCP6OptVendorClass(vcdata=[VENDOR_CLASS_DATA(data="something"), VENDOR_CLASS_DATA(data="somethingelse")])) == b'\x00\x10\x00\x1e\x00\x00\x00\x00\x00\tsomething\x00\rsomethingelse'

= DHCP6OptVendorClass - Dissection with two vendor class data rawuctures
a = DHCP6OptVendorClass(b'\x00\x10\x00\x1e\x00\x00\x00\x00\x00\tsomething\x00\rsomethingelse')
a.optcode == 16 and a.optlen == 30 and a.enterprisenum == 0 and len(a.vcdata) == 2 and isinstance(a.vcdata[0], VENDOR_CLASS_DATA) and isinstance(a.vcdata[1], VENDOR_CLASS_DATA) and a.vcdata[0].len == 9 and a.vcdata[0].data == b'something' and a.vcdata[1].len == 13 and a.vcdata[1].data == b'somethingelse'


############
############
+ Test DHCP6 Option - Vendor-specific information

= DHCP6OptVendorSpecificInfo - Basic Instantiation
raw(DHCP6OptVendorSpecificInfo()) == b'\x00\x11\x00\x04\x00\x00\x00\x00'

= DHCP6OptVendorSpecificInfo - Basic Dissection
a = DHCP6OptVendorSpecificInfo(b'\x00\x11\x00\x04\x00\x00\x00\x00')
a.optcode == 17 and a.optlen == 4 and a.enterprisenum == 0

= DHCP6OptVendorSpecificInfo - Instantiation with specific values (one option)
raw(DHCP6OptVendorSpecificInfo(enterprisenum=0xeeeeeeee, vso=[VENDOR_SPECIFIC_OPTION(optcode=43, optdata="something")])) == b'\x00\x11\x00\x11\xee\xee\xee\xee\x00+\x00\tsomething'

= DHCP6OptVendorSpecificInfo - Dissection with with specific values (one option)
a = DHCP6OptVendorSpecificInfo(b'\x00\x11\x00\x11\xee\xee\xee\xee\x00+\x00\tsomething')
a.optcode == 17 and a.optlen == 17 and a.enterprisenum == 0xeeeeeeee and len(a.vso) == 1 and isinstance(a.vso[0], VENDOR_SPECIFIC_OPTION) and a.vso[0].optlen == 9 and a.vso[0].optdata == b'something'

= DHCP6OptVendorSpecificInfo - Instantiation with specific values (two options)
raw(DHCP6OptVendorSpecificInfo(enterprisenum=0xeeeeeeee, vso=[VENDOR_SPECIFIC_OPTION(optcode=43, optdata="something"), VENDOR_SPECIFIC_OPTION(optcode=42, optdata="somethingelse")])) == b'\x00\x11\x00"\xee\xee\xee\xee\x00+\x00\tsomething\x00*\x00\rsomethingelse'

= DHCP6OptVendorSpecificInfo - Dissection with with specific values (two options)
a = DHCP6OptVendorSpecificInfo(b'\x00\x11\x00"\xee\xee\xee\xee\x00+\x00\tsomething\x00*\x00\rsomethingelse')
a.optcode == 17 and a.optlen == 34 and a.enterprisenum == 0xeeeeeeee and len(a.vso) == 2 and isinstance(a.vso[0], VENDOR_SPECIFIC_OPTION) and isinstance(a.vso[1], VENDOR_SPECIFIC_OPTION) and a.vso[0].optlen == 9 and a.vso[0].optdata == b'something' and a.vso[1].optlen == 13 and a.vso[1].optdata == b'somethingelse'


############
############
+ Test DHCP6 Option - Interface-Id 

= DHCP6OptIfaceId - Basic Instantiation
raw(DHCP6OptIfaceId()) == b'\x00\x12\x00\x00'

= DHCP6OptIfaceId - Basic Dissection
a = DHCP6OptIfaceId(b'\x00\x12\x00\x00')
a.optcode == 18 and a.optlen == 0

= DHCP6OptIfaceId - Instantiation with specific value
raw(DHCP6OptIfaceId(ifaceid="something")) == b'\x00\x12\x00\x09something'

= DHCP6OptIfaceId - Dissection with specific value
a = DHCP6OptIfaceId(b'\x00\x12\x00\x09something')
a.optcode == 18 and a.optlen == 9 and a.ifaceid == b"something"


############
############
+ Test DHCP6 Option - Reconfigure Message

= DHCP6OptReconfMsg - Basic Instantiation
raw(DHCP6OptReconfMsg()) == b'\x00\x13\x00\x01\x0b'

= DHCP6OptReconfMsg - Basic Dissection
a = DHCP6OptReconfMsg(b'\x00\x13\x00\x01\x0b')
a.optcode == 19 and a.optlen == 1 and a.msgtype == 11

= DHCP6OptReconfMsg - Instantiation with specific values
raw(DHCP6OptReconfMsg(optlen=4, msgtype=5)) == b'\x00\x13\x00\x04\x05'

= DHCP6OptReconfMsg - Dissection with specific values
a = DHCP6OptReconfMsg(b'\x00\x13\x00\x04\x05')
a.optcode == 19 and a.optlen == 4 and a.msgtype == 5


############
############
+ Test DHCP6 Option - Reconfigure Accept

= DHCP6OptReconfAccept - Basic Instantiation
raw(DHCP6OptReconfAccept()) == b'\x00\x14\x00\x00'

= DHCP6OptReconfAccept - Basic Dissection
a = DHCP6OptReconfAccept(b'\x00\x14\x00\x00')
a.optcode == 20 and a.optlen == 0

= DHCP6OptReconfAccept - Instantiation with specific values
raw(DHCP6OptReconfAccept(optlen=23)) == b'\x00\x14\x00\x17'

= DHCP6OptReconfAccept - Dssection with specific values
a = DHCP6OptReconfAccept(b'\x00\x14\x00\x17')
a.optcode == 20 and a.optlen == 23


############
############
+ Test DHCP6 Option - SIP Servers Domain Name List

= DHCP6OptSIPDomains - Basic Instantiation
raw(DHCP6OptSIPDomains()) == b'\x00\x15\x00\x00'

= DHCP6OptSIPDomains - Basic Dissection
a = DHCP6OptSIPDomains(b'\x00\x15\x00\x00') 
a.optcode == 21 and a.optlen == 0 and a.sipdomains == []

= DHCP6OptSIPDomains - Instantiation with one domain
raw(DHCP6OptSIPDomains(sipdomains=["toto.example.org"])) == b'\x00\x15\x00\x12\x04toto\x07example\x03org\x00'

= DHCP6OptSIPDomains - Dissection with one domain
a = DHCP6OptSIPDomains(b'\x00\x15\x00\x12\x04toto\x07example\x03org\x00')
a.optcode == 21 and a.optlen == 18 and len(a.sipdomains) == 1 and a.sipdomains[0] == "toto.example.org."

= DHCP6OptSIPDomains - Instantiation with two domains
raw(DHCP6OptSIPDomains(sipdomains=["toto.example.org", "titi.example.org"])) == b'\x00\x15\x00$\x04toto\x07example\x03org\x00\x04titi\x07example\x03org\x00'

= DHCP6OptSIPDomains - Dissection with two domains
a = DHCP6OptSIPDomains(b'\x00\x15\x00$\x04toto\x07example\x03org\x00\x04TITI\x07example\x03org\x00')
a.optcode == 21 and a.optlen == 36 and len(a.sipdomains) == 2 and a.sipdomains[0] == "toto.example.org." and a.sipdomains[1] == "TITI.example.org."

= DHCP6OptSIPDomains - Enforcing only one dot at end of domain
raw(DHCP6OptSIPDomains(sipdomains=["toto.example.org."])) == b'\x00\x15\x00\x12\x04toto\x07example\x03org\x00'


############
############
+ Test DHCP6 Option - SIP Servers IPv6 Address List

= DHCP6OptSIPServers - Basic Instantiation
raw(DHCP6OptSIPServers()) == b'\x00\x16\x00\x00'

= DHCP6OptSIPServers - Basic Dissection
a = DHCP6OptSIPServers(b'\x00\x16\x00\x00')
a.optcode == 22 and a. optlen == 0 and a.sipservers == []

= DHCP6OptSIPServers - Instantiation with specific values (1 address)
raw(DHCP6OptSIPServers(sipservers = ["2001:db8::1"] )) == b'\x00\x16\x00\x10 \x01\r\xb8\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01'

= DHCP6OptSIPServers - Dissection with specific values (1 address)
a = DHCP6OptSIPServers(b'\x00\x16\x00\x10 \x01\r\xb8\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01')
a.optcode == 22 and a.optlen == 16 and len(a.sipservers) == 1 and a.sipservers[0] == "2001:db8::1" 

= DHCP6OptSIPServers - Instantiation with specific values (2 addresses)
raw(DHCP6OptSIPServers(sipservers = ["2001:db8::1", "2001:db8::2"] )) == b'\x00\x16\x00  \x01\r\xb8\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01 \x01\r\xb8\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x02'

= DHCP6OptSIPServers - Dissection with specific values (2 addresses)
a = DHCP6OptSIPServers(b'\x00\x16\x00  \x01\r\xb8\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01 \x01\r\xb8\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x02')
a.optcode == 22 and a.optlen == 32 and len(a.sipservers) == 2 and a.sipservers[0] == "2001:db8::1" and a.sipservers[1] == "2001:db8::2"


############
############
+ Test DHCP6 Option - DNS Recursive Name Server

= DHCP6OptDNSServers - Basic Instantiation
raw(DHCP6OptDNSServers()) == b'\x00\x17\x00\x00'

= DHCP6OptDNSServers - Basic Dissection
a = DHCP6OptDNSServers(b'\x00\x17\x00\x00')
a.optcode == 23 and a. optlen == 0 and a.dnsservers == []

= DHCP6OptDNSServers - Instantiation with specific values (1 address)
raw(DHCP6OptDNSServers(dnsservers = ["2001:db8::1"] )) == b'\x00\x17\x00\x10 \x01\r\xb8\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01'

= DHCP6OptDNSServers - Dissection with specific values (1 address)
a = DHCP6OptDNSServers(b'\x00\x17\x00\x10 \x01\r\xb8\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01')
a.optcode == 23 and a.optlen == 16 and len(a.dnsservers) == 1 and a.dnsservers[0] == "2001:db8::1" 

= DHCP6OptDNSServers - Instantiation with specific values (2 addresses)
raw(DHCP6OptDNSServers(dnsservers = ["2001:db8::1", "2001:db8::2"] )) == b'\x00\x17\x00  \x01\r\xb8\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01 \x01\r\xb8\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x02'

= DHCP6OptDNSServers - Dissection with specific values (2 addresses)
a = DHCP6OptDNSServers(b'\x00\x17\x00  \x01\r\xb8\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01 \x01\r\xb8\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x02')
a.optcode == 23 and a.optlen == 32 and len(a.dnsservers) == 2 and a.dnsservers[0] == "2001:db8::1" and a.dnsservers[1] == "2001:db8::2"


############
############
+ Test DHCP6 Option - DNS Domain Search List Option

= DHCP6OptDNSDomains - Basic Instantiation
raw(DHCP6OptDNSDomains()) == b'\x00\x18\x00\x00'

= DHCP6OptDNSDomains - Basic Dissection
a = DHCP6OptDNSDomains(b'\x00\x18\x00\x00')
a.optcode == 24 and a.optlen == 0 and a.dnsdomains == []

= DHCP6OptDNSDomains - Instantiation with specific values (1 domain) 
raw(DHCP6OptDNSDomains(dnsdomains=["toto.example.com."])) == b'\x00\x18\x00\x12\x04toto\x07example\x03com\x00'

= DHCP6OptDNSDomains - Dissection with specific values (1 domain) 
a = DHCP6OptDNSDomains(b'\x00\x18\x00\x12\x04toto\x07example\x03com\x00')
a.optcode == 24 and a.optlen == 18 and len(a.dnsdomains) == 1 and a.dnsdomains[0] == "toto.example.com."

= DHCP6OptDNSDomains - Instantiation with specific values (2 domains) 
raw(DHCP6OptDNSDomains(dnsdomains=["toto.example.com.", "titi.example.com."])) == b'\x00\x18\x00$\x04toto\x07example\x03com\x00\x04titi\x07example\x03com\x00'

= DHCP6OptDNSDomains - Dissection with specific values (2 domains) 
a = DHCP6OptDNSDomains(b'\x00\x18\x00$\x04toto\x07example\x03com\x00\x04titi\x07example\x03com\x00')
a.optcode == 24 and a.optlen == 36 and len(a.dnsdomains) == 2 and a.dnsdomains[0] == "toto.example.com." and a.dnsdomains[1] == "titi.example.com."


############
############
+ Test DHCP6 Option - IA_PD Prefix Option

= DHCP6OptIAPrefix - Basic Instantiation
raw(DHCP6OptIAPrefix()) == b'\x00\x1a\x00\x19\x00\x00\x00\x00\x00\x00\x00\x000 \x01\r\xb8\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00'

#TODO : finish me


############
############
+ Test DHCP6 Option - Identity Association for Prefix Delegation

= DHCP6OptIA_PD - Basic Instantiation
raw(DHCP6OptIA_PD()) == b'\x00\x19\x00\x0c\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00'

#TODO : finish me


############
############
+ Test DHCP6 Option - NIS Servers

= DHCP6OptNISServers - Basic Instantiation
raw(DHCP6OptNISServers()) == b'\x00\x1b\x00\x00'

= DHCP6OptNISServers - Basic Dissection
a = DHCP6OptNISServers(b'\x00\x1b\x00\x00')
a.optcode == 27 and a. optlen == 0 and a.nisservers == []

= DHCP6OptNISServers - Instantiation with specific values (1 address)
raw(DHCP6OptNISServers(nisservers = ["2001:db8::1"] )) == b'\x00\x1b\x00\x10 \x01\r\xb8\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01'

= DHCP6OptNISServers - Dissection with specific values (1 address)
a = DHCP6OptNISServers(b'\x00\x1b\x00\x10 \x01\r\xb8\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01')
a.optcode == 27 and a.optlen == 16 and len(a.nisservers) == 1 and a.nisservers[0] == "2001:db8::1" 

= DHCP6OptNISServers - Instantiation with specific values (2 addresses)
raw(DHCP6OptNISServers(nisservers = ["2001:db8::1", "2001:db8::2"] )) == b'\x00\x1b\x00  \x01\r\xb8\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01 \x01\r\xb8\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x02'

= DHCP6OptNISServers - Dissection with specific values (2 addresses)
a = DHCP6OptNISServers(b'\x00\x1b\x00  \x01\r\xb8\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01 \x01\r\xb8\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x02')
a.optcode == 27 and a.optlen == 32 and len(a.nisservers) == 2 and a.nisservers[0] == "2001:db8::1" and a.nisservers[1] == "2001:db8::2"


############
############
+ Test DHCP6 Option - NIS+ Servers

= DHCP6OptNISPServers - Basic Instantiation
raw(DHCP6OptNISPServers()) == b'\x00\x1c\x00\x00'

= DHCP6OptNISPServers - Basic Dissection
a = DHCP6OptNISPServers(b'\x00\x1c\x00\x00')
a.optcode == 28 and a. optlen == 0 and a.nispservers == []

= DHCP6OptNISPServers - Instantiation with specific values (1 address)
raw(DHCP6OptNISPServers(nispservers = ["2001:db8::1"] )) == b'\x00\x1c\x00\x10 \x01\r\xb8\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01'

= DHCP6OptNISPServers - Dissection with specific values (1 address)
a = DHCP6OptNISPServers(b'\x00\x1c\x00\x10 \x01\r\xb8\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01')
a.optcode == 28 and a.optlen == 16 and len(a.nispservers) == 1 and a.nispservers[0] == "2001:db8::1" 

= DHCP6OptNISPServers - Instantiation with specific values (2 addresses)
raw(DHCP6OptNISPServers(nispservers = ["2001:db8::1", "2001:db8::2"] )) == b'\x00\x1c\x00  \x01\r\xb8\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01 \x01\r\xb8\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x02'

= DHCP6OptNISPServers - Dissection with specific values (2 addresses)
a = DHCP6OptNISPServers(b'\x00\x1c\x00  \x01\r\xb8\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01 \x01\r\xb8\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x02')
a.optcode == 28 and a.optlen == 32 and len(a.nispservers) == 2 and a.nispservers[0] == "2001:db8::1" and a.nispservers[1] == "2001:db8::2"


############
############
+ Test DHCP6 Option - NIS Domain Name

= DHCP6OptNISDomain - Basic Instantiation
raw(DHCP6OptNISDomain()) == b'\x00\x1d\x00\x00'

= DHCP6OptNISDomain - Basic Dissection
a = DHCP6OptNISDomain(b'\x00\x1d\x00\x00')
a.optcode == 29 and a.optlen == 0 and a.nisdomain == b""

= DHCP6OptNISDomain - Instantiation with one domain name
raw(DHCP6OptNISDomain(nisdomain="toto.example.org")) == b'\x00\x1d\x00\x11\x04toto\x07example\x03org'

= DHCP6OptNISDomain - Dissection with one domain name
a = DHCP6OptNISDomain(b'\x00\x1d\x00\x11\x04toto\x07example\x03org\x00')
a.optcode == 29 and a.optlen == 17 and a.nisdomain == b"toto.example.org"

= DHCP6OptNISDomain - Instantiation with one domain with trailing dot
raw(DHCP6OptNISDomain(nisdomain="toto.example.org.")) == b'\x00\x1d\x00\x12\x04toto\x07example\x03org\x00'


############
############
+ Test DHCP6 Option - NIS+ Domain Name

= DHCP6OptNISPDomain - Basic Instantiation
raw(DHCP6OptNISPDomain()) == b'\x00\x1e\x00\x00'

= DHCP6OptNISPDomain - Basic Dissection
a = DHCP6OptNISPDomain(b'\x00\x1e\x00\x00')
a.optcode == 30 and a.optlen == 0 and a.nispdomain == b""

= DHCP6OptNISPDomain - Instantiation with one domain name
raw(DHCP6OptNISPDomain(nispdomain="toto.example.org")) == b'\x00\x1e\x00\x11\x04toto\x07example\x03org'

= DHCP6OptNISPDomain - Dissection with one domain name
a = DHCP6OptNISPDomain(b'\x00\x1e\x00\x11\x04toto\x07example\x03org\x00')
a.optcode == 30 and a.optlen == 17 and a.nispdomain == b"toto.example.org"

= DHCP6OptNISPDomain - Instantiation with one domain with trailing dot
raw(DHCP6OptNISPDomain(nispdomain="toto.example.org.")) == b'\x00\x1e\x00\x12\x04toto\x07example\x03org\x00'


############
############
+ Test DHCP6 Option - SNTP Servers

= DHCP6OptSNTPServers - Basic Instantiation
raw(DHCP6OptSNTPServers()) == b'\x00\x1f\x00\x00'

= DHCP6OptSNTPServers - Basic Dissection
a = DHCP6OptSNTPServers(b'\x00\x1f\x00\x00')
a.optcode == 31 and a. optlen == 0 and a.sntpservers == []

= DHCP6OptSNTPServers - Instantiation with specific values (1 address)
raw(DHCP6OptSNTPServers(sntpservers = ["2001:db8::1"] )) == b'\x00\x1f\x00\x10 \x01\r\xb8\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01'

= DHCP6OptSNTPServers - Dissection with specific values (1 address)
a = DHCP6OptSNTPServers(b'\x00\x1f\x00\x10 \x01\r\xb8\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01')
a.optcode == 31 and a.optlen == 16 and len(a.sntpservers) == 1 and a.sntpservers[0] == "2001:db8::1" 

= DHCP6OptSNTPServers - Instantiation with specific values (2 addresses)
raw(DHCP6OptSNTPServers(sntpservers = ["2001:db8::1", "2001:db8::2"] )) == b'\x00\x1f\x00  \x01\r\xb8\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01 \x01\r\xb8\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x02'

= DHCP6OptSNTPServers - Dissection with specific values (2 addresses)
a = DHCP6OptSNTPServers(b'\x00\x1f\x00  \x01\r\xb8\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01 \x01\r\xb8\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x02')
a.optcode == 31 and a.optlen == 32 and len(a.sntpservers) == 2 and a.sntpservers[0] == "2001:db8::1" and a.sntpservers[1] == "2001:db8::2"

############
############
+ Test DHCP6 Option - Information Refresh Time

= DHCP6OptInfoRefreshTime - Basic Instantiation
raw(DHCP6OptInfoRefreshTime()) == b'\x00 \x00\x04\x00\x01Q\x80'

= DHCP6OptInfoRefreshTime - Basic Dissction
a = DHCP6OptInfoRefreshTime(b'\x00 \x00\x04\x00\x01Q\x80')
a.optcode == 32 and a.optlen == 4 and a.reftime == 86400

= DHCP6OptInfoRefreshTime - Instantiation with specific values
raw(DHCP6OptInfoRefreshTime(optlen=7, reftime=42)) == b'\x00 \x00\x07\x00\x00\x00*'

############
############
+ Test DHCP6 Option - BCMCS Servers

= DHCP6OptBCMCSServers - Basic Instantiation
raw(DHCP6OptBCMCSServers()) == b'\x00"\x00\x00'

= DHCP6OptBCMCSServers - Basic Dissection
a = DHCP6OptBCMCSServers(b'\x00"\x00\x00')
a.optcode == 34 and a. optlen == 0 and a.bcmcsservers == []

= DHCP6OptBCMCSServers - Instantiation with specific values (1 address)
raw(DHCP6OptBCMCSServers(bcmcsservers = ["2001:db8::1"] )) == b'\x00"\x00\x10 \x01\r\xb8\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01'

= DHCP6OptBCMCSServers - Dissection with specific values (1 address)
a = DHCP6OptBCMCSServers(b'\x00"\x00\x10 \x01\r\xb8\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01')
a.optcode == 34 and a.optlen == 16 and len(a.bcmcsservers) == 1 and a.bcmcsservers[0] == "2001:db8::1" 

= DHCP6OptBCMCSServers - Instantiation with specific values (2 addresses)
raw(DHCP6OptBCMCSServers(bcmcsservers = ["2001:db8::1", "2001:db8::2"] )) == b'\x00"\x00  \x01\r\xb8\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01 \x01\r\xb8\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x02'

= DHCP6OptBCMCSServers - Dissection with specific values (2 addresses)
a = DHCP6OptBCMCSServers(b'\x00"\x00  \x01\r\xb8\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01 \x01\r\xb8\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x02')
a.optcode == 34 and a.optlen == 32 and len(a.bcmcsservers) == 2 and a.bcmcsservers[0] == "2001:db8::1" and a.bcmcsservers[1] == "2001:db8::2"


############
############
+ Test DHCP6 Option - BCMCS Domains

= DHCP6OptBCMCSDomains - Basic Instantiation
raw(DHCP6OptBCMCSDomains()) == b'\x00!\x00\x00'

= DHCP6OptBCMCSDomains - Basic Dissection
a = DHCP6OptBCMCSDomains(b'\x00!\x00\x00')
a.optcode == 33 and a.optlen == 0 and a.bcmcsdomains == []

= DHCP6OptBCMCSDomains - Instantiation with specific values (1 domain) 
raw(DHCP6OptBCMCSDomains(bcmcsdomains=["toto.example.com."])) == b'\x00!\x00\x12\x04toto\x07example\x03com\x00'

= DHCP6OptBCMCSDomains - Dissection with specific values (1 domain) 
a = DHCP6OptBCMCSDomains(b'\x00!\x00\x12\x04toto\x07example\x03com\x00')
a.optcode == 33 and a.optlen == 18 and len(a.bcmcsdomains) == 1 and a.bcmcsdomains[0] == "toto.example.com."

= DHCP6OptBCMCSDomains - Instantiation with specific values (2 domains) 
raw(DHCP6OptBCMCSDomains(bcmcsdomains=["toto.example.com.", "titi.example.com."])) == b'\x00!\x00$\x04toto\x07example\x03com\x00\x04titi\x07example\x03com\x00'

= DHCP6OptBCMCSDomains - Dissection with specific values (2 domains) 
a = DHCP6OptBCMCSDomains(b'\x00!\x00$\x04toto\x07example\x03com\x00\x04titi\x07example\x03com\x00')
a.optcode == 33 and a.optlen == 36 and len(a.bcmcsdomains) == 2 and a.bcmcsdomains[0] == "toto.example.com." and a.bcmcsdomains[1] == "titi.example.com."


############
############
+ Test DHCP6 Option - Relay Agent Remote-ID

= DHCP6OptRemoteID - Basic Instantiation
raw(DHCP6OptRemoteID()) == b'\x00%\x00\x04\x00\x00\x00\x00'

= DHCP6OptRemoteID - Basic Dissection
a = DHCP6OptRemoteID(b'\x00%\x00\x04\x00\x00\x00\x00')
a.optcode == 37 and a.optlen == 4 and a.enterprisenum == 0 and a.remoteid == b""

= DHCP6OptRemoteID - Instantiation with specific values 
raw(DHCP6OptRemoteID(enterprisenum=0xeeeeeeee, remoteid="someid")) == b'\x00%\x00\n\xee\xee\xee\xeesomeid'

= DHCP6OptRemoteID - Dissection with specific values
a = DHCP6OptRemoteID(b'\x00%\x00\n\xee\xee\xee\xeesomeid')
a.optcode == 37 and a.optlen == 10 and a.enterprisenum == 0xeeeeeeee and a.remoteid == b"someid"


############
############
+ Test DHCP6 Option - Subscriber ID

= DHCP6OptSubscriberID - Basic Instantiation
raw(DHCP6OptSubscriberID()) == b'\x00&\x00\x00'

= DHCP6OptSubscriberID - Basic Dissection
a = DHCP6OptSubscriberID(b'\x00&\x00\x00')
a.optcode == 38 and a.optlen == 0 and a.subscriberid == b""

= DHCP6OptSubscriberID - Instantiation with specific values
raw(DHCP6OptSubscriberID(subscriberid="someid")) == b'\x00&\x00\x06someid'

= DHCP6OptSubscriberID - Dissection with specific values
a = DHCP6OptSubscriberID(b'\x00&\x00\x06someid')
a.optcode == 38 and a.optlen == 6 and a.subscriberid == b"someid"


############
############
+ Test DHCP6 Option - Client FQDN

= DHCP6OptClientFQDN - Basic Instantiation
raw(DHCP6OptClientFQDN()) == b"\x00'\x00\x01\x00"

= DHCP6OptClientFQDN - Basic Dissection
a = DHCP6OptClientFQDN(b"\x00'\x00\x01\x00")
a.optcode == 39 and a.optlen == 1 and a.res == 0 and a.flags == 0 and a.fqdn == b""

= DHCP6OptClientFQDN - Instantiation with various flags combinations
raw(DHCP6OptClientFQDN(flags="S")) == b"\x00'\x00\x01\x01" and raw(DHCP6OptClientFQDN(flags="O")) == b"\x00'\x00\x01\x02" and raw(DHCP6OptClientFQDN(flags="N")) == b"\x00'\x00\x01\x04" and raw(DHCP6OptClientFQDN(flags="SON")) == b"\x00'\x00\x01\x07" and raw(DHCP6OptClientFQDN(flags="ON")) == b"\x00'\x00\x01\x06"

= DHCP6OptClientFQDN - Instantiation with one fqdn 
raw(DHCP6OptClientFQDN(fqdn="toto.example.org")) == b"\x00'\x00\x12\x00\x04toto\x07example\x03org"

= DHCP6OptClientFQDN - Dissection with one fqdn 
a = DHCP6OptClientFQDN(b"\x00'\x00\x12\x00\x04toto\x07example\x03org\x00")
a.optcode == 39 and a.optlen == 18 and a.res == 0 and a.flags == 0 and a.fqdn == b"toto.example.org"


############
############
+ Test DHCP6 Option Relay Agent Echo Request Option

= DHCP6OptRelayAgentERO - Basic Instantiation
raw(DHCP6OptRelayAgentERO()) ==  b'\x00+\x00\x04\x00\x17\x00\x18'

= DHCP6OptRelayAgentERO - optlen field computation
raw(DHCP6OptRelayAgentERO(reqopts=[1,2,3,4])) == b'\x00+\x00\x08\x00\x01\x00\x02\x00\x03\x00\x04'

= DHCP6OptRelayAgentERO - instantiation with empty list
raw(DHCP6OptRelayAgentERO(reqopts=[])) == b'\x00+\x00\x00'

= DHCP6OptRelayAgentERO - Basic dissection
a=DHCP6OptRelayAgentERO(b'\x00+\x00\x00')
a.optcode == 43 and a.optlen == 0 and a.reqopts == [23,24]

= DHCP6OptRelayAgentERO - Dissection with specific value
a=DHCP6OptRelayAgentERO(b'\x00+\x00\x08\x00\x01\x00\x02\x00\x03\x00\x04')
a.optcode == 43 and a.optlen == 8 and a.reqopts == [1,2,3,4]


############
############
+ Test DHCP6 Option Client Link Layer address

= Basic build & dissect
s = raw(DHCP6OptClientLinkLayerAddr())
assert(s == b"\x00O\x00\x08\x00\x01\x00\x00\x00\x00\x00\x00")

p = DHCP6OptClientLinkLayerAddr(s)
assert(p.clladdr == "00:00:00:00:00:00")

r = b"\x00O\x00\x08\x00\x01\x00\x01\x02\x03\x04\x05"
p = DHCP6OptClientLinkLayerAddr(r)
assert(p.clladdr == "00:01:02:03:04:05")


############
############
+ Test DHCP6 Option Virtual Subnet Selection

= Basic build & dissect
s = raw(DHCP6OptVSS())
assert(s == b"\x00D\x00\x01\xff")

p = DHCP6OptVSS(s)
assert(p.type == 255)


############
############
+ Test DHCP6 Messages - DHCP6_Solicit

= DHCP6_Solicit - Basic Instantiation
raw(DHCP6_Solicit()) == b'\x01\x00\x00\x00'

= DHCP6_Solicit - Basic Dissection
a = DHCP6_Solicit(b'\x01\x00\x00\x00')
a.msgtype == 1 and a.trid == 0

= DHCP6_Solicit - Basic test of DHCP6_solicit.hashret() 
DHCP6_Solicit().hashret() == b'\x00\x00\x00'

= DHCP6_Solicit - Test of DHCP6_solicit.hashret() with specific values
DHCP6_Solicit(trid=0xbbccdd).hashret() == b'\xbb\xcc\xdd'

= DHCP6_Solicit - UDP ports overload
a=UDP()/DHCP6_Solicit()
a.sport == 546 and a.dport == 547

= DHCP6_Solicit - Dispatch based on UDP port 
a=UDP(raw(UDP()/DHCP6_Solicit()))
isinstance(a.payload, DHCP6_Solicit)


############
############
+ Test DHCP6 Messages - DHCP6_Advertise

= DHCP6_Advertise - Basic Instantiation
raw(DHCP6_Advertise()) == b'\x02\x00\x00\x00'

= DHCP6_Advertise - Basic test of DHCP6_solicit.hashret() 
DHCP6_Advertise().hashret() == b'\x00\x00\x00'

= DHCP6_Advertise - Test of DHCP6_Advertise.hashret() with specific values
DHCP6_Advertise(trid=0xbbccdd).hashret() == b'\xbb\xcc\xdd'

= DHCP6_Advertise - Basic test of answers() with solicit message
a = DHCP6_Solicit()
b = DHCP6_Advertise()
a > b

= DHCP6_Advertise - Test of answers() with solicit message
a = DHCP6_Solicit(trid=0xbbccdd)
b = DHCP6_Advertise(trid=0xbbccdd)
a > b

= DHCP6_Advertise - UDP ports overload
a=UDP()/DHCP6_Advertise()
a.sport == 547 and a.dport == 546


############
############
+ Test DHCP6 Messages - DHCP6_Request

= DHCP6_Request - Basic Instantiation
raw(DHCP6_Request()) == b'\x03\x00\x00\x00'

= DHCP6_Request - Basic Dissection
a=DHCP6_Request(b'\x03\x00\x00\x00')
a.msgtype == 3 and a.trid == 0 

= DHCP6_Request - UDP ports overload
a=UDP()/DHCP6_Request()
a.sport == 546 and a.dport == 547


############
############
+ Test DHCP6 Messages - DHCP6_Confirm

= DHCP6_Confirm - Basic Instantiation
raw(DHCP6_Confirm()) == b'\x04\x00\x00\x00'

= DHCP6_Confirm - Basic Dissection
a=DHCP6_Confirm(b'\x04\x00\x00\x00')
a.msgtype == 4 and a.trid == 0

= DHCP6_Confirm - UDP ports overload
a=UDP()/DHCP6_Confirm()
a.sport == 546 and a.dport == 547


############
############
+ Test DHCP6 Messages - DHCP6_Renew

= DHCP6_Renew - Basic Instantiation
raw(DHCP6_Renew()) == b'\x05\x00\x00\x00'

= DHCP6_Renew - Basic Dissection
a=DHCP6_Renew(b'\x05\x00\x00\x00')
a.msgtype == 5 and a.trid == 0

= DHCP6_Renew - UDP ports overload
a=UDP()/DHCP6_Renew()
a.sport == 546 and a.dport == 547


############
############
+ Test DHCP6 Messages - DHCP6_Rebind

= DHCP6_Rebind - Basic Instantiation
raw(DHCP6_Rebind()) == b'\x06\x00\x00\x00'

= DHCP6_Rebind - Basic Dissection
a=DHCP6_Rebind(b'\x06\x00\x00\x00')
a.msgtype == 6 and a.trid == 0

= DHCP6_Rebind - UDP ports overload
a=UDP()/DHCP6_Rebind()
a.sport == 546 and a.dport == 547


############
############
+ Test DHCP6 Messages - DHCP6_Reply

= DHCP6_Reply - Basic Instantiation
raw(DHCP6_Reply()) == b'\x07\x00\x00\x00'

= DHCP6_Reply - Basic Dissection
a=DHCP6_Reply(b'\x07\x00\x00\x00')
a.msgtype == 7 and a.trid == 0

= DHCP6_Reply - UDP ports overload
a=UDP()/DHCP6_Reply()
a.sport == 547 and a.dport == 546

= DHCP6_Reply - Answers

assert not DHCP6_Reply(trid=0).answers(DHCP6_Request(trid=1))
assert DHCP6_Reply(trid=1).answers(DHCP6_Request(trid=1))


############
############
+ Test DHCP6 Messages - DHCP6_Release

= DHCP6_Release - Basic Instantiation
raw(DHCP6_Release()) == b'\x08\x00\x00\x00'

= DHCP6_Release - Basic Dissection
a=DHCP6_Release(b'\x08\x00\x00\x00')
a.msgtype == 8 and a.trid == 0

= DHCP6_Release - UDP ports overload
a=UDP()/DHCP6_Release()
a.sport == 546 and a.dport == 547


############
############
+ Test DHCP6 Messages - DHCP6_Decline

= DHCP6_Decline - Basic Instantiation
raw(DHCP6_Decline()) == b'\x09\x00\x00\x00'

= DHCP6_Confirm - Basic Dissection
a=DHCP6_Confirm(b'\x09\x00\x00\x00')
a.msgtype == 9 and a.trid == 0

= DHCP6_Decline - UDP ports overload
a=UDP()/DHCP6_Decline()
a.sport == 546 and a.dport == 547


############
############
+ Test DHCP6 Messages - DHCP6_Reconf

= DHCP6_Reconf - Basic Instantiation
raw(DHCP6_Reconf()) == b'\x0A\x00\x00\x00'

= DHCP6_Reconf - Basic Dissection
a=DHCP6_Reconf(b'\x0A\x00\x00\x00')
a.msgtype == 10 and a.trid == 0

= DHCP6_Reconf - UDP ports overload
a=UDP()/DHCP6_Reconf()
a.sport == 547 and a.dport == 546


############
############
+ Test DHCP6 Messages - DHCP6_InfoRequest

= DHCP6_InfoRequest - Basic Instantiation
raw(DHCP6_InfoRequest()) == b'\x0B\x00\x00\x00'

= DHCP6_InfoRequest - Basic Dissection
a=DHCP6_InfoRequest(b'\x0B\x00\x00\x00')
a.msgtype == 11 and a.trid == 0

= DHCP6_InfoRequest - UDP ports overload
a=UDP()/DHCP6_InfoRequest()
a.sport == 546 and a.dport == 547


############
############
+ Test DHCP6 Messages - DHCP6_RelayForward

= DHCP6_RelayForward - Basic Instantiation
raw(DHCP6_RelayForward()) == b'\x0c\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00'

= DHCP6_RelayForward - Basic Dissection
a=DHCP6_RelayForward(b'\x0c\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00')
a.msgtype == 12 and a.hopcount == 0 and a.linkaddr == "::" and a.peeraddr == "::"

= DHCP6_RelayForward - Dissection with options
a = DHCP6_RelayForward(b'\x0c\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\t\x00\x04\x03\x01\x00\x00')
a.msgtype == 12 and DHCP6OptRelayMsg in a and isinstance(a.message, DHCP6_Request)

= DHCP6_RelayForward - Advanced dissection
s = b'`\x00\x00\x00\x002\x11@\xfe\x80\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01\xff\x02\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01\x00\x02\x02#\x02#\x002\xf0\xaf\x0c\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\t\x00\x04\x01\x00\x00\x00'
p = IPv6(s)
assert DHCP6OptRelayMsg in p and isinstance(p.message, DHCP6_Solicit)


############
############
+ Test DHCP6 Messages - DHCP6OptRelayMsg

= DHCP6OptRelayMsg - Basic Instantiation
raw(DHCP6OptRelayMsg(optcode=37)) == b'\x00%\x00\x04\x00\x00\x00\x00'

= DHCP6OptRelayMsg - Basic Dissection
a=DHCP6OptRelayMsg(b'\x00\r\x00\x00')
assert a.optcode == 13

= DHCP6OptRelayMsg - Embedded DHCP6 packet
p = DHCP6OptRelayMsg(b'\x00\t\x00\x04\x01\x00\x00\x00')
isinstance(p.message, DHCP6_Solicit)

############
############
+ Test DHCP6 Messages - DHCP6_RelayReply

= DHCP6_RelayReply - Basic Instantiation
raw(DHCP6_RelayReply()) == b'\r\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00'

= DHCP6_RelayReply - Basic Dissection
a=DHCP6_RelayReply(b'\r\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00')
a.msgtype == 13 and a.hopcount == 0 and a.linkaddr == "::" and a.peeraddr == "::"


############
############
+ Home Agent Address Discovery

= in6_getha()
in6_getha('2001:db8::') == '2001:db8::fdff:ffff:ffff:fffe'

= ICMPv6HAADRequest - build/dissection
p = IPv6(raw(IPv6(dst=in6_getha('2001:db8::'), src='2001:db8::1')/ICMPv6HAADRequest(id=42)))
p.cksum == 0x9620 and p.dst == '2001:db8::fdff:ffff:ffff:fffe' and p.R == 1

= ICMPv6HAADReply - build/dissection
p = IPv6(raw(IPv6(dst='2001:db8::1', src='2001:db8::42')/ICMPv6HAADReply(id=42, addresses=['2001:db8::2', '2001:db8::3'])))
p.cksum = 0x3747 and p.addresses == [ '2001:db8::2', '2001:db8::3' ]

= ICMPv6HAADRequest / ICMPv6HAADReply - build/dissection
a=ICMPv6HAADRequest(id=42) 
b=ICMPv6HAADReply(id=42)
not a < b and a > b


############
############
+ Mobile Prefix Solicitation/Advertisement

= ICMPv6MPSol - build (default values)

s = b'`\x00\x00\x00\x00\x08:@\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01\x92\x00m\xbb\x00\x00\x00\x00'
raw(IPv6()/ICMPv6MPSol()) == s

= ICMPv6MPSol - dissection (default values)
p = IPv6(s)
p[ICMPv6MPSol].type == 146 and p[ICMPv6MPSol].cksum == 0x6dbb and p[ICMPv6MPSol].id == 0

= ICMPv6MPSol - build
s = b'`\x00\x00\x00\x00\x08:@\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01\x92\x00(\x08\x00\x08\x00\x00'
raw(IPv6()/ICMPv6MPSol(cksum=0x2808, id=8)) == s

= ICMPv6MPSol - dissection
p = IPv6(s)
p[ICMPv6MPSol].cksum == 0x2808 and p[ICMPv6MPSol].id == 8

= ICMPv6MPAdv - build (default values)
s = b'`\x00\x00\x00\x00(:@\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01\x93\x00\xe8\xd6\x00\x00\x80\x00\x03\x04\x00\xc0\xff\xff\xff\xff\xff\xff\xff\xff\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00'
raw(IPv6()/ICMPv6MPAdv()/ICMPv6NDOptPrefixInfo()) == s

= ICMPv6MPAdv - dissection (default values)
p = IPv6(s)
p[ICMPv6MPAdv].type == 147 and p[ICMPv6MPAdv].cksum == 0xe8d6 and p[ICMPv6NDOptPrefixInfo].prefix == '::'

= ICMPv6MPAdv - build
s = b'`\x00\x00\x00\x00(:@\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01\x93\x00(\x07\x00*@\x00\x03\x04\x00@\xff\xff\xff\xff\x00\x00\x00\x0c\x00\x00\x00\x00 \x01\r\xb8\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01'
raw(IPv6()/ICMPv6MPAdv(cksum=0x2807, flags=1, id=42)/ICMPv6NDOptPrefixInfo(prefix='2001:db8::1', L=0, preferredlifetime=12)) == s

= ICMPv6MPAdv - dissection
p = IPv6(s)
p[ICMPv6MPAdv].cksum == 0x2807 and p[ICMPv6MPAdv].flags == 1 and p[ICMPv6MPAdv].id == 42 and p[ICMPv6NDOptPrefixInfo].prefix == '2001:db8::1' and p[ICMPv6NDOptPrefixInfo].preferredlifetime == 12


############
############
+ Type 2 Routing Header

= IPv6ExtHdrRouting - type 2 - build/dissection
p = IPv6(raw(IPv6(dst='2001:db8::1', src='2001:db8::2')/IPv6ExtHdrRouting(type=2, addresses=['2001:db8::3'])/ICMPv6EchoRequest()))
p.type == 2 and len(p.addresses) == 1 and p.cksum == 0x2446

= IPv6ExtHdrRouting - type 2 - hashret

p = IPv6()/IPv6ExtHdrRouting(addresses=["2001:db8::1", "2001:db8::2"])/ICMPv6EchoRequest()
p.hashret() == b" \x01\r\xb8\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00:\x00\x00\x00\x00"


############
############
+ Mobility Options - Binding Refresh Advice

= MIP6OptBRAdvice - build (default values)
s = b'\x02\x02\x00\x00'
raw(MIP6OptBRAdvice()) == s

= MIP6OptBRAdvice - dissection (default values)
p = MIP6OptBRAdvice(s)
p.otype == 2 and p.olen == 2 and p.rinter == 0

= MIP6OptBRAdvice - build
s = b'\x03*\n\xf7'
raw(MIP6OptBRAdvice(otype=3, olen=42, rinter=2807)) == s

= MIP6OptBRAdvice - dissection
p = MIP6OptBRAdvice(s)
p.otype == 3 and p.olen == 42 and p.rinter == 2807


############
############
+ Mobility Options - Alternate Care-of Address

= MIP6OptAltCoA - build (default values)
s = b'\x03\x10\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00'
raw(MIP6OptAltCoA()) == s

= MIP6OptAltCoA - dissection (default values)
p = MIP6OptAltCoA(s)
p.otype == 3 and p.olen == 16 and p.acoa == '::'

= MIP6OptAltCoA - build
s = b'*\x08 \x01\r\xb8\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01'
raw(MIP6OptAltCoA(otype=42, olen=8, acoa='2001:db8::1')) == s

= MIP6OptAltCoA - dissection
p = MIP6OptAltCoA(s)
p.otype == 42 and p.olen == 8 and p.acoa == '2001:db8::1'


############
############
+ Mobility Options - Nonce Indices

= MIP6OptNonceIndices - build (default values)
s = b'\x04\x10\x00\x00\x00\x00'
raw(MIP6OptNonceIndices()) == s

= MIP6OptNonceIndices - dissection (default values)
p = MIP6OptNonceIndices(s)
p.otype == 4 and p.olen == 16 and p.hni == 0 and p.coni == 0

= MIP6OptNonceIndices - build
s = b'\x04\x12\x00\x13\x00\x14'
raw(MIP6OptNonceIndices(olen=18, hni=19, coni=20)) == s

= MIP6OptNonceIndices - dissection
p = MIP6OptNonceIndices(s)
p.hni == 19 and p.coni == 20


############
############
+ Mobility Options - Binding Authentication Data

= MIP6OptBindingAuthData - build (default values)
s = b'\x05\x10\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00'
raw(MIP6OptBindingAuthData()) == s

= MIP6OptBindingAuthData - dissection (default values)
p = MIP6OptBindingAuthData(s)
p.otype == 5 and p.olen == 16 and p.authenticator == 0

= MIP6OptBindingAuthData - build
s = b'\x05*\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\n\xf7'
raw(MIP6OptBindingAuthData(olen=42, authenticator=2807)) == s

= MIP6OptBindingAuthData - dissection
p = MIP6OptBindingAuthData(s)
p.otype == 5 and p.olen == 42 and p.authenticator == 2807


############
############
+ Mobility Options - Mobile Network Prefix

= MIP6OptMobNetPrefix - build (default values)
s = b'\x06\x12\x00@\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00'
raw(MIP6OptMobNetPrefix()) == s

= MIP6OptMobNetPrefix - dissection (default values)
p = MIP6OptMobNetPrefix(s)
p.otype == 6 and p.olen == 18 and p.plen == 64 and p.prefix == '::'

= MIP6OptMobNetPrefix - build
s = b'\x06*\x02  \x01\r\xb8\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00'
raw(MIP6OptMobNetPrefix(olen=42, reserved=2, plen=32, prefix='2001:db8::')) == s

= MIP6OptMobNetPrefix - dissection
p = MIP6OptMobNetPrefix(s)
p.olen ==  42 and p.reserved  == 2 and p.plen == 32 and p.prefix == '2001:db8::'


############
############
+ Mobility Options - Link-Layer Address (MH-LLA)

= MIP6OptLLAddr - basic build
raw(MIP6OptLLAddr()) == b'\x07\x07\x02\x00\x00\x00\x00\x00\x00\x00'

= MIP6OptLLAddr - basic dissection
p = MIP6OptLLAddr(b'\x07\x07\x02\x00\x00\x00\x00\x00\x00\x00')
p.otype == 7 and p.olen == 7 and p.ocode == 2 and p.pad == 0 and p.lla == "00:00:00:00:00:00"

= MIP6OptLLAddr - build with specific values
raw(MIP6OptLLAddr(olen=42, ocode=4, pad=0xff, lla='EE:EE:EE:EE:EE:EE')) == b'\x07*\x04\xff\xee\xee\xee\xee\xee\xee'

= MIP6OptLLAddr - dissection with specific values
p = MIP6OptLLAddr(b'\x07*\x04\xff\xee\xee\xee\xee\xee\xee')

raw(MIP6OptLLAddr(olen=42, ocode=4, pad=0xff, lla='EE:EE:EE:EE:EE:EE'))
p.otype == 7 and p.olen == 42 and p.ocode == 4 and p.pad == 0xff and p.lla == "ee:ee:ee:ee:ee:ee"


############
############
+ Mobility Options - Mobile Node Identifier

= MIP6OptMNID - basic build
raw(MIP6OptMNID()) == b'\x08\x01\x01'

= MIP6OptMNID - basic dissection
p = MIP6OptMNID(b'\x08\x01\x01')
p.otype == 8 and p.olen == 1 and p.subtype == 1 and p.id == b""

= MIP6OptMNID - build with specific values
raw(MIP6OptMNID(subtype=42, id="someid")) == b'\x08\x07*someid'

= MIP6OptMNID - dissection with specific values
p = MIP6OptMNID(b'\x08\x07*someid')
p.otype == 8 and p.olen == 7 and p.subtype == 42 and p.id == b"someid"



############
############
+ Mobility Options - Message Authentication

= MIP6OptMsgAuth - basic build
raw(MIP6OptMsgAuth()) == b'\x09\x11\x01\x00\x00\x00\x00AAAAAAAAAAAA'

= MIP6OptMsgAuth - basic dissection
p = MIP6OptMsgAuth(b'\x09\x11\x01\x00\x00\x00\x00AAAAAAAAAAAA')
p.otype == 9 and p.olen == 17 and p.subtype == 1 and p.mspi == 0 and p.authdata == b"A"*12

= MIP6OptMsgAuth - build with specific values
raw(MIP6OptMsgAuth(authdata="B"*16, mspi=0xeeeeeeee, subtype=0xff)) == b'\t\x15\xff\xee\xee\xee\xeeBBBBBBBBBBBBBBBB'

= MIP6OptMsgAuth - dissection with specific values
p = MIP6OptMsgAuth(b'\t\x15\xff\xee\xee\xee\xeeBBBBBBBBBBBBBBBB')
p.otype == 9 and p.olen == 21 and p.subtype == 255 and p.mspi == 0xeeeeeeee and p.authdata == b"B"*16


############
############
+ Mobility Options - Replay Protection

= MIP6OptReplayProtection - basic build
raw(MIP6OptReplayProtection()) == b'\n\x08\x00\x00\x00\x00\x00\x00\x00\x00'

= MIP6OptReplayProtection - basic dissection
p = MIP6OptReplayProtection(b'\n\x08\x00\x00\x00\x00\x00\x00\x00\x00')
p.otype == 10 and p.olen == 8 and p.timestamp == 0

= MIP6OptReplayProtection - build with specific values
s = raw(MIP6OptReplayProtection(olen=42, timestamp=(72*31536000)<<32))
s == b'\n*\x87V|\x00\x00\x00\x00\x00'

= MIP6OptReplayProtection - dissection with specific values
p = MIP6OptReplayProtection(s)
p.otype == 10 and p.olen == 42 and p.timestamp == 9752118382559232000
p.fields_desc[-1].i2repr("", p.timestamp) == 'Mon, 13 Dec 1971 23:50:39 +0000 (9752118382559232000)'


############
############
+ Mobility Options - CGA Parameters
= MIP6OptCGAParams


############
############
+ Mobility Options - Signature
= MIP6OptSignature


############
############
+ Mobility Options - Permanent Home Keygen Token
= MIP6OptHomeKeygenToken


############
############
+ Mobility Options - Care-of Test Init
= MIP6OptCareOfTestInit


############
############
+ Mobility Options - Care-of Test
= MIP6OptCareOfTest


############
############
+ Mobility Options - Automatic Padding - MIP6OptBRAdvice
=  Mobility Options - Automatic Padding - MIP6OptBRAdvice
a = raw(MIP6MH_BU(seq=0x4242, options=[MIP6OptBRAdvice()]))                        ==b';\x01\x05\x00\x00\x00BB\xd0\x00\x00\x03\x02\x02\x00\x00'
b = raw(MIP6MH_BU(seq=0x4242, options=[Pad1(),MIP6OptBRAdvice()]))                 ==b';\x02\x05\x00\x00\x00BB\xd0\x00\x00\x03\x00\x00\x02\x02\x00\x00\x01\x04\x00\x00\x00\x00'
c = raw(MIP6MH_BU(seq=0x4242, options=[PadN(optdata=b'\x00'*0),MIP6OptBRAdvice()])) ==b';\x02\x05\x00\x00\x00BB\xd0\x00\x00\x03\x01\x00\x02\x02\x00\x00\x01\x04\x00\x00\x00\x00'
d = raw(MIP6MH_BU(seq=0x4242, options=[PadN(optdata=b'\x00'*1),MIP6OptBRAdvice()])) ==b';\x02\x05\x00\x00\x00BB\xd0\x00\x00\x03\x01\x01\x00\x00\x02\x02\x00\x00\x01\x02\x00\x00'
e = raw(MIP6MH_BU(seq=0x4242, options=[PadN(optdata=b'\x00'*2),MIP6OptBRAdvice()])) ==b';\x02\x05\x00\x00\x00BB\xd0\x00\x00\x03\x01\x02\x00\x00\x02\x02\x00\x00\x01\x02\x00\x00'
g = raw(MIP6MH_BU(seq=0x4242, options=[PadN(optdata=b'\x00'*3),MIP6OptBRAdvice()])) ==b';\x02\x05\x00\x00\x00BB\xd0\x00\x00\x03\x01\x03\x00\x00\x00\x00\x02\x02\x00\x00\x01\x00'
h = raw(MIP6MH_BU(seq=0x4242, options=[PadN(optdata=b'\x00'*4),MIP6OptBRAdvice()])) ==b';\x02\x05\x00\x00\x00BB\xd0\x00\x00\x03\x01\x04\x00\x00\x00\x00\x02\x02\x00\x00\x01\x00'
i = raw(MIP6MH_BU(seq=0x4242, options=[PadN(optdata=b'\x00'*5),MIP6OptBRAdvice()])) ==b';\x02\x05\x00\x00\x00BB\xd0\x00\x00\x03\x01\x05\x00\x00\x00\x00\x00\x00\x02\x02\x00\x00'
j = raw(MIP6MH_BU(seq=0x4242, options=[PadN(optdata=b'\x00'*6),MIP6OptBRAdvice()])) ==b';\x02\x05\x00\x00\x00BB\xd0\x00\x00\x03\x01\x06\x00\x00\x00\x00\x00\x00\x02\x02\x00\x00'
a and b and c and d and e and g and h and i and j
                                                
############
############
+ Mobility Options - Automatic Padding - MIP6OptAltCoA           
=  Mobility Options - Automatic Padding - MIP6OptAltCoA          
a = raw(MIP6MH_BU(seq=0x4242, options=[MIP6OptAltCoA()]))                        ==b';\x03\x05\x00\x00\x00BB\xd0\x00\x00\x03\x01\x00\x03\x10\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00'
b = raw(MIP6MH_BU(seq=0x4242, options=[Pad1(),MIP6OptAltCoA()]))                 ==b';\x03\x05\x00\x00\x00BB\xd0\x00\x00\x03\x00\x00\x03\x10\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00'
c = raw(MIP6MH_BU(seq=0x4242, options=[PadN(optdata=b'\x00'*0),MIP6OptAltCoA()])) ==b';\x03\x05\x00\x00\x00BB\xd0\x00\x00\x03\x01\x00\x03\x10\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00'
d = raw(MIP6MH_BU(seq=0x4242, options=[PadN(optdata=b'\x00'*1),MIP6OptAltCoA()])) ==b';\x04\x05\x00\x00\x00BB\xd0\x00\x00\x03\x01\x01\x00\x01\x05\x00\x00\x00\x00\x00\x03\x10\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00'
e = raw(MIP6MH_BU(seq=0x4242, options=[PadN(optdata=b'\x00'*2),MIP6OptAltCoA()])) ==b';\x04\x05\x00\x00\x00BB\xd0\x00\x00\x03\x01\x02\x00\x00\x01\x04\x00\x00\x00\x00\x03\x10\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00'
g = raw(MIP6MH_BU(seq=0x4242, options=[PadN(optdata=b'\x00'*3),MIP6OptAltCoA()])) ==b';\x04\x05\x00\x00\x00BB\xd0\x00\x00\x03\x01\x03\x00\x00\x00\x01\x03\x00\x00\x00\x03\x10\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00'
h = raw(MIP6MH_BU(seq=0x4242, options=[PadN(optdata=b'\x00'*4),MIP6OptAltCoA()])) ==b';\x04\x05\x00\x00\x00BB\xd0\x00\x00\x03\x01\x04\x00\x00\x00\x00\x01\x02\x00\x00\x03\x10\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00'
i = raw(MIP6MH_BU(seq=0x4242, options=[PadN(optdata=b'\x00'*5),MIP6OptAltCoA()])) ==b';\x04\x05\x00\x00\x00BB\xd0\x00\x00\x03\x01\x05\x00\x00\x00\x00\x00\x01\x01\x00\x03\x10\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00'
j = raw(MIP6MH_BU(seq=0x4242, options=[PadN(optdata=b'\x00'*6),MIP6OptAltCoA()])) ==b';\x04\x05\x00\x00\x00BB\xd0\x00\x00\x03\x01\x06\x00\x00\x00\x00\x00\x00\x01\x00\x03\x10\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00'
a and b and c and d and e and g and h and i and j

                                                
############
############
+ Mobility Options - Automatic Padding - MIP6OptNonceIndices                             
=  Mobility Options - Automatic Padding - MIP6OptNonceIndices                            
a = raw(MIP6MH_BU(seq=0x4242, options=[MIP6OptNonceIndices()]))                        ==b';\x02\x05\x00\x00\x00BB\xd0\x00\x00\x03\x04\x10\x00\x00\x00\x00\x01\x04\x00\x00\x00\x00'
b = raw(MIP6MH_BU(seq=0x4242, options=[Pad1(),MIP6OptNonceIndices()]))                 ==b';\x02\x05\x00\x00\x00BB\xd0\x00\x00\x03\x00\x00\x04\x10\x00\x00\x00\x00\x01\x02\x00\x00'
c = raw(MIP6MH_BU(seq=0x4242, options=[PadN(optdata=b'\x00'*0),MIP6OptNonceIndices()])) ==b';\x02\x05\x00\x00\x00BB\xd0\x00\x00\x03\x01\x00\x04\x10\x00\x00\x00\x00\x01\x02\x00\x00'
d = raw(MIP6MH_BU(seq=0x4242, options=[PadN(optdata=b'\x00'*1),MIP6OptNonceIndices()])) ==b';\x02\x05\x00\x00\x00BB\xd0\x00\x00\x03\x01\x01\x00\x00\x04\x10\x00\x00\x00\x00\x01\x00'
e = raw(MIP6MH_BU(seq=0x4242, options=[PadN(optdata=b'\x00'*2),MIP6OptNonceIndices()])) ==b';\x02\x05\x00\x00\x00BB\xd0\x00\x00\x03\x01\x02\x00\x00\x04\x10\x00\x00\x00\x00\x01\x00'
g = raw(MIP6MH_BU(seq=0x4242, options=[PadN(optdata=b'\x00'*3),MIP6OptNonceIndices()])) ==b';\x02\x05\x00\x00\x00BB\xd0\x00\x00\x03\x01\x03\x00\x00\x00\x00\x04\x10\x00\x00\x00\x00'
h = raw(MIP6MH_BU(seq=0x4242, options=[PadN(optdata=b'\x00'*4),MIP6OptNonceIndices()])) ==b';\x02\x05\x00\x00\x00BB\xd0\x00\x00\x03\x01\x04\x00\x00\x00\x00\x04\x10\x00\x00\x00\x00'
i = raw(MIP6MH_BU(seq=0x4242, options=[PadN(optdata=b'\x00'*5),MIP6OptNonceIndices()])) ==b';\x03\x05\x00\x00\x00BB\xd0\x00\x00\x03\x01\x05\x00\x00\x00\x00\x00\x00\x04\x10\x00\x00\x00\x00\x01\x04\x00\x00\x00\x00'
j = raw(MIP6MH_BU(seq=0x4242, options=[PadN(optdata=b'\x00'*6),MIP6OptNonceIndices()])) ==b';\x03\x05\x00\x00\x00BB\xd0\x00\x00\x03\x01\x06\x00\x00\x00\x00\x00\x00\x04\x10\x00\x00\x00\x00\x01\x04\x00\x00\x00\x00'
a and b and c and d and e and g and h and i and j

                                                
############
############
+ Mobility Options - Automatic Padding - MIP6OptBindingAuthData                          
=  Mobility Options - Automatic Padding - MIP6OptBindingAuthData                                 
a = raw(MIP6MH_BU(seq=0x4242, options=[MIP6OptBindingAuthData()]))                        ==b';\x03\x05\x00\x00\x00BB\xd0\x00\x00\x03\x01\x04\x00\x00\x00\x00\x05\x10\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00'
b = raw(MIP6MH_BU(seq=0x4242, options=[Pad1(),MIP6OptBindingAuthData()]))                 ==b';\x03\x05\x00\x00\x00BB\xd0\x00\x00\x03\x00\x01\x03\x00\x00\x00\x05\x10\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00'
c = raw(MIP6MH_BU(seq=0x4242, options=[PadN(optdata=b'\x00'*0),MIP6OptBindingAuthData()])) ==b';\x03\x05\x00\x00\x00BB\xd0\x00\x00\x03\x01\x00\x01\x02\x00\x00\x05\x10\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00'
d = raw(MIP6MH_BU(seq=0x4242, options=[PadN(optdata=b'\x00'*1),MIP6OptBindingAuthData()])) ==b';\x03\x05\x00\x00\x00BB\xd0\x00\x00\x03\x01\x01\x00\x01\x01\x00\x05\x10\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00'
e = raw(MIP6MH_BU(seq=0x4242, options=[PadN(optdata=b'\x00'*2),MIP6OptBindingAuthData()])) ==b';\x03\x05\x00\x00\x00BB\xd0\x00\x00\x03\x01\x02\x00\x00\x01\x00\x05\x10\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00'
g = raw(MIP6MH_BU(seq=0x4242, options=[PadN(optdata=b'\x00'*3),MIP6OptBindingAuthData()])) ==b';\x03\x05\x00\x00\x00BB\xd0\x00\x00\x03\x01\x03\x00\x00\x00\x00\x05\x10\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00'
h = raw(MIP6MH_BU(seq=0x4242, options=[PadN(optdata=b'\x00'*4),MIP6OptBindingAuthData()])) ==b';\x03\x05\x00\x00\x00BB\xd0\x00\x00\x03\x01\x04\x00\x00\x00\x00\x05\x10\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00'
i = raw(MIP6MH_BU(seq=0x4242, options=[PadN(optdata=b'\x00'*5),MIP6OptBindingAuthData()])) ==b';\x04\x05\x00\x00\x00BB\xd0\x00\x00\x03\x01\x05\x00\x00\x00\x00\x00\x01\x05\x00\x00\x00\x00\x00\x05\x10\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00'
j = raw(MIP6MH_BU(seq=0x4242, options=[PadN(optdata=b'\x00'*6),MIP6OptBindingAuthData()])) ==b';\x04\x05\x00\x00\x00BB\xd0\x00\x00\x03\x01\x06\x00\x00\x00\x00\x00\x00\x01\x04\x00\x00\x00\x00\x05\x10\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00'
a and b and c and d and e and g and h and i and j

                                                
############
############
+ Mobility Options - Automatic Padding - MIP6OptMobNetPrefix                             
=  Mobility Options - Automatic Padding - MIP6OptMobNetPrefix                            
a = raw(MIP6MH_BU(seq=0x4242, options=[MIP6OptMobNetPrefix()]))                        == b';\x03\x05\x00\x00\x00BB\xd0\x00\x00\x03\x06\x12\x00@\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00'
b = raw(MIP6MH_BU(seq=0x4242, options=[Pad1(),MIP6OptMobNetPrefix()]))                 == b';\x04\x05\x00\x00\x00BB\xd0\x00\x00\x03\x00\x01\x05\x00\x00\x00\x00\x00\x06\x12\x00@\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00'
c = raw(MIP6MH_BU(seq=0x4242, options=[PadN(optdata=b'\x00'*0),MIP6OptMobNetPrefix()])) == b';\x04\x05\x00\x00\x00BB\xd0\x00\x00\x03\x01\x00\x01\x04\x00\x00\x00\x00\x06\x12\x00@\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00'
d = raw(MIP6MH_BU(seq=0x4242, options=[PadN(optdata=b'\x00'*1),MIP6OptMobNetPrefix()])) == b';\x04\x05\x00\x00\x00BB\xd0\x00\x00\x03\x01\x01\x00\x01\x03\x00\x00\x00\x06\x12\x00@\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00'
e = raw(MIP6MH_BU(seq=0x4242, options=[PadN(optdata=b'\x00'*2),MIP6OptMobNetPrefix()])) == b';\x04\x05\x00\x00\x00BB\xd0\x00\x00\x03\x01\x02\x00\x00\x01\x02\x00\x00\x06\x12\x00@\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00'
g = raw(MIP6MH_BU(seq=0x4242, options=[PadN(optdata=b'\x00'*3),MIP6OptMobNetPrefix()])) == b';\x04\x05\x00\x00\x00BB\xd0\x00\x00\x03\x01\x03\x00\x00\x00\x01\x01\x00\x06\x12\x00@\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00'
h = raw(MIP6MH_BU(seq=0x4242, options=[PadN(optdata=b'\x00'*4),MIP6OptMobNetPrefix()])) == b';\x04\x05\x00\x00\x00BB\xd0\x00\x00\x03\x01\x04\x00\x00\x00\x00\x01\x00\x06\x12\x00@\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00'
i = raw(MIP6MH_BU(seq=0x4242, options=[PadN(optdata=b'\x00'*5),MIP6OptMobNetPrefix()])) == b';\x04\x05\x00\x00\x00BB\xd0\x00\x00\x03\x01\x05\x00\x00\x00\x00\x00\x00\x06\x12\x00@\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00'
j = raw(MIP6MH_BU(seq=0x4242, options=[PadN(optdata=b'\x00'*6),MIP6OptMobNetPrefix()])) == b';\x04\x05\x00\x00\x00BB\xd0\x00\x00\x03\x01\x06\x00\x00\x00\x00\x00\x00\x06\x12\x00@\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00'
a and b and c and d and e and g and h and i and j

                                                
############
############
+ Mobility Options - Automatic Padding - MIP6OptLLAddr                           
=  Mobility Options - Automatic Padding - MIP6OptLLAddr                          
a = raw(MIP6MH_BU(seq=0x4242, options=[MIP6OptLLAddr()]))                        ==b';\x02\x05\x00\x00\x00BB\xd0\x00\x00\x03\x07\x07\x02\x00\x00\x00\x00\x00\x00\x00\x01\x00'
b = raw(MIP6MH_BU(seq=0x4242, options=[Pad1(),MIP6OptLLAddr()]))                 ==b';\x02\x05\x00\x00\x00BB\xd0\x00\x00\x03\x00\x07\x07\x02\x00\x00\x00\x00\x00\x00\x00\x00'
c = raw(MIP6MH_BU(seq=0x4242, options=[PadN(optdata=b'\x00'*0),MIP6OptLLAddr()])) ==b';\x02\x05\x00\x00\x00BB\xd0\x00\x00\x03\x01\x00\x07\x07\x02\x00\x00\x00\x00\x00\x00\x00'
d = raw(MIP6MH_BU(seq=0x4242, options=[PadN(optdata=b'\x00'*1),MIP6OptLLAddr()])) ==b';\x03\x05\x00\x00\x00BB\xd0\x00\x00\x03\x01\x01\x00\x07\x07\x02\x00\x00\x00\x00\x00\x00\x00\x01\x05\x00\x00\x00\x00\x00'
e = raw(MIP6MH_BU(seq=0x4242, options=[PadN(optdata=b'\x00'*2),MIP6OptLLAddr()])) ==b';\x03\x05\x00\x00\x00BB\xd0\x00\x00\x03\x01\x02\x00\x00\x07\x07\x02\x00\x00\x00\x00\x00\x00\x00\x01\x04\x00\x00\x00\x00'
g = raw(MIP6MH_BU(seq=0x4242, options=[PadN(optdata=b'\x00'*3),MIP6OptLLAddr()])) ==b';\x03\x05\x00\x00\x00BB\xd0\x00\x00\x03\x01\x03\x00\x00\x00\x07\x07\x02\x00\x00\x00\x00\x00\x00\x00\x01\x03\x00\x00\x00'
h = raw(MIP6MH_BU(seq=0x4242, options=[PadN(optdata=b'\x00'*4),MIP6OptLLAddr()])) ==b';\x03\x05\x00\x00\x00BB\xd0\x00\x00\x03\x01\x04\x00\x00\x00\x00\x07\x07\x02\x00\x00\x00\x00\x00\x00\x00\x01\x02\x00\x00'
i = raw(MIP6MH_BU(seq=0x4242, options=[PadN(optdata=b'\x00'*5),MIP6OptLLAddr()])) ==b';\x03\x05\x00\x00\x00BB\xd0\x00\x00\x03\x01\x05\x00\x00\x00\x00\x00\x07\x07\x02\x00\x00\x00\x00\x00\x00\x00\x01\x01\x00'
j = raw(MIP6MH_BU(seq=0x4242, options=[PadN(optdata=b'\x00'*6),MIP6OptLLAddr()])) ==b';\x03\x05\x00\x00\x00BB\xd0\x00\x00\x03\x01\x06\x00\x00\x00\x00\x00\x00\x07\x07\x02\x00\x00\x00\x00\x00\x00\x00\x01\x00'
a and b and c and d and e and g and h and i and j

                                                
############
############
+ Mobility Options - Automatic Padding - MIP6OptMNID                             
=  Mobility Options - Automatic Padding - MIP6OptMNID                            
a = raw(MIP6MH_BU(seq=0x4242, options=[MIP6OptMNID()]))                        ==b';\x01\x05\x00\x00\x00BB\xd0\x00\x00\x03\x08\x01\x01\x00'
b = raw(MIP6MH_BU(seq=0x4242, options=[Pad1(),MIP6OptMNID()]))                 ==b';\x01\x05\x00\x00\x00BB\xd0\x00\x00\x03\x00\x08\x01\x01'
c = raw(MIP6MH_BU(seq=0x4242, options=[PadN(optdata=b'\x00'*0),MIP6OptMNID()])) ==b';\x02\x05\x00\x00\x00BB\xd0\x00\x00\x03\x01\x00\x08\x01\x01\x01\x05\x00\x00\x00\x00\x00'
d = raw(MIP6MH_BU(seq=0x4242, options=[PadN(optdata=b'\x00'*1),MIP6OptMNID()])) ==b';\x02\x05\x00\x00\x00BB\xd0\x00\x00\x03\x01\x01\x00\x08\x01\x01\x01\x04\x00\x00\x00\x00'
e = raw(MIP6MH_BU(seq=0x4242, options=[PadN(optdata=b'\x00'*2),MIP6OptMNID()])) ==b';\x02\x05\x00\x00\x00BB\xd0\x00\x00\x03\x01\x02\x00\x00\x08\x01\x01\x01\x03\x00\x00\x00'
g = raw(MIP6MH_BU(seq=0x4242, options=[PadN(optdata=b'\x00'*3),MIP6OptMNID()])) ==b';\x02\x05\x00\x00\x00BB\xd0\x00\x00\x03\x01\x03\x00\x00\x00\x08\x01\x01\x01\x02\x00\x00'
h = raw(MIP6MH_BU(seq=0x4242, options=[PadN(optdata=b'\x00'*4),MIP6OptMNID()])) ==b';\x02\x05\x00\x00\x00BB\xd0\x00\x00\x03\x01\x04\x00\x00\x00\x00\x08\x01\x01\x01\x01\x00'
i = raw(MIP6MH_BU(seq=0x4242, options=[PadN(optdata=b'\x00'*5),MIP6OptMNID()])) ==b';\x02\x05\x00\x00\x00BB\xd0\x00\x00\x03\x01\x05\x00\x00\x00\x00\x00\x08\x01\x01\x01\x00'
j = raw(MIP6MH_BU(seq=0x4242, options=[PadN(optdata=b'\x00'*6),MIP6OptMNID()])) ==b';\x02\x05\x00\x00\x00BB\xd0\x00\x00\x03\x01\x06\x00\x00\x00\x00\x00\x00\x08\x01\x01\x00'
a and b and c and d and e and g and h and i and j

                                                
############
############
+ Mobility Options - Automatic Padding - MIP6OptMsgAuth                          
=  Mobility Options - Automatic Padding - MIP6OptMsgAuth                                 
a = raw(MIP6MH_BU(seq=0x4242, options=[MIP6OptMsgAuth()]))                        ==b';\x03\x05\x00\x00\x00BB\xd0\x00\x00\x03\x00\t\x11\x01\x00\x00\x00\x00AAAAAAAAAAAA'
b = raw(MIP6MH_BU(seq=0x4242, options=[Pad1(),MIP6OptMsgAuth()]))                 ==b';\x03\x05\x00\x00\x00BB\xd0\x00\x00\x03\x00\t\x11\x01\x00\x00\x00\x00AAAAAAAAAAAA'
c = raw(MIP6MH_BU(seq=0x4242, options=[PadN(optdata=b'\x00'*0),MIP6OptMsgAuth()])) ==b';\x04\x05\x00\x00\x00BB\xd0\x00\x00\x03\x01\x00\x01\x01\x00\t\x11\x01\x00\x00\x00\x00AAAAAAAAAAAA\x01\x02\x00\x00'
d = raw(MIP6MH_BU(seq=0x4242, options=[PadN(optdata=b'\x00'*1),MIP6OptMsgAuth()])) ==b';\x04\x05\x00\x00\x00BB\xd0\x00\x00\x03\x01\x01\x00\x01\x00\t\x11\x01\x00\x00\x00\x00AAAAAAAAAAAA\x01\x02\x00\x00'
e = raw(MIP6MH_BU(seq=0x4242, options=[PadN(optdata=b'\x00'*2),MIP6OptMsgAuth()])) ==b';\x04\x05\x00\x00\x00BB\xd0\x00\x00\x03\x01\x02\x00\x00\x00\t\x11\x01\x00\x00\x00\x00AAAAAAAAAAAA\x01\x02\x00\x00'
g = raw(MIP6MH_BU(seq=0x4242, options=[PadN(optdata=b'\x00'*3),MIP6OptMsgAuth()])) ==b';\x04\x05\x00\x00\x00BB\xd0\x00\x00\x03\x01\x03\x00\x00\x00\t\x11\x01\x00\x00\x00\x00AAAAAAAAAAAA\x01\x02\x00\x00'
h = raw(MIP6MH_BU(seq=0x4242, options=[PadN(optdata=b'\x00'*4),MIP6OptMsgAuth()])) ==b';\x04\x05\x00\x00\x00BB\xd0\x00\x00\x03\x01\x04\x00\x00\x00\x00\x01\x01\x00\t\x11\x01\x00\x00\x00\x00AAAAAAAAAAAA'
i = raw(MIP6MH_BU(seq=0x4242, options=[PadN(optdata=b'\x00'*5),MIP6OptMsgAuth()])) ==b';\x04\x05\x00\x00\x00BB\xd0\x00\x00\x03\x01\x05\x00\x00\x00\x00\x00\x01\x00\t\x11\x01\x00\x00\x00\x00AAAAAAAAAAAA'
j = raw(MIP6MH_BU(seq=0x4242, options=[PadN(optdata=b'\x00'*6),MIP6OptMsgAuth()])) ==b';\x04\x05\x00\x00\x00BB\xd0\x00\x00\x03\x01\x06\x00\x00\x00\x00\x00\x00\x00\t\x11\x01\x00\x00\x00\x00AAAAAAAAAAAA'
a and b and c and d and e and g and h and i and j

                                                
############
############
+ Mobility Options - Automatic Padding - MIP6OptReplayProtection                                 
=  Mobility Options - Automatic Padding - MIP6OptReplayProtection                                
a = raw(MIP6MH_BU(seq=0x4242, options=[MIP6OptReplayProtection()]))                        ==b';\x03\x05\x00\x00\x00BB\xd0\x00\x00\x03\x01\x04\x00\x00\x00\x00\n\x08\x00\x00\x00\x00\x00\x00\x00\x00\x01\x02\x00\x00'
b = raw(MIP6MH_BU(seq=0x4242, options=[Pad1(),MIP6OptReplayProtection()]))                 ==b';\x03\x05\x00\x00\x00BB\xd0\x00\x00\x03\x00\x01\x03\x00\x00\x00\n\x08\x00\x00\x00\x00\x00\x00\x00\x00\x01\x02\x00\x00'
c = raw(MIP6MH_BU(seq=0x4242, options=[PadN(optdata=b'\x00'*0),MIP6OptReplayProtection()])) ==b';\x03\x05\x00\x00\x00BB\xd0\x00\x00\x03\x01\x00\x01\x02\x00\x00\n\x08\x00\x00\x00\x00\x00\x00\x00\x00\x01\x02\x00\x00'
d = raw(MIP6MH_BU(seq=0x4242, options=[PadN(optdata=b'\x00'*1),MIP6OptReplayProtection()])) ==b';\x03\x05\x00\x00\x00BB\xd0\x00\x00\x03\x01\x01\x00\x01\x01\x00\n\x08\x00\x00\x00\x00\x00\x00\x00\x00\x01\x02\x00\x00'
e = raw(MIP6MH_BU(seq=0x4242, options=[PadN(optdata=b'\x00'*2),MIP6OptReplayProtection()])) ==b';\x03\x05\x00\x00\x00BB\xd0\x00\x00\x03\x01\x02\x00\x00\x01\x00\n\x08\x00\x00\x00\x00\x00\x00\x00\x00\x01\x02\x00\x00'
g = raw(MIP6MH_BU(seq=0x4242, options=[PadN(optdata=b'\x00'*3),MIP6OptReplayProtection()])) ==b';\x03\x05\x00\x00\x00BB\xd0\x00\x00\x03\x01\x03\x00\x00\x00\x00\n\x08\x00\x00\x00\x00\x00\x00\x00\x00\x01\x02\x00\x00'
h = raw(MIP6MH_BU(seq=0x4242, options=[PadN(optdata=b'\x00'*4),MIP6OptReplayProtection()])) ==b';\x03\x05\x00\x00\x00BB\xd0\x00\x00\x03\x01\x04\x00\x00\x00\x00\n\x08\x00\x00\x00\x00\x00\x00\x00\x00\x01\x02\x00\x00'
i = raw(MIP6MH_BU(seq=0x4242, options=[PadN(optdata=b'\x00'*5),MIP6OptReplayProtection()])) ==b';\x04\x05\x00\x00\x00BB\xd0\x00\x00\x03\x01\x05\x00\x00\x00\x00\x00\x01\x05\x00\x00\x00\x00\x00\n\x08\x00\x00\x00\x00\x00\x00\x00\x00\x01\x02\x00\x00'
j = raw(MIP6MH_BU(seq=0x4242, options=[PadN(optdata=b'\x00'*6),MIP6OptReplayProtection()])) ==b';\x04\x05\x00\x00\x00BB\xd0\x00\x00\x03\x01\x06\x00\x00\x00\x00\x00\x00\x01\x04\x00\x00\x00\x00\n\x08\x00\x00\x00\x00\x00\x00\x00\x00\x01\x02\x00\x00'
a and b and c and d and e and g and h and i and j

                                                
############
############
+ Mobility Options - Automatic Padding - MIP6OptCGAParamsReq                             
=  Mobility Options - Automatic Padding - MIP6OptCGAParamsReq                            
a = raw(MIP6MH_BU(seq=0x4242, options=[MIP6OptCGAParamsReq()]))                        ==b';\x01\x05\x00\x00\x00BB\xd0\x00\x00\x03\x0b\x00\x01\x00'
b = raw(MIP6MH_BU(seq=0x4242, options=[Pad1(),MIP6OptCGAParamsReq()]))                 ==b';\x01\x05\x00\x00\x00BB\xd0\x00\x00\x03\x00\x0b\x00\x00'
c = raw(MIP6MH_BU(seq=0x4242, options=[PadN(optdata=b'\x00'*0),MIP6OptCGAParamsReq()])) ==b';\x01\x05\x00\x00\x00BB\xd0\x00\x00\x03\x01\x00\x0b\x00'
d = raw(MIP6MH_BU(seq=0x4242, options=[PadN(optdata=b'\x00'*1),MIP6OptCGAParamsReq()])) ==b';\x02\x05\x00\x00\x00BB\xd0\x00\x00\x03\x01\x01\x00\x0b\x00\x01\x05\x00\x00\x00\x00\x00'
e = raw(MIP6MH_BU(seq=0x4242, options=[PadN(optdata=b'\x00'*2),MIP6OptCGAParamsReq()])) ==b';\x02\x05\x00\x00\x00BB\xd0\x00\x00\x03\x01\x02\x00\x00\x0b\x00\x01\x04\x00\x00\x00\x00'
g = raw(MIP6MH_BU(seq=0x4242, options=[PadN(optdata=b'\x00'*3),MIP6OptCGAParamsReq()])) ==b';\x02\x05\x00\x00\x00BB\xd0\x00\x00\x03\x01\x03\x00\x00\x00\x0b\x00\x01\x03\x00\x00\x00'
h = raw(MIP6MH_BU(seq=0x4242, options=[PadN(optdata=b'\x00'*4),MIP6OptCGAParamsReq()])) ==b';\x02\x05\x00\x00\x00BB\xd0\x00\x00\x03\x01\x04\x00\x00\x00\x00\x0b\x00\x01\x02\x00\x00'
i = raw(MIP6MH_BU(seq=0x4242, options=[PadN(optdata=b'\x00'*5),MIP6OptCGAParamsReq()])) ==b';\x02\x05\x00\x00\x00BB\xd0\x00\x00\x03\x01\x05\x00\x00\x00\x00\x00\x0b\x00\x01\x01\x00'
j = raw(MIP6MH_BU(seq=0x4242, options=[PadN(optdata=b'\x00'*6),MIP6OptCGAParamsReq()])) ==b';\x02\x05\x00\x00\x00BB\xd0\x00\x00\x03\x01\x06\x00\x00\x00\x00\x00\x00\x0b\x00\x01\x00'
a and b and c and d and e and g and h and i and j
                                                

############
############
+ Mobility Options - Automatic Padding - MIP6OptCGAParams                                
=  Mobility Options - Automatic Padding - MIP6OptCGAParams                               
a = raw(MIP6MH_BU(seq=0x4242, options=[MIP6OptCGAParams()]))                        ==b';\x01\x05\x00\x00\x00BB\xd0\x00\x00\x03\x0c\x00\x01\x00'
b = raw(MIP6MH_BU(seq=0x4242, options=[Pad1(),MIP6OptCGAParams()]))                 ==b';\x01\x05\x00\x00\x00BB\xd0\x00\x00\x03\x00\x0c\x00\x00'
c = raw(MIP6MH_BU(seq=0x4242, options=[PadN(optdata=b'\x00'*0),MIP6OptCGAParams()])) ==b';\x01\x05\x00\x00\x00BB\xd0\x00\x00\x03\x01\x00\x0c\x00'
d = raw(MIP6MH_BU(seq=0x4242, options=[PadN(optdata=b'\x00'*1),MIP6OptCGAParams()])) ==b';\x02\x05\x00\x00\x00BB\xd0\x00\x00\x03\x01\x01\x00\x0c\x00\x01\x05\x00\x00\x00\x00\x00'
e = raw(MIP6MH_BU(seq=0x4242, options=[PadN(optdata=b'\x00'*2),MIP6OptCGAParams()])) ==b';\x02\x05\x00\x00\x00BB\xd0\x00\x00\x03\x01\x02\x00\x00\x0c\x00\x01\x04\x00\x00\x00\x00'
g = raw(MIP6MH_BU(seq=0x4242, options=[PadN(optdata=b'\x00'*3),MIP6OptCGAParams()])) ==b';\x02\x05\x00\x00\x00BB\xd0\x00\x00\x03\x01\x03\x00\x00\x00\x0c\x00\x01\x03\x00\x00\x00'
h = raw(MIP6MH_BU(seq=0x4242, options=[PadN(optdata=b'\x00'*4),MIP6OptCGAParams()])) ==b';\x02\x05\x00\x00\x00BB\xd0\x00\x00\x03\x01\x04\x00\x00\x00\x00\x0c\x00\x01\x02\x00\x00'
i = raw(MIP6MH_BU(seq=0x4242, options=[PadN(optdata=b'\x00'*5),MIP6OptCGAParams()])) ==b';\x02\x05\x00\x00\x00BB\xd0\x00\x00\x03\x01\x05\x00\x00\x00\x00\x00\x0c\x00\x01\x01\x00'
j = raw(MIP6MH_BU(seq=0x4242, options=[PadN(optdata=b'\x00'*6),MIP6OptCGAParams()])) ==b';\x02\x05\x00\x00\x00BB\xd0\x00\x00\x03\x01\x06\x00\x00\x00\x00\x00\x00\x0c\x00\x01\x00'
a and b and c and d and e and g and h and i and j

                                                
############
############
+ Mobility Options - Automatic Padding - MIP6OptSignature                                
=  Mobility Options - Automatic Padding - MIP6OptSignature                               
a = raw(MIP6MH_BU(seq=0x4242, options=[MIP6OptSignature()]))                        ==b';\x01\x05\x00\x00\x00BB\xd0\x00\x00\x03\r\x00\x01\x00'
b = raw(MIP6MH_BU(seq=0x4242, options=[Pad1(),MIP6OptSignature()]))                 ==b';\x01\x05\x00\x00\x00BB\xd0\x00\x00\x03\x00\r\x00\x00'
c = raw(MIP6MH_BU(seq=0x4242, options=[PadN(optdata=b'\x00'*0),MIP6OptSignature()])) ==b';\x01\x05\x00\x00\x00BB\xd0\x00\x00\x03\x01\x00\r\x00'
d = raw(MIP6MH_BU(seq=0x4242, options=[PadN(optdata=b'\x00'*1),MIP6OptSignature()])) ==b';\x02\x05\x00\x00\x00BB\xd0\x00\x00\x03\x01\x01\x00\r\x00\x01\x05\x00\x00\x00\x00\x00'
e = raw(MIP6MH_BU(seq=0x4242, options=[PadN(optdata=b'\x00'*2),MIP6OptSignature()])) ==b';\x02\x05\x00\x00\x00BB\xd0\x00\x00\x03\x01\x02\x00\x00\r\x00\x01\x04\x00\x00\x00\x00'
g = raw(MIP6MH_BU(seq=0x4242, options=[PadN(optdata=b'\x00'*3),MIP6OptSignature()])) ==b';\x02\x05\x00\x00\x00BB\xd0\x00\x00\x03\x01\x03\x00\x00\x00\r\x00\x01\x03\x00\x00\x00'
h = raw(MIP6MH_BU(seq=0x4242, options=[PadN(optdata=b'\x00'*4),MIP6OptSignature()])) ==b';\x02\x05\x00\x00\x00BB\xd0\x00\x00\x03\x01\x04\x00\x00\x00\x00\r\x00\x01\x02\x00\x00'
i = raw(MIP6MH_BU(seq=0x4242, options=[PadN(optdata=b'\x00'*5),MIP6OptSignature()])) ==b';\x02\x05\x00\x00\x00BB\xd0\x00\x00\x03\x01\x05\x00\x00\x00\x00\x00\r\x00\x01\x01\x00'
j = raw(MIP6MH_BU(seq=0x4242, options=[PadN(optdata=b'\x00'*6),MIP6OptSignature()])) ==b';\x02\x05\x00\x00\x00BB\xd0\x00\x00\x03\x01\x06\x00\x00\x00\x00\x00\x00\r\x00\x01\x00'
a and b and c and d and e and g and h and i and j

                                                
############
############
+ Mobility Options - Automatic Padding - MIP6OptHomeKeygenToken                          
=  Mobility Options - Automatic Padding - MIP6OptHomeKeygenToken                                 
a = raw(MIP6MH_BU(seq=0x4242, options=[MIP6OptHomeKeygenToken()]))                        ==b';\x01\x05\x00\x00\x00BB\xd0\x00\x00\x03\x0e\x00\x01\x00'
b = raw(MIP6MH_BU(seq=0x4242, options=[Pad1(),MIP6OptHomeKeygenToken()]))                 ==b';\x01\x05\x00\x00\x00BB\xd0\x00\x00\x03\x00\x0e\x00\x00'
c = raw(MIP6MH_BU(seq=0x4242, options=[PadN(optdata=b'\x00'*0),MIP6OptHomeKeygenToken()])) ==b';\x01\x05\x00\x00\x00BB\xd0\x00\x00\x03\x01\x00\x0e\x00'
d = raw(MIP6MH_BU(seq=0x4242, options=[PadN(optdata=b'\x00'*1),MIP6OptHomeKeygenToken()])) ==b';\x02\x05\x00\x00\x00BB\xd0\x00\x00\x03\x01\x01\x00\x0e\x00\x01\x05\x00\x00\x00\x00\x00'
e = raw(MIP6MH_BU(seq=0x4242, options=[PadN(optdata=b'\x00'*2),MIP6OptHomeKeygenToken()])) ==b';\x02\x05\x00\x00\x00BB\xd0\x00\x00\x03\x01\x02\x00\x00\x0e\x00\x01\x04\x00\x00\x00\x00'
g = raw(MIP6MH_BU(seq=0x4242, options=[PadN(optdata=b'\x00'*3),MIP6OptHomeKeygenToken()])) ==b';\x02\x05\x00\x00\x00BB\xd0\x00\x00\x03\x01\x03\x00\x00\x00\x0e\x00\x01\x03\x00\x00\x00'
h = raw(MIP6MH_BU(seq=0x4242, options=[PadN(optdata=b'\x00'*4),MIP6OptHomeKeygenToken()])) ==b';\x02\x05\x00\x00\x00BB\xd0\x00\x00\x03\x01\x04\x00\x00\x00\x00\x0e\x00\x01\x02\x00\x00'
i = raw(MIP6MH_BU(seq=0x4242, options=[PadN(optdata=b'\x00'*5),MIP6OptHomeKeygenToken()])) ==b';\x02\x05\x00\x00\x00BB\xd0\x00\x00\x03\x01\x05\x00\x00\x00\x00\x00\x0e\x00\x01\x01\x00'
j = raw(MIP6MH_BU(seq=0x4242, options=[PadN(optdata=b'\x00'*6),MIP6OptHomeKeygenToken()])) ==b';\x02\x05\x00\x00\x00BB\xd0\x00\x00\x03\x01\x06\x00\x00\x00\x00\x00\x00\x0e\x00\x01\x00'
a and b and c and d and e and g and h and i and j

                                                
############
############
+ Mobility Options - Automatic Padding - MIP6OptCareOfTestInit                           
=  Mobility Options - Automatic Padding - MIP6OptCareOfTestInit                          
a = raw(MIP6MH_BU(seq=0x4242, options=[MIP6OptCareOfTestInit()]))                        ==b';\x01\x05\x00\x00\x00BB\xd0\x00\x00\x03\x0f\x00\x01\x00'
b = raw(MIP6MH_BU(seq=0x4242, options=[Pad1(),MIP6OptCareOfTestInit()]))                 ==b';\x01\x05\x00\x00\x00BB\xd0\x00\x00\x03\x00\x0f\x00\x00'
c = raw(MIP6MH_BU(seq=0x4242, options=[PadN(optdata=b'\x00'*0),MIP6OptCareOfTestInit()])) ==b';\x01\x05\x00\x00\x00BB\xd0\x00\x00\x03\x01\x00\x0f\x00'
d = raw(MIP6MH_BU(seq=0x4242, options=[PadN(optdata=b'\x00'*1),MIP6OptCareOfTestInit()])) ==b';\x02\x05\x00\x00\x00BB\xd0\x00\x00\x03\x01\x01\x00\x0f\x00\x01\x05\x00\x00\x00\x00\x00'
e = raw(MIP6MH_BU(seq=0x4242, options=[PadN(optdata=b'\x00'*2),MIP6OptCareOfTestInit()])) ==b';\x02\x05\x00\x00\x00BB\xd0\x00\x00\x03\x01\x02\x00\x00\x0f\x00\x01\x04\x00\x00\x00\x00'
g = raw(MIP6MH_BU(seq=0x4242, options=[PadN(optdata=b'\x00'*3),MIP6OptCareOfTestInit()])) ==b';\x02\x05\x00\x00\x00BB\xd0\x00\x00\x03\x01\x03\x00\x00\x00\x0f\x00\x01\x03\x00\x00\x00'
h = raw(MIP6MH_BU(seq=0x4242, options=[PadN(optdata=b'\x00'*4),MIP6OptCareOfTestInit()])) ==b';\x02\x05\x00\x00\x00BB\xd0\x00\x00\x03\x01\x04\x00\x00\x00\x00\x0f\x00\x01\x02\x00\x00'
i = raw(MIP6MH_BU(seq=0x4242, options=[PadN(optdata=b'\x00'*5),MIP6OptCareOfTestInit()])) ==b';\x02\x05\x00\x00\x00BB\xd0\x00\x00\x03\x01\x05\x00\x00\x00\x00\x00\x0f\x00\x01\x01\x00'
j = raw(MIP6MH_BU(seq=0x4242, options=[PadN(optdata=b'\x00'*6),MIP6OptCareOfTestInit()])) ==b';\x02\x05\x00\x00\x00BB\xd0\x00\x00\x03\x01\x06\x00\x00\x00\x00\x00\x00\x0f\x00\x01\x00'
a and b and c and d and e and g and h and i and j

                                                
############
############
+ Mobility Options - Automatic Padding - MIP6OptCareOfTest                               
=  Mobility Options - Automatic Padding - MIP6OptCareOfTest                              
a = raw(MIP6MH_BU(seq=0x4242, options=[MIP6OptCareOfTest()]))                        ==b';\x02\x05\x00\x00\x00BB\xd0\x00\x00\x03\x10\x08\x00\x00\x00\x00\x00\x00\x00\x00\x01\x00'
b = raw(MIP6MH_BU(seq=0x4242, options=[Pad1(),MIP6OptCareOfTest()]))                 ==b';\x02\x05\x00\x00\x00BB\xd0\x00\x00\x03\x00\x10\x08\x00\x00\x00\x00\x00\x00\x00\x00\x00'
c = raw(MIP6MH_BU(seq=0x4242, options=[PadN(optdata=b'\x00'*0),MIP6OptCareOfTest()])) ==b';\x02\x05\x00\x00\x00BB\xd0\x00\x00\x03\x01\x00\x10\x08\x00\x00\x00\x00\x00\x00\x00\x00'
d = raw(MIP6MH_BU(seq=0x4242, options=[PadN(optdata=b'\x00'*1),MIP6OptCareOfTest()])) ==b';\x03\x05\x00\x00\x00BB\xd0\x00\x00\x03\x01\x01\x00\x10\x08\x00\x00\x00\x00\x00\x00\x00\x00\x01\x05\x00\x00\x00\x00\x00'
e = raw(MIP6MH_BU(seq=0x4242, options=[PadN(optdata=b'\x00'*2),MIP6OptCareOfTest()])) ==b';\x03\x05\x00\x00\x00BB\xd0\x00\x00\x03\x01\x02\x00\x00\x10\x08\x00\x00\x00\x00\x00\x00\x00\x00\x01\x04\x00\x00\x00\x00'
g = raw(MIP6MH_BU(seq=0x4242, options=[PadN(optdata=b'\x00'*3),MIP6OptCareOfTest()])) ==b';\x03\x05\x00\x00\x00BB\xd0\x00\x00\x03\x01\x03\x00\x00\x00\x10\x08\x00\x00\x00\x00\x00\x00\x00\x00\x01\x03\x00\x00\x00'
h = raw(MIP6MH_BU(seq=0x4242, options=[PadN(optdata=b'\x00'*4),MIP6OptCareOfTest()])) ==b';\x03\x05\x00\x00\x00BB\xd0\x00\x00\x03\x01\x04\x00\x00\x00\x00\x10\x08\x00\x00\x00\x00\x00\x00\x00\x00\x01\x02\x00\x00'
i = raw(MIP6MH_BU(seq=0x4242, options=[PadN(optdata=b'\x00'*5),MIP6OptCareOfTest()])) ==b';\x03\x05\x00\x00\x00BB\xd0\x00\x00\x03\x01\x05\x00\x00\x00\x00\x00\x10\x08\x00\x00\x00\x00\x00\x00\x00\x00\x01\x01\x00'
j = raw(MIP6MH_BU(seq=0x4242, options=[PadN(optdata=b'\x00'*6),MIP6OptCareOfTest()])) ==b';\x03\x05\x00\x00\x00BB\xd0\x00\x00\x03\x01\x06\x00\x00\x00\x00\x00\x00\x10\x08\x00\x00\x00\x00\x00\x00\x00\x00\x01\x00'
a and b and c and d and e and g and h and i and j


############
############
+ Binding Refresh Request Message
= MIP6MH_BRR - Build (default values)
raw(IPv6(src="2001:db8::1", dst="2001:db8::2")/MIP6MH_BRR()) == b'`\x00\x00\x00\x00\x08\x87@ \x01\r\xb8\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01 \x01\r\xb8\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x02;\x00\x00\x00h\xfb\x00\x00'

= MIP6MH_BRR - Build with specific values
raw(IPv6(src="2001:db8::1", dst="2001:db8::2")/MIP6MH_BRR(nh=0xff, res=0xee, res2=0xaaaa, options=[MIP6OptLLAddr(), MIP6OptAltCoA()])) == b'`\x00\x00\x00\x00(\x87@ \x01\r\xb8\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01 \x01\r\xb8\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x02\xff\x04\x00\xee\xec$\xaa\xaa\x07\x07\x02\x00\x00\x00\x00\x00\x00\x00\x01\x02\x00\x00\x03\x10\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00'

= MIP6MH_BRR - Basic dissection
a=IPv6(b'`\x00\x00\x00\x00\x08\x87@ \x01\r\xb8\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01 \x01\r\xb8\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x02;\x00\x00\x00h\xfb\x00\x00')
b=a.payload
a.nh == 135 and isinstance(b, MIP6MH_BRR) and b.nh == 59 and b.len == 0 and b.mhtype == 0 and b.res == 0 and b.cksum == 0x68fb and b.res2 == 0 and b.options == []

= MIP6MH_BRR - Dissection with specific values
a=IPv6(b'`\x00\x00\x00\x00(\x87@ \x01\r\xb8\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01 \x01\r\xb8\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x02\xff\x04\x00\xee\xec$\xaa\xaa\x07\x07\x02\x00\x00\x00\x00\x00\x00\x00\x01\x02\x00\x00\x03\x10\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00')
b=a.payload
a.nh == 135 and isinstance(b, MIP6MH_BRR) and b.nh == 0xff and b.len == 4 and b.mhtype == 0 and b.res == 238 and b.cksum == 0xec24 and b.res2 == 43690 and len(b.options) == 3 and isinstance(b.options[0], MIP6OptLLAddr) and isinstance(b.options[1], PadN) and isinstance(b.options[2], MIP6OptAltCoA)

= MIP6MH_BRR / MIP6MH_BU / MIP6MH_BA hashret() and answers()
hoa="2001:db8:9999::1"
coa="2001:db8:7777::1"
cn="2001:db8:8888::1"
ha="2001db8:6666::1"
a=IPv6(raw(IPv6(src=cn, dst=hoa)/MIP6MH_BRR()))
b=IPv6(raw(IPv6(src=coa, dst=cn)/IPv6ExtHdrDestOpt(options=HAO(hoa=hoa))/MIP6MH_BU(flags=0x01)))
b2=IPv6(raw(IPv6(src=coa, dst=cn)/IPv6ExtHdrDestOpt(options=HAO(hoa=hoa))/MIP6MH_BU(flags=~0x01)))
c=IPv6(raw(IPv6(src=cn, dst=coa)/IPv6ExtHdrRouting(type=2, addresses=[hoa])/MIP6MH_BA()))
b.answers(a) and not a.answers(b) and c.answers(b) and not b.answers(c) and not c.answers(b2)

len(b[IPv6ExtHdrDestOpt].options) == 2


############
############
+ Home Test Init Message

= MIP6MH_HoTI - Build (default values)
raw(IPv6(src="2001:db8::1", dst="2001:db8::2")/MIP6MH_HoTI()) == b'`\x00\x00\x00\x00\x10\x87@ \x01\r\xb8\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01 \x01\r\xb8\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x02;\x01\x01\x00g\xf2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00'

= MIP6MH_HoTI - Dissection (default values)
a=IPv6(b'`\x00\x00\x00\x00\x10\x87@ \x01\r\xb8\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01 \x01\r\xb8\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x02;\x01\x01\x00g\xf2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00')
b = a.payload
a.nh == 135 and isinstance(b, MIP6MH_HoTI) and b.nh==59 and b.mhtype == 1 and b.len== 1 and b.res == 0 and b.cksum == 0x67f2 and b.cookie == b'\x00'*8


= MIP6MH_HoTI - Build (specific values)
raw(IPv6(src="2001:db8::1", dst="2001:db8::2")/MIP6MH_HoTI(res=0x77, cksum=0x8899, cookie=b"\xAA"*8)) == b'`\x00\x00\x00\x00\x10\x87@ \x01\r\xb8\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01 \x01\r\xb8\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x02;\x01\x01w\x88\x99\x00\x00\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa'

= MIP6MH_HoTI - Dissection (specific values)
a=IPv6(b'`\x00\x00\x00\x00\x10\x87@ \x01\r\xb8\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01 \x01\r\xb8\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x02;\x01\x01w\x88\x99\x00\x00\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa')
b=a.payload
a.nh == 135 and isinstance(b, MIP6MH_HoTI) and b.nh==59 and b.mhtype == 1 and b.len == 1 and b.res == 0x77 and b.cksum == 0x8899 and b.cookie == b'\xAA'*8


############
############
+ Care-of Test Init Message

= MIP6MH_CoTI - Build (default values)
raw(IPv6(src="2001:db8::1", dst="2001:db8::2")/MIP6MH_CoTI()) == b'`\x00\x00\x00\x00\x10\x87@ \x01\r\xb8\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01 \x01\r\xb8\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x02;\x01\x02\x00f\xf2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00'

= MIP6MH_CoTI - Dissection (default values)
a=IPv6(b'`\x00\x00\x00\x00\x10\x87@ \x01\r\xb8\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01 \x01\r\xb8\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x02;\x01\x02\x00f\xf2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00')
b = a.payload
a.nh == 135 and isinstance(b, MIP6MH_CoTI) and b.nh==59 and b.mhtype == 2 and b.len== 1 and b.res == 0 and b.cksum == 0x66f2 and b.cookie == b'\x00'*8

= MIP6MH_CoTI - Build (specific values)
raw(IPv6(src="2001:db8::1", dst="2001:db8::2")/MIP6MH_CoTI(res=0x77, cksum=0x8899, cookie=b"\xAA"*8)) == b'`\x00\x00\x00\x00\x10\x87@ \x01\r\xb8\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01 \x01\r\xb8\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x02;\x01\x02w\x88\x99\x00\x00\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa'

= MIP6MH_CoTI - Dissection (specific values)
a=IPv6(b'`\x00\x00\x00\x00\x10\x87@ \x01\r\xb8\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01 \x01\r\xb8\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x02;\x01\x02w\x88\x99\x00\x00\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa')
b=a.payload
a.nh == 135 and isinstance(b, MIP6MH_CoTI) and b.nh==59 and b.mhtype == 2 and b.len == 1 and b.res == 0x77 and b.cksum == 0x8899 and b.cookie == b'\xAA'*8


############
############
+ Home Test Message

= MIP6MH_HoT - Build (default values)
raw(IPv6(src="2001:db8::1", dst="2001:db8::2")/MIP6MH_HoT()) == b'`\x00\x00\x00\x00\x18\x87@ \x01\r\xb8\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01 \x01\r\xb8\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x02;\x02\x03\x00e\xe9\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00'

= MIP6MH_HoT - Dissection (default values)
a=IPv6(b'`\x00\x00\x00\x00\x18\x87@ \x01\r\xb8\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01 \x01\r\xb8\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x02;\x02\x03\x00e\xe9\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00')
b = a.payload
a.nh == 135 and isinstance(b, MIP6MH_HoT) and b.nh==59 and b.mhtype == 3 and b.len== 2 and b.res == 0 and b.cksum == 0x65e9 and b.index == 0 and b.cookie == b'\x00'*8 and b.token == b'\x00'*8

= MIP6MH_HoT - Build (specific values)
raw(IPv6(src="2001:db8::1", dst="2001:db8::2")/MIP6MH_HoT(res=0x77, cksum=0x8899, cookie=b"\xAA"*8, index=0xAABB, token=b'\xCC'*8)) == b'`\x00\x00\x00\x00\x18\x87@ \x01\r\xb8\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01 \x01\r\xb8\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x02;\x02\x03w\x88\x99\xaa\xbb\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xcc\xcc\xcc\xcc\xcc\xcc\xcc\xcc'

= MIP6MH_HoT - Dissection (specific values)
a=IPv6(b'`\x00\x00\x00\x00\x18\x87@ \x01\r\xb8\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01 \x01\r\xb8\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x02;\x02\x03w\x88\x99\xaa\xbb\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xcc\xcc\xcc\xcc\xcc\xcc\xcc\xcc')
b = a.payload
a.nh == 135 and isinstance(b, MIP6MH_HoT) and b.nh==59 and b.mhtype == 3 and b.len== 2 and b.res == 0x77 and b.cksum == 0x8899 and b.index == 0xAABB and b.cookie == b'\xAA'*8 and b.token == b'\xCC'*8

= MIP6MH_HoT answers
a1, a2 = "2001:db8::1", "2001:db8::2"
cookie = RandString(8)._fix()
p1 = IPv6(src=a1, dst=a2)/MIP6MH_HoTI(cookie=cookie)
p2 = IPv6(src=a2, dst=a1)/MIP6MH_HoT(cookie=cookie)
p2_ko = IPv6(src=a2, dst=a1)/MIP6MH_HoT(cookie="".join(chr((orb(b'\xff') + 1) % 256)))
assert p1.hashret() == p2.hashret() and p2.answers(p1) and not p1.answers(p2)
assert p1.hashret() != p2_ko.hashret() and not p2_ko.answers(p1) and not p1.answers(p2_ko)


############
############
+ Care-of Test Message

= MIP6MH_CoT - Build (default values)
raw(IPv6(src="2001:db8::1", dst="2001:db8::2")/MIP6MH_CoT()) == b'`\x00\x00\x00\x00\x18\x87@ \x01\r\xb8\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01 \x01\r\xb8\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x02;\x02\x04\x00d\xe9\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00'

= MIP6MH_CoT - Dissection (default values)
a=IPv6(b'`\x00\x00\x00\x00\x18\x87@ \x01\r\xb8\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01 \x01\r\xb8\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x02;\x02\x04\x00d\xe9\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00')
b = a.payload
a.nh == 135 and isinstance(b, MIP6MH_HoT) and b.nh==59 and b.mhtype == 4 and b.len== 2 and b.res == 0 and b.cksum == 0x64e9 and b.index == 0 and b.cookie == b'\x00'*8 and b.token == b'\x00'*8

= MIP6MH_CoT - Build (specific values)
raw(IPv6(src="2001:db8::1", dst="2001:db8::2")/MIP6MH_CoT(res=0x77, cksum=0x8899, cookie=b"\xAA"*8, index=0xAABB, token=b'\xCC'*8)) == b'`\x00\x00\x00\x00\x18\x87@ \x01\r\xb8\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01 \x01\r\xb8\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x02;\x02\x04w\x88\x99\xaa\xbb\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xcc\xcc\xcc\xcc\xcc\xcc\xcc\xcc'

= MIP6MH_CoT - Dissection (specific values)
a=IPv6(b'`\x00\x00\x00\x00\x18\x87@ \x01\r\xb8\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01 \x01\r\xb8\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x02;\x02\x04w\x88\x99\xaa\xbb\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xcc\xcc\xcc\xcc\xcc\xcc\xcc\xcc')
b = a.payload
a.nh == 135 and isinstance(b, MIP6MH_CoT) and b.nh==59 and b.mhtype == 4 and b.len== 2 and b.res == 0x77 and b.cksum == 0x8899 and b.index == 0xAABB and b.cookie == b'\xAA'*8 and b.token == b'\xCC'*8


############
############
+ Binding Update Message

= MIP6MH_BU - build (default values)
s= b'`\x00\x00\x00\x00(<@\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01\x87\x02\x01\x02\x00\x00\xc9\x10\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00;\x01\x05\x00\xee`\x00\x00\xd0\x00\x00\x03\x01\x02\x00\x00'
raw(IPv6()/IPv6ExtHdrDestOpt(options=[HAO()])/MIP6MH_BU()) == s

= MIP6MH_BU - dissection (default values)
p = IPv6(s)
p[MIP6MH_BU].len == 1

= MIP6MH_BU - build
s = b'`\x00\x00\x00\x00P<@\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01\x87\x02\x01\x02\x00\x00\xc9\x10 \x01\r\xb8\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xca\xfe;\x06\x05\x00\xea\xf2\x00\x00\xd0\x00\x00*\x01\x00\x03\x10\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01\x02\x00\x00\x06\x12\x00@\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00'
raw(IPv6()/IPv6ExtHdrDestOpt(options=[HAO(hoa='2001:db8::cafe')])/MIP6MH_BU(mhtime=42, options=[MIP6OptAltCoA(),MIP6OptMobNetPrefix()])) == s

= MIP6MH_BU - dissection
p = IPv6(s)
p[MIP6MH_BU].cksum == 0xeaf2 and p[MIP6MH_BU].len == 6 and len(p[MIP6MH_BU].options) == 4 and p[MIP6MH_BU].mhtime == 42


############
############
+ Binding ACK Message

=  MIP6MH_BA - build
s = b'`\x00\x00\x00\x00\x10\x87@\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01;\x01\x06\x00\xbc\xb9\x00\x80\x00\x00\x00*\x01\x02\x00\x00'
raw(IPv6()/MIP6MH_BA(mhtime=42)) == s

=  MIP6MH_BA - dissection
p = IPv6(s)
p[MIP6MH_BA].cksum == 0xbcb9 and p[MIP6MH_BA].len == 1 and len(p[MIP6MH_BA].options) == 1 and p[MIP6MH_BA].mhtime == 42


############
############
+ Binding ERR Message

=  MIP6MH_BE - build
s = b'`\x00\x00\x00\x00\x18\x87@\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01;\x02\x07\x00\xbbY\x02\x00\x00\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x02'
raw(IPv6()/MIP6MH_BE(status=2, ha='1::2')) == s

=  MIP6MH_BE - dissection
p = IPv6(s)
p[MIP6MH_BE].cksum=0xba10 and p[MIP6MH_BE].len == 1 and len(p[MIP6MH_BE].options) == 1


############
############
+ Netflow v5

= NetflowHeaderV5 - basic building

raw(NetflowHeader()/NetflowHeaderV5()) == b'\x00\x05\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00'

raw(NetflowHeaderV5(engineID=42)) == b'\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00*\x00\x00'

raw(NetflowRecordV5(dst="192.168.0.1")) == b'\x7f\x00\x00\x01\xc0\xa8\x00\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01\x00\x00\x00<\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x02\x06\x00\x00\x00\x00\x00\x00\x00\x00\x00'

raw(NetflowHeader()/NetflowHeaderV5(count=1)/NetflowRecordV5(dst="192.168.0.1")) == b'\x00\x05\x00\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x7f\x00\x00\x01\xc0\xa8\x00\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01\x00\x00\x00<\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x02\x06\x00\x00\x00\x00\x00\x00\x00\x00\x00'

= NetflowHeaderV5 - UDP bindings

s = raw(IP(src="127.0.0.1")/UDP()/NetflowHeader()/NetflowHeaderV5())
assert s == b'E\x00\x004\x00\x01\x00\x00@\x11|\xb6\x7f\x00\x00\x01\x7f\x00\x00\x01\x08\x07\x08\x07\x00 \xf1\x98\x00\x05\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00'
pkt = IP(s)
assert NetflowHeaderV5 in pkt

= NetflowHeaderV5 - basic dissection

nf5 = NetflowHeader(b'\x00\x05\x00\x02\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x7f\x00\x00\x01\x7f\x00\x00\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01\x00\x00\x00<\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x02\x06\x00\x00\x00\x00\x00\x00\x00\x00\x00\x7f\x00\x00\x01\x7f\x00\x00\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01\x00\x00\x00<\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x02\x06\x00\x00\x00\x00\x00\x00\x00\x00\x00')
nf5.version == 5 and nf5[NetflowHeaderV5].count == 2 and isinstance(nf5[NetflowRecordV5].payload, NetflowRecordV5)

############
############
+ Netflow v9

= NetflowV9 - advanced dissection

import os
tmp = "/test/pcaps/netflowv9.pcap"
filename = os.path.abspath(os.path.join(os.path.dirname(__file__),"../")) + tmp
filename = os.getenv("SCAPY_ROOT_DIR")+tmp if not os.path.exists(filename) else filename
a = rdpcap(filename)
a = netflowv9_defragment(a)

nfv9_fl = a[4]
assert NetflowFlowsetV9 in nfv9_fl
assert len(nfv9_fl.templates[0].template_fields) == 21

nfv9_ds = a[61]
assert NetflowDataflowsetV9 in nfv9_ds
assert len(nfv9_ds[NetflowDataflowsetV9].records) == 24
assert nfv9_ds[NetflowDataflowsetV9].records[21].IP_PROTOCOL_VERSION == 4
assert nfv9_ds.records[21].IPV4_SRC_ADDR == '20.0.0.248'
assert nfv9_ds.records[21].IPV4_DST_ADDR == '30.0.0.248'

nfv9_options_fl = a[5]
assert NetflowOptionsFlowsetV9 in nfv9_options_fl
assert isinstance(nfv9_options_fl[NetflowOptionsFlowsetV9].scopes[0], NetflowOptionsFlowsetScopeV9)
assert isinstance(nfv9_options_fl[NetflowOptionsFlowsetV9].options[0], NetflowOptionsFlowsetOptionV9)
assert nfv9_options_fl[NetflowOptionsFlowsetV9].options[0].optionFieldType == 36

nfv9_options_ds = a[255]
assert NetflowDataflowsetV9 in nfv9_options_ds
assert isinstance(nfv9_options_ds.records[0], NetflowOptionsRecordScopeV9)

= NetflowV9 - Multiple FlowSets in one packet

nfv9_multiple_flowsets = NetflowHeader(b'\x00\t\x00\x03\x00\x00K [F\x17\x97\x00\x00\x00\x01\x00\x00\x00\x00\x00\x00\x00H\x04\x00\x00\x10\x00\x08\x00\x04\x00\x0c\x00\x04\x00\x15\x00\x04\x00\x16\x00\x04\x00\x01\x00\x08\x00\x02\x00\x08\x00\n\x00\x04\x00\x0e\x00\x04\x00\x07\x00\x02\x00\x0b\x00\x02\x00\x04\x00\x01\x00\x06\x00\x01\x00<\x00\x01\x00\x05\x00\x01\x00 \x00\x02\x00:\x00\x02\x00\x00\x00L\x08\x00\x00\x11\x00\x1b\x00\x10\x00\x1c\x00\x10\x00\x1f\x00\x04\x00\x15\x00\x04\x00\x16\x00\x04\x00\x01\x00\x08\x00\x02\x00\x08\x00\n\x00\x04\x00\x0e\x00\x04\x00\x07\x00\x02\x00\x0b\x00\x02\x00\x04\x00\x01\x00\x06\x00\x01\x00<\x00\x01\x00\x05\x00\x01\x00 \x00\x02\x00:\x00\x02\x04\x00\x008\x7f\x00\x00\x01\x7f\x00\x00\x01\x00\x00\x10\xac\x00\x00\x10\x83\x00\x00\x00\x00\x00\x00\x0b\xb8\x00\x00\x00\x00\x00\x00\x002\x00\x00\x00\x00\x00\x00\x00\x01\x005\x005\x11\x00\x04\x00\x00\x00\x00e')
assert nfv9_multiple_flowsets.haslayer(NetflowFlowsetV9)
assert nfv9_multiple_flowsets.haslayer(NetflowDataflowsetV9)
nfv9_defrag = netflowv9_defragment(list(nfv9_multiple_flowsets))
assert nfv9_defrag[0].records[0].IP_PROTOCOL_VERSION == 4
assert nfv9_defrag[0].records[0].PROTOCOL == 17
assert nfv9_defrag[0].records[0].IPV4_SRC_ADDR == "127.0.0.1"

############
############
+ pcap / pcapng format support

= Variable creations
from io import BytesIO
pcapfile = BytesIO(b'\xd4\xc3\xb2\xa1\x02\x00\x04\x00\x00\x00\x00\x00\x00\x00\x00\x00\xff\xff\x00\x00e\x00\x00\x00\xcf\xc5\xacVo*\n\x00(\x00\x00\x00(\x00\x00\x00E\x00\x00(\x00\x01\x00\x00@\x06|\xcd\x7f\x00\x00\x01\x7f\x00\x00\x01\x00\x14\x00P\x00\x00\x00\x00\x00\x00\x00\x00P\x02 \x00\x91|\x00\x00\xcf\xc5\xacV_-\n\x00\x1c\x00\x00\x00\x1c\x00\x00\x00E\x00\x00\x1c\x00\x01\x00\x00@\x11|\xce\x7f\x00\x00\x01\x7f\x00\x00\x01\x005\x005\x00\x08\x01r\xcf\xc5\xacV\xf90\n\x00\x1c\x00\x00\x00\x1c\x00\x00\x00E\x00\x00\x1c\x00\x01\x00\x00@\x01|\xde\x7f\x00\x00\x01\x7f\x00\x00\x01\x08\x00\xf7\xff\x00\x00\x00\x00')
pcapngfile = BytesIO(b'\n\r\r\n\\\x00\x00\x00M<+\x1a\x01\x00\x00\x00\xff\xff\xff\xff\xff\xff\xff\xff\x01\x00,\x00File created by merging: \nFile1: test.pcap \n\x04\x00\x08\x00mergecap\x00\x00\x00\x00\\\x00\x00\x00\x01\x00\x00\x00\\\x00\x00\x00e\x00\x00\x00\xff\xff\x00\x00\x02\x006\x00Unknown/not available in original file format(libpcap)\x00\x00\t\x00\x01\x00\x06\x00\x00\x00\x00\x00\x00\x00\\\x00\x00\x00\x06\x00\x00\x00H\x00\x00\x00\x00\x00\x00\x00\x8d*\x05\x00/\xfc[\xcd(\x00\x00\x00(\x00\x00\x00E\x00\x00(\x00\x01\x00\x00@\x06|\xcd\x7f\x00\x00\x01\x7f\x00\x00\x01\x00\x14\x00P\x00\x00\x00\x00\x00\x00\x00\x00P\x02 \x00\x91|\x00\x00H\x00\x00\x00\x06\x00\x00\x00<\x00\x00\x00\x00\x00\x00\x00\x8d*\x05\x00\x1f\xff[\xcd\x1c\x00\x00\x00\x1c\x00\x00\x00E\x00\x00\x1c\x00\x01\x00\x00@\x11|\xce\x7f\x00\x00\x01\x7f\x00\x00\x01\x005\x005\x00\x08\x01r<\x00\x00\x00\x06\x00\x00\x00<\x00\x00\x00\x00\x00\x00\x00\x8d*\x05\x00\xb9\x02\\\xcd\x1c\x00\x00\x00\x1c\x00\x00\x00E\x00\x00\x1c\x00\x01\x00\x00@\x01|\xde\x7f\x00\x00\x01\x7f\x00\x00\x01\x08\x00\xf7\xff\x00\x00\x00\x00<\x00\x00\x00')
pcapnanofile = BytesIO(b"M<\xb2\xa1\x02\x00\x04\x00\x00\x00\x00\x00\x00\x00\x00\x00\xff\xff\x00\x00e\x00\x00\x00\xcf\xc5\xacV\xc9\xc1\xb5'(\x00\x00\x00(\x00\x00\x00E\x00\x00(\x00\x01\x00\x00@\x06|\xcd\x7f\x00\x00\x01\x7f\x00\x00\x01\x00\x14\x00P\x00\x00\x00\x00\x00\x00\x00\x00P\x02 \x00\x91|\x00\x00\xcf\xc5\xacV-;\xc1'\x1c\x00\x00\x00\x1c\x00\x00\x00E\x00\x00\x1c\x00\x01\x00\x00@\x11|\xce\x7f\x00\x00\x01\x7f\x00\x00\x01\x005\x005\x00\x08\x01r\xcf\xc5\xacV\x9aL\xcf'\x1c\x00\x00\x00\x1c\x00\x00\x00E\x00\x00\x1c\x00\x01\x00\x00@\x01|\xde\x7f\x00\x00\x01\x7f\x00\x00\x01\x08\x00\xf7\xff\x00\x00\x00\x00")
pcapwirelenfile = BytesIO(b'\xd4\xc3\xb2\xa1\x02\x00\x04\x00\x00\x00\x00\x00\x00\x00\x00\x00\xff\xff\x00\x00\x01\x00\x00\x00}\x87pZ.\xa2\x08\x00\x0f\x00\x00\x00\x10\x00\x00\x00\xff\xff\xff\xff\xff\xff GG\xee\xdd\xa8\x90\x00a')

= Read a pcap file
pktpcap = rdpcap(pcapfile)

= Read a pcapng file
pktpcapng = rdpcap(pcapngfile)

= Read a pcap file with nanosecond precision
pktpcapnano = rdpcap(pcapnanofile)

= Read a pcap file with wirelen != captured len
pktpcapwirelen = rdpcap(pcapwirelenfile)

= Check all packet lists are the same
assert list(pktpcap) == list(pktpcapng) == list(pktpcapnano)
assert [p.time for p in pktpcap] == [p.time for p in pktpcapng] == [p.time for p in pktpcapnano]

= Check packets from pcap file
assert all(IP in pkt for pkt in pktpcap)
assert all(any(proto in pkt for pkt in pktpcap) for proto in [ICMP, UDP, TCP])

= Check wirelen value from pcap file
assert len(pktpcapwirelen) == 1
assert pktpcapwirelen[0].wirelen is not None
assert len(pktpcapwirelen[0]) < pktpcapwirelen[0].wirelen

= Check wrpcap() then rdpcap() with wirelen
import os, tempfile
fdesc, filename = tempfile.mkstemp()
fdesc = os.fdopen(fdesc, "wb")
wrpcap(fdesc, pktpcapwirelen)
fdesc.close()
newpktpcapwirelen = rdpcap(filename)
assert len(newpktpcapwirelen) == 1
assert newpktpcapwirelen[0].wirelen is not None
assert len(newpktpcapwirelen[0]) < newpktpcapwirelen[0].wirelen
assert newpktpcapwirelen[0].wirelen == pktpcapwirelen[0].wirelen

= Check wrpcap()
fdesc, filename = tempfile.mkstemp()
fdesc = os.fdopen(fdesc, "wb")
wrpcap(fdesc, pktpcap)
fdesc.close()

= Check offline sniff() (by filename)
assert list(pktpcap) == list(sniff(offline=filename))

= Check offline sniff() (by file object)
fdesc = open(filename, "rb")
assert list(pktpcap) == list(sniff(offline=fdesc))
fdesc.close()

= Check offline sniff() with a filter (by filename)
~ tcpdump
pktpcap_flt = [(proto, sniff(offline=filename, filter=proto.__name__.lower()))
               for proto in [ICMP, UDP, TCP]]
assert all(list(pktpcap[proto]) == list(packets) for proto, packets in pktpcap_flt)

= Check offline sniff() with a filter (by file object)
~ tcpdump
fdesc = open(filename, "rb")
pktpcap_tcp = sniff(offline=fdesc, filter="tcp")
fdesc.close()
assert list(pktpcap[TCP]) == list(pktpcap_tcp)
os.unlink(filename)

= Check wrpcap(nano=True)
fdesc, filename = tempfile.mkstemp()
fdesc = os.fdopen(fdesc, "wb")
pktpcapnano[0].time += 0.000000001
wrpcap(fdesc, pktpcapnano, nano=True)
fdesc.close()
pktpcapnanoread = rdpcap(filename)
assert pktpcapnanoread[0].time == pktpcapnano[0].time
assert pktpcapnanoread[0].time == pktpcap[0].time + 0.000000001
os.unlink(filename)

= Check PcapNg with nanosecond precision using obsolete packet block
* first packet from capture file icmp2.ntar -- https://wiki.wireshark.org/Development/PcapNg?action=AttachFile&do=view&target=icmp2.ntar
pcapngfile = BytesIO(b'\n\r\r\n\x1c\x00\x00\x00M<+\x1a\x01\x00\x00\x00\xa8\x03\x00\x00\x00\x00\x00\x00\x1c\x00\x00\x00\x01\x00\x00\x00(\x00\x00\x00\x01\x00\x00\x00\xff\xff\x00\x00\r\x00\x01\x00\x04\x04K\x00\t\x00\x01\x00\tK=N\x00\x00\x00\x00(\x00\x00\x00\x02\x00\x00\x00n\x00\x00\x00\x00\x00\x00\x00e\x14\x00\x00)4\'ON\x00\x00\x00N\x00\x00\x00\x00\x12\xf0\x11h\xd6\x00\x13r\t{\xea\x08\x00E\x00\x00<\x90\xa1\x00\x00\x80\x01\x8e\xad\xc0\xa8M\x07\xc0\xa8M\x1a\x08\x00r[\x03\x00\xd8\x00abcdefghijklmnopqrstuvwabcdefghi\xeay$\xf6\x00\x00n\x00\x00\x00')
pktpcapng = rdpcap(pcapngfile)
assert len(pktpcapng) == 1
pkt = pktpcapng[0]
# weird, but wireshark agrees
assert pkt.time == 22425.352221737
assert isinstance(pkt, Ether)
pkt = pkt.payload
assert isinstance(pkt, IP)
pkt = pkt.payload
assert isinstance(pkt, ICMP)
pkt = pkt.payload
assert isinstance(pkt, Raw) and pkt.load == b'abcdefghijklmnopqrstuvwabcdefghi'
pkt = pkt.payload
assert isinstance(pkt, Padding) and pkt.load == b'\xeay$\xf6'
pkt = pkt.payload
assert isinstance(pkt, NoPayload)

= Check PcapNg using Simple Packet Block
* previous file with the (obsolete) packet block replaced by a Simple Packet Block
pcapngfile = BytesIO(b'\n\r\r\n\x1c\x00\x00\x00M<+\x1a\x01\x00\x00\x00\xa8\x03\x00\x00\x00\x00\x00\x00\x1c\x00\x00\x00\x01\x00\x00\x00(\x00\x00\x00\x01\x00\x00\x00\xff\xff\x00\x00\r\x00\x01\x00\x04\x04K\x00\t\x00\x01\x00\tK=N\x00\x00\x00\x00(\x00\x00\x00\x03\x00\x00\x00`\x00\x00\x00N\x00\x00\x00\x00\x12\xf0\x11h\xd6\x00\x13r\t{\xea\x08\x00E\x00\x00<\x90\xa1\x00\x00\x80\x01\x8e\xad\xc0\xa8M\x07\xc0\xa8M\x1a\x08\x00r[\x03\x00\xd8\x00abcdefghijklmnopqrstuvwabcdefghi\xeay$\xf6\x00\x00`\x00\x00\x00')
pktpcapng = rdpcap(pcapngfile)
assert len(pktpcapng) == 1
pkt = pktpcapng[0]
assert isinstance(pkt, Ether)
pkt = pkt.payload
assert isinstance(pkt, IP)
pkt = pkt.payload
assert isinstance(pkt, ICMP)
pkt = pkt.payload
assert isinstance(pkt, Raw) and pkt.load == b'abcdefghijklmnopqrstuvwabcdefghi'
pkt = pkt.payload
assert isinstance(pkt, Padding) and pkt.load == b'\xeay$\xf6'
pkt = pkt.payload
assert isinstance(pkt, NoPayload)

= Check tcpdump()
~ tcpdump
* No very specific tests because we do not want to depend on tcpdump output
pcapfile = BytesIO(b'\xd4\xc3\xb2\xa1\x02\x00\x04\x00\x00\x00\x00\x00\x00\x00\x00\x00\xff\xff\x00\x00e\x00\x00\x00\xcf\xc5\xacVo*\n\x00(\x00\x00\x00(\x00\x00\x00E\x00\x00(\x00\x01\x00\x00@\x06|\xcd\x7f\x00\x00\x01\x7f\x00\x00\x01\x00\x14\x00P\x00\x00\x00\x00\x00\x00\x00\x00P\x02 \x00\x91|\x00\x00\xcf\xc5\xacV_-\n\x00\x1c\x00\x00\x00\x1c\x00\x00\x00E\x00\x00\x1c\x00\x01\x00\x00@\x11|\xce\x7f\x00\x00\x01\x7f\x00\x00\x01\x005\x005\x00\x08\x01r\xcf\xc5\xacV\xf90\n\x00\x1c\x00\x00\x00\x1c\x00\x00\x00E\x00\x00\x1c\x00\x01\x00\x00@\x01|\xde\x7f\x00\x00\x01\x7f\x00\x00\x01\x08\x00\xf7\xff\x00\x00\x00\x00')
data = tcpdump(pcapfile, dump=True, args=['-n']).split(b'\n')
print(data)
assert b'IP 127.0.0.1.20 > 127.0.0.1.80:' in data[0]
assert b'IP 127.0.0.1.53 > 127.0.0.1.53:' in data[1]
assert b'IP 127.0.0.1 > 127.0.0.1:' in data[2]

= Check tcpdump() command with tshark
~ tshark
pcapfile = BytesIO(b'\xd4\xc3\xb2\xa1\x02\x00\x04\x00\x00\x00\x00\x00\x00\x00\x00\x00\xff\xff\x00\x00e\x00\x00\x00\xcf\xc5\xacVo*\n\x00(\x00\x00\x00(\x00\x00\x00E\x00\x00(\x00\x01\x00\x00@\x06|\xcd\x7f\x00\x00\x01\x7f\x00\x00\x01\x00\x14\x00P\x00\x00\x00\x00\x00\x00\x00\x00P\x02 \x00\x91|\x00\x00\xcf\xc5\xacV_-\n\x00\x1c\x00\x00\x00\x1c\x00\x00\x00E\x00\x00\x1c\x00\x01\x00\x00@\x11|\xce\x7f\x00\x00\x01\x7f\x00\x00\x01\x005\x005\x00\x08\x01r\xcf\xc5\xacV\xf90\n\x00\x1c\x00\x00\x00\x1c\x00\x00\x00E\x00\x00\x1c\x00\x01\x00\x00@\x01|\xde\x7f\x00\x00\x01\x7f\x00\x00\x01\x08\x00\xf7\xff\x00\x00\x00\x00')
values = [tuple(int(val) for val in line[:-1].split(b'\t')) for line in tcpdump(pcapfile, prog=conf.prog.tshark, getfd=True, args=['-T', 'fields', '-e', 'ip.ttl', '-e', 'ip.proto'])]
assert values == [(64, 6), (64, 17), (64, 1)]

= Run scapy's tshark command
~ netaccess
tshark(count=1, timeout=3)

= Check Raw IP pcap files

import tempfile
filename = tempfile.mktemp(suffix=".pcap")
wrpcap(filename, [IP()/UDP(), IPv6()/UDP()], linktype=DLT_RAW)
packets = rdpcap(filename)
assert(isinstance(packets[0], IP) and isinstance(packets[1], IPv6))

= Check wrpcap() with no packet

import tempfile
filename = tempfile.mktemp(suffix=".pcap")
wrpcap(filename, [])
fstat = os.stat(filename)
assert fstat.st_size != 0
os.remove(filename)

############
############
+ LLMNR protocol

= Simple packet dissection
pkt = Ether(b'\x11\x11\x11\x11\x11\x11\x99\x99\x99\x99\x99\x99\x08\x00E\x00\x00(\x00\x01\x00\x00@\x11:\xa4\xc0\xa8\x00w\x7f\x00\x00\x01\x14\xeb\x14\xeb\x00\x14\x95\xcf\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00')
assert pkt.sport == 5355
assert pkt.dport == 5355
assert pkt[LLMNRQuery].opcode == 0

= Packet build / dissection
pkt = UDP(raw(UDP()/LLMNRResponse()))
assert LLMNRResponse in pkt
assert pkt.qr == 1
assert pkt.c == 0
assert pkt.tc == 0
assert pkt.z == 0
assert pkt.rcode == 0
assert pkt.qdcount == 0
assert pkt.arcount == 0
assert pkt.nscount == 0
assert pkt.ancount == 0

= Answers - building
a = UDP()/LLMNRResponse(id=12)
b = UDP()/LLMNRQuery(id=12)
assert a.answers(b)
assert not b.answers(a)
assert b.hashret() == b'\x00\x0c'

= Answers - dissecting
a = Ether(b'\xd0P\x99V\xdd\xf9\x14\x0cv\x8f\xfe(\x08\x00E\x00\x00(\x00\x01\x00\x00@\x11:\xa4\x7f\x00\x00\x01\xc0\xa8\x00w\x14\xeb\x14\xeb\x00\x14\x95\xcf\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00')
b = Ether(b'\x14\x0cv\x8f\xfe(\xd0P\x99V\xdd\xf9\x08\x00E\x00\x00(\x00\x01\x00\x00@\x11:\xa4\xc0\xa8\x00w\x7f\x00\x00\x01\x14\xeb\x14\xeb\x00\x14\x15\xcf\x00\x00\x80\x00\x00\x00\x00\x00\x00\x00\x00\x00')
assert b.answers(a)
assert not a.answers(b)

############
############
+ LLTD protocol

= Simple packet dissection
pkt = Ether(b'\xff\xff\xff\xff\xff\xff\x86\x14\xf0\xc7[.\x88\xd9\x01\x00\x00\x01\xff\xff\xff\xff\xff\xff\x86\x14\xf0\xc7[.\x00\x00\xfe\xe9[\xa9\xaf\xc1\x0bS[\xa9\xaf\xc1\x0bS\x01\x06}[G\x8f\xec.\x02\x04p\x00\x00\x00\x03\x04\x00\x00\x00\x06\x07\x04\xac\x19\x88\xe4\t\x02\x00l\n\x08\x00\x00\x00\x00\x00\x0fB@\x0c\x04\x00\x08=`\x0e\x00\x0f\x0eT\x00E\x00S\x00T\x00-\x00A\x00P\x00\x12\x10\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x14\x04\x00\x00\x00\x00\x15\x01\x02\x18\x00\x19\x02\x04\x00\x1a\x00\x00')
assert pkt.dst == pkt.real_dst
assert pkt.src == pkt.real_src
assert pkt.current_mapper_address == pkt.apparent_mapper_address
assert pkt.mac == '7d:5b:47:8f:ec:2e'
assert pkt.hostname == "TEST-AP"
assert isinstance(pkt[LLTDAttributeEOP].payload, NoPayload)

= Packet build / dissection
pkt = Ether(raw(Ether(dst=ETHER_BROADCAST, src=RandMAC()) / LLTD(tos=0, function=0)))
assert LLTD in pkt
assert pkt.dst == pkt.real_dst
assert pkt.src == pkt.real_src
assert pkt.tos == 0
assert pkt.function == 0

= Attribute build / dissection
assert isinstance(LLTDAttribute(), LLTDAttribute)
assert isinstance(LLTDAttribute(raw(LLTDAttribute())), LLTDAttribute)
assert all(isinstance(LLTDAttribute(type=i), LLTDAttribute) for i in six.moves.range(256))
assert all(isinstance(LLTDAttribute(raw(LLTDAttribute(type=i))), LLTDAttribute) for i in six.moves.range(256))

= Large TLV
m1, m2, seq = RandMAC()._fix(), RandMAC()._fix(), 123
preqbase = Ether(src=m1, dst=m2) / LLTD() / \
           LLTDQueryLargeTlv(type="Detailed Icon Image")
prespbase = Ether(src=m2, dst=m1) / LLTD() / \
            LLTDQueryLargeTlvResp()
plist = []
pkt = preqbase.copy()
pkt.seq = seq
plist.append(Ether(raw(pkt)))
pkt = prespbase.copy()
pkt.seq = seq
pkt.flags = "M"
pkt.value = "abcd"
plist.append(Ether(raw(pkt)))
pkt = preqbase.copy()
pkt.seq = seq + 1
pkt.offset = 4
plist.append(Ether(raw(pkt)))
pkt = prespbase.copy()
pkt.seq = seq + 1
pkt.value = "efg"
plist.append(Ether(raw(pkt)))
builder = LargeTlvBuilder()
builder.parse(plist)
data = builder.get_data()
assert len(data) == 1
key, value = data.popitem()
assert key.endswith(' [Detailed Icon Image]')
assert value == 'abcdefg'


############
############
+ Test fragment() / defragment() functions

= fragment()
payloadlen, fragsize = 100, 8
assert fragsize % 8 == 0
fragcount = (payloadlen // fragsize) + bool(payloadlen % fragsize)
* create the packet
pkt = IP() / ("X" * payloadlen)
* create the fragments
frags = fragment(pkt, fragsize)
* count the fragments
assert len(frags) == fragcount
* each fragment except the last one should have MF set
assert all(p.flags == 1 for p in frags[:-1])
assert frags[-1].flags == 0
* each fragment except the last one should have a payload of fragsize bytes
assert all(len(p.payload) == 8 for p in frags[:-1])
assert len(frags[-1].payload) == ((payloadlen % fragsize) or fragsize)

= fragment() and overloaded_fields
pkt1 = Ether() / IP() / UDP()
pkt2 = fragment(pkt1)[0]
pkt3 = pkt2.__class__(raw(pkt2))
assert pkt1[IP].proto == pkt2[IP].proto == pkt3[IP].proto

= fragment() already fragmented packets
payloadlen = 1480 * 3
ffrags = fragment(IP() / ("X" * payloadlen), 1480)
ffrags = fragment(ffrags, 1400)
len(ffrags) == 6
* each fragment except the last one should have MF set
assert all(p.flags == 1 for p in ffrags[:-1])
assert ffrags[-1].flags == 0
* fragment offset should be well computed
plen = 0
for p in ffrags:
    assert p.frag == plen // 8
    plen += len(p.payload)

assert plen == payloadlen

= defrag()
nonfrag, unfrag, badfrag = defrag(frags)
assert not nonfrag
assert not badfrag
assert len(unfrag) == 1

= defragment()
defrags = defragment(frags)
* we should have one single packet
assert len(defrags) == 1
* which should be the same as pkt reconstructed
assert defrags[0] == IP(raw(pkt))

= defrag() / defragment() - Real DNS packets

import base64

a = base64.b64decode('bnmYJ63mREVTUwEACABFAAV0U8UgADIR+u0EAgIECv0DxAA1sRIL83Z7gbCBgAABAB0AAAANA255YwNnb3YAAP8AAcAMAAYAAQAAA4QAKgZ2d2FsbDDADApob3N0bWFzdGVywAx4Og5wAAA4QAAADhAAJOoAAAACWMAMAC4AAQAAA4QAmwAGCAIAAAOEWWm9jVlgdP0mfQNueWMDZ292AHjCDBL0C1rEKUjsuG6Zg3+Rs6gj6llTABm9UZnWk+rRu6nPqW4N7AEllTYqNK+r6uFJ2KhfG3MDPS1F/M5QCVR8qkcbgrqPVRBJAG67/ZqpGORppQV6ib5qqo4ST5KyrgKpa8R1fWH8Fyp881NWLOZekM3TQyczcLFrvw9FFjdRwAwAAQABAAADhAAEobkenMAMAC4AAQAAA4QAmwABCAIAAAOEWWm9jVlgdP0mfQNueWMDZ292ABW8t5tEv9zTLdB6UsoTtZIF6Kx/c4ukIud8UIGM0XdXnJYx0ZDyPDyLVy2rfwmXdEph3KBWAi5dpRT16nthlMmWPQxD1ecg9rc8jcaTGo8z833fYJjzPT8MpMTxhapu4ANSBVbv3LRBnce2abu9QaoCdlHPFHdNphp6JznCLt4jwAwAMAABAAADhAEIAQEDCAMBAAF77useCfI+6T+m6Tsf2ami8/q5XDtgS0Ae7F0jUZ0cpyYxy/28DLFjJaS57YiwAYaabkkugxsoSv9roqBNZjD+gjoUB+MK8fmfaqqkSOgQuIQLZJeOORWD0gAj8mekw+S84DECylbKyYEGf8CB3/59IfV+YkTcHhXBYrMNxhMK1Eiypz4cgYxXiYUSz7jbOmqE3hU2GinhRmNW4Trt4ImUruSO+iQbTTj6LtCtIsScOF4vn4gcLJURLHOs+mf1NU9Yqq9mPC9wlYZk+8rwqcjVIiRpDmmv83huv4be1x1kkz2YqTFwtc33Fzt6SZk96Qtk2wCgg8ZQqLKGx5uwIIyrwAwAMAABAAADhAEIAQEDCAMBAAGYc7SWbSinSc3u8ZcYlO0+yZcJD1vqC5JARxZjKNzszHxc9dpabBtR9covySVu1YaBVrlxNBzfyFd4PKyjvPcBER5sQImoCikC+flD5NwXJbnrO1SG0Kzp8XXDCZpBASxuBF0vjUSU9yMqp0FywCrIfrbfCcOGAFIVP0M2u8dVuoI4nWbkRFc0hiRefoxc1O2IdpR22GAp2OYeeN2/tnFBz/ZMQitU2IZIKBMybKmWLC96tPcqVdWJX6+M1an1ox0+NqBZuPjsCx0/lZbuB/rLHppJOmkRc7q2Fw/tpHOyWHV+ulCfXem9Up/sbrMcP7uumFz0FeNhBPtg3u5kA5OVwAwAMAABAAADhACIAQADCAMBAAF5mlzmmq8cs6Hff0qZLlGKYCGPlG23HZw2qAd7N2FmrLRqPQ0R/hbnw54MYiIs18zyfm2J+ZmzUvGd+gjHGx3ooRRffQQ4RFLq6g6oxaLTbtvqPFbWt4Kr2GwX3UslgZCzH5mXLNpPI2QoetIcQCNRdcxn5QpWxPppCVXbKdNvvcAMADAAAQAAA4QAiAEAAwgDAQABqeGHtNFc0Yh6Pp/aM+ntlDW1fLwuAWToGQhmnQFBTiIUZlH7QMjwh5oMExNp5/ABUb3qBsyk9CLanRfateRgFJCYCNYofrI4S2yqT5X9vvtCXeIoG/QqMSl3PJk4ClYufIKjMPgl5IyN6yBIMNmmsATlMMu5TxM68a/CLCh92L3ADAAuAAEAAAOEAJsAMAgCAAADhFlpvY1ZYHT9Jn0DbnljA2dvdgAViVpFoYwy9dMUbOPDHTKt/LOtoicvtQbHeXiUSQeBkGWTLyiPc/NTW9ZC4WK5AuSj/0+V')
b = base64.b64decode('bnmYJ63mREVTUwEACABFAAV0U8UgrDIR+kEEAgIECv0DxApz1F5olFRytjhNlG/JbdW0NSAFeUUF4rBRqsly/h6nFWKoQfih35Lm+BFLE0FoMaikWCjGJQIuf0CXiElMSQifiDM+KTeecNkCgTXADAAuAAEAAAOEARsAMAgCAAADhFlpvY1ZYHT9VwUDbnljA2dvdgAdRZxvC6VlbYUVarYjan0/PlP70gSz1SiYCDZyw5dsGo9vrZd+lMcAm5GFjtKYDXeCb5gVuegzHSNzxDQOa5lVKLQZfXgVHsl3jguCpYwKAygRR3mLBGtnhPrbYcPGMOzIxO6/UE5Hltx9SDqKNe2+rtVeZs5FyHQE5pTVGVjNED9iaauEW9UF3bwEP3K+wLgxWeVycjNry/l4vt9Z0fyTU15kogCZG8MXyStJlzIgdzVZRB96gTJbGBDRFQJfbE2Af+INl0HRY4p+bqQYwFomWg6Tzs30LcqAnkptknb5peUNmQTBI/MU00A6NeVJxkKK3+lf2EuuiJl+nFpfWiKpwAwAMwABAAADhAAJAQAADASqu8zdwAwALgABAAADhACbADMIAgAAA4RZab2NWWB0/SZ9A255YwNnb3YAVhcqgSl33lqjLLFR8pQ2cNhdX7dKZ2gRy0vUHOa+980Nljcj4I36rfjEVJCLKodpbseQl0OeTsbfNfqOmi1VrsypDl+YffyPMtHferm02xBK0agcTMdP/glpuKzdKHTiHTlnSOuBpPnEpgxYPNeBGx8yzMvIaU5rOCxuO49Sh/PADAACAAEAAAOEAAoHdndhbGw0YcAMwAwAAgABAAADhAAKB3Z3YWxsMmHADMAMAAIAAQAAA4QACgd2d2FsbDNhwAzADAACAAEAAAOEAAoHdndhbGwxYcAMwAwALgABAAADhACbAAIIAgAAA4RZab2NWWB0/SZ9A255YwNnb3YANn7LVY7YsKLtpH7LKhUz0SVsM/Gk3T/V8I9wIEZ4vEklM9hI92D2aYe+9EKxOts+/py6itZfANXU197pCufktASDxlH5eWSc9S2uqrRnUNnMUe4p3Jy9ZCGhiHDemgFphKGWYTNZUJoML2+SDzbv9tXo4sSbZiKJCDkNdzSv2lfADAAQAAEAAAOEAEVEZ29vZ2xlLXNpdGUtdmVyaWZpY2F0aW9uPWMycnhTa2VPZUxpSG5iY24tSXhZZm5mQjJQcTQzU3lpeEVka2k2ODZlNDTADAAQAAEAAAOEADc2dj1zcGYxIGlwNDoxNjEuMTg1LjIuMC8yNSBpcDQ6MTY3LjE1My4xMzIuMC8yNSBteCAtYWxswAwALgABAAADhACbABAIAgAAA4RZab2NWWB0/SZ9A255YwNnb3YAjzLOj5HUtVGhi/emNG90g2zK80hrI6gh2d+twgVLYgWebPeTI2D2ylobevXeq5rK5RQgbg2iG1UiTBnlKPgLPYt8ZL+bi+/v5NTaqHfyHFYdKzZeL0dhrmebRbYzG7tzOllcAOOqieeO29Yr4gz1rpiU6g75vkz6yQoHNfmNVMXADAAPAAEAAAOEAAsAZAZ2d2FsbDLADMAMAA8AAQAAA4QACwBkBnZ3YWxsNMAMwAwADwABAAADhAALAAoGdndhbGwzwAzADAAPAAEAAAOEAAsACgZ2d2FsbDXADMAMAA8AAQAAA4QACwAKBnZ3YWxsNsAMwAwADwABAAADhAALAAoGdndhbGw3wAzADAAPAAEAAAOEAAsACgZ2d2FsbDjADMAMAA8AAQAAA4QACwBkBnZ3YWxsMcAMwAwALgABAAADhACbAA8IAgAAA4RZab2NWWB0/SZ9A255YwNnb3YAooXBSj6PfsdBd8sEN/2AA4cvOl2bcioO')
c = base64.b64decode('bnmYJ63mREVTUwEACABFAAFHU8UBWDIRHcMEAgIECv0DxDtlufeCT1zQktat4aEVA8MF0FO1sNbpEQtqfu5Al//OJISaRvtaArR/tLUj2CoZjS7uEnl7QpP/Ui/gR0YtyLurk9yTw7Vei0lSz4cnaOJqDiTGAKYwzVxjnoR1F3n8lplgQaOalVsHx9UAAQABAAADLAAEobkBA8epAAEAAQAAAywABKG5AQzHvwABAAEAAAMsAASnmYIMx5MAAQABAAADLAAEp5mCDcn9AAEAAQAAAqUABKeZhAvKFAABAAEAAAOEAAShuQIfyisAAQABAAADhAAEobkCKcpCAAEAAQAAA4QABKG5AjPKWQABAAEAAAOEAAShuQI9ynAAAQABAAADhAAEobkCC8nPAAEAAQAAA4QABKG5AgzJ5gABAAEAAAOEAASnmYQMAAApIAAAAAAAAAA=')
d = base64.b64decode('////////REVTUwEACABFAABOawsAAIARtGoK/QExCv0D/wCJAIkAOry/3wsBEAABAAAAAAAAIEVKRkRFQkZFRUJGQUNBQ0FDQUNBQ0FDQUNBQ0FDQUFBAAAgAAEAABYP/WUAAB6N4XIAAB6E4XsAAACR/24AADyEw3sAABfu6BEAAAkx9s4AABXB6j4AAANe/KEAAAAT/+wAAB7z4QwAAEuXtGgAAB304gsAABTB6z4AAAdv+JAAACCu31EAADm+xkEAABR064sAABl85oMAACTw2w8AADrKxTUAABVk6psAABnF5joAABpA5b8AABjP5zAAAAqV9WoAAAUW+ukAACGS3m0AAAEP/vAAABoa5eUAABYP6fAAABX/6gAAABUq6tUAADXIyjcAABpy5Y0AABzb4yQAABqi5V0AAFXaqiUAAEmRtm4AACrL1TQAAESzu0wAAAzs8xMAAI7LcTQAABxN47IAAAbo+RcAABLr7RQAAB3Q4i8AAAck+NsAABbi6R0AAEdruJQAAJl+ZoEAABDH7zgAACOA3H8AAAB5/4YAABQk69sAAEo6tcUAABJU7asAADO/zEAAABGA7n8AAQ9L8LMAAD1DwrwAAB8F4PoAABbG6TkAACmC1n0AAlHErjkAABG97kIAAELBvT4AAEo0tcsAABtC5L0AAA9u8JEAACBU36sAAAAl/9oAABBO77EAAA9M8LMAAA8r8NQAAAp39YgAABB874MAAEDxvw4AAEgyt80AAGwsk9MAAB1O4rEAAAxL87QAADtmxJkAAATo+xcAAAM8/MMAABl55oYAACKh3V4AACGj3lwAAE5ssZMAAC1x0o4AAAO+/EEAABNy7I0AACYp2dYAACb+2QEAABB974IAABc36MgAAA1c8qMAAAf++AEAABDo7xcAACLq3RUAAA8L8PQAAAAV/+oAACNU3KsAABBv75AAABFI7rcAABuH5HgAABAe7+EAAB++4EEAACBl35oAAB7c4SMAADgJx/YAADeVyGoAACKN3XIAAA/C8D0AAASq+1UAAOHPHjAAABRI67cAAABw/48=')

old_debug_dissector = conf.debug_dissector
conf.debug_dissector = 0
plist = PacketList([Ether(x) for x in [a, b, c, d]])
conf.debug_dissector = old_debug_dissector

left, defragmented, errored = defrag(plist)
assert len(left) == 1
assert left[0] == Ether(d)
assert len(defragmented) == 1
assert len(defragmented[0]) == 3093
assert defragmented[0][DNSRR].rrname == b'nyc.gov.'
assert len(errored) == 0

plist_def = defragment(plist)
assert len(plist_def) == 2
assert len(plist_def[0]) == 3093
assert plist_def[0][DNSRR].rrname == b'nyc.gov.'

= Packet().fragment()
payloadlen, fragsize = 100, 8
assert fragsize % 8 == 0
fragcount = (payloadlen // fragsize) + bool(payloadlen % fragsize)
* create the packet
pkt = IP() / ("X" * payloadlen)
* create the fragments
frags = pkt.fragment(fragsize)
* count the fragments
assert len(frags) == fragcount
* each fragment except the last one should have MF set
assert all(p.flags == 1 for p in frags[:-1])
assert frags[-1].flags == 0
* each fragment except the last one should have a payload of fragsize bytes
assert all(len(p.payload) == 8 for p in frags[:-1])
assert len(frags[-1].payload) == ((payloadlen % fragsize) or fragsize)

= Packet().fragment() and overloaded_fields
pkt1 = Ether() / IP() / UDP()
pkt2 = pkt1.fragment()[0]
pkt3 = pkt2.__class__(raw(pkt2))
assert pkt1[IP].proto == pkt2[IP].proto == pkt3[IP].proto

= Packet().fragment() already fragmented packets
payloadlen = 1480 * 3
ffrags = (IP() / ("X" * payloadlen)).fragment(1480)
ffrags = reduce(lambda x, y: x + y, (pkt.fragment(1400) for pkt in ffrags))
len(ffrags) == 6
* each fragment except the last one should have MF set
assert all(p.flags == 1 for p in ffrags[:-1])
assert ffrags[-1].flags == 0
* fragment offset should be well computed
plen = 0
for p in ffrags:
    assert p.frag == plen / 8
    plen += len(p.payload)

assert plen == payloadlen


############
############
+ TCP/IP tests

= TCP options: UTO - basic build
raw(TCP(options=[("UTO", 0xffff)])) == b"\x00\x14\x00\x50\x00\x00\x00\x00\x00\x00\x00\x00\x60\x02\x20\x00\x00\x00\x00\x00\x1c\x04\xff\xff"

= TCP options: UTO - basic dissection
uto = TCP(b"\x00\x14\x00\x50\x00\x00\x00\x00\x00\x00\x00\x00\x60\x02\x20\x00\x00\x00\x00\x00\x1c\x04\xff\xff")
uto[TCP].options[0][0] == "UTO" and uto[TCP].options[0][1] == 0xffff

= TCP options: SAck - basic build
raw(TCP(options=[(5, b"abcdefgh")])) == b"\x00\x14\x00P\x00\x00\x00\x00\x00\x00\x00\x00\x80\x02 \x00\x00\x00\x00\x00\x05\nabcdefgh\x00\x00"

= TCP options: SAck - basic dissection
sack = TCP(b"\x00\x14\x00P\x00\x00\x00\x00\x00\x00\x00\x00\x80\x02 \x00\x00\x00\x00\x00\x05\nabcdefgh\x00\x00")
sack[TCP].options[0][0] == "SAck" and sack[TCP].options[0][1] == (1633837924, 1701209960)

= TCP options: SAckOK - basic build
raw(TCP(options=[('SAckOK', b'')])) == b"\x00\x14\x00P\x00\x00\x00\x00\x00\x00\x00\x00`\x02 \x00\x00\x00\x00\x00\x04\x02\x00\x00"

= TCP options: SAckOK - basic dissection
sackok = TCP(b"\x00\x14\x00P\x00\x00\x00\x00\x00\x00\x00\x00`\x02 \x00\x00\x00\x00\x00\x04\x02\x00\x00")
sackok[TCP].options[0][0] == "SAckOK" and sackok[TCP].options[0][1] == b''

= TCP options: EOL - basic build
raw(TCP(options=[(0, '')])) == b"\x00\x14\x00P\x00\x00\x00\x00\x00\x00\x00\x00`\x02 \x00\x00\x00\x00\x00\x00\x00\x00\x00"

= TCP options: EOL - basic dissection
eol = TCP(b"\x00\x14\x00P\x00\x00\x00\x00\x00\x00\x00\x00`\x02 \x00\x00\x00\x00\x00\x00\x02\x00\x00")
eol[TCP].options[0][0] == "EOL" and eol[TCP].options[0][1] == None

= TCP options: malformed - build
raw(TCP(options=[('unknown', b'')])) == raw(TCP())

= TCP options: malformed - dissection
raw(TCP(b"\x00\x14\x00P\x00\x00\x00\x00\x00\x00\x00\x00`\x02 \x00\x00\x00\x00\x00\x03\x00\x00\x00")) == b"\x00\x14\x00P\x00\x00\x00\x00\x00\x00\x00\x00`\x02 \x00\x00\x00\x00\x00\x03\x00\x00\x00"

= TCP options: MPTCP - basic build using bytes
raw(TCP(options=[(30, b"\x10\x03\xc1\x1c\x95\x9b\x81R_1")])) == b"\x00\x14\x00P\x00\x00\x00\x00\x00\x00\x00\x00\x80\x02 \x00\x00\x00\x00\x00\x1e\x0c\x10\x03\xc1\x1c\x95\x9b\x81R_1"

= TCP random options
pkt = TCP()
random.seed(0x2807)
pkt = fuzz(pkt)
options = pkt.options._fix()
options
if six.PY2:
    assert options == [('WScale', (32,)), ('NOP', ''), ('WScale', (145,)), ('WScale', (165,))]
else:
    assert options in [[('TFO', (1822729092, 2707522527)), ('Mood', (b'\x19',)), ('WScale', (117,))], [('TFO', (725644109, 3830853589)), ('Timestamp', (2604802746, 4137267106)), ('WScale', (227,)), ('Timestamp', (38044154, 828782501)), ('AltChkSum', (126, 40603))]]

= IP, TCP & UDP checksums (these tests highly depend on default values)
pkt = IP() / TCP()
bpkt = IP(raw(pkt))
assert bpkt.chksum == 0x7ccd and bpkt.payload.chksum == 0x917c

pkt = IP(len=40) / TCP()
bpkt = IP(raw(pkt))
assert bpkt.chksum == 0x7ccd and bpkt.payload.chksum == 0x917c

pkt = IP(len=40, ihl=5) / TCP()
bpkt = IP(raw(pkt))
assert bpkt.chksum == 0x7ccd and bpkt.payload.chksum == 0x917c

pkt = IP() / TCP() / ("A" * 10)
bpkt = IP(raw(pkt))
assert bpkt.chksum == 0x7cc3 and bpkt.payload.chksum == 0x4b2c

pkt = IP(len=50) / TCP() / ("A" * 10)
bpkt = IP(raw(pkt))
assert bpkt.chksum == 0x7cc3 and bpkt.payload.chksum == 0x4b2c

pkt = IP(len=50, ihl=5) / TCP() / ("A" * 10)
bpkt = IP(raw(pkt))
assert bpkt.chksum == 0x7cc3 and bpkt.payload.chksum == 0x4b2c

pkt = IP(options=[IPOption_RR()]) / TCP() / ("A" * 10)
bpkt = IP(raw(pkt))
assert bpkt.chksum == 0x70bc and bpkt.payload.chksum == 0x4b2c

pkt = IP(len=54, options=[IPOption_RR()]) / TCP() / ("A" * 10)
bpkt = IP(raw(pkt))
assert bpkt.chksum == 0x70bc and bpkt.payload.chksum == 0x4b2c

pkt = IP(len=54, ihl=6, options=[IPOption_RR()]) / TCP() / ("A" * 10)
bpkt = IP(raw(pkt))
assert bpkt.chksum == 0x70bc and bpkt.payload.chksum == 0x4b2c

pkt = IP() / UDP()
bpkt = IP(raw(pkt))
assert bpkt.chksum == 0x7cce and bpkt.payload.chksum == 0x0172

pkt = IP(len=28) / UDP()
bpkt = IP(raw(pkt))
assert bpkt.chksum == 0x7cce and bpkt.payload.chksum == 0x0172

pkt = IP(len=28, ihl=5) / UDP()
bpkt = IP(raw(pkt))
assert bpkt.chksum == 0x7cce and bpkt.payload.chksum == 0x0172

pkt = IP() / UDP() / ("A" * 10)
bpkt = IP(raw(pkt))
assert bpkt.chksum == 0x7cc4 and bpkt.payload.chksum == 0xbb17

pkt = IP(len=38) / UDP() / ("A" * 10)
bpkt = IP(raw(pkt))
assert bpkt.chksum == 0x7cc4 and bpkt.payload.chksum == 0xbb17

pkt = IP(len=38, ihl=5) / UDP() / ("A" * 10)
bpkt = IP(raw(pkt))
assert bpkt.chksum == 0x7cc4 and bpkt.payload.chksum == 0xbb17

pkt = IP(options=[IPOption_RR()]) / UDP() / ("A" * 10)
bpkt = IP(raw(pkt))
assert bpkt.chksum == 0x70bd and bpkt.payload.chksum == 0xbb17

pkt = IP(len=42, options=[IPOption_RR()]) / UDP() / ("A" * 10)
bpkt = IP(raw(pkt))
assert bpkt.chksum == 0x70bd and bpkt.payload.chksum == 0xbb17

pkt = IP(len=42, ihl=6, options=[IPOption_RR()]) / UDP() / ("A" * 10)
bpkt = IP(raw(pkt))
assert bpkt.chksum == 0x70bd and bpkt.payload.chksum == 0xbb17

= IP with forced-length 0
p = IP()/TCP()
p[IP].len = 0
p = IP(raw(p))

assert p.len == 0

= TCP payload with IP Total Length 0
data = b'1234567890abcdef123456789ABCDEF'
pkt = IP()/TCP()/data
pkt2 = IP(raw(pkt))
pkt2.len = 0
pkt3 = IP(raw(pkt2))
assert pkt3.load == data

= DNS
~ dns

* DNS over UDP
pkt = IP(raw(IP(src="10.0.0.1", dst="8.8.8.8")/UDP(sport=RandShort(), dport=53)/DNS(qd=DNSQR(qname="secdev.org."))))
assert UDP in pkt and isinstance(pkt[UDP].payload, DNS)
assert pkt[UDP].dport == 53 and pkt[UDP].length is None
assert pkt[DNS].qdcount == 1 and pkt[DNS].qd.qname == b"secdev.org."

* DNS over TCP
pkt = IP(raw(IP(src="10.0.0.1", dst="8.8.8.8")/TCP(sport=RandShort(), dport=53, flags="P")/DNS(qd=DNSQR(qname="secdev.org."))))
assert TCP in pkt and isinstance(pkt[TCP].payload, DNS)
assert pkt[TCP].dport == 53 and pkt[DNS].length is not None
assert pkt[DNS].qdcount == 1 and pkt[DNS].qd.qname == b"secdev.org."

= DNS frame with advanced decompression
~ dns

a = b'\x01\x00^\x00\x00\xfb$\xa2\xe1\x90\xa9]\x08\x00E\x00\x01P\\\xdd\x00\x00\xff\x11\xbb\x93\xc0\xa8\x00\x88\xe0\x00\x00\xfb\x14\xe9\x14\xe9\x01<*\x81\x00\x00\x84\x00\x00\x00\x00\x03\x00\x00\x00\x04\x01B\x019\x015\x019\x013\x014\x017\x013\x016\x017\x010\x012\x010\x01D\x018\x011\x010\x010\x010\x010\x010\x010\x010\x010\x010\x010\x010\x010\x010\x018\x01E\x01F\x03ip6\x04arpa\x00\x00\x0c\x80\x01\x00\x00\x00x\x00\x0f\x07Zalmoid\x05local\x00\x011\x01A\x019\x014\x017\x01E\x01A\x014\x01B\x01A\x01F\x01B\x012\x011\x014\x010\x010\x016\x01E\x01F\x017\x011\x01F\x012\x015\x013\x01E\x010\x011\x010\x01A\x012\xc0L\x00\x0c\x80\x01\x00\x00\x00x\x00\x02\xc0`\x03136\x010\x03168\x03192\x07in-addr\xc0P\x00\x0c\x80\x01\x00\x00\x00x\x00\x02\xc0`\xc0\x0c\x00/\x80\x01\x00\x00\x00x\x00\x06\xc0\x0c\x00\x02\x00\x08\xc0o\x00/\x80\x01\x00\x00\x00x\x00\x06\xc0o\x00\x02\x00\x08\xc0\xbd\x00/\x80\x01\x00\x00\x00x\x00\x06\xc0\xbd\x00\x02\x00\x08\x00\x00)\x05\xa0\x00\x00\x11\x94\x00\x12\x00\x04\x00\x0e\x00\xc1&\xa2\xe1\x90\xa9]$\xa2\xe1\x90\xa9]'
pkt = Ether(a)
assert pkt.ancount == 3
assert pkt.arcount == 4
assert pkt.an[1].rdata == b'Zalmoid.local.'
assert pkt.an[2].rdata == b'Zalmoid.local.'
assert pkt.ar[1].nextname == b'1.A.9.4.7.E.A.4.B.A.F.B.2.1.4.0.0.6.E.F.7.1.F.2.5.3.E.0.1.0.A.2.ip6.arpa.'
assert pkt.ar[2].nextname == b'136.0.168.192.in-addr.arpa.'
pkt.show()

= DNS frame with DNSRRSRV
~ dns

b = Ether(b'33\x00\x00\x00\xfb$\xe3\x14M\x84\xc0\x86\xdd`\t\xc0f\x02b\x11\xff\xfe\x80\x00\x00\x00\x00\x00\x00\x04*,\x03\xab+/\x14\xff\x02\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xfb\x14\xe9\x14\xe9\x02b_\xd8\x00\x00\x84\x00\x00\x00\x00\x0b\x00\x00\x00\x06\x014\x011\x01F\x012\x01B\x012\x01B\x01A\x013\x010\x01C\x012\x01A\x012\x014\x010\x010\x010\x010\x010\x010\x010\x010\x010\x010\x010\x010\x010\x010\x018\x01E\x01F\x03ip6\x04arpa\x00\x00\x0c\x80\x01\x00\x00\x00x\x00\x14\x0csCapys-fLuff\x05local\x00\x03177\x010\x03168\x03192\x07in-addr\xc0P\x00\x0c\x80\x01\x00\x00\x00x\x00\x02\xc0`\x01E\x01F\x017\x01D\x01B\x018\x014\x01C\x014\x01B\x016\x01E\x015\x017\x018\x010\x010\x016\x01E\x01F\x017\x011\x01F\x012\x015\x013\x01E\x010\x011\x010\x01A\x012\xc0L\x00\x0c\x80\x01\x00\x00\x00x\x00\x02\xc0`+24:e3:14:4d:84:c0@fe80::26e3:14ff:fe4d:84c0\x0e_apple-mobdev2\x04_tcp\xc0m\x00\x10\x80\x01\x00\x00\x11\x94\x00\x01\x00\t_services\x07_dns-sd\x04_udp\xc0m\x00\x0c\x00\x01\x00\x00\x11\x94\x00\x02\xc1\x12\x08521805b3\x04_sub\xc1\x12\x00\x0c\x00\x01\x00\x00\x11\x94\x00\x02\xc0\xe6\xc1\x12\x00\x0c\x00\x01\x00\x00\x11\x94\x00\x02\xc0\xe6\xc0\xe6\x00!\x80\x01\x00\x00\x00x\x00\x08\x00\x00\x00\x00~\xf2\xc0`\xc0`\x00\x1c\x80\x01\x00\x00\x00x\x00\x10\xfe\x80\x00\x00\x00\x00\x00\x00\x04*,\x03\xab+/\x14\xc0`\x00\x01\x80\x01\x00\x00\x00x\x00\x04\xc0\xa8\x00\xb1\xc0`\x00\x1c\x80\x01\x00\x00\x00x\x00\x10*\x01\x0e5/\x17\xfe`\x08u\xe6\xb4\xc4\x8b\xd7\xfe\xc0\x0c\x00/\x80\x01\x00\x00\x00x\x00\x06\xc0\x0c\x00\x02\x00\x08\xc0t\x00/\x80\x01\x00\x00\x00x\x00\x06\xc0t\x00\x02\x00\x08\xc0\x98\x00/\x80\x01\x00\x00\x00x\x00\x06\xc0\x98\x00\x02\x00\x08\xc0\xe6\x00/\x80\x01\x00\x00\x11\x94\x00\t\xc0\xe6\x00\x05\x00\x00\x80\x00@\xc0`\x00/\x80\x01\x00\x00\x00x\x00\x08\xc0`\x00\x04@\x00\x00\x08\x00\x00)\x05\xa0\x00\x00\x11\x94\x00\x12\x00\x04\x00\x0e\x00\xcf&\xe3\x14M\x84\xc0$\xe3\x14M\x84\xc0')
assert isinstance(b.an[7], DNSRRSRV)
assert b.an[7].target == b'sCapys-fLuff.local.'
assert b.an[6].rrname == b'_apple-mobdev2._tcp.local.'
assert b.an[6].rdata == b'24:e3:14:4d:84:c0@fe80::26e3:14ff:fe4d:84c0._apple-mobdev2._tcp.local.'

= DNS frame with decompression hidden args
~ dns

c = b'\x01\x00^\x00\x00\xfb\x14\x0cv\x8f\xfe(\x08\x00E\x00\x01C\xe3\x91@\x00\xff\x11\xf4u\xc0\xa8\x00\xfe\xe0\x00\x00\xfb\x14\xe9\x14\xe9\x01/L \x00\x00\x84\x00\x00\x00\x00\x04\x00\x00\x00\x00\x05_raop\x04_tcp\x05local\x00\x00\x0c\x00\x01\x00\x00\x11\x94\x00\x1e\x1b140C768FFE28@Freebox Server\xc0\x0c\xc0(\x00\x10\x80\x01\x00\x00\x11\x94\x00\xa0\ttxtvers=1\x08vs=190.9\x04ch=2\x08sr=44100\x05ss=16\x08pw=false\x06et=0,1\x04ek=1\ntp=TCP,UDP\x13am=FreeboxServer1,2\ncn=0,1,2,3\x06md=0,2\x07sf=0x44\x0bft=0xBF0A00\x08sv=false\x07da=true\x08vn=65537\x04vv=2\xc0(\x00!\x80\x01\x00\x00\x00x\x00\x19\x00\x00\x00\x00\x13\x88\x10Freebox-Server-3\xc0\x17\xc1\x04\x00\x01\x80\x01\x00\x00\x00x\x00\x04\xc0\xa8\x00\xfe'
pkt = Ether(c)
assert DNS in pkt
assert pkt.an.rdata == b'140C768FFE28@Freebox Server._raop._tcp.local.'
assert pkt.an.getlayer(DNSRR, type=1).rrname == b'Freebox-Server-3.local.'
assert pkt.an.getlayer(DNSRR, type=1).rdata == '192.168.0.254'
assert pkt.an.getlayer(DNSRR, type=16).rdata == [b'txtvers=1', b'vs=190.9', b'ch=2', b'sr=44100', b'ss=16', b'pw=false', b'et=0,1', b'ek=1', b'tp=TCP,UDP', b'am=FreeboxServer1,2', b'cn=0,1,2,3', b'md=0,2', b'sf=0x44', b'ft=0xBF0A00', b'sv=false', b'da=true', b'vn=65537', b'vv=2']

= DNS advanced building
~ dns

pkt = DNS(qr=1, aa=1, rd=1)
pkt.an = DNSRR(type=12, rrname='_raop._tcp.local.', rdata='140C768FFE28@Freebox Server._raop._tcp.local.')/DNSRR(rrname='140C768FFE28@Freebox Server._raop._tcp.local.', type=16, rdata=[b'txtvers=1', b'vs=190.9', b'ch=2', b'sr=44100', b'ss=16', b'pw=false', b'et=0,1', b'ek=1', b'tp=TCP,UDP', b'am=FreeboxServer1,2', b'cn=0,1,2,3', b'md=0,2', b'sf=0x44', b'ft=0xBF0A00', b'sv=false', b'da=true', b'vn=65537', b'vv=2'])/DNSRRSRV(rrname='140C768FFE28@Freebox Server._raop._tcp.local.', target='Freebox-Server-3.local.', port=5000, type=33, rclass=32769)/DNSRR(rrname='Freebox-Server-3.local.', rdata='192.168.0.254', rclass=32769, type=1, ttl=120)

pkt = DNS(raw(pkt))

assert DNSRRSRV in pkt.an
assert pkt[DNSRRSRV].target == b'Freebox-Server-3.local.'
assert pkt[DNSRRSRV].rrname == b'140C768FFE28@Freebox Server._raop._tcp.local.'
assert isinstance(pkt[DNSRRSRV].payload, DNSRR)
assert pkt[DNSRRSRV].payload.rrname == b'Freebox-Server-3.local.'
assert pkt[DNSRRSRV].payload.rdata == '192.168.0.254'

= Basic DNS Compression
~ dns

assert len(pkt) == 426

z = pkt.compress()

assert len(z) == 295
assert z.an[0].rrname == b'_raop._tcp.local.'
assert z.an[0].rdata == b'\x1b140C768FFE28@Freebox Server\xc0\x0c'
assert z.an[1].rrname == z.an[2].rrname == b'\xc0('
assert z.an[2].target == b'\x10Freebox-Server-3\xc0\x17'
assert z.an[3].rrname == b'\xc1\x04'

raw(z)

assert raw(z) == b'\x00\x00\x85\x00\x00\x00\x00\x04\x00\x00\x00\x00\x05_raop\x04_tcp\x05local\x00\x00\x0c\x00\x01\x00\x00\x00\x00\x00\x1e\x1b140C768FFE28@Freebox Server\xc0\x0c\xc0(\x00\x10\x00\x01\x00\x00\x00\x00\x00\xa0\ttxtvers=1\x08vs=190.9\x04ch=2\x08sr=44100\x05ss=16\x08pw=false\x06et=0,1\x04ek=1\ntp=TCP,UDP\x13am=FreeboxServer1,2\ncn=0,1,2,3\x06md=0,2\x07sf=0x44\x0bft=0xBF0A00\x08sv=false\x07da=true\x08vn=65537\x04vv=2\xc0(\x00!\x80\x01\x00\x00\x00\x00\x00\x19\x00\x00\x00\x00\x13\x88\x10Freebox-Server-3\xc0\x17\xc1\x04\x00\x01\x80\x01\x00\x00\x00x\x00\x04\xc0\xa8\x00\xfe'

recompressed = DNS(raw(z))
recompressed.clear_cache()
recompressed.an[0].rdlen = None
recompressed.an[1].rdlen = None
recompressed.an[2].rdlen = None
recompressed.an[3].rdlen = None

assert raw(recompressed) == raw(pkt)

= Advanced dns_get_str tests
~ dns

assert dns_get_str(b"\x06cheese\x00blobofdata....\x06hamand\xc0\x0c", 22, _internal=True)[0] == b'hamand.cheese.'

from scapy.tools.UTscapy import Bunch
assert dns_get_str(b"\x06hamand\xc0\x0c", 0, pkt=Bunch(_orig_s=b"\x06cheese\x00blobofdata", _orig_p=22))[0] == b'hamand.cheese.'

= Decompression loop in dns_get_str
~ dns

assert dns_get_str(b"\x04data\xc0\x0c", 0, _internal=True)[0] == b"data."

= Prematured end in dns_get_str
~ dns

assert dns_get_str(b"\x06da", 0, _internal=True)[0] == b"da."
assert dns_get_str(b"\x04data\xc0\x01", 0, _internal=True)[0] == b"data."

= Layer binding

* Test DestMACField & DestIPField
pkt = Ether(raw(Ether()/IP()/UDP(dport=5353)/DNS()))
assert isinstance(pkt, Ether) and pkt.dst == '01:00:5e:00:00:fb'
pkt = pkt.payload
assert isinstance(pkt, IP) and pkt.dst == '224.0.0.251'
pkt = pkt.payload
assert isinstance(pkt, UDP) and pkt.dport == 5353
pkt = pkt.payload
assert isinstance(pkt, DNS) and isinstance(pkt.payload, NoPayload)

* Same with IPv6
pkt = Ether(raw(Ether()/IPv6()/UDP(dport=5353)/DNS()))
assert isinstance(pkt, Ether) and pkt.dst == '33:33:00:00:00:fb'
pkt = pkt.payload
assert isinstance(pkt, IPv6) and pkt.dst == 'ff02::fb'
pkt = pkt.payload
assert isinstance(pkt, UDP) and pkt.dport == 5353
pkt = pkt.payload
assert isinstance(pkt, DNS) and isinstance(pkt.payload, NoPayload)


############
############
+ Mocked read_routes() calls

= Truncated netstat -rn output on OS X
~ mock_read_routes_bsd

import mock
from io import StringIO

@mock.patch("scapy.arch.unix.get_if_addr")
@mock.patch("scapy.arch.unix.os")
def test_osx_netstat_truncated(mock_os, mock_get_if_addr):
    """Test read_routes() on OS X 10.? with a long interface name"""
    # netstat & ifconfig outputs from https://github.com/secdev/scapy/pull/119
    netstat_output = u"""
Routing tables

Internet:
Destination        Gateway            Flags        Refs      Use   Netif Expire
default            192.168.1.1        UGSc          460        0     en1
default            link#11            UCSI            1        0 bridge1
127                127.0.0.1          UCS             1        0     lo0
127.0.0.1          127.0.0.1          UH             10  2012351     lo0
"""
    ifconfig_output = u"lo0 en1 bridge10\n"
    # Mocked file descriptors
    def se_popen(command):
        """Perform specific side effects"""
        if command.startswith("netstat -rn"):
            return StringIO(netstat_output)
        elif command == "ifconfig -l":
            ret = StringIO(ifconfig_output)
            def unit():
                return ret
            ret.__call__ = unit
            ret.__enter__ = unit
            ret.__exit__ = lambda x,y,z: None
            return ret
        raise Exception("Command not mocked: %s" % command)
    mock_os.popen.side_effect = se_popen
    # Mocked get_if_addr() behavior
    def se_get_if_addr(iface):
        """Perform specific side effects"""
        if iface == "bridge1":
            oserror_exc = OSError()
            oserror_exc.message = "Device not configured"
            raise oserror_exc
        return "1.2.3.4"
    mock_get_if_addr.side_effect = se_get_if_addr
    # Test the function
    from scapy.arch.unix import read_routes
    routes = read_routes()
    assert(len(routes) == 4)
    assert([r for r in routes if r[3] == "bridge10"])


test_osx_netstat_truncated()


= OpenBSD 6.3
~ mock_read_routes_bsd

import mock
from io import StringIO

@mock.patch("scapy.arch.unix.OPENBSD")
@mock.patch("scapy.arch.unix.os")
def test_openbsd_6_3(mock_os, mock_openbsd):
    """Test read_routes() on OpenBSD 6.3"""
    # 'netstat -rn -f inet' output
    netstat_output = u"""
Routing tables

Internet:
Destination        Gateway            Flags   Refs      Use   Mtu  Prio Iface
default            10.0.1.254         UGS        0        0     -     8 bge0 
224/4              127.0.0.1          URS        0       23 32768     8 lo0  
10.0.1/24          10.0.1.26          UCn        4      192     -     4 bge0 
10.0.1.1           00:30:48:57:ed:0b  UHLc       2      338     -     3 bge0 
10.0.1.2           00:03:ba:0c:0b:52  UHLc       1      186     -     3 bge0 
10.0.1.26          00:30:48:62:b3:f4  UHLl       0    47877     -     1 bge0 
10.0.1.135         link#1             UHLch      1      194     -     3 bge0 
10.0.1.254         link#1             UHLch      1      190     -     3 bge0 
10.0.1.255         10.0.1.26          UHb        0        0     -     1 bge0 
10.188.6/24        10.188.6.17        Cn         0        0     -     4 tap3 
10.188.6.17        fe:e1:ba:d7:ff:32  UHLl       0       25     -     1 tap3 
10.188.6.255       10.188.6.17        Hb         0        0     -     1 tap3 
10.188.135/24      10.0.1.135         UGS        0        0  1350 L   8 bge0 
127/8              127.0.0.1          UGRS       0        0 32768     8 lo0  
127.0.0.1          127.0.0.1          UHhl       1  3835230 32768     1 lo0  
"""
    # Mocked file descriptor
    strio = StringIO(netstat_output)
    mock_os.popen = mock.MagicMock(return_value=strio)
    
    # Mocked OpenBSD parsing behavior
    mock_openbsd = True
    # Test the function
    from scapy.arch.unix import read_routes
    routes = read_routes()
    for r in routes:
        print(ltoa(r[0]), ltoa(r[1]), r)
        # check that default route exists in parsed data structure
        if ltoa(r[0]) == "0.0.0.0":
            default=r
        # check that route with locked mtu exists in parsed data structure
        if ltoa(r[0]) == "10.188.135.0":
            locked=r
    assert(len(routes) == 11)
    assert(default[2] == "10.0.1.254")
    assert(default[3] == "bge0")
    assert(locked[2] == "10.0.1.135")
    assert(locked[3] == "bge0")

test_openbsd_6_3()


############
############
+ Mocked _parse_tcpreplay_result(stdout, stderr, argv, results_dict)
~ mock_parse_tcpreplay_result

= Test mocked _parse_tcpreplay_result

from scapy.sendrecv import _parse_tcpreplay_result

stdout = """Actual: 1024 packets (198929 bytes) sent in 67.88 seconds.              Rated: 2930.6 bps, 0.02 Mbps, 15.09 pps
Statistics for network device: mon0
        Attempted packets:         1024
        Successful packets:        1024
        Failed packets:            0
        Retried packets (ENOBUFS): 0
        Retried packets (EAGAIN):  0"""

stderr = """Warning in sendpacket.c:sendpacket_open_pf() line 669:
Unsupported physical layer type 0x0323 on mon0.  Maybe it works, maybe it won't.  See tickets #123/318
sending out mon0
processing file: replay-example.pcap"""

argv = ['tcpreplay' '--intf1=mon0' '--multiplier=1.00' '--timer=nano' 'replay-example.pcap']
results_dict = _parse_tcpreplay_result(stdout, stderr, argv)

results_dict

assert(results_dict["packets"] == 1024)
assert(results_dict["bytes"] == 198929)
assert(results_dict["time"] == 67.88)
assert(results_dict["bps"] == 2930.6)
assert(results_dict["mbps"] == 0.02)
assert(results_dict["pps"] == 15.09)
assert(results_dict["attempted"] == 1024)
assert(results_dict["successful"] == 1024)
assert(results_dict["failed"] == 0)
assert(results_dict["retried_enobufs"] == 0)
assert(results_dict["retried_eagain"] == 0)
assert(results_dict["command"] == str(argv))
assert(len(results_dict["warnings"]) == 3)


############
############
+ Mocked read_routes6() calls

= Preliminary definitions
~ mock_read_routes_bsd

import mock
from io import StringIO

def valid_output_read_routes6(routes):
    """"Return True if 'routes' contains correctly formatted entries, False otherwise"""
    for destination, plen, next_hop, dev, cset, me  in routes:
        if not in6_isvalid(destination) or not type(plen) == int:
            return False
        if not in6_isvalid(next_hop) or not isinstance(dev, six.string_types):
            return False
        for address in cset:
            if not in6_isvalid(address):
                return False
    return True

def check_mandatory_ipv6_routes(routes6):
    """Ensure that mandatory IPv6 routes are present"""
    if len([r for r in routes6 if r[0] == "::1" and r[4] == ["::1"]]) < 1:
        return False
    if len([r for r in routes6 if r[0] == "fe80::" and r[1] == 64]) < 1:
        return False
    if len([r for r in routes6 if in6_islladdr(r[0]) and r[1] == 128 and \
            r[4] == ["::1"]]) < 1:
        return False
    return True


= Mac OS X 10.9.5
~ mock_read_routes_bsd

@mock.patch("scapy.arch.unix.in6_getifaddr")
@mock.patch("scapy.arch.unix.os")
def test_osx_10_9_5(mock_os, mock_in6_getifaddr):
    """Test read_routes6() on OS X 10.9.5"""
    # 'netstat -rn -f inet6' output
    netstat_output = u"""
Routing tables

Internet6:
Destination                             Gateway                         Flags         Netif Expire
::1                                     ::1                             UHL             lo0
fe80::%lo0/64                           fe80::1%lo0                     UcI             lo0
fe80::1%lo0                             link#1                          UHLI            lo0
fe80::%en0/64                           link#4                          UCI             en0
fe80::ba26:6cff:fe5f:4eee%en0           b8:26:6c:5f:4e:ee               UHLWIi          en0
fe80::bae8:56ff:fe45:8ce6%en0           b8:e8:56:45:8c:e6               UHLI            lo0
ff01::%lo0/32                           ::1                             UmCI            lo0
ff01::%en0/32                           link#4                          UmCI            en0
ff02::%lo0/32                           ::1                             UmCI            lo0
ff02::%en0/32                           link#4                          UmCI            en0
"""
    # Mocked file descriptor
    strio = StringIO(netstat_output)
    mock_os.popen = mock.MagicMock(return_value=strio)
    # Mocked in6_getifaddr() output
    mock_in6_getifaddr.return_value = [("::1", IPV6_ADDR_LOOPBACK, "lo0"),
                                       ("fe80::ba26:6cff:fe5f:4eee", IPV6_ADDR_LINKLOCAL, "en0")]
    # Test the function
    from scapy.arch.unix import read_routes6
    routes = read_routes6()
    for r in routes:
        print(r)
    assert(len(routes) == 6)
    assert(check_mandatory_ipv6_routes(routes))

test_osx_10_9_5()


= Mac OS X 10.9.5 with global IPv6 connectivity
~ mock_read_routes_bsd
@mock.patch("scapy.arch.unix.in6_getifaddr")
@mock.patch("scapy.arch.unix.os")
def test_osx_10_9_5_global(mock_os, mock_in6_getifaddr):
    """Test read_routes6() on OS X 10.9.5 with an IPv6 connectivity"""
    # 'netstat -rn -f inet6' output
    netstat_output = u"""
Routing tables

Internet6:
Destination                             Gateway                         Flags         Netif Expire
default                                 fe80::ba26:8aff:fe5f:4eef%en0   UGc             en0
::1                                     ::1                             UHL             lo0
2a01:ab09:7d:1f01::/64                  link#4                          UC              en0
2a01:ab09:7d:1f01:420:205c:9fab:5be7    b8:e9:55:44:7c:e5               UHL             lo0
2a01:ab09:7d:1f01:ba26:8aff:fe5f:4eef   b8:26:8a:5f:4e:ef               UHLWI           en0
2a01:ab09:7d:1f01:bae9:55ff:fe44:7ce5   b8:e9:55:44:7c:e5               UHL             lo0
fe80::%lo0/64                           fe80::1%lo0                     UcI             lo0
fe80::1%lo0                             link#1                          UHLI            lo0
fe80::%en0/64                           link#4                          UCI             en0
fe80::5664:d9ff:fe79:4e00%en0           54:64:d9:79:4e:0                UHLWI           en0
fe80::6ead:f8ff:fe74:945a%en0           6c:ad:f8:74:94:5a               UHLWI           en0
fe80::a2f3:c1ff:fec4:5b50%en0           a0:f3:c1:c4:5b:50               UHLWI           en0
fe80::ba26:8aff:fe5f:4eef%en0           b8:26:8a:5f:4e:ef               UHLWIir         en0
fe80::bae9:55ff:fe44:7ce5%en0           b8:e9:55:44:7c:e5               UHLI            lo0
ff01::%lo0/32                           ::1                             UmCI            lo0
ff01::%en0/32                           link#4                          UmCI            en0
ff02::%lo0/32                           ::1                             UmCI            lo
"""
    # Mocked file descriptor
    strio = StringIO(netstat_output)
    mock_os.popen = mock.MagicMock(return_value=strio)
    # Mocked in6_getifaddr() output
    mock_in6_getifaddr.return_value = [("::1", IPV6_ADDR_LOOPBACK, "lo0"),
                                       ("fe80::ba26:6cff:fe5f:4eee", IPV6_ADDR_LINKLOCAL, "en0")]
    # Test the function
    from scapy.arch.unix import read_routes6
    routes = read_routes6()
    print(routes)
    assert(valid_output_read_routes6(routes))
    for r in routes:
        print(r)
    assert(len(routes) == 11)
    assert(check_mandatory_ipv6_routes(routes))

test_osx_10_9_5_global()


= Mac OS X 10.10.4
~ mock_read_routes_bsd

@mock.patch("scapy.arch.unix.in6_getifaddr")
@mock.patch("scapy.arch.unix.os")
def test_osx_10_10_4(mock_os, mock_in6_getifaddr):
    """Test read_routes6() on OS X 10.10.4"""
    # 'netstat -rn -f inet6' output
    netstat_output = u"""
Routing tables

Internet6:
Destination                             Gateway                         Flags         Netif Expire
::1                                     ::1                             UHL             lo0
fe80::%lo0/64                           fe80::1%lo0                     UcI             lo0
fe80::1%lo0                             link#1                          UHLI            lo0
fe80::%en0/64                           link#4                          UCI             en0
fe80::a00:27ff:fe9b:c965%en0            8:0:27:9b:c9:65                 UHLI            lo0
ff01::%lo0/32                           ::1                             UmCI            lo0
ff01::%en0/32                           link#4                          UmCI            en0
ff02::%lo0/32                           ::1                             UmCI            lo0
ff02::%en0/32                           link#4                          UmCI            en0
"""
    # Mocked file descriptor
    strio = StringIO(netstat_output)
    mock_os.popen = mock.MagicMock(return_value=strio)
    # Mocked in6_getifaddr() output
    mock_in6_getifaddr.return_value = [("::1", IPV6_ADDR_LOOPBACK, "lo0"),
                                       ("fe80::a00:27ff:fe9b:c965", IPV6_ADDR_LINKLOCAL, "en0")]
    # Test the function
    from scapy.arch.unix import read_routes6
    routes = read_routes6()
    for r in routes:
        print(r)
    assert(len(routes) == 5)
    assert(check_mandatory_ipv6_routes(routes))

test_osx_10_10_4()


= FreeBSD 10.2
~ mock_read_routes_bsd

@mock.patch("scapy.arch.unix.in6_getifaddr")
@mock.patch("scapy.arch.unix.os")
def test_freebsd_10_2(mock_os, mock_in6_getifaddr):
    """Test read_routes6() on FreeBSD 10.2"""
    # 'netstat -rn -f inet6' output
    netstat_output = u"""
Routing tables

Internet6:
Destination                       Gateway                       Flags      Netif Expire
::/96                             ::1                           UGRS        lo0
::1                               link#2                        UH          lo0
::ffff:0.0.0.0/96                 ::1                           UGRS        lo0
fe80::/10                         ::1                           UGRS        lo0
fe80::%lo0/64                     link#2                        U           lo0
fe80::1%lo0                       link#2                        UHS         lo0
ff01::%lo0/32                     ::1                           U           lo0
ff02::/16                         ::1                           UGRS        lo0
ff02::%lo0/32                     ::1                           U           lo0
"""
    # Mocked file descriptor
    strio = StringIO(netstat_output)
    mock_os.popen = mock.MagicMock(return_value=strio)
    # Mocked in6_getifaddr() output
    mock_in6_getifaddr.return_value = [("::1", IPV6_ADDR_LOOPBACK, "lo0")]
    # Test the function
    from scapy.arch.unix import read_routes6
    routes = read_routes6()
    for r in routes:
        print(r)
    assert(len(routes) == 3)
    assert(check_mandatory_ipv6_routes(routes))

test_freebsd_10_2()


= OpenBSD 5.5
~ mock_read_routes_bsd

@mock.patch("scapy.arch.unix.OPENBSD")
@mock.patch("scapy.arch.unix.in6_getifaddr")
@mock.patch("scapy.arch.unix.os")
def test_openbsd_5_5(mock_os, mock_in6_getifaddr, mock_openbsd):
    """Test read_routes6() on OpenBSD 5.5"""
    # 'netstat -rn -f inet6' output
    netstat_output = u"""
Routing tables

Internet6:
Destination                        Gateway                        Flags   Refs      Use   Mtu  Prio Iface
::/104                             ::1                            UGRS       0        0     -     8 lo0  
::/96                              ::1                            UGRS       0        0     -     8 lo0  
::1                                ::1                            UH        14        0 33144     4 lo0  
::127.0.0.0/104                    ::1                            UGRS       0        0     -     8 lo0  
::224.0.0.0/100                    ::1                            UGRS       0        0     -     8 lo0  
::255.0.0.0/104                    ::1                            UGRS       0        0     -     8 lo0  
::ffff:0.0.0.0/96                  ::1                            UGRS       0        0     -     8 lo0  
2002::/24                          ::1                            UGRS       0        0     -     8 lo0  
2002:7f00::/24                     ::1                            UGRS       0        0     -     8 lo0  
2002:e000::/20                     ::1                            UGRS       0        0     -     8 lo0  
2002:ff00::/24                     ::1                            UGRS       0        0     -     8 lo0  
fe80::/10                          ::1                            UGRS       0        0     -     8 lo0  
fe80::%em0/64                      link#1                         UC         0        0     -     4 em0  
fe80::a00:27ff:fe04:59bf%em0       08:00:27:04:59:bf              UHL        0        0     -     4 lo0  
fe80::%lo0/64                      fe80::1%lo0                    U          0        0     -     4 lo0  
fe80::1%lo0                        link#3                         UHL        0        0     -     4 lo0  
fec0::/10                          ::1                            UGRS       0        0     -     8 lo0  
ff01::/16                          ::1                            UGRS       0        0     -     8 lo0  
ff01::%em0/32                      link#1                         UC         0        0     -     4 em0  
ff01::%lo0/32                      fe80::1%lo0                    UC         0        0     -     4 lo0  
ff02::/16                          ::1                            UGRS       0        0     -     8 lo0  
ff02::%em0/32                      link#1                         UC         0        0     -     4 em0  
ff02::%lo0/32                      fe80::1%lo0                    UC         0        0     -     4 lo0 
"""
    # Mocked file descriptor
    strio = StringIO(netstat_output)
    mock_os.popen = mock.MagicMock(return_value=strio)
    
    # Mocked in6_getifaddr() output
    mock_in6_getifaddr.return_value = [("::1", IPV6_ADDR_LOOPBACK, "lo0"),
                                       ("fe80::a00:27ff:fe04:59bf", IPV6_ADDR_LINKLOCAL, "em0")]
    # Mocked OpenBSD parsing behavior
    mock_openbsd = True
    # Test the function
    from scapy.arch.unix import read_routes6
    routes = read_routes6()
    for r in routes:
        print(r)
    assert(len(routes) == 5)
    assert(check_mandatory_ipv6_routes(routes))

test_openbsd_5_5()


= NetBSD 7.0
~ mock_read_routes_bsd

@mock.patch("scapy.arch.unix.NETBSD")
@mock.patch("scapy.arch.unix.in6_getifaddr")
@mock.patch("scapy.arch.unix.os")
def test_netbsd_7_0(mock_os, mock_in6_getifaddr, mock_netbsd):
    """Test read_routes6() on NetBSD 7.0"""
    # 'netstat -rn -f inet6' output
    netstat_output = u"""
Routing tables

Internet6:
Destination                        Gateway                        Flags    Refs      Use    Mtu Interface
::/104                             ::1                            UGRS        -        -      -  lo0
::/96                              ::1                            UGRS        -        -      -  lo0
::1                                ::1                            UH          -        -  33648  lo0
::127.0.0.0/104                    ::1                            UGRS        -        -      -  lo0
::224.0.0.0/100                    ::1                            UGRS        -        -      -  lo0
::255.0.0.0/104                    ::1                            UGRS        -        -      -  lo0
::ffff:0.0.0.0/96                  ::1                            UGRS        -        -      -  lo0
2001:db8::/32                      ::1                            UGRS        -        -      -  lo0
2002::/24                          ::1                            UGRS        -        -      -  lo0
2002:7f00::/24                     ::1                            UGRS        -        -      -  lo0
2002:e000::/20                     ::1                            UGRS        -        -      -  lo0
2002:ff00::/24                     ::1                            UGRS        -        -      -  lo0
fe80::/10                          ::1                            UGRS        -        -      -  lo0
fe80::%wm0/64                      link#1                         UC          -        -      -  wm0
fe80::acd1:3989:180e:fde0          08:00:27:a1:64:d8              UHL         -        -      -  lo0
fe80::%lo0/64                      fe80::1                        U           -        -      -  lo0
fe80::1                            link#2                         UHL         -        -      -  lo0
ff01:1::/32                        link#1                         UC          -        -      -  wm0
ff01:2::/32                        ::1                            UC          -        -      -  lo0
ff02::%wm0/32                      link#1                         UC          -        -      -  wm0
ff02::%lo0/32                      ::1                            UC          -        -      -  lo0
"""
    # Mocked file descriptor
    strio = StringIO(netstat_output)
    mock_os.popen = mock.MagicMock(return_value=strio)
    # Mocked in6_getifaddr() output
    mock_in6_getifaddr.return_value = [("::1", IPV6_ADDR_LOOPBACK, "lo0"),
                                       ("fe80::acd1:3989:180e:fde0", IPV6_ADDR_LINKLOCAL, "wm0")]
    # Test the function
    from scapy.arch.unix import read_routes6
    routes = read_routes6()
    for r in routes:
        print(r)
    assert(len(routes) == 5)
    assert(check_mandatory_ipv6_routes(routes))

test_netbsd_7_0()


############
############
+ Mocked route() calls

= Mocked IPv4 routes calls

import scapy

old_routes = conf.route.routes
old_iface = conf.iface
old_loopback = scapy.consts.LOOPBACK_INTERFACE
try:
    conf.iface = 'enp3s0'
    scapy.consts.LOOPBACK_INTERFACE = 'lo'
    conf.route.invalidate_cache()
    conf.route.routes = [
        (4294967295, 4294967295, '0.0.0.0', 'wlan0', '', 281),
        (4294967295, 4294967295, '0.0.0.0', 'lo', '', 291),
        (4294967295, 4294967295, '0.0.0.0', 'enp3s0', '192.168.0.119', 281),
        (3758096384, 4026531840, '0.0.0.0', 'lo', '', 291),
        (3758096384, 4026531840, '0.0.0.0', 'wlan0', '', 281),
        (3758096384, 4026531840, '0.0.0.0', 'enp3s0', '1.1.1.1', 281),
        (3232235775, 4294967295, '0.0.0.0', 'enp3s0', '2.2.2.2', 281),
        (3232235639, 4294967295, '0.0.0.0', 'enp3s0', '3.3.3.3', 281),
        (3232235520, 4294967040, '0.0.0.0', 'enp3s0', '4.4.4.4', 281),
        (0, 0, '192.168.0.254', 'enp3s0', '192.168.0.119', 25)
    ]
    assert conf.route.route("192.168.0.0-10") == ('enp3s0', '4.4.4.4', '0.0.0.0')
    assert conf.route.route("192.168.0.119") == ('lo', '192.168.0.119', '0.0.0.0')
    assert conf.route.route("224.0.0.0") == ('enp3s0', '1.1.1.1', '0.0.0.0')
    assert conf.route.route("255.255.255.255") == ('enp3s0', '192.168.0.119', '0.0.0.0')
    assert conf.route.route("*") == ('enp3s0', '192.168.0.119', '192.168.0.254')
finally:
    scapy.consts.LOOPBACK_INTERFACE = old_loopback
    conf.iface = old_iface
    conf.route.routes = old_routes
    conf.route.invalidate_cache()


= Mocked IPv6 routes calls

old_routes = conf.route6.routes
old_iface = conf.iface
old_loopback = scapy.consts.LOOPBACK_INTERFACE
try:
    conf.iface = 'enp3s0'
    scapy.consts.LOOPBACK_INTERFACE = 'lo'
    conf.route6.invalidate_cache()
    conf.route6.routes = [
        ('fe80::dd17:1fa6:a123:ab4', 128, '::', 'lo', ['fe80::dd17:1fa6:a123:ab4'], 291),
        ('fe80::7101:5678:1234:da65', 128, '::', 'enp3s0', ['fe80::7101:5678:1234:da65'], 281),
        ('fe80::1f:ae12:4d2c:abff', 128, '::', 'wlan0', ['fe80::1f:ae12:4d2c:abff'], 281),
        ('fe80::', 64, '::', 'wlan0', ['fe80::1f:ae12:4d2c:abff'], 281),
        ('fe80::', 64, '::', 'lo', ['fe80::dd17:1fa6:a123:ab4'], 291),
        ('fe80::', 64, '::', 'enp3s0', ['fe80::7101:5678:1234:da65'], 281),
        ('2a01:e35:1e06:ab56:7010:6548:9646:fa77', 128, '::', 'enp3s0', ['2a01:e35:1e06:ab56:7010:6548:9646:fa77', '2a01:e35:1e06:ab56:512:8bb7:8ab8:14a8'], 281),
        ('2a01:e35:1e06:ab56:512:8bb7:8ab8:14a8', 128, '::', 'enp3s0', ['2a01:e35:1e06:ab56:7010:6548:9646:fa77', '2a01:e35:1e06:ab56:512:8bb7:8ab8:14a8'], 281),
        ('2a01:e35:1e06:ab56::', 64, '::', 'enp3s0', ['2a01:e35:1e06:ab56:7010:6548:9646:fa77', '2a01:e35:1e06:ab56:512:8bb7:8ab8:14a8'], 281),
        ('::', 0, 'fe80::160c:64aa:ef6f:fe14', 'enp3s0', ['2a01:e35:1e06:ab56:7010:6548:9646:fa77', '2a01:e35:1e06:ab56:512:8bb7:8ab8:14a8'], 281)
    ]
    assert conf.route6.route("2a01:e35:1e06:ab56:512:8bb7:8ab8:14a8") == ('enp3s0', '2a01:e35:1e06:ab56:7010:6548:9646:fa77', '::')
    assert conf.route6.route("::1") == ('enp3s0', '2a01:e35:1e06:ab56:7010:6548:9646:fa77', 'fe80::160c:64aa:ef6f:fe14')
    assert conf.route6.route("ff02::1") == ('enp3s0', 'fe80::7101:5678:1234:da65', '::')
    assert conf.route6.route("fe80::1") == ('enp3s0', 'fe80::7101:5678:1234:da65', '::')
    assert conf.route6.route("fe80::1", dev='lo') == ('lo', 'fe80::dd17:1fa6:a123:ab4', '::')
finally:
    scapy.consts.LOOPBACK_INTERFACE = old_loopback
    conf.iface = old_iface
    conf.route6.routes = old_routes
    conf.route6.invalidate_cache()

= Windows: reset routes properly

if WINDOWS:
    route_add_loopback()

############
############
+ STP tests

= STP - Basic Instantiation
assert raw(STP()) == b'\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01\x00\x14\x00\x02\x00\x0f\x00'

= STP - Basic Dissection

s = STP(b'\x00\x00\x00\x00\x00\x00\x00\x12\x13\x14\x15\x16\x17\x00\x00\x00\x00\x00\x00\xaa\xaa\xaa\xaa\xaa\xaa\x00\x00\x01\x00\x14\x00\x05\x00\x0f\x00')
assert s.rootmac == "12:13:14:15:16:17"
assert s.bridgemac == "aa:aa:aa:aa:aa:aa"
assert s.hellotime == 5

############
############
+ EAPOL class tests

= EAPOL - Basic Instantiation
raw(EAPOL()) == b'\x01\x00\x00\x00'

= EAPOL - Instantiation with specific values
raw(EAPOL(version = 3, type = 5)) == b'\x03\x05\x00\x00'

= EAPOL - Dissection (1)
s = b'\x03\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00'
eapol = EAPOL(s)
assert(eapol.version == 3)
assert(eapol.type == 1)
assert(eapol.len == 0)

= EAPOL - Dissection (2)
s = b'\x03\x00\x00\x05\x01\x01\x00\x05\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00'
eapol = EAPOL(s)
assert(eapol.version == 3)
assert(eapol.type == 0)
assert(eapol.len == 5)

= EAPOL - Dissection (3)
s = b'\x03\x00\x00\x0e\x02\x01\x00\x0e\x01anonymous\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00'
eapol = EAPOL(s)
assert(eapol.version == 3)
assert(eapol.type == 0)
assert(eapol.len == 14)

= EAPOL - Dissection (4)
req = EAPOL(b'\x03\x00\x00\x05\x01\x01\x00\x05\x01')
ans = EAPOL(b'\x03\x00\x00\x0e\x02\x01\x00\x0e\x01anonymous')
ans.answers(req)

= EAPOL - Dissection (5)
s = b'\x02\x00\x00\x06\x01\x01\x00\x06\r '
eapol = EAPOL(s)
assert(eapol.version == 2)
assert(eapol.type == 0)
assert(eapol.len == 6)
assert(eapol.haslayer(EAP_TLS))

= EAPOL - Dissection (6)
s = b'\x03\x00\x00<\x02\x9e\x00<+\x01\x16\x03\x01\x001\x01\x00\x00-\x03\x01dr1\x93ZS\x0en\xad\x1f\xbaH\xbb\xfe6\xe6\xd0\xcb\xec\xd7\xc0\xd7\xb9\xa5\xc9\x0c\xfd\x98o\xa7T \x00\x00\x04\x004\x00\x00\x01\x00\x00\x00'
eapol = EAPOL(s)
assert(eapol.version == 3)
assert(eapol.type == 0)
assert(eapol.len == 60)
assert(eapol.haslayer(EAP_FAST))


############
############
+ EAPOL-MKA class tests

= EAPOL-MKA - With Basic parameter set - Dissection
eapol = None
s = b'\x03\x05\x00T\x01\xff\xf0<\x00Bh\xa8\x1e\x03\x00\n\xbcj\x00\x96Ywz\x82:\x90\xd9\xe7\x00\x00\x00\x01\x00\x80\xc2\x01\x11\x11\x11\x11\x11\x11\x11\x11\x11\x11\x11\x11\x11\x11\x11\x11\x11\x11\x11\x11\x11\x11\x11\x11\x11\x11\x11\x11\x11\x11\x11\x11\xff\x00\x00\x10\xe5\xf5j\x86V\\\xb1\xcc\xa9\xb95\x04m*Cj'
eapol = EAPOL(s)
assert(eapol.version == 3)
assert(eapol.type == 5)
assert(eapol.len == 84)
assert(eapol.haslayer(MKAPDU))
assert(eapol[MKAPDU].basic_param_set.actor_member_id == b"\xbcj\x00\x96Ywz\x82:\x90\xd9\xe7")
assert(eapol[MKAPDU].haslayer(MKAICVSet))
assert(eapol[MKAPDU][MKAICVSet].icv == b"\xe5\xf5j\x86V\\\xb1\xcc\xa9\xb95\x04m*Cj")


= EAPOL-MKA - With Potential Peer List parameter set - Dissection
eapol = None
s = b'\x03\x05\x00h\x01\x10\xe0<\xccN$\xc4\xf7\x7f\x00\x80q\x8b\x8a9\x86k/X\x14\xc9\xdc\xf6\x00\x00\x00}\x00\x80\xc2\x01\x11\x11\x11\x11\x11\x11\x11\x11\x11\x11\x11\x11\x11\x11\x11\x11\x11\x11\x11\x11\x11\x11\x11\x11\x11\x11\x11\x11\x11\x11\x11\x11\x02\x00\x00\x10\xbcj\x00\x96Ywz\x82:\x90\xd9\xe7\x00\x00\x00\x01\xff\x00\x00\x105\x01\xdc)\xfd\xd1\xff\xd55\x9c_o\xc9\x9c\xca\xc0'
eapol = EAPOL(s)
assert(eapol.version == 3)
assert(eapol.type == 5)
assert(eapol.len == 104)
assert(eapol.haslayer(MKAPDU))
assert(eapol[MKAPDU].basic_param_set.actor_member_id == b"q\x8b\x8a9\x86k/X\x14\xc9\xdc\xf6")
assert(eapol.haslayer(MKAPotentialPeerListParamSet))
assert(eapol[MKAPDU][MKAPotentialPeerListParamSet].member_id_message_num[0].member_id == b"\xbcj\x00\x96Ywz\x82:\x90\xd9\xe7")
assert(eapol[MKAPDU].haslayer(MKAICVSet))
assert(eapol[MKAPDU][MKAICVSet].icv == b"5\x01\xdc)\xfd\xd1\xff\xd55\x9c_o\xc9\x9c\xca\xc0")

= EAPOL-MKA - With Live Peer List parameter set - Dissection
eapol = None
s = b"\x03\x05\x00h\x01\xffp<\x00Bh\xa8\x1e\x03\x00\n\xbcj\x00\x96Ywz\x82:\x90\xd9\xe7\x00\x00\x00\x02\x00\x80\xc2\x01\x11\x11\x11\x11\x11\x11\x11\x11\x11\x11\x11\x11\x11\x11\x11\x11\x11\x11\x11\x11\x11\x11\x11\x11\x11\x11\x11\x11\x11\x11\x11\x11\x01\x00\x00\x10q\x8b\x8a9\x86k/X\x14\xc9\xdc\xf6\x00\x00\x00\x80\xff\x00\x00\x10\xf4\xa1d\x18\tD\xa2}\x8e'\x0c/\xda,\xea\xb7"
eapol = EAPOL(s)
assert(eapol.version == 3)
assert(eapol.type == 5)
assert(eapol.len == 104)
assert(eapol.haslayer(MKAPDU))
assert(eapol[MKAPDU].basic_param_set.actor_member_id == b'\xbcj\x00\x96Ywz\x82:\x90\xd9\xe7')
assert(eapol.haslayer(MKALivePeerListParamSet))
assert(eapol[MKAPDU][MKALivePeerListParamSet].member_id_message_num[0].member_id == b"q\x8b\x8a9\x86k/X\x14\xc9\xdc\xf6")
assert(eapol[MKAPDU].haslayer(MKAICVSet))
assert(eapol[MKAPDU][MKAICVSet].icv == b"\xf4\xa1d\x18\tD\xa2}\x8e'\x0c/\xda,\xea\xb7")

= EAPOL-MKA - With SAK Use parameter set - Dissection
eapol = None
s = b'\x03\x05\x00\x94\x01\xffp<\x00Bh\xa8\x1e\x03\x00\n\xbcj\x00\x96Ywz\x82:\x90\xd9\xe7\x00\x00\x00\x03\x00\x80\xc2\x01\x11\x11\x11\x11\x11\x11\x11\x11\x11\x11\x11\x11\x11\x11\x11\x11\x11\x11\x11\x11\x11\x11\x11\x11\x11\x11\x11\x11\x11\x11\x11\x11\x03\x10\x00(q\x8b\x8a9\x86k/X\x14\xc9\xdc\xf6\x00\x00\x00\x01\x00\x00\x00\x00q\x8b\x8a9\x86k/X\x14\xc9\xdc\xf6\x00\x00\x00\x01\x00\x00\x00\x00\x01\x00\x00\x10q\x8b\x8a9\x86k/X\x14\xc9\xdc\xf6\x00\x00\x00\x83\xff\x00\x00\x10OF\x84\xf1@%\x95\xe6Fw9\x1a\xfa\x03(\xae'
eapol = EAPOL(s)
assert(eapol.version == 3)
assert(eapol.type == 5)
assert(eapol.len == 148)
assert(eapol.haslayer(MKAPDU))
assert(eapol[MKAPDU].basic_param_set.actor_member_id == b'\xbcj\x00\x96Ywz\x82:\x90\xd9\xe7')
assert(eapol.haslayer(MKASAKUseParamSet))
assert(eapol[MKAPDU][MKASAKUseParamSet].latest_key_key_server_member_id == b"q\x8b\x8a9\x86k/X\x14\xc9\xdc\xf6")
assert(eapol.haslayer(MKALivePeerListParamSet))
assert(eapol[MKAPDU][MKALivePeerListParamSet].member_id_message_num[0].member_id == b"q\x8b\x8a9\x86k/X\x14\xc9\xdc\xf6")
assert(eapol[MKAPDU].haslayer(MKAICVSet))
assert(eapol[MKAPDU][MKAICVSet].icv == b"OF\x84\xf1@%\x95\xe6Fw9\x1a\xfa\x03(\xae")

= EAPOL-MKA - With Distributed SAK parameter set - Dissection
eapol = None
s = b"\x03\x05\x00\xb4\x01\x10\xe0<\xccN$\xc4\xf7\x7f\x00\x80q\x8b\x8a9\x86k/X\x14\xc9\xdc\xf6\x00\x00\x00\x81\x00\x80\xc2\x01\x11\x11\x11\x11\x11\x11\x11\x11\x11\x11\x11\x11\x11\x11\x11\x11\x11\x11\x11\x11\x11\x11\x11\x11\x11\x11\x11\x11\x11\x11\x11\x11\x01\x00\x00\x10\xbcj\x00\x96Ywz\x82:\x90\xd9\xe7\x00\x00\x00\x02\x03\x10\x00(q\x8b\x8a9\x86k/X\x14\xc9\xdc\xf6\x00\x00\x00\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x04\x10\x00\x1c\x00\x00\x00\x01Cz\x05\x88\x9f\xe8-\x94W+?\x13~\xfb\x016yVB?\xbd\xa1\x9fu\xff\x00\x00\x10\xb0H\xcf\xe0:\xa1\x94RD'\x03\xe67\xe1Ur"
eapol = EAPOL(s)
assert(eapol.version == 3)
assert(eapol.type == 5)
assert(eapol.len == 180)
assert(eapol.haslayer(MKAPDU))
assert(eapol[MKAPDU].basic_param_set.actor_member_id == b"q\x8b\x8a9\x86k/X\x14\xc9\xdc\xf6")
assert(eapol.haslayer(MKASAKUseParamSet))
assert(eapol[MKAPDU][MKASAKUseParamSet].latest_key_key_server_member_id == b"q\x8b\x8a9\x86k/X\x14\xc9\xdc\xf6")
assert(eapol.haslayer(MKALivePeerListParamSet))
assert(eapol[MKAPDU][MKALivePeerListParamSet].member_id_message_num[0].member_id == b"\xbcj\x00\x96Ywz\x82:\x90\xd9\xe7")
assert(eapol.haslayer(MKADistributedSAKParamSet))
assert(eapol[MKADistributedSAKParamSet].sak_aes_key_wrap == b"Cz\x05\x88\x9f\xe8-\x94W+?\x13~\xfb\x016yVB?\xbd\xa1\x9fu")
assert(eapol[MKAPDU].haslayer(MKAICVSet))
assert(eapol[MKAPDU][MKAICVSet].icv == b"\xb0H\xcf\xe0:\xa1\x94RD'\x03\xe67\xe1Ur")


############
############
############
+ EAP class tests

= EAP - Basic Instantiation
raw(EAP()) == b'\x04\x00\x00\x04'

= EAP - Instantiation with specific values
raw(EAP(code = 1, id = 1, len = 5, type = 1)) == b'\x01\x01\x00\x05\x01'

= EAP - Instantiation - Multiple desired authentication types
raw(EAP(code=2, type=3, desired_auth_types=[13,21,25,43])) == b'\x02\x00\x00\t\x03\r\x15\x19+'

= EAP - Dissection (1)
s = b'\x01\x01\x00\x05\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00'
eap = EAP(s)
assert(eap.code == 1)
assert(eap.id == 1)
assert(eap.len == 5)
assert(hasattr(eap, "type"))
assert(eap.type == 1)

= EAP - Dissection (2)
s = b'\x02\x01\x00\x0e\x01anonymous\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00'
eap = EAP(s)
assert(eap.code == 2)
assert(eap.id == 1)
assert(eap.len == 14)
assert(eap.type == 1)
assert(hasattr(eap, 'identity'))
assert(eap.identity == b'anonymous')

= EAP - Dissection (3)
s = b'\x01\x01\x00\x06\r '
eap = EAP(s)
assert(eap.code == 1)
assert(eap.id == 1)
assert(eap.len == 6)
assert(eap.type == 13)
assert(eap.haslayer(EAP_TLS))
assert(eap[EAP_TLS].L == 0)
assert(eap[EAP_TLS].M == 0)
assert(eap[EAP_TLS].S == 1)

= EAP - Dissection (4)
s = b'\x02\x01\x00\xd1\r\x00\x16\x03\x01\x00\xc6\x01\x00\x00\xc2\x03\x01UK\x02\xdf\x1e\xde5\xab\xfa[\x15\xef\xbe\xa2\xe4`\xc6g\xb9\xa8\xaa%vAs\xb2\x1cXt\x1c0\xb7\x00\x00P\xc0\x14\xc0\n\x009\x008\x00\x88\x00\x87\xc0\x0f\xc0\x05\x005\x00\x84\xc0\x12\xc0\x08\x00\x16\x00\x13\xc0\r\xc0\x03\x00\n\xc0\x13\xc0\t\x003\x002\x00\x9a\x00\x99\x00E\x00D\xc0\x0e\xc0\x04\x00/\x00\x96\x00A\xc0\x11\xc0\x07\xc0\x0c\xc0\x02\x00\x05\x00\x04\x00\x15\x00\x12\x00\t\x00\xff\x01\x00\x00I\x00\x0b\x00\x04\x03\x00\x01\x02\x00\n\x004\x002\x00\x0e\x00\r\x00\x19\x00\x0b\x00\x0c\x00\x18\x00\t\x00\n\x00\x16\x00\x17\x00\x08\x00\x06\x00\x07\x00\x14\x00\x15\x00\x04\x00\x05\x00\x12\x00\x13\x00\x01\x00\x02\x00\x03\x00\x0f\x00\x10\x00\x11\x00#\x00\x00\x00\x0f\x00\x01\x01'
eap = EAP(s)
assert(eap.code == 2)
assert(eap.id == 1)
assert(eap.len == 209)
assert(eap.type == 13)
assert(eap.haslayer(EAP_TLS))
assert(eap[EAP_TLS].L == 0)
assert(eap[EAP_TLS].M == 0)
assert(eap[EAP_TLS].S == 0)

= EAP - Dissection (5)
s = b'\x02\x9e\x00<+\x01\x16\x03\x01\x001\x01\x00\x00-\x03\x01dr1\x93ZS\x0en\xad\x1f\xbaH\xbb\xfe6\xe6\xd0\xcb\xec\xd7\xc0\xd7\xb9\xa5\xc9\x0c\xfd\x98o\xa7T \x00\x00\x04\x004\x00\x00\x01\x00\x00\x00'
eap = EAP(s)
assert(eap.code == 2)
assert(eap.id == 158)
assert(eap.len == 60)
assert(eap.type == 43)
assert(eap.haslayer(EAP_FAST))
assert(eap[EAP_FAST].L == 0)
assert(eap[EAP_FAST].M == 0)
assert(eap[EAP_FAST].S == 0)
assert(eap[EAP_FAST].version == 1)

= EAP - Dissection (6)
s = b'\x02\x9f\x01L+\x01\x16\x03\x01\x01\x06\x10\x00\x01\x02\x01\x00Y\xc9\x8a\tcw\t\xdcbU\xfd\x035\xcd\x1a\t\x10f&[(9\xf6\x88W`\xc6\x0f\xb3\x84\x15\x19\xf5\tk\xbd\x8fp&0\xb0\xa4B\x85\x0c<:s\xf2zT\xc3\xbd\x8a\xe4D{m\xe7\x97\xfe>\xda\x14\xb8T1{\xd7H\x9c\xa6\xcb\xe3,u\xdf\xe0\x82\xe5R\x1e<\xe5\x03}\xeb\x98\xe2\xf7\x8d3\xc6\x83\xac"\x8f\xd7\x12\xe5{:"\x84A\xd9\x14\xc2cZF\xd4\t\xab\xdar\xc7\xe0\x0e\x00o\xce\x05g\xdc?\xcc\xf7\xe83\x83E\xb3>\xe8<3-QB\xfd$C/\x1be\xcf\x03\xd6Q4\xbe\\h\xba)<\x99N\x89\xd9\xb1\xfa!\xd7a\xef\xa3\xd3o\xed8Uz\xb5k\xb0`\xfeC\xbc\xb3aS,d\xe6\xdc\x13\xa4A\x1e\x9b\r{\xd6s \xd0cQ\x95y\xc8\x1d\xc3\xd9\x87\xf2=\x81\x96q~\x99E\xc3\x97\xa8px\xe2\xc7\x92\xeb\xff/v\x84\x1e\xfb\x00\x95#\xba\xfb\xd88h\x90K\xa7\xbd9d\xb4\xf2\xf2\x14\x02vtW\xaa\xadY\x14\x03\x01\x00\x01\x01\x16\x03\x01\x000\x97\xc5l\xd6\xef\xffcM\x81\x90Q\x96\xf6\xfeX1\xf7\xfc\x84\xc6\xa0\xf6Z\xcd\xb6\xe1\xd4\xdb\x88\xf9t%Q!\xe7,~#2G-\xdf\x83\xbf\x86Q\xa2$'
eap = EAP(s)
assert(eap.code == 2)
assert(eap.id == 159)
assert(eap.len == 332)
assert(eap.type == 43)
assert(eap.haslayer(EAP_FAST))
assert(eap[EAP_FAST].L == 0)
assert(eap[EAP_FAST].M == 0)
assert(eap[EAP_FAST].S == 0)
assert(eap[EAP_FAST].version == 1)

= EAP - Dissection (7)
s = b'\x02\xf1\x00\t\x03\r\x15\x19+'
eap = EAP(s)
assert(eap.code == 2)
assert(eap.id == 241)
assert(eap.len == 9)
assert(eap.type == 3)
assert(hasattr(eap, 'desired_auth_types'))
assert(eap.desired_auth_types == [13,21,25,43])

= EAP - Dissection (8)
s = b"\x02\x03\x01\x15\x15\x00\x16\x03\x01\x01\n\x01\x00\x01\x06\x03\x03\xd5\xd9\xd5rT\x9e\xb8\xbe,>\xcf!\xcf\xc7\x02\x8c\xb1\x1e^F\xf7\xc84\x8c\x01t4\x91[\x02\xc8/\x00\x00\x8c\xc00\xc0,\xc0(\xc0$\xc0\x14\xc0\n\x00\xa5\x00\xa3\x00\xa1\x00\x9f\x00k\x00j\x00i\x00h\x009\x008\x007\x006\x00\x88\x00\x87\x00\x86\x00\x85\xc02\xc0.\xc0*\xc0&\xc0\x0f\xc0\x05\x00\x9d\x00=\x005\x00\x84\xc0/\xc0+\xc0'\xc0#\xc0\x13\xc0\t\x00\xa4\x00\xa2\x00\xa0\x00\x9e\x00g\x00@\x00?\x00>\x003\x002\x001\x000\x00\x9a\x00\x99\x00\x98\x00\x97\x00E\x00D\x00C\x00B\xc01\xc0-\xc0)\xc0%\xc0\x0e\xc0\x04\x00\x9c\x00<\x00/\x00\x96\x00A\x00\xff\x01\x00\x00Q\x00\x0b\x00\x04\x03\x00\x01\x02\x00\n\x00\x1c\x00\x1a\x00\x17\x00\x19\x00\x1c\x00\x1b\x00\x18\x00\x1a\x00\x16\x00\x0e\x00\r\x00\x0b\x00\x0c\x00\t\x00\n\x00\r\x00 \x00\x1e\x06\x01\x06\x02\x06\x03\x05\x01\x05\x02\x05\x03\x04\x01\x04\x02\x04\x03\x03\x01\x03\x02\x03\x03\x02\x01\x02\x02\x02\x03\x00\x0f\x00\x01\x01"
eap = EAP(s)
assert(eap.code == 2)
assert(eap.id == 3)
assert(eap.len == 277)
assert(eap.type == 21)
assert(eap.haslayer(EAP_TTLS))
assert(eap[EAP_TTLS].L == 0)
assert(eap[EAP_TTLS].M == 0)
assert(eap[EAP_TTLS].S == 0)
assert(eap[EAP_TTLS].version == 0)

= EAP - EAP_TLS - Basic Instantiation
raw(EAP_TLS()) == b'\x01\x00\x00\x06\r\x00'

= EAP - EAP_FAST - Basic Instantiation
raw(EAP_FAST()) == b'\x01\x00\x00\x06+\x00'

= EAP - EAP_TTLS - Basic Instantiation
raw(EAP_TTLS()) == b'\x01\x00\x00\x06\x15\x00'

= EAP - EAP_PEAP - Basic Instantiation
raw(EAP_PEAP()) == b'\x01\x00\x00\x06\x19\x01'

= EAP - EAP_MD5 - Basic Instantiation
raw(EAP_MD5()) == b'\x01\x00\x00\x06\x04\x00'

= EAP - EAP_MD5 - Request - Dissection (8)
s = b'\x01\x02\x00\x16\x04\x10\x86\xf9\x89\x94\x81\x01\xb3 nHh\x1b\x8d\xe7^\xdb\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00'
eap = EAP(s)
assert(eap.code == 1)
assert(eap.id == 2)
assert(eap.len == 22)
assert(eap.type == 4)
assert(eap.haslayer(EAP_MD5))
assert(eap[EAP_MD5].value_size == 16)
assert(eap[EAP_MD5].value == b'\x86\xf9\x89\x94\x81\x01\xb3 nHh\x1b\x8d\xe7^\xdb')
assert(eap[EAP_MD5].optional_name == b'')

= EAP - EAP_MD5 - Response - Dissection (9)
s = b'\x02\x02\x00\x16\x04\x10\xfd\x1e\xffe\xf5\x80y\xa8\xe3\xc8\xf1\xbd\xc2\x85\xae\xcf\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00'
eap = EAP(s)
assert(eap.code == 2)
assert(eap.id == 2)
assert(eap.len == 22)
assert(eap.type == 4)
assert(eap.haslayer(EAP_MD5))
assert(eap[EAP_MD5].value_size == 16)
assert(eap[EAP_MD5].value == b'\xfd\x1e\xffe\xf5\x80y\xa8\xe3\xc8\xf1\xbd\xc2\x85\xae\xcf')
assert(eap[EAP_MD5].optional_name == b'')

= EAP - LEAP - Basic Instantiation
raw(LEAP()) == b'\x01\x00\x00\x08\x11\x01\x00\x00'

= EAP - LEAP - Request - Dissection (10)
s = b'\x01D\x00\x1c\x11\x01\x00\x088\xb6\xd7\xa1E<!\x15supplicant-1'
eap = LEAP(s)
assert(eap.code == 1)
assert(eap.id == 68)
assert(eap.len == 28)
assert(eap.type == 17)
assert(eap.haslayer(LEAP))
assert(eap[LEAP].version == 1)
assert(eap[LEAP].count == 8)
assert(eap[LEAP].challenge_response == b'8\xb6\xd7\xa1E<!\x15')
assert(eap[LEAP].username == b"supplicant-1")

= EAP - LEAP - Response - Dissection (11)
s = b'\x02D\x00,\x11\x01\x00\x18\xb3\x82[\x82\x8a\xc8M*\xf3\xe7\xb3\xad,7\x8b\xbfG\x81\xda\xbf\xe6\xc1\x9b\x95supplicant-1'
eap = LEAP(s)
assert(eap.code == 2)
assert(eap.id == 68)
assert(eap.len == 44)
assert(eap.type == 17)
assert(eap.haslayer(LEAP))
assert(eap[LEAP].version == 1)
assert(eap[LEAP].count == 24)
assert(eap[LEAP].challenge_response == b'\xb3\x82[\x82\x8a\xc8M*\xf3\xe7\xb3\xad,7\x8b\xbfG\x81\xda\xbf\xe6\xc1\x9b\x95')
assert(eap[LEAP].username == b"supplicant-1")

= EAP - PEAP - Request - Dissection
s = b'\x01\x03\x00\x06\x19 '
eap = EAP_PEAP(s)
assert(eap.code == 1)
assert(eap.id == 3)
assert(eap.len == 6)
assert(eap.type == 25)
assert(eap.haslayer(EAP_PEAP))
assert(eap[EAP_PEAP].S == 1)
assert(eap[EAP_PEAP].version == 0)

= EAP - PEAP - Response - Dissection
s = b'\x02\x03\x008\x19\x01\x16\x03\x03\x00-\x01\x00\x00)\x03\x03Zt9\xb6\xdem\xb9\xd4\x00\xed\xa5Bp>\x9a9\x8a[\x91\xe1U\xfa\xb6H\xd1\xbd\x9b\xd5\xadl\rV\x00\x00\x02\x00/\x01\x00'
eap = EAP_PEAP(s)
assert(eap.code == 2)
assert(eap.id == 3)
assert(eap.len == 56)
assert(eap.type == 25)
assert(eap.haslayer(EAP_PEAP))
assert(eap[EAP_PEAP].S == 0)
assert(eap[EAP_PEAP].version == 1)
assert(hasattr(eap[EAP_PEAP], "tls_data"))

= EAP - Layers (1)
eap = EAP_MD5()
assert(EAP_MD5 in eap)
assert(not EAP_TLS in eap)
assert(not EAP_FAST in eap)
assert(not LEAP in eap)
assert(EAP in eap)
eap = EAP_TLS()
assert(EAP_TLS in eap)
assert(not EAP_MD5 in eap)
assert(not EAP_FAST in eap)
assert(not LEAP in eap)
assert(EAP in eap)
eap = EAP_FAST()
assert(EAP_FAST in eap)
assert(not EAP_MD5 in eap)
assert(not EAP_TLS in eap)
assert(not LEAP in eap)
assert(EAP in eap)
eap = EAP_TTLS()
assert(EAP_TTLS in eap)
assert(not EAP_MD5 in eap)
assert(not EAP_TLS in eap)
assert(not EAP_FAST in eap)
assert(not LEAP in eap)
assert(EAP in eap)
eap = EAP_PEAP()
assert(EAP_PEAP in eap)
assert(EAP in eap)
eap = LEAP()
assert(not EAP_MD5 in eap)
assert(not EAP_TLS in eap)
assert(not EAP_FAST in eap)
assert(LEAP in eap)
assert(EAP in eap)

= EAP - Layers (2)
eap = EAP_MD5()
assert(type(eap[EAP]) == EAP_MD5)
eap = EAP_TLS()
assert(type(eap[EAP]) == EAP_TLS)
eap = EAP_FAST()
assert(type(eap[EAP]) == EAP_FAST)
eap = EAP_TTLS()
assert(type(eap[EAP]) == EAP_TTLS)
eap = EAP_PEAP()
assert(type(eap[EAP]) == EAP_PEAP)
eap = LEAP()
assert(type(eap[EAP]) == LEAP)

= EAP - sessions (1)
p = IP()/TCP()/EAP()
l = PacketList(p)
s = l.sessions()  # Crashed on commit: e42ecdc54556c4852ca06b1a6da6c1ccbf3f522e
assert len(s) == 1

= EAP - sessions (2)
p = IP()/UDP()/EAP()
l = PacketList(p)
s = l.sessions()  # Crashed on commit: e42ecdc54556c4852ca06b1a6da6c1ccbf3f522e
assert len(s) == 1


############
############
+ NTP module tests

= NTP - Layers (1)
p = NTPHeader()
assert(NTPHeader in p)
assert(not NTPControl in p)
assert(not NTPPrivate in p)
assert(NTP in p)
p = NTPControl()
assert(not NTPHeader in p)
assert(NTPControl in p)
assert(not NTPPrivate in p)
assert(NTP in p)
p = NTPPrivate()
assert(not NTPHeader in p)
assert(not NTPControl in p)
assert(NTPPrivate in p)
assert(NTP in p)

= NTP - Layers (2)
p = NTPHeader()
assert(type(p[NTP]) == NTPHeader)
p = NTPControl()
assert(type(p[NTP]) == NTPControl)
p = NTPPrivate()
assert(type(p[NTP]) == NTPPrivate)

= NTP - sessions (1)
p = IP()/TCP()/NTP()
l = PacketList(p)
s = l.sessions()  # Crashed on commit: e42ecdc54556c4852ca06b1a6da6c1ccbf3f522e
assert len(s) == 1

= NTP - sessions (2)
p = IP()/UDP()/NTP()
l = PacketList(p)
s = l.sessions()  # Crashed on commit: e42ecdc54556c4852ca06b1a6da6c1ccbf3f522e
assert len(s) == 1

############
############
+ NTPHeader tests

= NTPHeader - Basic checks
len(raw(NTP())) == 48


= NTPHeader - Dissection
s = b"!\x0b\x06\xea\x00\x00\x00\x00\x00\x00\xf2\xc1\x7f\x7f\x01\x00\xdb9\xe8\xa21\x02\xe6\xbc\xdb9\xe8\x81\x02U8\xef\xdb9\xe8\x80\xdcl+\x06\xdb9\xe8\xa91\xcbI\xbf\x00\x00\x00\x01\xady\xf3\xa1\xe5\xfc\xd02\xd2j\x1e'\xc3\xc1\xb6\x0e"
p = NTP(s)
assert(isinstance(p, NTPHeader))
assert(p[NTPAuthenticator].key_id == 1)
assert(bytes_hex(p[NTPAuthenticator].dgst) == b'ad79f3a1e5fcd032d26a1e27c3c1b60e')


= NTPHeader - KoD
s = b'\xe4\x00\x06\xe8\x00\x00\x00\x00\x00\x00\x02\xcaINIT\x00\x00\x00\x00\x00\x00\x00\x00\xdb@\xe3\x9eH\xa3pj\xdb@\xe3\x9eH\xf0\xc3\\\xdb@\xe3\x9eH\xfaL\xac\x00\x00\x00\x01B\x86)\xc1Q4\x8bW8\xe7Q\xda\xd0Z\xbc\xb8'
p = NTP(s)
assert(isinstance(p, NTPHeader))
assert(p.leap == 3)
assert(p.version == 4)
assert(p.mode == 4)
assert(p.stratum == 0)
assert(p.ref_id == b'INIT')


= NTPHeader - Extension dissection test
s = b'#\x02\n\x00\x00\x00\x00\x00\x00\x00\x00\x00\x7f\x00\x00\x01\x00\x00\x00\x00\x00\x00\x00\x00\xdbM\xdf\x19e\x87\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xdbM\xdf\x19e\x89\xf0\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00'
p = NTP(s)
assert(isinstance(p, NTPHeader))
assert(p.leap == 0)
assert(p.version == 4)
assert(p.mode == 3)
assert(p.stratum == 2)


############
############
+ NTP Control (mode 6) tests

= NTP Control (mode 6) - CTL_OP_READSTAT (1) - request
s = b'\x16\x01\x00\x0c\x00\x00\x00\x00\x00\x00\x00\x00'
p = NTP(s)
assert(isinstance(p, NTPControl))
assert(p.version == 2)
assert(p.mode == 6)
assert(p.response == 0)
assert(p.err == 0)
assert(p.more == 0)
assert(p.op_code == 1)
assert(p.sequence == 12)
assert(p.status == 0)
assert(p.association_id == 0)
assert(p.offset == 0)
assert(p.count == 0)
assert(p.data == b'')


= NTP Control (mode 6) - CTL_OP_READSTAT (2) - response
s = b'\x16\x81\x00\x0c\x06d\x00\x00\x00\x00\x00\x04\xe5\xfc\xf6$'
p = NTP(s)
assert(isinstance(p, NTPControl))
assert(p.version == 2)
assert(p.mode == 6)
assert(p.response == 1)
assert(p.err == 0)
assert(p.more == 0)
assert(p.op_code == 1)
assert(p.sequence == 12)
assert(isinstance(p.status_word, NTPSystemStatusPacket))
assert(p.status_word.leap_indicator == 0)
assert(p.status_word.clock_source == 6)
assert(p.status_word.system_event_counter == 6)
assert(p.status_word.system_event_code == 4)
assert(p.association_id == 0)
assert(p.offset == 0)
assert(p.count == 4)
assert(isinstance(p.data, NTPPeerStatusDataPacket))
assert(p.data.association_id == 58876)
assert(isinstance(p.data.peer_status, NTPPeerStatusPacket))
assert(p.data.peer_status.configured == 1)
assert(p.data.peer_status.auth_enabled == 1)
assert(p.data.peer_status.authentic == 1)
assert(p.data.peer_status.reachability == 1)
assert(p.data.peer_status.reserved == 0)
assert(p.data.peer_status.peer_sel == 6)
assert(p.data.peer_status.peer_event_counter == 2)
assert(p.data.peer_status.peer_event_code == 4)


= NTP Control (mode 6) - CTL_OP_READVAR (1) - request
s = b'\x16\x02\x00\x12\x00\x00\xfc\x8f\x00\x00\x00\x00'
p = NTP(s)
assert(isinstance(p, NTPControl))
assert(p.version == 2)
assert(p.mode == 6)
assert(p.response == 0)
assert(p.op_code == 2)
assert(p.sequence == 18)
assert(p.status == 0)
assert(p.association_id == 64655)
assert(p.data == b'')


= NTP Control (mode 6) - CTL_OP_READVAR (2) - response (1st packet)
s = b'\xd6\xa2\x00\x12\xc0\x11\xfc\x8f\x00\x00\x01\xd4srcadr=192.168.122.1, srcport=123, dstadr=192.168.122.100, dstport=123,\r\nleap=3, stratum=16, precision=-24, rootdelay=0.000, rootdisp=0.000,\r\nrefid=INIT, reftime=0x00000000.00000000, rec=0x00000000.00000000,\r\nreach=0x0, unreach=5, hmode=1, pmode=0, hpoll=6, ppoll=10, headway=62,\r\nflash=0x1200, keyid=1, offset=0.000, delay=0.000, dispersion=15937.500,\r\njitter=0.000, xleave=0.240,\r\nfiltdelay= 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00,\r\nfiltoffset= 0.00 0.00 0.00 0.00 '
p = NTP(s)
assert(isinstance(p, NTPControl))
assert(p.version == 2)
assert(p.mode == 6)
assert(p.response == 1)
assert(p.err == 0)
assert(p.more == 1)
assert(p.op_code == 2)
assert(p.sequence == 18)
assert(isinstance(p.status_word, NTPPeerStatusPacket))
assert(p.status_word.configured == 1)
assert(p.status_word.auth_enabled == 1)
assert(p.status_word.authentic == 0)
assert(p.status_word.reachability == 0)
assert(p.status_word.peer_sel == 0)
assert(p.status_word.peer_event_counter == 1)
assert(p.status_word.peer_event_code == 1)
assert(p.association_id == 64655)
assert(p.offset == 0)
assert(p.count == 468)
assert(p.data.load == b'srcadr=192.168.122.1, srcport=123, dstadr=192.168.122.100, dstport=123,\r\nleap=3, stratum=16, precision=-24, rootdelay=0.000, rootdisp=0.000,\r\nrefid=INIT, reftime=0x00000000.00000000, rec=0x00000000.00000000,\r\nreach=0x0, unreach=5, hmode=1, pmode=0, hpoll=6, ppoll=10, headway=62,\r\nflash=0x1200, keyid=1, offset=0.000, delay=0.000, dispersion=15937.500,\r\njitter=0.000, xleave=0.240,\r\nfiltdelay= 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00,\r\nfiltoffset= 0.00 0.00 0.00 0.00 ')
 

= NTP Control (mode 6) - CTL_OP_READVAR (3) - response (2nd packet)
s = b'\xd6\x82\x00\x12\xc0\x11\xfc\x8f\x01\xd4\x00i0.00 0.00 0.00 0.00,\r\nfiltdisp= 16000.00 16000.00 16000.00 16000.00 16000.00 16000.00 16000.00 16000.00\r\n\x00\x00\x00'
p = NTP(s)
assert(isinstance(p, NTPControl))
assert(p.version == 2)
assert(p.mode == 6)
assert(p.response == 1)
assert(p.err == 0)
assert(p.more == 0)
assert(p.op_code == 2)
assert(p.sequence == 18)
assert(isinstance(p.status_word, NTPPeerStatusPacket))
assert(p.association_id == 64655)
assert(p.offset == 468)
assert(p.count == 105)
assert(p.data.load == b'0.00 0.00 0.00 0.00,\r\nfiltdisp= 16000.00 16000.00 16000.00 16000.00 16000.00 16000.00 16000.00 16000.00\r\n\x00\x00\x00')


= NTP Control (mode 6) - CTL_OP_READVAR (4) - request
s = b'\x16\x02\x00\x13\x00\x00s\xb5\x00\x00\x00\x0btest1,test2\x00\x00\x00\x00\x01=\xc2;\xc7\xed\xb9US9\xd6\x89\x08\xc8\xaf\xa6\x12'
p = NTP(s)
assert(isinstance(p, NTPControl))
assert(p.version == 2)
assert(p.mode == 6)
assert(p.response == 0)
assert(p.err == 0)
assert(p.more == 0)
assert(p.op_code == 2)
assert(len(p.data.load) == 12)
assert(p.authenticator.key_id == 1)
assert(bytes_hex(p.authenticator.dgst) == b'3dc23bc7edb9555339d68908c8afa612')


= NTP Control (mode 6) - CTL_OP_READVAR (5) - response
s = b'\xd6\xc2\x00\x13\x05\x00s\xb5\x00\x00\x00\x00\x00\x00\x00\x01\x97(\x02I\xdb\xa0s8\xedr(`\xdbJX\n'
p = NTP(s)
assert(isinstance(p, NTPControl))
assert(p.version == 2)
assert(p.mode == 6)
assert(p.response == 1)
assert(p.err == 1)
assert(p.more == 0)
assert(p.op_code == 2)
assert(len(p.data.load) == 0)
assert(p.authenticator.key_id == 1)
assert(bytes_hex(p.authenticator.dgst) == b'97280249dba07338ed722860db4a580a')


= NTP Control (mode 6) - CTL_OP_WRITEVAR (1) - request
s = b'\x16\x03\x00\x11\x00\x00\x00\x00\x00\x00\x00\x0btest1,test2\x00\x00\x00\x00\x01\xaf\xf1\x0c\xb4\xc9\x94m\xfcM\x90\tJ\xa1p\x94J'
p = NTP(s)
assert(isinstance(p, NTPControl))
assert(p.version == 2)
assert(p.mode == 6)
assert(p.response == 0)
assert(p.err == 0)
assert(p.more == 0)
assert(p.op_code == 3)
assert(len(p.data.load) == 12)
assert(p.authenticator.key_id == 1)
assert(bytes_hex(p.authenticator.dgst) == b'aff10cb4c9946dfc4d90094aa170944a')


= NTP Control (mode 6) - CTL_OP_WRITEVAR (2) - response
s = b'\xd6\xc3\x00\x11\x05\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01\x80z\x80\xfb\xaf\xc4pg\x98S\xa8\xe5xe\x81\x1c'
p = NTP(s)
assert(isinstance(p, NTPControl))
assert(p.version == 2)
assert(p.mode == 6)
assert(p.response == 1)
assert(p.err == 1)
assert(p.more == 0)
assert(p.op_code == 3)
assert(hasattr(p, 'status_word'))
assert(isinstance(p.status_word, NTPErrorStatusPacket))
assert(p.status_word.error_code == 5)
assert(len(p.data.load) == 0)
assert(p.authenticator.key_id == 1)
assert(bytes_hex(p.authenticator.dgst) == b'807a80fbafc470679853a8e57865811c')


= NTP Control (mode 6) - CTL_OP_CONFIGURE (1) - request
s = b'\x16\x08\x00\x16\x00\x00\x00\x00\x00\x00\x00\x0ccontrolkey 1\x00\x00\x00\x01\xea\xa7\xac\xa8\x1bj\x9c\xdbX\xe1S\r6\xfb\xef\xa4'
p = NTP(s)
assert(isinstance(p, NTPControl))
assert(p.version == 2)
assert(p.mode == 6)
assert(p.response == 0)
assert(p.err == 0)
assert(p.more == 0)
assert(p.op_code == 8)
assert(p.count == 12)
assert(p.data.load == b'controlkey 1')
assert(p.authenticator.key_id == 1)
assert(bytes_hex(p.authenticator.dgst) == b'eaa7aca81b6a9cdb58e1530d36fbefa4')


= NTP Control (mode 6) - CTL_OP_CONFIGURE (2) - response
s = b'\xd6\x88\x00\x16\x00\x00\x00\x00\x00\x00\x00\x12Config Succeeded\r\n\x00\x00\x00\x00\x00\x01\xbf\xa6\xd8_\xf9m\x1e2l)<\xac\xee\xc2\xa59'
p = NTP(s)
assert(isinstance(p, NTPControl))
assert(p.version == 2)
assert(p.mode == 6)
assert(p.response == 1)
assert(p.err == 0)
assert(p.more == 0)
assert(p.op_code == 8)
assert(p.count == 18)
assert(p.data.load == b'Config Succeeded\r\n\x00\x00')
assert(p.authenticator.key_id == 1)
assert(bytes_hex(p.authenticator.dgst) == b'bfa6d85ff96d1e326c293caceec2a539')


= NTP Control (mode 6) - CTL_OP_SAVECONFIG (1) - request
s = b'\x16\t\x00\x1d\x00\x00\x00\x00\x00\x00\x00\x0fntp.test.2.conf\x00\x00\x00\x00\x00\x00\x00\x00\x01\xc9\xfb\x8a\xbe<`_\xfa6\xd2\x18\xc3\xb7d\x89#'
p = NTP(s)
assert(isinstance(p, NTPControl))
assert(p.version == 2)
assert(p.mode == 6)
assert(p.response == 0)
assert(p.err == 0)
assert(p.more == 0)
assert(p.op_code == 9)
assert(p.count == 15)
assert(p.data.load == b'ntp.test.2.conf\x00')
assert(p.authenticator.key_id == 1)
assert(bytes_hex(p.authenticator.dgst) == b'c9fb8abe3c605ffa36d218c3b7648923')


= NTP Control (mode 6) - CTL_OP_SAVECONFIG (2) - response
s = b"\xd6\x89\x00\x1d\x00\x00\x00\x00\x00\x00\x00*Configuration saved to 'ntp.test.2.conf'\r\n\x00\x00\x00\x00\x00\x012\xc2\xbaY\xc53\xfe(\xf5P\xe5\xa0\x86\x02\x95\xd9"
p = NTP(s)
assert(isinstance(p, NTPControl))
assert(p.version == 2)
assert(p.mode == 6)
assert(p.response == 1)
assert(p.err == 0)
assert(p.more == 0)
assert(p.op_code == 9)
assert(p.count == 42)
assert(p.data.load == b"Configuration saved to 'ntp.test.2.conf'\r\n\x00\x00")
assert(p.authenticator.key_id == 1)
assert(bytes_hex(p.authenticator.dgst) == b'32c2ba59c533fe28f550e5a0860295d9')


= NTP Control (mode 6) - CTL_OP_REQ_NONCE (1) - request
s = b'\x16\x0c\x00\x07\x00\x00\x00\x00\x00\x00\x00\x00'
p = NTP(s)
assert(isinstance(p, NTPControl))
assert(p.version == 2)
assert(p.mode == 6)
assert(p.response == 0)
assert(p.err == 0)
assert(p.more == 0)
assert(p.op_code == 12)
assert(p.data == b'')
assert(p.authenticator == b'')


= NTP Control (mode 6) - CTL_OP_REQ_NONCE (2) - response
s = b'\xd6\x8c\x00\x07\x00\x00\x00\x00\x00\x00\x00 nonce=db4186a2e1d9022472e24bc9\r\n'
p = NTP(s)
assert(isinstance(p, NTPControl))
assert(p.version == 2)
assert(p.mode == 6)
assert(p.response == 1)
assert(p.err == 0)
assert(p.more == 0)
assert(p.op_code == 12)
assert(p.data.load == b'nonce=db4186a2e1d9022472e24bc9\r\n')
assert(p.authenticator == b'')


= NTP Control (mode 6) - CTL_OP_READ_MRU (1) - request
s = b'\x16\n\x00\x08\x00\x00\x00\x00\x00\x00\x00(nonce=db4186a2e1d9022472e24bc9, frags=32'
p = NTP(s)
assert(isinstance(p, NTPControl))
assert(p.version == 2)
assert(p.mode == 6)
assert(p.response == 0)
assert(p.err == 0)
assert(p.op_code == 10)
assert(p.count == 40)
assert(p.data.load == b'nonce=db4186a2e1d9022472e24bc9, frags=32')
assert(p.authenticator == b'')

= NTP Control (mode 6) - CTL_OP_READ_MRU (2) - response
s = b'\xd6\x8a\x00\x08\x00\x00\x00\x00\x00\x00\x00\xe9nonce=db4186a2e2073198b93c6419, addr.0=192.168.122.100:123,\r\nfirst.0=0xdb418673.323e1a89, last.0=0xdb418673.323e1a89, ct.0=1,\r\nmv.0=36, rs.0=0x0, WWQ.0=18446744073709509383, now=0xdb4186a2.e20ff8f4,\r\nlast.newest=0xdb418673.323e1a89\r\n\x00\x00\x00'
p = NTP(s)
assert(isinstance(p, NTPControl))
assert(p.version == 2)
assert(p.mode == 6)
assert(p.response == 1)
assert(p.err == 0)
assert(p.op_code == 10)
assert(p.count == 233)
assert(p.data.load == b'nonce=db4186a2e2073198b93c6419, addr.0=192.168.122.100:123,\r\nfirst.0=0xdb418673.323e1a89, last.0=0xdb418673.323e1a89, ct.0=1,\r\nmv.0=36, rs.0=0x0, WWQ.0=18446744073709509383, now=0xdb4186a2.e20ff8f4,\r\nlast.newest=0xdb418673.323e1a89\r\n\x00\x00\x00')
assert(p.authenticator == b'')


############
############
+ NTP Private (mode 7) tests

= NTP Private (mode 7) - error - Dissection
s = b'\x97\x00\x03\x1d@\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00'
p = NTP(s)
assert(isinstance(p, NTPPrivate))
assert(p.response == 1)
assert(p.version == 2)
assert(p.mode == 7)
assert(p.request_code == 29)
assert(p.err == 4)
assert(p.nb_items == 0)
assert(p.data_item_size == 0)


= NTP Private (mode 7) - REQ_PEER_LIST (1) - request
s = b'\x17\x00\x03\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00'
p = NTP(s)
assert(isinstance(p, NTPPrivate))
assert(p.response == 0)
assert(p.version == 2)
assert(p.mode == 7)
assert(p.request_code == 0)
assert(p.nb_items == 0)
assert(p.data_item_size == 0)


= NTP Private (mode 7) - REQ_PEER_LIST (2) - response
s = b'\x97\x00\x03\x00\x00\x01\x00 \x7f\x7f\x01\x00\x00{\x03\x83\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00'
p = NTP(s)
assert(isinstance(p, NTPPrivate))
assert(p.response == 1)
assert(p.version == 2)
assert(p.mode == 7)
assert(p.request_code == 0)
assert(p.nb_items == 1)
assert(p.data_item_size == 32)
assert(type(p.data[0]) == NTPInfoPeerList)
assert(p.data[0].addr) == "127.127.1.0"
assert(p.data[0].port) == 123


= NTP Private (mode 7) - REQ_PEER_INFO (1) - request
s = b'\x17\x00\x03\x02\x00\x01\x00 \xc0\xa8zf\x00{\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00'
p = NTP(s)
assert(isinstance(p, NTPPrivate))
assert(p.response == 0)
assert(p.version == 2)
assert(p.mode == 7)
assert(p.request_code == 2)
assert(p.nb_items == 1)
assert(p.data_item_size == 32)
assert(isinstance(p.req_data[0], NTPInfoPeerList))
assert(p.req_data[0].addr == "192.168.122.102")
assert(p.req_data[0].port == 123)


= NTP Private (mode 7) - REQ_PEER_INFO (2) - response
s = b'\x97\x00\x03\x02\x00\x01\x01\x18\xc0\xa8zf\xc0\xa8ze\x00{\x01\x03\x01\x00\x10\x06\n\xea\x04\x00\x00\xaf"\x00"\x16\x04\xb3\x01\x00\x00\x00\x00\x00\x00\x00INIT\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01\x82\x9d\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xdb<\x8d\xc5\xde\x7fB\x89\xdb<\x8d\xc5\xde\x7fB\x89\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01\x02\x03\x04\x05\x06\x07\x00\x00\x00\x00\x00\x03\xfd\xff\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00'
p = NTP(s)
assert(isinstance(p, NTPPrivate))
assert(p.response == 1)
assert(p.version == 2)
assert(p.mode == 7)
assert(p.request_code == 2)
assert(isinstance(p.data[0], NTPInfoPeer))
assert(p.data[0].dstaddr == "192.168.122.102")
assert(p.data[0].srcaddr == "192.168.122.101")
assert(p.data[0].srcport == 123)
assert(p.data[0].associd == 1203)
assert(p.data[0].keyid == 1)


= NTP Private (mode 7) - REQ_PEER_LIST_SUM (1) - request
s = b'\x17\x00\x03\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00'
p = NTP(s)
assert(isinstance(p, NTPPrivate))
assert(p.response == 0)
assert(p.version == 2)
assert(p.mode == 7)
assert(p.request_code == 1)


= NTP Private (mode 7) - REQ_PEER_LIST_SUM (2) - response (1st packet)
s = b'\xd7\x00\x03\x01\x00\x06\x00H\n\x00\x02\x0f\xc0\x00\x02\x01\x00{\x10\x06\n\x00\x01\x03\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x03\xfd\xff\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\n\x00\x02\x0f\xc0\x00\x02\x02\x00{\x10\x06\n\x00\x01\x03\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x03\xfd\xff\x00\x00\x00\x00\x00\x00\x01\x02\x01\x01\x01\x01\x01\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\n\x00\x02\x0f\xc0\xa8d\x01\x00{\x10\x07\n\x00\x01\x03\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x03\xfd\xff\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01eth0\xc0\xa8zg\x00{\x01\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\n\x00\x02\x0f\xc0\xa8d\x02\x00{\x10\x07\n\x00\x01\x03\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x03\xfd\xff\x00\x00\x00\x00\x00\x00\x00\x02\xc0\xa8zh\x00{\x01\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01\n\x00\x02\x0f\xc0\xa8d\r\x00{\x10\x07\n\x00\x01\x03\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x03\xfd\xff\x00\x00\x00\x00\x00{\x01\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xc0\xa8zk\x00{\x01\x01\xc0\xa8ze\xc0\xa8zf\x00{\x0b\x06\x07\xf4\x83\x01\x00\x00\x07\x89\x00\x00\x00\x007\xb1\x00h\x00\x00o?\x00\x00\x00\x00\x00\x00\x00\x00\x00\n\x00\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xc0\xa8zm\x00{\x01\x01\x00\x00\x00\x00\x00\x00\x00\x00'
p = NTP(s)
assert(isinstance(p, NTPPrivate))
assert(p.response == 1)
assert(p.more == 1)
assert(p.version == 2)
assert(p.mode == 7)
assert(p.request_code == 1)
assert(isinstance(x, NTPInfoPeerSummary) for x in p.data)
assert(p.data[0].srcaddr == "192.0.2.1")


= NTP Private (mode 7) - REQ_PEER_LIST_SUM (3) - response (2nd packet)
s = b'\xd7\x01\x03\x01\x00\x06\x00H\xc0\xa8ze\xc0\xa8zg\x00{\x10\x08\n\x00\x01\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x03\xfd\xff\x00\x00\x00\x00\xff\xff\xff\xff\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01eth1\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xc0\xa8ze\xc0\xa8zg\x00{\x10\x08\n\x00\x11\x03\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x03\xfd\xff\x00\x00\x00\x00\x00\x00\x01\x02\x01\x01\x01\x01\x01\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xc0\xa8ze\xc0\xa8zh\x00{\x10\x08\n\x00\x01\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x03\xfd\xff\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01eth0\xc0\xa8zg\x00{\x01\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xc0\xa8ze\xc0\xa8zi\x00{\x10\x07\n\x00\x01\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x03\xfd\xff\x00\x00\x00\x00\x00\x00\x00\x02\xc0\xa8zh\x00{\x01\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01\xc0\xa8ze\xc0\xa8zj\x00{\x10\x07\n\x00\x01\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x03\xfd\xff\x00\x00\x00\x00\x00{\x01\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xc0\xa8zk\x00{\x01\x01\xc0\xa8ze\xc0\xa8zk\x00{\x10\x07\n\x00\x01\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x03\xfd\xff\x00\x00\x00\x00\x00\x00\x00\x00\x00\n\x00\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xc0\xa8zm\x00{\x01\x01\x00\x00\x00\x00\x00\x00\x00\x00'
p = NTP(s)

assert(isinstance(p, NTPPrivate))
assert(p.response == 1)
assert(p.more == 1)
assert(p.version == 2)
assert(p.mode == 7)
assert(p.request_code == 1)
assert(isinstance(x, NTPInfoPeerSummary) for x in p.data)
assert(p.data[0].srcaddr == "192.168.122.103")


= NTP Private (mode 7) - REQ_PEER_LIST_SUM (3) - response (3rd packet)
s = b'\x97\x02\x03\x01\x00\x02\x00H\xc0\xa8ze\xc0\xa8zl\x00{\x10\x07\n\x00\x01\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x03\xfd\xff\x00\x00\x00\x00\xff\xff\xff\xff\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01eth1\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xc0\xa8ze\xc0\xa8zm\x00{\x10\x07\n\x00\x01\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x03\xfd\xff\x00\x00\x00\x00\x00\x00\x01\x02\x01\x01\x01\x01\x01\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00'
p = NTP(s)

assert(isinstance(p, NTPPrivate))
assert(p.response == 1)
assert(p.more == 0)
assert(p.version == 2)
assert(p.mode == 7)
assert(p.request_code == 1)
assert(isinstance(x, NTPInfoPeerSummary) for x in p.data)
assert(p.data[0].srcaddr == "192.168.122.108")


= NTP Private (mode 7) - REQ_PEER_STATS (1) - request
s = b'\x17\x00\x03\x03\x00\x01\x00 \xc0\xa8ze\x00{\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00'
p = NTP(s)
assert(isinstance(p, NTPPrivate))
assert(p.response == 0)
assert(p.more == 0)
assert(p.version == 2)
assert(p.mode == 7)
assert(p.request_code == 3)
assert(isinstance(p.req_data[0], NTPInfoPeerList))


= NTP Private (mode 7) - REQ_PEER_STATS (2) - response
s = b'\x97\x00\x03\x03\x00\x01\x00x\xc0\xa8zf\xc0\xa8ze\x00{\x00\x01\x01\x00\x10\x06\x00\x00\x00)\x00\x00\x00\x1e\x00\x02\xda|\x00\x00\x00\xbc\x00\x00\x00\x00\x00\x00\x0b\x07\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\nJ\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x0b\x07\x00\x00\x00\x00\xde\x7fB\x89\x00<\x8d\xc5\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00'
p = NTP(s)

assert(isinstance(p, NTPPrivate))
assert(p.response == 1)
assert(p.more == 0)
assert(p.version == 2)
assert(p.mode == 7)
assert(p.request_code == 3)
assert(isinstance(x, NTPInfoPeerStats) for x in p.data)


= NTP Private (mode 7) - REQ_SYS_INFO (1) - request
s = b'\x17\x00\x03\x04\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00'
p = NTP(s)

assert(isinstance(p, NTPPrivate))
assert(p.response == 0)
assert(p.more == 0)
assert(p.version == 2)
assert(p.mode == 7)
assert(p.request_code == 4)


= NTP Private (mode 7) - REQ_SYS_INFO (2) - response
s = b'\x97\x00\x03\x04\x00\x01\x00P\x7f\x7f\x01\x00\x03\x00\x0b\xf0\x00\x00\x00\x00\x00\x00\x03\x06\x7f\x7f\x01\x00\xdb<\xca\xf3\xa1\x92\xe1\xf7\x06\x00\x00\x00\xce\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x0b\x07\x00\x00\x00\x00\xde\x7fB\x89\x00<\x8d\xc5'
p = NTP(s)

assert(isinstance(p, NTPPrivate))
assert(p.response == 1)
assert(p.more == 0)
assert(p.version == 2)
assert(p.mode == 7)
assert(p.request_code == 4)
assert(isinstance(p.data[0], NTPInfoSys))
assert(p.data[0].peer == "127.127.1.0")
assert(p.data[0].peer_mode == 3)
assert(p.data[0].leap == 0)
assert(p.data[0].stratum == 11)
assert(p.data[0].precision == 240)
assert(p.data[0].refid == "127.127.1.0")


= NTP Private (mode 7) - REQ_SYS_STATS (1) - request
s = b'\x17\x00\x03\x05\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00'
p = NTP(s)
assert(isinstance(p, NTPPrivate))
assert(p.response == 0)
assert(p.more == 0)
assert(p.version == 2)
assert(p.mode == 7)
assert(p.request_code == 5)


= NTP Private (mode 7) - REQ_SYS_STATS (2) - response
s = b'\x97\x00\x03\x05\x00\x01\x00,\x00\x02\xe2;\x00\x02\xe2;\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x0b%\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x0b%\x00\x00\x00\x00\x00\x00\x0b=\x00\x00\x00\x00'
p = NTP(s)
assert(isinstance(p, NTPPrivate))
assert(p.response == 1)
assert(p.more == 0)
assert(p.version == 2)
assert(p.mode == 7)
assert(p.request_code == 5)
assert(isinstance(p.data[0], NTPInfoSysStats))
assert(p.data[0].timeup == 188987)
assert(p.data[0].received == 2877)


= NTP Private (mode 7) - REQ_IO_STATS (1) - request
s = b'\x17\x00\x03\x06\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00'
p = NTP(s)
assert(isinstance(p, NTPPrivate))
assert(p.response == 0)
assert(p.more == 0)
assert(p.version == 2)
assert(p.mode == 7)
assert(p.request_code == 6)


= NTP Private (mode 7) - REQ_IO_STATS (2) - response
s = b'\x97\x00\x03\x06\x00\x01\x00(\x00\x00\x03\x04\x00\n\x00\t\x00\x00\x00\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00J\x00\x00\x00\xd9\x00\x00\x00\x00\x00\x00\x00J\x00\x00\x00J'
p = NTP(s)
assert(isinstance(p, NTPPrivate))
assert(p.response == 1)
assert(p.more == 0)
assert(p.version == 2)
assert(p.mode == 7)
assert(p.request_code == 6)
assert(p.data[0].timereset == 772)
assert(p.data[0].sent == 217)


= NTP Private (mode 7) - REQ_MEM_STATS (1) - request
s = b'\x17\x00\x03\x07\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00'
p = NTP(s)
assert(isinstance(p, NTPPrivate))
assert(p.response == 0)
assert(p.more == 0)
assert(p.version == 2)
assert(p.mode == 7)
assert(p.request_code == 7)


= NTP Private (mode 7) - REQ_MEM_STATS (2) - response
s = b'\x97\x00\x03\x07\x00\x01\x00\x94\x00\x00\n\xee\x00\x0f\x00\r\x00\x00\x00<\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00'
p = NTP(s)
assert(isinstance(p, NTPPrivate))
assert(p.response == 1)
assert(p.more == 0)
assert(p.version == 2)
assert(p.mode == 7)
assert(p.request_code == 7)
assert(p.data[0].timereset == 2798)
assert(p.data[0].totalpeermem == 15)
assert(p.data[0].freepeermem == 13)
assert(p.data[0].findpeer_calls == 60)
assert(p.data[0].hashcount[25] == 1 and p.data[0].hashcount[89] == 1)


= NTP Private (mode 7) - REQ_LOOP_INFO (1) - request
s = b'\x17\x00\x03\x08\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00'
p = NTP(s)
assert(isinstance(p, NTPPrivate))
assert(p.response == 0)
assert(p.more == 0)
assert(p.version == 2)
assert(p.mode == 7)
assert(p.request_code == 8)


= NTP Private (mode 7) - REQ_LOOP_INFO (2) - response
s = b'\x97\x00\x03\x08\x00\x01\x00\x18\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x06\x00\x00\x00\x04'
p = NTP(s)
assert(isinstance(p, NTPPrivate))
assert(p.response == 1)
assert(p.more == 0)
assert(p.version == 2)
assert(p.mode == 7)
assert(p.request_code == 8)
assert(p.data[0].last_offset == 0.0)
assert(p.data[0].watchdog_timer == 4)



= NTP Private (mode 7) - REQ_TIMER_STATS (1) - request
s = b'\x17\x00\x03\t\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00'
p = NTP(s)
assert(isinstance(p, NTPPrivate))
assert(p.response == 0)
assert(p.more == 0)
assert(p.version == 2)
assert(p.mode == 7)
assert(p.request_code == 9)


= NTP Private (mode 7) - REQ_TIMER_STATS (2) - response
s = b'\x97\x00\x03\t\x00\x01\x00\x10\x00\x00\x01h\x00\x00\x01h\x00\x00\x00\x00\x00\x00\x00\x00'
p = NTP(s)
assert(isinstance(p, NTPPrivate))
assert(p.response == 1)
assert(p.more == 0)
assert(p.version == 2)
assert(p.mode == 7)
assert(p.request_code == 9)
assert(p.data[0].timereset == 360)
assert(p.data[0].alarms == 360)


= NTP Private (mode 7) - REQ_CONFIG (1) - request
s = b'\x17\x80\x03\n\x00\x01\x00\xa8\xc0\xa8zm\x01\x03\x06\n\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xdb9\xec\x93\xb1\xa8\xa0a\x00\x00\x00\x01Z\xba\xfe\x01\x1cr\x05d\xa1\x14\xb1)\xe9vD\x8d'
p = NTP(s)
assert(isinstance(p, NTPPrivate))
assert(p.response == 0)
assert(p.more == 0)
assert(p.version == 2)
assert(p.mode == 7)
assert(p.request_code == 10)
assert(p.nb_items == 1)
assert(p.data_item_size == 168)
assert(hasattr(p, 'req_data'))
assert(isinstance(p.req_data[0], NTPConfPeer))
assert(p.req_data[0].peeraddr == "192.168.122.109")
assert(p.req_data[0].hmode == 1)
assert(p.req_data[0].version == 3)
assert(p.req_data[0].minpoll == 6)
assert(p.req_data[0].maxpoll == 10)
assert(hasattr(p, 'authenticator'))
assert(p.authenticator.key_id == 1)
assert(bytes_hex(p.authenticator.dgst) == b'5abafe011c720564a114b129e976448d')


= NTP Private (mode 7) - REQ_CONFIG (2) - response
s = b'\x97\x00\x03\n\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00'
p = NTP(s)
assert(isinstance(p, NTPPrivate))
assert(p.response == 1)
assert(p.more == 0)
assert(p.version == 2)
assert(p.mode == 7)
assert(p.auth == 0)
assert(p.request_code == 10)
assert(p.err == 0)
assert(p.nb_items == 0)
assert(p.data_item_size == 0)


= NTP Private (mode 7) - REQ_UNCONFIG (1) - request
s = b'\x17\x80\x03\x0b\x00\x01\x00\x18\xc0\xa8zk\x00\x00\x00\x00X\x88P\xb1\xff\x7f\x00\x008\x88P\xb1\xff\x7f\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xdb9\xf0\x1bq\xc8\xe5\xa6\x00\x00\x00\x01\x1dM;\xfeZ~]Z\xe3Ea\x92\x9aE\xd8%'
p = NTP(s)
assert(isinstance(p, NTPPrivate))
assert(p.response == 0)
assert(p.more == 0)
assert(p.version == 2)
assert(p.mode == 7)
assert(p.request_code == 11)
assert(p.nb_items == 1)
assert(p.data_item_size == 24)
assert(hasattr(p, 'req_data'))
assert(isinstance(p.req_data[0], NTPConfUnpeer))
assert(p.req_data[0].peeraddr == "192.168.122.107")
assert(p.req_data[0].v6_flag == 0)
assert(hasattr(p, 'authenticator'))
assert(p.authenticator.key_id == 1)
assert(bytes_hex(p.authenticator.dgst) == b'1d4d3bfe5a7e5d5ae34561929a45d825')


= NTP Private (mode 7) - REQ_UNCONFIG (2) - response
s = b'\x97\x00\x03\x0b\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00'
p = NTP(s)
assert(isinstance(p, NTPPrivate))
assert(p.response == 1)
assert(p.more == 0)
assert(p.version == 2)
assert(p.mode == 7)
assert(p.auth == 0)
assert(p.request_code == 11)
assert(p.err == 0)
assert(p.nb_items == 0)
assert(p.data_item_size == 0)


= NTP Private (mode 7) - REQ_RESADDFLAGS (1) - request
s = b'\x17\x80\x03\x11\x00\x01\x000\xc0\xa8zi\xff\xff\xff\xff\x04\x00\x00\x00\x00\x00\x00\x00"\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xdb9\xf0V\xa9"\xe6_\x00\x00\x00\x01>=\xb70Tp\xee\xae\xe1\xad4b\xef\xe3\x80\xc8'
p = NTP(s)
assert(isinstance(p, NTPPrivate))
assert(p.response == 0)
assert(p.more == 0)
assert(p.version == 2)
assert(p.mode == 7)
assert(p.request_code == 17)
assert(p.nb_items == 1)
assert(p.data_item_size == 48)
assert(hasattr(p, 'req_data'))
assert(isinstance(p.req_data[0], NTPConfRestrict))
assert(p.req_data[0].addr == "192.168.122.105")
assert(p.req_data[0].mask == "255.255.255.255")
assert(hasattr(p, 'authenticator'))
assert(p.authenticator.key_id == 1)
assert(bytes_hex(p.authenticator.dgst) == b'3e3db7305470eeaee1ad3462efe380c8')


= NTP Private (mode 7) - REQ_RESSUBFLAGS (1) - request
s = b'\x17\x80\x03\x12\x00\x01\x000\xc0\xa8zi\xff\xff\xff\xff\x00\x10\x00\x00\x00\x00\x00\x00"\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xdb9\xf0F\xe0C\xa9@\x00\x00\x00\x01>e\r\xdf\xdb\x1e1h\xd0\xca)L\x07k\x90\n'
p = NTP(s)
assert(isinstance(p, NTPPrivate))
assert(p.response == 0)
assert(p.more == 0)
assert(p.version == 2)
assert(p.mode == 7)
assert(p.request_code == 18)
assert(p.nb_items == 1)
assert(p.data_item_size == 48)
assert(hasattr(p, 'req_data'))
assert(isinstance(p.req_data[0], NTPConfRestrict))
assert(p.req_data[0].addr == "192.168.122.105")
assert(p.req_data[0].mask == "255.255.255.255")
assert(hasattr(p, 'authenticator'))
assert(p.authenticator.key_id == 1)
assert(bytes_hex(p.authenticator.dgst) == b'3e650ddfdb1e3168d0ca294c076b900a')


= NTP Private (mode 7) - REQ_RESET_PEER (1) - request
s = b"\x17\x80\x03\x16\x00\x01\x00\x18\xc0\xa8zf\x00\x00\x00\x00X\x88P\xb1\xff\x7f\x00\x008\x88P\xb1\xff\x7f\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xdb9\xef!\x99\x88\xa3\xf1\x00\x00\x00\x01\xb1\xff\xe8\xefB=\xa9\x96\xdc\xe3\x13'\xb3\xfc\xc2\xf5"
p = NTP(s)
assert(isinstance(p, NTPPrivate))
assert(p.response == 0)
assert(p.more == 0)
assert(p.version == 2)
assert(p.mode == 7)
assert(p.request_code == 22)
assert(p.nb_items == 1)
assert(p.data_item_size == 24)
assert(hasattr(p, 'req_data'))
assert(isinstance(p.req_data[0], NTPConfUnpeer))
assert(p.req_data[0].peeraddr == "192.168.122.102")
assert(p.req_data[0].v6_flag == 0)


= NTP Private (mode 7) - REQ_AUTHINFO (1) - response
s = b'\x97\x00\x03\x1c\x00\x01\x00$\x00\x00\x01\xdd\x00\x00\x00\x02\x00\x00\x00\n\x00\x00\x00`\x00\x00\x00\x00\x00\x00\x00\t\x00\x00\x00/\x00\x00\x00\x00\x00\x00\x00\x01'
p = NTP(s)
assert(isinstance(p, NTPPrivate))
assert(p.response == 1)
assert(p.more == 0)
assert(p.version == 2)
assert(p.mode == 7)
assert(p.auth == 0)
assert(p.request_code == 28)
assert(p.err == 0)
assert(p.nb_items == 1)
assert(p.data_item_size == 36)
assert(hasattr(p, 'data'))
assert(isinstance(p.data[0], NTPInfoAuth))
assert(p.data[0].timereset == 477)
assert(p.data[0].numkeys == 2)
assert(p.data[0].numfreekeys == 10)
assert(p.data[0].keylookups == 96)
assert(p.data[0].keynotfound == 0)
assert(p.data[0].encryptions == 9)
assert(p.data[0].decryptions == 47)
assert(p.data[0].expired == 0)
assert(p.data[0].keyuncached == 1)


= NTP Private (mode 7) - REQ_ADD_TRAP (1) - request
s = b'\x17\x80\x03\x1e\x00\x01\x000\x00\x00\x00\x00\xc0\x00\x02\x03H\x0f\x00\x00\x00\x00\x00\x00"\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xdb9\xedB\xdd\xda\x7f\x97\x00\x00\x00\x01b$\xb8IM.\xa61\xd0\x85I\x8f\xa7\'\x89\x92'
p = NTP(s)
assert(isinstance(p, NTPPrivate))
assert(p.response == 0)
assert(p.more == 0)
assert(p.version == 2)
assert(p.mode == 7)
assert(p.auth == 1)
assert(p.request_code == 30)
assert(p.err == 0)
assert(p.nb_items == 1)
assert(hasattr(p, 'req_data'))
assert(isinstance(p.req_data[0], NTPConfTrap))
assert(p.req_data[0].trap_address == '192.0.2.3')
assert(hasattr(p, 'authenticator'))
assert(p.authenticator.key_id == 1)
assert(bytes_hex(p.authenticator.dgst) == b'6224b8494d2ea631d085498fa7278992')


= NTP Private (mode 7) - REQ_ADD_TRAP (2) - response
s = b'\x97\x00\x03\x1e\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00'
p = NTP(s)
assert(isinstance(p, NTPPrivate))
assert(p.response == 1)
assert(p.more == 0)
assert(p.version == 2)
assert(p.mode == 7)
assert(p.auth == 0)
assert(p.request_code == 30)
assert(p.err == 0)
assert(p.nb_items == 0)
assert(p.data_item_size == 0)


= NTP Private (mode 7) - REQ_CLR_TRAP (1) - request
s = b'\x17\x80\x03\x1f\x00\x01\x000\x00\x00\x00\x00\xc0\x00\x02\x03H\x0f\x00\x00\x00\x00\x00\x00"\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xdb9\xedb\xb3\x18\x1c\x00\x00\x00\x00\x01\xa5_V\x9e\xb8qD\x92\x1b\x1c>Z\xad]*\x89'
p = NTP(s)
assert(isinstance(p, NTPPrivate))
assert(p.response == 0)
assert(p.more == 0)
assert(p.version == 2)
assert(p.mode == 7)
assert(p.auth == 1)
assert(p.request_code == 31)
assert(p.err == 0)
assert(p.nb_items == 1)
assert(hasattr(p, 'req_data'))
assert(isinstance(p.req_data[0], NTPConfTrap))
assert(p.req_data[0].trap_address == '192.0.2.3')
assert(hasattr(p, 'authenticator'))
assert(p.authenticator.key_id == 1)
assert(bytes_hex(p.authenticator.dgst) == b'a55f569eb87144921b1c3e5aad5d2a89')


= NTP Private (mode 7) - REQ_CLR_TRAP (2) - response
s = b'\x97\x00\x03\x1f\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00'
p = NTP(s)
assert(isinstance(p, NTPPrivate))
assert(p.response == 1)
assert(p.more == 0)
assert(p.version == 2)
assert(p.mode == 7)
assert(p.auth == 0)
assert(p.request_code == 31)
assert(p.err == 0)
assert(p.nb_items == 0)
assert(p.data_item_size == 0)


= NTP Private (mode 7) - REQ_GET_CTLSTATS - response
s = b'\x97\x00\x03"\x00\x01\x00<\x00\x00\x00\xed\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00'
p = NTP(s)
assert(isinstance(p, NTPPrivate))
assert(p.response == 1)
assert(p.more == 0)
assert(p.version == 2)
assert(p.mode == 7)
assert(p.auth == 0)
assert(p.request_code == 34)
assert(p.nb_items == 1)
assert(p.data_item_size == 60)
assert(type(p.data[0]) == NTPInfoControl)
assert(p.data[0].ctltimereset == 237)


= NTP Private (mode 7) - REQ_GET_KERNEL (1) - request
s = b'\x17\x00\x03&\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00'
p = NTP(s)
assert(isinstance(p, NTPPrivate))
assert(p.response == 0)
assert(p.more == 0)
assert(p.version == 2)
assert(p.mode == 7)
assert(p.auth == 0)
assert(p.request_code == 38)
assert(p.nb_items == 0)
assert(p.data_item_size == 0)


= NTP Private (mode 7) - REQ_GET_KERNEL (2) - response
s = b'\x97\x00\x03&\x00\x01\x00<\x00\x00\x00\x00\x00\x00\x00\x00\x00\xf4$\x00\x00\xf4$\x00 A\x00\x00\x00\x00\x00\x03\x00\x00\x00\x01\x01\xf4\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00'
p = NTP(s)
assert(isinstance(p, NTPPrivate))
assert(p.response == 1)
assert(p.more == 0)
assert(p.version == 2)
assert(p.mode == 7)
assert(p.auth == 0)
assert(p.request_code == 38)
assert(p.nb_items == 1)
assert(p.data_item_size == 60)
assert(isinstance(p.data[0], NTPInfoKernel))
assert(p.data[0].maxerror == 16000000)
assert(p.data[0].esterror == 16000000)
assert(p.data[0].status == 8257)
assert(p.data[0].constant == 3)
assert(p.data[0].precision == 1)
assert(p.data[0].tolerance == 32768000)



= NTP Private (mode 7) - REQ_MON_GETLIST_1 (1) - request
s = b'\x17\x00\x03*\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00'
p = NTP(s)
assert(isinstance(p, NTPPrivate))
assert(p.response == 0)
assert(p.more == 0)
assert(p.version == 2)
assert(p.mode == 7)
assert(p.request_code == 42)
assert(p.nb_items == 0)
assert(p.data_item_size == 0)


= NTP Private (mode 7) - REQ_MON_GETLIST_1 (2) - response
s = b'\xd7\x00\x03*\x00\x06\x00H\x00\x00\x00;\x00\x00\x00;\x00\x00\x01\xd0\x00\x00\x00\x01\x94mw\xe9\xc0\xa8zg\x00\x00\x00\x01\x00{\x03\x04\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00;\x00\x00\x00;\x00\x00\x01\xd0\x00\x00\x00\x01\x13\xb6\xa9J\xc0\xa8zg\x00\x00\x00\x01\x00{\x03\x04\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00;\x00\x00\x00;\x00\x00\x01\xd0\x00\x00\x00\x01\xbb]\x81\xea\xc0\xa8zg\x00\x00\x00\x01\x00{\x03\x04\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00;\x00\x00\x00;\x00\x00\x01\xd0\x00\x00\x00\x01\xfc\xbf\xd5a\xc0\xa8zg\x00\x00\x00\x01\x00{\x03\x04\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00;\x00\x00\x00;\x00\x00\x01\xd0\x00\x00\x00\x01\xbe\x10x\xa8\xc0\xa8zg\x00\x00\x00\x01\x00{\x03\x04\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00;\x00\x00\x00;\x00\x00\x01\xd0\x00\x00\x00\x01\xde[ng\xc0\xa8zg\x00\x00\x00\x01\x00{\x03\x04\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00'
p = NTP(s)
assert(isinstance(p, NTPPrivate))
assert(p.response == 1)
assert(p.more == 1)
assert(p.version == 2)
assert(p.mode == 7)
assert(p.request_code == 42)
assert(p.nb_items == 6)
assert(p.data_item_size == 72)


= NTP Private (mode 7) - REQ_IF_STATS (1) - request
s = b'\x17\x80\x03,\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xdb9\xeb\xdd\x8cH\xefe\x00\x00\x00\x01\x8b\xfb\x90u\xa8ad\xe8\x87\xca\xbf\x96\xd2\x9d\xddI'
p = NTP(s)
assert(isinstance(p, NTPPrivate))
assert(p.response == 0)
assert(p.more == 0)
assert(p.version == 2)
assert(p.mode == 7)
assert(p.auth == 1)
assert(p.request_code == 44)
assert(p.nb_items == 0)
assert(p.data_item_size == 0)
assert(hasattr(p, 'authenticator'))
assert(p.authenticator.key_id == 1)
assert(bytes_hex(p.authenticator.dgst) == b'8bfb9075a86164e887cabf96d29ddd49')


= NTP Private (mode 7) - REQ_IF_STATS (2) - response
s = b"\xd7\x00\x03,\x00\x03\x00\x88\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\x00\x00\x00\x01lo\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x05\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00.\x00\x00\x00\x01\x00\x00\x00\x01\x00\x00\x00\x07\x00\x00\x00\x00\x00\n\x00\x01\x00\x00\x00\x00\xfe\x80\x00\x00\x00\x00\x00\x00\n\x00'\xff\xfe\xe3\x81r\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xff\xff\xff\xff\xff\xff\xff\xff\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01eth0\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x11\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00.\x00\x00\x00\x02\x00\x00\x00\x02\x00\x00\x00\x06\x00\x00\x00\x00\x00\n\x00\x01\x00\x00\x00\x00\xfe\x80\x00\x00\x00\x00\x00\x00\n\x00'\xff\xfe\xa0\x1d\xd0\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xff\xff\xff\xff\xff\xff\xff\xff\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01eth1\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x11\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00.\x00\x00\x00\x03\x00\x00\x00\x03\x00\x00\x00\x05\x00\x00\x00\x00\x00\n\x00\x01\x00\x00\x00\x00"
p = NTP(s)
assert(isinstance(p, NTPPrivate))
assert(p.response == 1)
assert(p.more == 1)
assert(p.version == 2)
assert(p.mode == 7)
assert(p.auth == 0)
assert(p.request_code == 44)
assert(p.err == 0)
assert(p.nb_items == 3)
assert(p.data_item_size == 136)
assert(isinstance(p.data[0], NTPInfoIfStatsIPv6))
assert(p.data[0].unaddr == "::1")
assert(p.data[0].unmask == "ffff:ffff:ffff:ffff:ffff:ffff:ffff:ffff")
assert(p.data[0].ifname.startswith(b"lo"))


= NTP Private (mode 7) - REQ_IF_STATS (3) - response
s = b'\xd7\x01\x03,\x00\x03\x00\x88\xc0\xa8ze\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xc0\xa8z\xff\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xff\xff\xff\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00eth1\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x19\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x07\x00\x00\x00\x11\x00\x00\x00\x00\x00\x00\x00.\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x04\x00\x00\x00\x02\x00\x02\x00\x01\x00\x00\x00\x00\n\x00\x02\x0f\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\n\x00\x02\xff\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xff\xff\xff\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00eth0\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x19\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00.\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x03\x00\x00\x00\x00\x00\x02\x00\x01\x00\x00\x00\x00\x7f\x00\x00\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xff\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00lo\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x05\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00.\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x02\x00\x00\x00\x00\x00\x02\x00\x01\x00\x00\x00\x00'
p = NTP(s)
assert(isinstance(p, NTPPrivate))
assert(p.response == 1)
assert(p.more == 1)
assert(p.version == 2)
assert(p.mode == 7)
assert(p.auth == 0)
assert(p.request_code == 44)
assert(p.err == 0)
assert(p.nb_items == 3)
assert(p.data_item_size == 136)
assert(isinstance(p.data[0], NTPInfoIfStatsIPv4))
assert(p.data[0].unaddr == "192.168.122.101")
assert(p.data[0].unmask == "255.255.255.0")
assert(p.data[0].ifname.startswith(b"eth1"))


= NTP Private (mode 7) - REQ_IF_RELOAD (1) - request
s = b'\x17\x80\x03-\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xdb9\xed\xa3\xdc\x7f\xc6\x11\x00\x00\x00\x01\xfb>\x96*\xe7O\xf7\x8feh\xd4\x07L\xc0\x08\xcb'
p = NTP(s)
assert(isinstance(p, NTPPrivate))
assert(p.response == 0)
assert(p.more == 0)
assert(p.version == 2)
assert(p.mode == 7)
assert(p.auth == 1)
assert(p.request_code == 45)
assert(p.nb_items == 0)
assert(p.data_item_size == 0)
assert(hasattr(p, 'authenticator'))
assert(p.authenticator.key_id == 1)
assert(bytes_hex(p.authenticator.dgst) == b'fb3e962ae74ff78f6568d4074cc008cb')


= NTP Private (mode 7) - REQ_IF_RELOAD (2) - response
s = b'\xd7\x00\x03-\x00\x03\x00\x88\x7f\x00\x00\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xff\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00lo\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x05\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01\xf4\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x02\x00\x00\x00\x00\x00\x02\x00\x01\x00\x00\x00\x00\n\x00\x02\x0f\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\n\x00\x02\xff\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xff\xff\xff\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00eth0\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x19\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x13\x00\x00\x00\x00\x00\x00\x01\xf4\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x03\x00\x00\x00\x05\x00\x02\x00\x01\x00\x00\x00\x00\xc0\xa8ze\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xc0\xa8z\xff\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xff\xff\xff\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00eth1\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x19\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00=\x00\x00\x00}\x00\x00\x00\x00\x00\x00\x01\xf4\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x04\x00\x00\x00\t\x00\x02\x00\x01\x00\x00\x00\x00'
p = NTP(s)
assert(isinstance(p, NTPPrivate))
assert(p.response == 1)
assert(p.more == 1)
assert(p.version == 2)
assert(p.mode == 7)
assert(p.auth == 0)
assert(p.request_code == 45)
assert(p.err == 0)
assert(p.nb_items == 3)
assert(p.data_item_size == 136)
assert(isinstance(p.data[0], NTPInfoIfStatsIPv4))
assert(p.data[0].unaddr == "127.0.0.1")
assert(p.data[0].unmask == "255.0.0.0")
assert(p.data[0].ifname.startswith(b"lo"))


############
############
+ VXLAN layer

= Build a VXLAN packet with VNI of 42
raw(UDP(sport=1024, dport=4789, len=None, chksum=None)/VXLAN(flags=0x08, vni=42)) == b'\x04\x00\x12\xb5\x00\x10\x00\x00\x08\x00\x00\x00\x00\x00\x2a\x00'

= Verify VXLAN Ethernet Binding
pkt = VXLAN(raw(VXLAN(vni=23)/Ether(dst="11:11:11:11:11:11", src="11:11:11:11:11:11", type=0x800)))
pkt.flags.NextProtocol and pkt.NextProtocol == 3

= Verify UDP dport overloading
p = Ether(dst="11:11:11:11:11:11", src="22:22:22:22:22:22")
p /= IP(src="1.1.1.1", dst="2.2.2.2") / UDP(sport=1111)
p /= VXLAN(flags=0xC, vni=42, NextProtocol=0) / Ether() / IP()
p = Ether(raw(p))
assert(p[UDP].dport == 4789)
assert(p[Ether:2].type == 0x800)

= Build a VXLAN packet with next protocol field
p = Ether(dst="11:11:11:11:11:11", src="22:22:22:22:22:22")
p /= IP(src="1.1.1.1", dst="2.2.2.2") / UDP(sport=1111)
p /= VXLAN(flags=0xC, vni=42, NextProtocol=3) / Ether() / IP()
p = Ether(raw(p))
assert(p[UDP].dport == 4789)
assert(p[VXLAN].reserved0 == 0x0)
assert(p[VXLAN].NextProtocol == 3)
assert(p[Ether:2].type == 0x800)

= Build a VXLAN packet with no group policy ID
p = Ether(dst="11:11:11:11:11:11", src="22:22:22:22:22:22")
p /= IP(src="1.1.1.1", dst="2.2.2.2") / UDP(sport=1111)
p /= VXLAN(flags=0xC, vni=42) / Ether() / IP()
p = Ether(raw(p))
assert(p[VXLAN].reserved2 == 0x0)
assert(p[VXLAN].gpid is None)
assert(p[Ether:2].type == 0x800)

= Build a VXLAN packet with group policy ID = 42
p = Ether(dst="11:11:11:11:11:11", src="22:22:22:22:22:22")
p /= IP(src="1.1.1.1", dst="2.2.2.2") / UDP(sport=1111)
p /= VXLAN(flags=0x8C, gpid=42, vni=42) / Ether() / IP()
p = Ether(raw(p))
assert(p[VXLAN].gpid == 42)
assert(p[VXLAN].reserved1 is None)
assert(p[Ether:2].type == 0x800)

= Build a VXLAN packet followed by and IP or IPv6 layer
etherproto = 0x0
ipproto = 0x1
ipv6proto = 0x2
iptest = "192.168.20.20"
ipv6test = "659f:2c23:565:3fab:32d5:bb95:a0ed:2e3b"

expkt = UDP() / VXLAN() / IP(dst=iptest) / "testing"
expkt = UDP(bytes(expkt))
assert(expkt[VXLAN].NextProtocol == ipproto)
assert(IP in expkt)
assert(expkt[IP].dst == iptest)

expkt = UDP() / VXLAN() / IPv6(dst=ipv6test) / "testing"
expkt = UDP(bytes(expkt))
assert(expkt[VXLAN].NextProtocol == ipv6proto)
assert(IPv6 in expkt)
assert(expkt[IPv6].dst == ipv6test)

expkt = UDP() / VXLAN(flags=0x4, NextProtocol=ipproto) / "0xfffffffffffffffffffffffffffffffffffffffffffff"
expkt = UDP(bytes(expkt))
assert(IP in expkt)

expkt = UDP() / VXLAN(flags=0x4, NextProtocol=ipv6proto) / "0xfffffffffffffffffffffffffffffffffffffffffffff"
expkt = UDP(bytes(expkt))
assert(IPv6 in expkt)

expkt = UDP() / VXLAN(flags=0x4, NextProtocol=etherproto) / "0xfffffffffffffffffffffffffffffffffffffffffffff"
expkt = UDP(bytes(expkt))
assert(Ether in expkt)

############
############
############
+ Tests of StreamSocket

= Test with DNS over TCP
~ netaccess

import socket
sck = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
sck.connect(("8.8.8.8", 53))

class DNSTCP(Packet):
    name = "DNS over TCP"
    fields_desc = [ FieldLenField("len", None, fmt="!H", length_of="dns"),
                    PacketLenField("dns", 0, DNS, length_from=lambda p: p.len)]

ssck = StreamSocket(sck)
ssck.basecls = DNSTCP

r = ssck.sr1(DNSTCP(dns=DNS(rd=1, qd=DNSQR(qname="www.example.com"))))
sck.close()
assert(DNSTCP in r and len(r.dns.an))

############
+ Tests of SSLStreamContext

= Test with recv() calls that return exact packet-length rawings
~ sslraweamsocket

import socket
class MockSocket(object):
    def __init__(self):
        self.l = [ b'\x00\x00\x00\x01', b'\x00\x00\x00\x02', b'\x00\x00\x00\x03' ]
    def recv(self, x):
        if len(self.l) == 0:
            raise socket.error(100, 'EOF')
        return self.l.pop(0)

class TestPacket(Packet):
    name = 'TestPacket'
    fields_desc = [
        IntField('data', 0)
    ]
    def guess_payload_class(self, p):
        return conf.padding_layer

s = MockSocket()
ss = SSLStreamSocket(s, basecls=TestPacket)

p = ss.recv()
assert(p.data == 1)
p = ss.recv()
assert(p.data == 2)
p = ss.recv()
assert(p.data == 3)
try:
    ss.recv()
    ret = False
except socket.error:
    ret = True

assert(ret)

= Test with recv() calls that return twice as much data as the exact packet-length
~ sslraweamsocket

import socket
class MockSocket(object):
    def __init__(self):
        self.l = [ b'\x00\x00\x00\x01\x00\x00\x00\x02', b'\x00\x00\x00\x03\x00\x00\x00\x04' ]
    def recv(self, x):
        if len(self.l) == 0:
            raise socket.error(100, 'EOF')
        return self.l.pop(0)

class TestPacket(Packet):
    name = 'TestPacket'
    fields_desc = [
        IntField('data', 0)
    ]
    def guess_payload_class(self, p):
        return conf.padding_layer

s = MockSocket()
ss = SSLStreamSocket(s, basecls=TestPacket)

p = ss.recv()
assert(p.data == 1)
p = ss.recv()
assert(p.data == 2)
p = ss.recv()
assert(p.data == 3)
p = ss.recv()
assert(p.data == 4)
try:
    ss.recv()
    ret = False
except socket.error:
    ret = True

assert(ret)

= Test with recv() calls that return not enough data
~ sslraweamsocket

import socket
class MockSocket(object):
    def __init__(self):
        self.l = [ b'\x00\x00', b'\x00\x01', b'\x00\x00\x00', b'\x02', b'\x00\x00', b'\x00', b'\x03' ]
    def recv(self, x):
        if len(self.l) == 0:
            raise socket.error(100, 'EOF')
        return self.l.pop(0)

class TestPacket(Packet):
    name = 'TestPacket'
    fields_desc = [
        IntField('data', 0)
    ]
    def guess_payload_class(self, p):
        return conf.padding_layer

s = MockSocket()
ss = SSLStreamSocket(s, basecls=TestPacket)

try:
    p = ss.recv()
    ret = False
except:
    ret = True

assert(ret)
p = ss.recv()
assert(p.data == 1)
try:
    p = ss.recv()
    ret = False
except:
    ret = True

assert(ret)
p = ss.recv()
assert(p.data == 2)
try:
    p = ss.recv()
    ret = False
except:
    ret = True

assert(ret)
try:
    p = ss.recv()
    ret = False
except:
    ret = True

assert(ret)
p = ss.recv()
assert(p.data == 3)


############
############
+ Test correct conversion from binary to rawing of IPv6 addresses

= IPv6 bin to rawing conversion
from scapy.pton_ntop import _inet6_ntop, inet_ntop
import socket
for binfrm, address in [
        (b'\x00' * 16, '::'),
        (b'\x11\x11\x22\x22\x33\x33\x44\x44\x55\x55\x66\x66\x77\x77\x88\x88',
         '1111:2222:3333:4444:5555:6666:7777:8888'),
        (b'\x11\x11\x22\x22\x33\x33\x44\x44\x55\x55\x00\x00\x00\x00\x00\x00',
         '1111:2222:3333:4444:5555::'),
        (b'\x00\x00\x00\x00\x00\x00\x44\x44\x55\x55\x66\x66\x77\x77\x88\x88',
         '::4444:5555:6666:7777:8888'),
        (b'\x00\x00\x00\x00\x33\x33\x44\x44\x00\x00\x00\x00\x00\x00\x88\x88',
         '0:0:3333:4444::8888'),
        (b'\x00\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00',
         '1::'),
        (b'\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01',
         '::1'),
        (b'\x11\x11\x00\x00\x00\x00\x44\x44\x00\x00\x00\x00\x77\x77\x88\x88',
         '1111::4444:0:0:7777:8888'),
        (b'\x10\x00\x02\x00\x00\x30\x00\x04\x00\x05\x00\x60\x07\x00\x80\x00',
         '1000:200:30:4:5:60:700:8000'),
]:
    addr1 = inet_ntop(socket.AF_INET6, binfrm)
    addr2 = _inet6_ntop(binfrm)
    assert address == addr1 == addr2

= IPv6 bin to rawing conversion - Zero-block of length 1
binfrm = b'\x11\x11\x22\x22\x33\x33\x44\x44\x55\x55\x66\x66\x00\x00\x88\x88'
addr1, addr2 = inet_ntop(socket.AF_INET6, binfrm), _inet6_ntop(binfrm)
# On Mac OS socket.inet_ntop is not fully compliant with RFC 5952 and
# shortens the single zero block to '::'. This is a valid IPv6 address
# representation anyway.
assert(addr1 in ['1111:2222:3333:4444:5555:6666:0:8888',
                 '1111:2222:3333:4444:5555:6666::8888'])
assert(addr2 == '1111:2222:3333:4444:5555:6666:0:8888')

= IPv6 bin to rawing conversion - Illegal sizes
for binfrm in ["\x00" * 15, b"\x00" * 17]:
    rc = False
    try:
        inet_ntop(socket.AF_INET6, binfrm)
    except Exception as exc1:
        _exc1 = exc1
        rc = True
    assert rc
    try:
        _inet6_ntop(binfrm)
    except Exception as exc2:
        rc = isinstance(exc2, type(_exc1))
    assert rc


############
############
+ Netbios tests

= NBNSQueryRequest - build

z = NBNSQueryRequest(SUFFIX="file server service", QUESTION_NAME='TEST1', QUESTION_TYPE='NB')

assert raw(z) == b'\x00\x00\x01\x10\x00\x01\x00\x00\x00\x00\x00\x00 FEEFFDFEDBCACACACACACACACACACACA\x00\x00 \x00\x01'

pkt = IP(dst='192.168.0.255')/UDP(sport=137, dport='netbios_ns')/z
pkt = IP(raw(pkt))
assert pkt.QUESTION_NAME == b'TEST1          '


############
############
+ VRRP tests

= VRRP - build
s = raw(IP()/VRRP())
s == b'E\x00\x00$\x00\x01\x00\x00@p|g\x7f\x00\x00\x01\x7f\x00\x00\x01!\x01d\x00\x00\x01z\xfd\x00\x00\x00\x00\x00\x00\x00\x00'

= VRRP - dissection
p = IP(s)
VRRP in p and p[VRRP].chksum == 0x7afd

= VRRP - chksums
# VRRPv3
p = Ether(src="00:00:5e:00:02:02",dst="01:00:5e:00:00:12")/IP(src="20.0.0.3", dst="224.0.0.18",ttl=255)/VRRPv3(priority=254,vrid=2,version=3,adv=1,addrlist=["20.0.1.2","20.0.1.3"])
a = Ether(raw(p))
assert a[VRRPv3].chksum == 0xb25e
# VRRPv1
p = Ether(src="00:00:5e:00:02:02",dst="01:00:5e:00:00:12")/IP(src="20.0.0.3", dst="224.0.0.18",ttl=255)/VRRP(priority=254,vrid=2,version=1,adv=1,addrlist=["20.0.1.2","20.0.1.3"])
b = Ether(raw(p))
assert b[VRRP].chksum == 0xc6f4

############
############
+ L2TP tests

= L2TP - build
s = raw(IP()/UDP()/L2TP())
s == b'E\x00\x00"\x00\x01\x00\x00@\x11|\xc8\x7f\x00\x00\x01\x7f\x00\x00\x01\x06\xa5\x06\xa5\x00\x0e\xf4\x83\x00\x02\x00\x00\x00\x00'

= L2TP - dissection
p = IP(s)
L2TP in p and len(p[L2TP]) == 6 and p.tunnel_id == 0 and p.session_id == 0 and p[UDP].chksum == 0xf483


############
############
+ MGCP tests

= MGCP - build
s = raw(IP(src="127.0.0.1")/UDP()/MGCP(endpoint="scapy@secdev.org", transaction_id="04523"))
s == b'E\x00\x00I\x00\x01\x00\x00@\x11|\xa1\x7f\x00\x00\x01\x7f\x00\x00\x01\n\xa7\n\xa7\x005\xf8\xaeAUEP 04523 scapy@secdev.org MGCP 1.0 NCS 1.0\n'

= MGCP - dissect
pkt = Ether(b'\x1b\x81\xb8\xa8J5\xe3\xebn\x90q\xb8\x08\x00E\x00\x00E\x00\x01\x00\x00@\x11\xf7\xde\xc0\xa8\x00\xff\xc0\xa8\x00y\n\xa7\n\xa7\x001\x05\xb5AUEP 155 god@heaven.com MGCP 1.0 NCS 1.0\n')
assert pkt[MGCP].endpoint == b'god@heaven.com'


############
############
+ MobileIP tests

= MobileIP - build
s = raw(IP(src="127.0.0.1")/UDP()/MobileIP()/MobileIPRRP(homeaddr='156.133.50.141', haaddr='95.83.86.216'))
s == b'E\x00\x000\x00\x01\x00\x00@\x11|\xba\x7f\x00\x00\x01\x7f\x00\x00\x01\x01\xb2\x01\xb2\x00\x1cu]\x03\x00\x00\xb4\x9c\x852\x8d_SV\xd8\x00\x00\x00\x00\x00\x00\x00\x00'

= MobileIP - dissect
pkt = IP(s)
assert pkt[MobileIP][MobileIPRRP].haaddr == '95.83.86.216'


############
############
+ HSRP tests

= HSRP - build & dissection
defaddr = conf.route.route('0.0.0.0')[1]
pkt = IP(raw(IP()/UDP(dport=1985, sport=1985)/HSRP()/HSRPmd5()))
assert pkt[IP].dst == "224.0.0.2" and pkt[UDP].sport == pkt[UDP].dport == 1985
assert pkt[HSRP].opcode == 0 and pkt[HSRP].state == 16
assert pkt[HSRPmd5].type == 4 and pkt[HSRPmd5].sourceip == defaddr


############
############
+ RIP tests

= RIP - build
s = raw(IP()/UDP(sport=520)/RIP()/RIPEntry()/RIPAuth(authtype=2, password="scapy"))
s == b'E\x00\x00H\x00\x01\x00\x00@\x11|\xa2\x7f\x00\x00\x01\x7f\x00\x00\x01\x02\x08\x02\x08\x004\xae\x99\x01\x01\x00\x00\x00\x02\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01\xff\xff\x00\x02scapy\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00'

= RIP - UDP bindings
w = IP(raw(IP()/UDP()/RIP()/RIPEntry()/RIPAuth(authtype=2, password="scapy")))
assert RIPAuth in w
assert w[RIPAuth].password.startswith(b"scapy")

= RIP - dissection
p = IP(s)
RIPEntry in p and RIPAuth in p and p[RIPAuth].password.startswith(b"scapy")


############
############
+ RADIUS tests

= IP/UDP/RADIUS - Build
s = raw(IP()/UDP(sport=1812)/Radius(authenticator="scapy")/RadiusAttribute(value="scapy"))
s == b'E\x00\x007\x00\x01\x00\x00@\x11|\xb3\x7f\x00\x00\x01\x7f\x00\x00\x01\x07\x14\x07\x15\x00#U\xb2\x01\x00\x00\x1bscapy\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01\x07scapy'

= IP/UDP/RADIUS - Dissection
p = IP(s)
Radius in p and len(p[Radius].attributes) == 1 and p[Radius].attributes[0].value == b"scapy"

= RADIUS - Access-Request - Dissection (1)
s = b'\x01\xae\x01\x17>k\xd4\xc4\x19V\x0b*1\x99\xc8D\xea\xc2\x94Z\x01\x06leap\x06\x06\x00\x00\x00\x02\x1a\x1b\x00\x00\x00\t\x01\x15service-type=Framed\x0c\x06\x00\x00#\xee\x1e\x13AC-7E-8A-4E-E2-92\x1f\x1300-26-73-9E-0F-D3O\x0b\x02\x01\x00\t\x01leapP\x12U\xbc\x12\xcdM\x00\xf8\xdb4\xf1\x18r\xca_\x8c\xf6f\x02\x1a1\x00\x00\x00\t\x01+audit-session-id=0AC8090E0000001A0354CA00\x1a\x14\x00\x00\x00\t\x01\x0emethod=dot1x\x08\x06\xc0\xa8\n\xb9\x04\x06\xc0\xa8\n\x80\x1a\x1d\x00\x00\x00\t\x02\x17GigabitEthernet1/0/18W\x17GigabitEthernet1/0/18=\x06\x00\x00\x00\x0f\x05\x06\x00\x00\xc3\xc6'
radius_packet = Radius(s)
assert(radius_packet.id == 174)
assert(radius_packet.len == 279)
assert(radius_packet.authenticator == b'>k\xd4\xc4\x19V\x0b*1\x99\xc8D\xea\xc2\x94Z')
assert(len(radius_packet.attributes) == 17)
assert(radius_packet.attributes[0].type == 1)
assert(type(radius_packet.attributes[0]) == RadiusAttribute)
assert(radius_packet.attributes[0].len == 6)
assert(radius_packet.attributes[0].value == b"leap")
assert(radius_packet.attributes[1].type == 6)
assert(type(radius_packet.attributes[1]) == RadiusAttr_Service_Type)
assert(radius_packet.attributes[1].len == 6)
assert(radius_packet.attributes[1].value == 2)
assert(radius_packet.attributes[2].type == 26)
assert(type(radius_packet.attributes[2]) == RadiusAttr_Vendor_Specific)
assert(radius_packet.attributes[2].len == 27)
assert(radius_packet.attributes[2].vendor_id == 9)
assert(radius_packet.attributes[2].vendor_type == 1)
assert(radius_packet.attributes[2].vendor_len == 21)
assert(radius_packet.attributes[2].value == b"service-type=Framed")
assert(radius_packet.attributes[6].type == 79)
assert(type(radius_packet.attributes[6]) == RadiusAttr_EAP_Message)
assert(radius_packet.attributes[6].len == 11)
assert(radius_packet.attributes[6].value.haslayer(EAP))
assert(radius_packet.attributes[6].value[EAP].code == 2)
assert(radius_packet.attributes[6].value[EAP].id == 1)
assert(radius_packet.attributes[6].value[EAP].len == 9)
assert(radius_packet.attributes[6].value[EAP].type == 1)
assert(hasattr(radius_packet.attributes[6].value[EAP], "identity"))
assert(radius_packet.attributes[6].value[EAP].identity == b"leap")
assert(radius_packet.attributes[7].type == 80)
assert(type(radius_packet.attributes[7]) == RadiusAttr_Message_Authenticator)
assert(radius_packet.attributes[7].len == 18)
assert(radius_packet.attributes[7].value == b'U\xbc\x12\xcdM\x00\xf8\xdb4\xf1\x18r\xca_\x8c\xf6')
assert(radius_packet.attributes[11].type == 8)
assert(type(radius_packet.attributes[11]) == RadiusAttr_Framed_IP_Address)
assert(radius_packet.attributes[11].len == 6)
assert(radius_packet.attributes[11].value == '192.168.10.185')
assert(radius_packet.attributes[16].type == 5)
assert(type(radius_packet.attributes[16]) == RadiusAttr_NAS_Port)
assert(radius_packet.attributes[16].len == 6)
assert(radius_packet.attributes[16].value == 50118)

f,v = radius_packet.getfield_and_val("authenticator")
assert f.i2repr(None, v) == '3e6bd4c419560b2a3199c844eac2945a'

= RADIUS - compute_message_authenticator()
ram = radius_packet[RadiusAttr_Message_Authenticator]
assert ram.compute_message_authenticator(radius_packet, b"dummy bytes", b"scapy") == b'\x19\xa4\x0e*Y4\xe0l?,\x94\x9f \xb8Jb'

= RADIUS - Access-Challenge - Dissection (2)
s = b'\x0b\xae\x00[\xc7\xae\xfc6\xa1=\xb5\x99&^\xdf=\xe9\x00\xa6\xe8\x12\rHello, leapO\x16\x01\x02\x00\x14\x11\x01\x00\x08\xb8\xc4\x1a4\x97x\xd3\x82leapP\x12\xd3\x12\x17\xa6\x0c.\x94\x85\x03]t\xd1\xdb\xd0\x13\x8c\x18\x12iQs\xf7iSb@k\x9d,\xa0\x99\x8ehO'
radius_packet = Radius(s)
assert(radius_packet.id == 174)
assert(radius_packet.len == 91)
assert(radius_packet.authenticator == b'\xc7\xae\xfc6\xa1=\xb5\x99&^\xdf=\xe9\x00\xa6\xe8')
assert(len(radius_packet.attributes) == 4)
assert(radius_packet.attributes[0].type == 18)
assert(type(radius_packet.attributes[0]) == RadiusAttribute)
assert(radius_packet.attributes[0].len == 13)
assert(radius_packet.attributes[0].value == b"Hello, leap")
assert(radius_packet.attributes[1].type == 79)
assert(type(radius_packet.attributes[1]) == RadiusAttr_EAP_Message)
assert(radius_packet.attributes[1].len == 22)
assert(radius_packet.attributes[1][EAP].code == 1)
assert(radius_packet.attributes[1][EAP].id == 2)
assert(radius_packet.attributes[1][EAP].len == 20)
assert(radius_packet.attributes[1][EAP].type == 17)
assert(radius_packet.attributes[2].type == 80)
assert(type(radius_packet.attributes[2]) == RadiusAttr_Message_Authenticator)
assert(radius_packet.attributes[2].len == 18)
assert(radius_packet.attributes[2].value == b'\xd3\x12\x17\xa6\x0c.\x94\x85\x03]t\xd1\xdb\xd0\x13\x8c')
assert(radius_packet.attributes[3].type == 24)
assert(type(radius_packet.attributes[3]) == RadiusAttr_State)
assert(radius_packet.attributes[3].len == 18)
assert(radius_packet.attributes[3].value == b'iQs\xf7iSb@k\x9d,\xa0\x99\x8ehO')

= RADIUS - Access-Request - Dissection (3)
s = b'\x01\xaf\x01DC\xbe!J\x08\xdf\xcf\x9f\x00v~,\xfb\x8e`\xc8\x01\x06leap\x06\x06\x00\x00\x00\x02\x1a\x1b\x00\x00\x00\t\x01\x15service-type=Framed\x0c\x06\x00\x00#\xee\x1e\x13AC-7E-8A-4E-E2-92\x1f\x1300-26-73-9E-0F-D3O&\x02\x02\x00$\x11\x01\x00\x18\rE\xc9\x92\xf6\x9ae\x04\xa2\x06\x13\x8f\x0b#\xf1\xc56\x8eU\xd9\x89\xe5\xa1)leapP\x12|\x1c\x9d[dv\x9c\x19\x96\xc6\xec\xb82\x8f\n f\x02\x1a1\x00\x00\x00\t\x01+audit-session-id=0AC8090E0000001A0354CA00\x1a\x14\x00\x00\x00\t\x01\x0emethod=dot1x\x08\x06\xc0\xa8\n\xb9\x04\x06\xc0\xa8\n\x80\x1a\x1d\x00\x00\x00\t\x02\x17GigabitEthernet1/0/18W\x17GigabitEthernet1/0/18=\x06\x00\x00\x00\x0f\x05\x06\x00\x00\xc3\xc6\x18\x12iQs\xf7iSb@k\x9d,\xa0\x99\x8ehO'
radius_packet = Radius(s)
assert(radius_packet.id == 175)
assert(radius_packet.len == 324)
assert(radius_packet.authenticator == b'C\xbe!J\x08\xdf\xcf\x9f\x00v~,\xfb\x8e`\xc8')
assert(len(radius_packet.attributes) == 18)
assert(radius_packet.attributes[0].type == 1)
assert(type(radius_packet.attributes[0]) == RadiusAttribute)
assert(radius_packet.attributes[0].len == 6)
assert(radius_packet.attributes[0].value == b"leap")
assert(radius_packet.attributes[1].type == 6)
assert(type(radius_packet.attributes[1]) == RadiusAttr_Service_Type)
assert(radius_packet.attributes[1].len == 6)
assert(radius_packet.attributes[1].value == 2)
assert(radius_packet.attributes[2].type == 26)
assert(type(radius_packet.attributes[2]) == RadiusAttr_Vendor_Specific)
assert(radius_packet.attributes[2].len == 27)
assert(radius_packet.attributes[2].vendor_id == 9)
assert(radius_packet.attributes[2].vendor_type == 1)
assert(radius_packet.attributes[2].vendor_len == 21)
assert(radius_packet.attributes[2].value == b"service-type=Framed")
assert(radius_packet.attributes[6].type == 79)
assert(type(radius_packet.attributes[6]) == RadiusAttr_EAP_Message)
assert(radius_packet.attributes[6].len == 38)
assert(radius_packet.attributes[6].value.haslayer(EAP))
assert(radius_packet.attributes[6].value[EAP].code == 2)
assert(radius_packet.attributes[6].value[EAP].id == 2)
assert(radius_packet.attributes[6].value[EAP].len == 36)
assert(radius_packet.attributes[6].value[EAP].type == 17)
assert(radius_packet.attributes[7].type == 80)
assert(type(radius_packet.attributes[7]) == RadiusAttr_Message_Authenticator)
assert(radius_packet.attributes[7].len == 18)
assert(radius_packet.attributes[7].value == b'|\x1c\x9d[dv\x9c\x19\x96\xc6\xec\xb82\x8f\n ')
assert(radius_packet.attributes[11].type == 8)
assert(type(radius_packet.attributes[11]) == RadiusAttr_Framed_IP_Address)
assert(radius_packet.attributes[11].len == 6)
assert(radius_packet.attributes[11].value == '192.168.10.185')
assert(radius_packet.attributes[16].type == 5)
assert(type(radius_packet.attributes[16]) == RadiusAttr_NAS_Port)
assert(radius_packet.attributes[16].len == 6)
assert(radius_packet.attributes[16].value == 50118)
assert(radius_packet.attributes[17].type == 24)
assert(type(radius_packet.attributes[17]) == RadiusAttr_State)
assert(radius_packet.attributes[17].len == 18)
assert(radius_packet.attributes[17].value == b'iQs\xf7iSb@k\x9d,\xa0\x99\x8ehO')

= RADIUS - Access-Challenge - Dissection (4)
s = b'\x0b\xaf\x00K\x82 \x95=\xfd\x80\x05 -l}\xab)\xa5kU\x12\rHello, leapO\x06\x03\x03\x00\x04P\x12l0\xb9\x8d\xca\xfc!\xf3\xa7\x08\x80\xe1\xf6}\x84\xff\x18\x12iQs\xf7hRb@k\x9d,\xa0\x99\x8ehO'
radius_packet = Radius(s)
assert(radius_packet.id == 175)
assert(radius_packet.len == 75)
assert(radius_packet.authenticator == b'\x82 \x95=\xfd\x80\x05 -l}\xab)\xa5kU')
assert(len(radius_packet.attributes) == 4)
assert(radius_packet.attributes[0].type == 18)
assert(type(radius_packet.attributes[0]) == RadiusAttribute)
assert(radius_packet.attributes[0].len == 13)
assert(radius_packet.attributes[0].value == b"Hello, leap")
assert(radius_packet.attributes[1].type == 79)
assert(type(radius_packet.attributes[1]) == RadiusAttr_EAP_Message)
assert(radius_packet.attributes[1].len == 6)
assert(radius_packet.attributes[1][EAP].code == 3)
assert(radius_packet.attributes[1][EAP].id == 3)
assert(radius_packet.attributes[1][EAP].len == 4)
assert(radius_packet.attributes[2].type == 80)
assert(type(radius_packet.attributes[2]) == RadiusAttr_Message_Authenticator)
assert(radius_packet.attributes[2].len == 18)
assert(radius_packet.attributes[2].value == b'l0\xb9\x8d\xca\xfc!\xf3\xa7\x08\x80\xe1\xf6}\x84\xff')
assert(radius_packet.attributes[3].type == 24)
assert(type(radius_packet.attributes[3]) == RadiusAttr_State)
assert(radius_packet.attributes[3].len == 18)
assert(radius_packet.attributes[3].value == b'iQs\xf7hRb@k\x9d,\xa0\x99\x8ehO')

= RADIUS - Response Authenticator computation
s = b'\x01\xae\x01\x17>k\xd4\xc4\x19V\x0b*1\x99\xc8D\xea\xc2\x94Z\x01\x06leap\x06\x06\x00\x00\x00\x02\x1a\x1b\x00\x00\x00\t\x01\x15service-type=Framed\x0c\x06\x00\x00#\xee\x1e\x13AC-7E-8A-4E-E2-92\x1f\x1300-26-73-9E-0F-D3O\x0b\x02\x01\x00\t\x01leapP\x12U\xbc\x12\xcdM\x00\xf8\xdb4\xf1\x18r\xca_\x8c\xf6f\x02\x1a1\x00\x00\x00\t\x01+audit-session-id=0AC8090E0000001A0354CA00\x1a\x14\x00\x00\x00\t\x01\x0emethod=dot1x\x08\x06\xc0\xa8\n\xb9\x04\x06\xc0\xa8\n\x80\x1a\x1d\x00\x00\x00\t\x02\x17GigabitEthernet1/0/18W\x17GigabitEthernet1/0/18=\x06\x00\x00\x00\x0f\x05\x06\x00\x00\xc3\xc6'
access_request = Radius(s)
s = b'\x0b\xae\x00[\xc7\xae\xfc6\xa1=\xb5\x99&^\xdf=\xe9\x00\xa6\xe8\x12\rHello, leapO\x16\x01\x02\x00\x14\x11\x01\x00\x08\xb8\xc4\x1a4\x97x\xd3\x82leapP\x12\xd3\x12\x17\xa6\x0c.\x94\x85\x03]t\xd1\xdb\xd0\x13\x8c\x18\x12iQs\xf7iSb@k\x9d,\xa0\x99\x8ehO'
access_challenge = Radius(s)
access_challenge.compute_authenticator(access_request.authenticator, b"radiuskey") == access_challenge.authenticator

= RADIUS - Layers (1)
radius_attr = RadiusAttr_EAP_Message(value = EAP())
assert(RadiusAttr_EAP_Message in radius_attr)
assert(RadiusAttribute in radius_attr)
type(radius_attr[RadiusAttribute])
assert(type(radius_attr[RadiusAttribute]) == RadiusAttr_EAP_Message)
assert(EAP in radius_attr.value)

= RADIUS - sessions (1)
p = IP()/TCP(sport=1812)/Radius(authenticator="scapy")/RadiusAttribute(value="scapy")
l = PacketList(p)
s = l.sessions()  # Crashed on commit: e42ecdc54556c4852ca06b1a6da6c1ccbf3f522e
assert len(s) == 1

= RADIUS - sessions (2)
p = IP()/UDP(sport=1812)/Radius(authenticator="scapy")/RadiusAttribute(value="scapy")
l = PacketList(p)
s = l.sessions()  # Crashed on commit: e42ecdc54556c4852ca06b1a6da6c1ccbf3f522e
assert len(s) == 1

= Issue GH#1407
s = b"Z\xa5\xaaUZ\xa5\xaaU\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xe9\xc5\x00\x00\x14'\x02\x00\x00\x001\x9a\xe44\xea4"
isinstance(Radius(s), Radius)


############
############
+ Skinny tests

= Skinny - build & dissection
p = raw(IP(src="127.0.0.1")/TCP()/Skinny(msg="ServiceURLStatMessage"))
assert p == b'E\x00\x004\x00\x01\x00\x00@\x06|\xc1\x7f\x00\x00\x01\x7f\x00\x00\x01\x07\xd0\x07\xd0\x00\x00\x00\x00\x00\x00\x00\x00P\x02 \x00S3\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00/\x01\x00\x00'
assert IP(p)[Skinny].msg == 303


############
############
+ Addresses generators

= Net

n1 = Net("192.168.0.0/31")
[ip for ip in n1] == ["192.168.0.0", "192.168.0.1"]

n2 = Net("192.168.0.*")
len([ip for ip in n2]) == 256
assert n2.__iterlen__() == 256

n3 = Net("192.168.0.1-5")
len([ip for ip in n3]) == 5
assert n3.__iterlen__() == 5

(n1 == n3) == False

(n3 in n2) == True

= Net using web address

ip = IP(dst="www.google.com")
n1 = ip.dst
assert isinstance(n1, Net)
assert n1.ip_regex.match(str(n1))
ip.show()

= Multiple IP addresses test
~ netaccess

ip = IP(dst=['192.168.0.1', 'www.google.fr'],ihl=(1,5))
assert ip.dst[0] == '192.168.0.1'
assert isinstance(ip.dst[1], Net)
src = ip.src
assert src
assert isinstance(src, str)

= OID

oid = OID("1.2.3.4.5.6-8")
len([ o for o in oid ]) == 3
assert oid.__iterlen__() == 3

= Net6

n1 = Net6("2001:db8::/127")
len([ip for ip in n1]) == 2

n2 = Net6("fec0::/110")
#len([x for x in n2]) returns 262144 (very slow)
assert n2.__iterlen__() == 262144

= Net6 using web address
~ netaccess ipv6

ip = IPv6(dst="www.google.com")
n1 = ip.dst
assert isinstance(n1, Net6)
assert n1.ip_regex.match(str(n1))
ip.show()

= Multiple IPv6 addresses test
~ netaccess ipv6

ip = IPv6(dst=['2001:db8::1', 'www.google.fr'],hlim=(1,5))
assert ip.dst[0] == '2001:db8::1'
assert isinstance(ip.dst[1], Net6)
src = ip.src
assert src
assert isinstance(src, str)

= Test repr on Net
~ netaccess

conf.color_theme = BlackAndWhite()
assert "Net('www.google.com')" in repr(IP(src="www.google.com"))

= Test repr on Net
~ netaccess ipv6

conf.color_theme = BlackAndWhite()
assert "Net6('www.google.com')" in repr(IPv6(src="www.google.com"))

############
############
+ IPv6 helpers

= in6_getLocalUniquePrefix()

p = in6_getLocalUniquePrefix()
len(inet_pton(socket.AF_INET6, p)) == 16 and p.startswith("fd")

= Misc addresses manipulation functions

teredoAddrExtractInfo("2001:0:0a0b:0c0d:0028:f508:f508:08f5") == ("10.11.12.13", 40, "10.247.247.10", 2807)

ip6 = IP6Field("test", None)
ip6.i2repr("", "2001:0:0a0b:0c0d:0028:f508:f508:08f5") == "2001:0:0a0b:0c0d:0028:f508:f508:08f5 [Teredo srv: 10.11.12.13 cli: 10.247.247.10:2807]"
ip6.i2repr("", "2002:0102:0304::1") == "2002:0102:0304::1 [6to4 GW: 1.2.3.4]"

in6_iseui64("fe80::bae8:58ff:fed4:e5f6") == True

in6_isanycast("2001:db8::fdff:ffff:ffff:ff80") == True

a = inet_pton(socket.AF_INET6, "2001:db8::2807")
in6_xor(a, a) == b"\x00" * 16

a = inet_pton(socket.AF_INET6, "fe80::bae8:58ff:fed4:e5f6")
r = inet_ntop(socket.AF_INET6, in6_getnsma(a)) 
r == "ff02::1:ffd4:e5f6"

in6_isllsnmaddr(r) == True

in6_isdocaddr("2001:db8::2807") == True

in6_isaddrllallnodes("ff02::1") == True

in6_isaddrllallservers("ff02::2") == True

= in6_getscope()

assert in6_getscope("2001:db8::2807") == IPV6_ADDR_GLOBAL
assert in6_getscope("fec0::2807") == IPV6_ADDR_SITELOCAL
assert in6_getscope("fe80::2807") == IPV6_ADDR_LINKLOCAL
assert in6_getscope("ff02::2807") == IPV6_ADDR_LINKLOCAL
assert in6_getscope("ff0e::2807") == IPV6_ADDR_GLOBAL
assert in6_getscope("ff05::2807") == IPV6_ADDR_SITELOCAL
assert in6_getscope("ff01::2807") == IPV6_ADDR_LOOPBACK
assert in6_getscope("::1") == IPV6_ADDR_LOOPBACK

= construct_source_candidate_set()

dev_addresses = [('fe80::', IPV6_ADDR_LINKLOCAL, "linklocal"),('fec0::', IPV6_ADDR_SITELOCAL, "sitelocal"),('ff0e::', IPV6_ADDR_GLOBAL, "global")]

assert construct_source_candidate_set("2001:db8::2807", 0, dev_addresses) == ["ff0e::"]
assert construct_source_candidate_set("fec0::2807", 0, dev_addresses) == ["fec0::"]
assert construct_source_candidate_set("fe80::2807", 0, dev_addresses) == ["fe80::"]
assert construct_source_candidate_set("ff02::2807", 0, dev_addresses) == ["fe80::"]
assert construct_source_candidate_set("ff0e::2807", 0, dev_addresses) == ["ff0e::"]
assert construct_source_candidate_set("ff05::2807", 0, dev_addresses) == ["fec0::"]
assert construct_source_candidate_set("ff01::2807", 0, dev_addresses) == ["::1"]
assert construct_source_candidate_set("::", 0, dev_addresses) == ["ff0e::"]

= inet_pton()

from scapy.pton_ntop import _inet6_pton, inet_pton
import socket

ip6_bad_addrs = ["fe80::2e67:ef2d:7eca::ed8a",
                 "fe80:1234:abcd::192.168.40.12:abcd",
                 "fe80:1234:abcd::192.168.40",
                 "fe80:1234:abcd::192.168.400.12",
                 "1234:5678:9abc:def0:1234:5678:9abc:def0:",
                 "1234:5678:9abc:def0:1234:5678:9abc:def0:1234"]
for ip6 in ip6_bad_addrs:
    rc = False
    exc1 = None
    try:
        res1 = inet_pton(socket.AF_INET6, ip6)
    except Exception as e:
        rc = True
        exc1 = e
    assert rc
    rc = False
    try:
        res2 = _inet6_pton(ip6)
    except Exception as exc2:
        rc = isinstance(exc2, type(exc1))
    assert rc

ip6_good_addrs = [("fe80:1234:abcd::192.168.40.12",
                   b'\xfe\x80\x124\xab\xcd\x00\x00\x00\x00\x00\x00\xc0\xa8(\x0c'),
                  ("fe80:1234:abcd::fe06",
                   b'\xfe\x80\x124\xab\xcd\x00\x00\x00\x00\x00\x00\x00\x00\xfe\x06'),
                  ("fe80::2e67:ef2d:7ece:ed8a",
                   b'\xfe\x80\x00\x00\x00\x00\x00\x00.g\xef-~\xce\xed\x8a'),
                  ("::ffff",
                   b'\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xff\xff'),
                  ("ffff::",
                   b'\xff\xff\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00'),
                  ('::', b'\x00' * 16)]
for ip6, res in ip6_good_addrs:
    res1 = inet_pton(socket.AF_INET6, ip6)
    res2 = _inet6_pton(ip6)
    assert res == res1 == res2


############
############
+ Test Route class

= make_route()

r4 = Route()
tmp_route = r4.make_route(host="10.12.13.14")
(tmp_route[0], tmp_route[1], tmp_route[2]) == (168561934, 4294967295, '0.0.0.0')

tmp_route = r4.make_route(net="10.12.13.0/24")
(tmp_route[0], tmp_route[1], tmp_route[2]) == (168561920, 4294967040, '0.0.0.0')

= add() & delt()

r4 = Route()
len_r4 = len(r4.routes)
r4.add(net="192.168.1.0/24", gw="1.2.3.4")
len(r4.routes) == len_r4 + 1
r4.delt(net="192.168.1.0/24", gw="1.2.3.4")
len(r4.routes) == len_r4

= ifchange()

r4.add(net="192.168.1.0/24", gw="1.2.3.4", dev=get_dummy_interface())
r4.ifchange(get_dummy_interface(), "5.6.7.8")
r4.routes[-1][4] == "5.6.7.8"

= ifdel()

r4.ifdel(get_dummy_interface())
len(r4.routes) == len_r4

= ifadd() & get_if_bcast()

r4 = Route()
len_r4 = len(r4.routes)

r4.ifadd(get_dummy_interface(), "1.2.3.4/24")
len(r4.routes) == len_r4 +1 

r4.get_if_bcast(get_dummy_interface()) == "1.2.3.255"

r4.ifdel(get_dummy_interface())
len(r4.routes) == len_r4


############
############
+ Random objects

= RandomEnumeration

re = RandomEnumeration(0, 7, seed=0x2807, forever=False)
[x for x in re] == ([3, 4, 2, 5, 1, 6, 0, 7] if six.PY2 else [5, 0, 2, 7, 6, 3, 1, 4])

= RandIP6

random.seed(0x2807)
r6 = RandIP6()
assert(r6 == ("d279:1205:e445:5a9f:db28:efc9:afd7:f594" if six.PY2 else
              "240b:238f:b53f:b727:d0f9:bfc4:2007:e265"))

random.seed(0x2807)
r6 = RandIP6("2001:db8::-") 
assert(r6 == ("2001:0db8::e445" if six.PY2 else "2001:0db8::b53f"))

r6 = RandIP6("2001:db8::*")
assert(r6 == ("2001:0db8::efc9" if six.PY2 else "2001:0db8::bfc4"))

= RandMAC

random.seed(0x2807)
rm = RandMAC() 
assert(rm == ("d2:12:e4:5a:db:ef" if six.PY2 else "24:23:b5:b7:d0:bf"))

rm = RandMAC("00:01:02:03:04:0-7")
assert(rm == ("00:01:02:03:04:05" if six.PY2 else "00:01:02:03:04:01"))


= RandOID

random.seed(0x2807)
ro = RandOID()
assert(ro == "7.222.44.194.276.116.320.6.84.97.31.5.25.20.13.84.104.18")

ro = RandOID("1.2.3.*")
assert(ro == "1.2.3.41")

ro = RandOID("1.2.3.0-28")
assert(ro == ("1.2.3.11" if six.PY2 else "1.2.3.12"))

= RandRegExp

random.seed(0x2807)
re = RandRegExp("[g-v]* @? [0-9]{3} . (g|v)")
bytes(re) == ('vmuvr @ 906 \x9e g' if six.PY2 else b'irrtv @ 517 \xc2\xb8 v')

= Corrupted(Bytes|Bits)

random.seed(0x2807)
cb = CorruptedBytes("ABCDE", p=0.5)
assert(sane(raw(cb)) in [".BCD)", "&BCDW"])

cb = CorruptedBits("ABCDE", p=0.2)
assert(sane(raw(cb)) in ["ECk@Y", "QB.P."])

= RandEnumKeys
~ not_pypy random_weird_py3
random.seed(0x2807)
rek = RandEnumKeys({'a': 1, 'b': 2, 'c': 3}, seed=0x2807)
rek.enum.sort()
assert(rek == ('c' if six.PY2 else 'a'))

= RandSingNum
~ not_pypy random_weird_py3
random.seed(0x2807)
rs = RandSingNum(-28, 7)
assert(rs == (3 if six.PY2 else 2))
assert(rs == (-27 if six.PY2 else -17))

= Rand*
random.seed(0x2807)
rss = RandSingString()
assert(rss == ("CON:" if six.PY2 else "foo.exe:"))

random.seed(0x2807)
rts = RandTermString(4, "scapy")
assert(sane(raw(rts)) in ["...Zscapy", "$#..scapy"])

= RandInt (test __bool__)
a = "True" if RandNum(False, True) else "False"
assert a in ["True", "False"]

############
############
+ Flags

= IP flags
~ IP

pkt = IP(flags="MF")
assert pkt.flags.MF
assert not pkt.flags.DF
assert not pkt.flags.evil
assert repr(pkt.flags) == '<Flag 1 (MF)>'
pkt.flags.MF = 0
pkt.flags.DF = 1
assert not pkt.flags.MF
assert pkt.flags.DF
assert not pkt.flags.evil
assert repr(pkt.flags) == '<Flag 2 (DF)>'
pkt.flags |= 'evil+MF'
pkt.flags &= 'DF+MF'
assert pkt.flags.MF
assert pkt.flags.DF
assert not pkt.flags.evil
assert repr(pkt.flags) == '<Flag 3 (MF+DF)>'

pkt = IP(flags=3)
assert pkt.flags.MF
assert pkt.flags.DF
assert not pkt.flags.evil
assert repr(pkt.flags) == '<Flag 3 (MF+DF)>'
pkt.flags = 6
assert not pkt.flags.MF
assert pkt.flags.DF
assert pkt.flags.evil
assert repr(pkt.flags) == '<Flag 6 (DF+evil)>'

assert len({IP().flags, IP().flags}) == 1

pkt = IP()
pkt.flags = ""
assert pkt.flags == 0

= TCP flags
~ TCP

pkt = TCP(flags="SA")
assert pkt.flags == 18
assert pkt.flags.S
assert pkt.flags.A
assert pkt.flags.SA
assert not any(getattr(pkt.flags, f) for f in 'FRPUECN')
assert repr(pkt.flags) == '<Flag 18 (SA)>'
pkt.flags.U = True
pkt.flags.S = False
assert pkt.flags.A
assert pkt.flags.U
assert pkt.flags.AU
assert not any(getattr(pkt.flags, f) for f in 'FSRPECN')
assert repr(pkt.flags) == '<Flag 48 (AU)>'
pkt.flags &= 'SFA'
pkt.flags |= 'P'
assert pkt.flags.P
assert pkt.flags.A
assert pkt.flags.PA
assert not any(getattr(pkt.flags, f) for f in 'FSRUECN')

pkt = TCP(flags=56)
assert all(getattr(pkt.flags, f) for f in 'PAU')
assert pkt.flags.PAU
assert not any(getattr(pkt.flags, f) for f in 'FSRECN')
assert repr(pkt.flags) == '<Flag 56 (PAU)>'
pkt.flags = 50
assert all(getattr(pkt.flags, f) for f in 'SAU')
assert pkt.flags.SAU
assert not any(getattr(pkt.flags, f) for f in 'FRPECN')
assert repr(pkt.flags) == '<Flag 50 (SAU)>'

= Flag values mutation with .raw_packet_cache
~ IP TCP

pkt = IP(raw(IP(flags="MF")/TCP(flags="SA")))
assert pkt.raw_packet_cache is not None
assert pkt[TCP].raw_packet_cache is not None
assert pkt.flags.MF
assert not pkt.flags.DF
assert not pkt.flags.evil
assert repr(pkt.flags) == '<Flag 1 (MF)>'
assert pkt[TCP].flags.S
assert pkt[TCP].flags.A
assert pkt[TCP].flags.SA
assert not any(getattr(pkt[TCP].flags, f) for f in 'FRPUECN')
assert repr(pkt[TCP].flags) == '<Flag 18 (SA)>'
pkt.flags.MF = 0
pkt.flags.DF = 1
pkt[TCP].flags.U = True
pkt[TCP].flags.S = False
pkt = IP(raw(pkt))
assert not pkt.flags.MF
assert pkt.flags.DF
assert not pkt.flags.evil
assert repr(pkt.flags) == '<Flag 2 (DF)>'
assert pkt[TCP].flags.A
assert pkt[TCP].flags.U
assert pkt[TCP].flags.AU
assert not any(getattr(pkt[TCP].flags, f) for f in 'FSRPECN')
assert repr(pkt[TCP].flags) == '<Flag 48 (AU)>'

= Operations on flag values
~ TCP

p1, p2 = TCP(flags="SU"), TCP(flags="AU")
assert (p1.flags & p2.flags).U
assert not any(getattr(p1.flags & p2.flags, f) for f in 'FSRPAECN')
assert all(getattr(p1.flags | p2.flags, f) for f in 'SAU')
assert (p1.flags | p2.flags).SAU
assert not any(getattr(p1.flags | p2.flags, f) for f in 'FRPECN')

assert TCP(flags="SA").flags & TCP(flags="S").flags == TCP(flags="S").flags
assert TCP(flags="SA").flags | TCP(flags="S").flags == TCP(flags="SA").flags

= Using tuples and lists as flag values
~ IP TCP

plist = PacketList(list(IP()/TCP(flags=(0, 2**9 - 1))))
assert [p[TCP].flags for p in plist] == [x for x in range(512)]

plist = PacketList(list(IP()/TCP(flags=["S", "SA", "A"])))
assert [p[TCP].flags for p in plist] == [2, 18, 16]


############
############
+ SCTP

= SCTP - Chunk Init - build
s = raw(IP()/SCTP()/SCTPChunkInit(params=[SCTPChunkParamIPv4Addr()]))
s == b'E\x00\x00<\x00\x01\x00\x00@\x84|;\x7f\x00\x00\x01\x7f\x00\x00\x01\x00\x00\x00\x00\x00\x00\x00\x00@,\x0b_\x01\x00\x00\x1c\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x05\x00\x08\x7f\x00\x00\x01'

= SCTP - Chunk Init - dissection
p = IP(s)
SCTPChunkParamIPv4Addr in p and p[SCTP].chksum == 0x402c0b5f and p[SCTPChunkParamIPv4Addr].addr == "127.0.0.1"

= SCTP - SCTPChunkSACK - build
s = raw(IP()/SCTP()/SCTPChunkSACK(gap_ack_list=["7:28"]))
s == b'E\x00\x004\x00\x01\x00\x00@\x84|C\x7f\x00\x00\x01\x7f\x00\x00\x01\x00\x00\x00\x00\x00\x00\x00\x00;\x01\xd4\x04\x03\x00\x00\x14\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01\x00\x00\x00\x07\x00\x1c'

= SCTP - SCTPChunkSACK - dissection
p = IP(s)
SCTPChunkSACK in p and p[SCTP].chksum == 0x3b01d404 and p[SCTPChunkSACK].gap_ack_list[0] == "7:28"

= SCTP - answers
(IP()/SCTP()).answers(IP()/SCTP()) == True

= SCTP basic header - Dissection
~ sctp
blob = b"\x1A\x85\x26\x94\x00\x00\x00\x0D\x00\x00\x04\xD2"
p = SCTP(blob)
assert(p.dport == 9876)
assert(p.sport == 6789)
assert(p.tag == 13)
assert(p.chksum == 1234)

= basic SCTPChunkData - Dissection
~ sctp
blob = b"\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x14\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x64\x61\x74\x61"
p = SCTP(blob).lastlayer()
assert(isinstance(p, SCTPChunkData))
assert(p.reserved == 0)
assert(p.delay_sack == 0)
assert(p.unordered == 0)
assert(p.beginning == 0)
assert(p.ending == 0)
assert(p.tsn == 0)
assert(p.stream_id == 0)
assert(p.stream_seq == 0)
assert(p.len == (len("data") + 16))
assert(p.data == b"data")

= basic SCTPChunkInit - Dissection
~ sctp
blob = b"\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01\x00\x00\x14\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"
p = SCTP(blob).lastlayer()
assert(isinstance(p, SCTPChunkInit))
assert(p.flags == 0)
assert(p.len == 20)
assert(p.init_tag == 0)
assert(p.a_rwnd == 0)
assert(p.n_out_streams == 0)
assert(p.n_in_streams == 0)
assert(p.init_tsn == 0)
assert(p.params == [])

= SCTPChunkInit multiple valid parameters - Dissection
~ sctp
blob = b"\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01\x00\x00\x5C\x00\x00\x00\x65\x00\x00\x00\x66\x00\x67\x00\x68\x00\x00\x00\x69\x00\x0C\x00\x06\x00\x05\x00\x00\x80\x00\x00\x04\xC0\x00\x00\x04\x80\x08\x00\x07\x0F\xC1\x80\x00\x80\x03\x00\x04\x80\x02\x00\x24\x87\x77\x21\x29\x3F\xDA\x62\x0C\x06\x6F\x10\xA5\x39\x58\x60\x98\x4C\xD4\x59\xD8\x8A\x00\x85\xFB\x9E\x2E\x66\xBA\x3A\x23\x54\xEF\x80\x04\x00\x06\x00\x01\x00\x00"
p = SCTP(blob).lastlayer()
assert(isinstance(p, SCTPChunkInit))
assert(p.flags == 0)
assert(p.len == 92)
assert(p.init_tag == 101)
assert(p.a_rwnd == 102)
assert(p.n_out_streams == 103)
assert(p.n_in_streams == 104)
assert(p.init_tsn == 105)
assert(len(p.params) == 7)
params = {type(param): param for param in p.params}
assert(set(params.keys()) == {SCTPChunkParamECNCapable, SCTPChunkParamFwdTSN,
                              SCTPChunkParamSupportedExtensions, SCTPChunkParamChunkList,
                              SCTPChunkParamRandom, SCTPChunkParamRequestedHMACFunctions,
                              SCTPChunkParamSupportedAddrTypes})
assert(params[SCTPChunkParamECNCapable] == SCTPChunkParamECNCapable())
assert(params[SCTPChunkParamFwdTSN] == SCTPChunkParamFwdTSN())
assert(params[SCTPChunkParamSupportedExtensions] == SCTPChunkParamSupportedExtensions(len=7))
assert(params[SCTPChunkParamChunkList] == SCTPChunkParamChunkList(len=4))
assert(params[SCTPChunkParamRandom].len == 4+32)
assert(len(params[SCTPChunkParamRandom].random) == 32)
assert(params[SCTPChunkParamRequestedHMACFunctions] == SCTPChunkParamRequestedHMACFunctions(len=6))
assert(params[SCTPChunkParamSupportedAddrTypes] == SCTPChunkParamSupportedAddrTypes(len=6))

= basic SCTPChunkInitAck - Dissection
~ sctp
blob = b"\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x02\x00\x00\x14\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"
p = SCTP(blob).lastlayer()
assert(isinstance(p, SCTPChunkInitAck))
assert(p.flags == 0)
assert(p.len == 20)
assert(p.init_tag == 0)
assert(p.a_rwnd == 0)
assert(p.n_out_streams == 0)
assert(p.n_in_streams == 0)
assert(p.init_tsn == 0)
assert(p.params == [])

= SCTPChunkInitAck with state cookie - Dissection
~ sctp
blob = b"\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x02\x00\x00\x4C\x00\x00\x00\x65\x00\x00\x00\x66\x00\x67\x00\x68\x00\x00\x00\x69\x80\x00\x00\x04\x00\x0B\x00\x0D\x6C\x6F\x63\x61\x6C\x68\x6F\x73\x74\x00\x00\x00\xC0\x00\x00\x04\x80\x08\x00\x07\x0F\xC1\x80\x00\x00\x07\x00\x14\x00\x10\x9E\xB2\x86\xCE\xE1\x7D\x0F\x6A\xAD\xFD\xB3\x5D\xBC\x00"
p = SCTP(blob).lastlayer()
assert(isinstance(p, SCTPChunkInitAck))
assert(p.flags == 0)
assert(p.len == 76)
assert(p.init_tag == 101)
assert(p.a_rwnd == 102)
assert(p.n_out_streams == 103)
assert(p.n_in_streams == 104)
assert(p.init_tsn == 105)
assert(len(p.params) == 5)
params = {type(param): param for param in p.params}
assert(set(params.keys()) == {SCTPChunkParamECNCapable, SCTPChunkParamHostname,
                              SCTPChunkParamFwdTSN, SCTPChunkParamSupportedExtensions,
                              SCTPChunkParamStateCookie})
assert(params[SCTPChunkParamECNCapable] == SCTPChunkParamECNCapable())
assert(raw(params[SCTPChunkParamHostname]) == raw(SCTPChunkParamHostname(len=13, hostname="localhost")))
assert(params[SCTPChunkParamFwdTSN] == SCTPChunkParamFwdTSN())
assert(params[SCTPChunkParamSupportedExtensions] == SCTPChunkParamSupportedExtensions(len=7))
assert(params[SCTPChunkParamStateCookie].len == 4+16)
assert(len(params[SCTPChunkParamStateCookie].cookie) == 16)

= basic SCTPChunkSACK - Dissection
~ sctp
blob = b"\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x03\x00\x00\x10\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"
p = SCTP(blob).lastlayer()
assert(isinstance(p, SCTPChunkSACK))
assert(p.flags == 0)
assert(p.len == 16)
assert(p.cumul_tsn_ack == 0)
assert(p.a_rwnd == 0)
assert(p.n_gap_ack == 0)
assert(p.n_dup_tsn == 0)
assert(p.gap_ack_list == [])
assert(p.dup_tsn_list == [])

= basic SCTPChunkHeartbeatReq - Dissection
~ sctp
blob = b"\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x04\x00\x00\x04"
p = SCTP(blob).lastlayer()
assert(isinstance(p, SCTPChunkHeartbeatReq))
assert(p.flags == 0)
assert(p.len == 4)
assert(p.params == [])

= basic SCTPChunkHeartbeatAck - Dissection
~ sctp
blob = b"\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x05\x00\x00\x04"
p = SCTP(blob).lastlayer()
assert(isinstance(p, SCTPChunkHeartbeatAck))
assert(p.flags == 0)
assert(p.len == 4)
assert(p.params == [])

= basic SCTPChunkAbort - Dissection
~ sctp
blob = b"\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x06\x00\x00\x04"
p = SCTP(blob).lastlayer()
assert(isinstance(p, SCTPChunkAbort))
assert(p.reserved == 0)
assert(p.TCB == 0)
assert(p.len == 4)
assert(p.error_causes == b"")

= basic SCTPChunkShutDown - Dissection
~ sctp
blob = b"\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x07\x00\x00\x08\x00\x00\x00\x00"
p = SCTP(blob).lastlayer()
assert(isinstance(p, SCTPChunkShutdown))
assert(p.flags == 0)
assert(p.len == 8)
assert(p.cumul_tsn_ack == 0)

= basic SCTPChunkShutDownAck - Dissection
~ sctp
blob = b"\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x08\x00\x00\x04"
p = SCTP(blob).lastlayer()
assert(isinstance(p, SCTPChunkShutdownAck))
assert(p.flags == 0)
assert(p.len == 4)

= basic SCTPChunkError - Dissection
~ sctp
blob = b"\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x09\x00\x00\x04"
p = SCTP(blob).lastlayer()
assert(isinstance(p, SCTPChunkError))
assert(p.flags == 0)
assert(p.len == 4)
assert(p.error_causes == b"")

= basic SCTPChunkCookieEcho - Dissection
~ sctp
blob = b"\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x0A\x00\x00\x04"
p = SCTP(blob).lastlayer()
assert(isinstance(p, SCTPChunkCookieEcho))
assert(p.flags == 0)
assert(p.len == 4)
assert(p.cookie == b"")

= basic SCTPChunkCookieAck - Dissection
~ sctp
blob = b"\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x0B\x00\x00\x04"
p = SCTP(blob).lastlayer()
assert(isinstance(p, SCTPChunkCookieAck))
assert(p.flags == 0)
assert(p.len == 4)

= basic SCTPChunkShutdownComplete - Dissection
~ sctp
blob = b"\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x0E\x00\x00\x04"
p = SCTP(blob).lastlayer()
assert(isinstance(p, SCTPChunkShutdownComplete))
assert(p.reserved == 0)
assert(p.TCB == 0)
assert(p.len == 4)

= basic SCTPChunkAuthentication - Dissection
~ sctp
blob = b"\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x0f\x00\x00\x08\x00\x00\x00\x00"
p = SCTP(blob).lastlayer()
assert(isinstance(p, SCTPChunkAuthentication))
assert(p.flags == 0)
assert(p.len == 8)
assert(p.shared_key_id == 0)
assert(p.HMAC_function == 0)

= basic SCTPChunkAddressConf - Dissection
~ sctp
blob = b"\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xc1\x00\x00\x08\x00\x00\x00\x00"
p = SCTP(blob).lastlayer()
assert(isinstance(p, SCTPChunkAddressConf))
assert(p.flags == 0)
assert(p.len == 8)
assert(p.seq == 0)
assert(p.params == [])

= basic SCTPChunkAddressConfAck - Dissection
~ sctp
blob = b"\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x80\x00\x00\x08\x00\x00\x00\x00"
p = SCTP(blob).lastlayer()
assert(isinstance(p, SCTPChunkAddressConfAck))
assert(p.flags == 0)
assert(p.len == 8)
assert(p.seq == 0)
assert(p.params == [])

= SCTPChunkParamRandom - Consecutive calls
~ sctp
param1, param2 = SCTPChunkParamRandom(), SCTPChunkParamRandom()
assert(param1.random != param2.random)

############
############
+ DHCP

= BOOTP - misc
assert BOOTP().answers(BOOTP())
assert BOOTP().hashret() == b"\x00\x00\x00\x00"

import random
random.seed(0x2807)
assert str(RandDHCPOptions(size=1)) in ["[('max_dhcp_size', 9227)]", "[('SMTP_server', '18.228.90.219')]"]

= DHCPOptionsField

value = [("hostname", "scapy")]
dof = DHCPOptionsField("options", "")
assert dof.i2repr("", value) == "[hostname='scapy']"
assert dof.i2repr("", ["opt", "opt2"]) == "[opt opt2]"
assert dof.i2m("", value) == b'\x0c\x05scapy'
assert dof.m2i("", b'\x0cunknown') == [b'\x0cunknown']
assert dof.m2i("", b'\x0c\x05scapy') == [('hostname', b'scapy')]

unknown_value_end = b"\xfe" + b"\xff"*257
udof = DHCPOptionsField("options", unknown_value_end)
assert udof.m2i("", unknown_value_end) == [(254, b'\xff'*255), 'end']

unknown_value_pad = b"\xfe" + b"\xff"*256 + b"\x00"
udof = DHCPOptionsField("options", unknown_value_pad)
assert udof.m2i("", unknown_value_pad) == [(254, b'\xff'*255), 'pad']

= DHCP - build
s = raw(IP(src="127.0.0.1")/UDP()/BOOTP(chaddr="00:01:02:03:04:05")/DHCP(options=[("message-type","discover"),"end"]))
assert s == b'E\x00\x01\x10\x00\x01\x00\x00@\x11{\xda\x7f\x00\x00\x01\x7f\x00\x00\x01\x00C\x00D\x00\xfcf\xea\x01\x01\x06\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x0000:01:02:03:04:0\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00c\x82Sc5\x01\x01\xff'

s2 = raw(IP(src="127.0.0.1")/UDP()/BOOTP(chaddr="05:04:03:02:01:00")/DHCP(options=[("param_req_list",[12,57,45,254]),("requested_addr", "192.168.0.1"),"end"]))
assert s2 == b'E\x00\x01\x19\x00\x01\x00\x00@\x11{\xd1\x7f\x00\x00\x01\x7f\x00\x00\x01\x00C\x00D\x01\x058\xeb\x01\x01\x06\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x0005:04:03:02:01:0\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00c\x82Sc7\x04\x0c9-\xfe2\x04\xc0\xa8\x00\x01\xff'

= DHCP - dissection
p = IP(s)
assert DHCP in p and p[DHCP].options[0] == ('message-type', 1)

p2 = IP(s2)
assert DHCP in p2
assert p2[DHCP].options[0] == ("param_req_list",[12,57,45,254])
assert p2[DHCP].options[1] == ("requested_addr", "192.168.0.1")

############
############
+ 802.11

= 802.11 - misc
PrismHeader().answers(PrismHeader()) == True

dpl = Dot11PacketList([Dot11()/LLC()/SNAP()/IP()/UDP()])
len(dpl) == 1

dpl_ether = dpl.toEthernet()
len(dpl_ether) == 1 and Ether in dpl_ether[0]

= Dot11 - build
s = raw(Dot11())
s == b'\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00'

= Dot11 - dissection
p = Dot11(s)
Dot11 in p and p.addr3 == "00:00:00:00:00:00"
p.mysummary() == '802.11 Management 0 00:00:00:00:00:00 > 00:00:00:00:00:00'

= Dot11QoS - build
s = raw(Dot11()/Dot11QoS(Ack_Policy=1))
assert s == b'\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00 \x00'

s = raw(Dot11(type=2, subtype=8)/Dot11QoS(TID=4))
assert s == b'\x88\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x04\x00'

= Dot11 - binary in SSID
pkt = Dot11() / Dot11Beacon() / Dot11Elt(ID=0, info=b"".join(chb(i) for i in range(32)))
pkt.show()
pkt.summary()
assert pkt[Dot11Elt::{"ID": 0}].summary() in [
    "SSID='%s'" % "".join(repr(chr(d))[1:-1] for d in range(32)),
    'SSID="%s"' % "".join(repr(chr(d))[1:-1] for d in range(32)),
]
pkt = Dot11(raw(pkt))
pkt.show()
pkt.summary()
assert pkt[Dot11Elt::{"ID": 0}].summary() in [
    "SSID='%s'" % "".join(repr(chr(d))[1:-1] for d in range(32)),
    'SSID="%s"' % "".join(repr(chr(d))[1:-1] for d in range(32)),
]

= Dot11QoS - dissection
p = Dot11(s)
Dot11QoS in p

= Dot11 - answers
query = Dot11(type=0, subtype=0)
Dot11(type=0, subtype=1).answers(query) == True

= Dot11 - misc
assert Dot11Elt(info="scapy").summary() == "SSID='scapy'"
assert Dot11Elt(ID=1).mysummary() == ""
assert Dot11(b'\x84\x00\x00\x00\x00\x11\x22\x33\x44\x55\x00\x11\x22\x33\x44\x55').addr2 == '00:11:22:33:44:55'

= Multiple Dot11Elt layers
pkt = Dot11() / Dot11Beacon() / Dot11Elt(ID="Rates") / Dot11Elt(ID="SSID", info="Scapy")
assert pkt[Dot11Elt::{"ID": 0}].info == b"Scapy"
assert pkt.getlayer(Dot11Elt, ID=0).info == b"Scapy"

= Dot11WEP - build
~ crypto
conf.wepkey = ""
assert raw(PPI()/Dot11(FCfield=0x40)/Dot11WEP()) == b'\x00\x00\x08\x00i\x00\x00\x00\x00@\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00'
conf.wepkey = "test123"
assert raw(PPI()/Dot11(type=2, subtype=8, FCfield=0x40)/Dot11QoS()/Dot11WEP()) == b'\x00\x00\x08\x00i\x00\x00\x00\x88@\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x008(^a'

= Dot11WEP - dissect
~ crypto
conf.wepkey = "test123"
a = PPI(b'\x00\x00\x08\x00i\x00\x00\x00\x88@\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x008(^a')
assert a[Dot11QoS][Dot11WEP].icv == 942169697

= Dot11 - answers
a = Dot11()/Dot11Auth(seqnum=1)
b = Dot11()/Dot11Auth(seqnum=2)
assert b.answers(a)
assert not a.answers(b)

assert not (Dot11()/Dot11Ack()).answers(Dot11())
assert (Dot11()/LLC(dsap=2, ctrl=4)).answers(Dot11()/LLC(dsap=1, ctrl=5))

= RSNCipherSuite
assert bytes(RSNCipherSuite()) == b'\x00\x0f\xac\x04'
rsn =  RSNCipherSuite(b'\x00\x0f\xac\x04')
assert rsn.oui == 0x0fac
assert rsn.cipher == 0x04

= AKMSuite
assert bytes(AKMSuite()) == b'\x00\x0f\xac\x01'
akm = AKMSuite(b'\x00\x0f\xac\x01')
assert akm.oui == 0x0fac
assert akm.suite == 0x01

= PMKIDListPacket
assert bytes(PMKIDListPacket()) == b'\x00\x00'
pmkids = PMKIDListPacket(b'\x01\x00LD\xfe\xf2l\xdcV\xce\x0b7\xab\xc62\x02O\x11')
assert pmkids.nb_pmkids == 1
assert len(pmkids.pmkid_list) == 1
assert pmkids.pmkid_list[0] == b'LD\xfe\xf2l\xdcV\xce\x0b7\xab\xc62\x02O\x11'

= Dot11EltRSN
assert bytes(Dot11EltRSN()) == b'0\x14\x01\x00\x00\x0f\xac\x04\x01\x00\x00\x0f\xac\x04\x01\x00\x00\x0f\xac\x01\x00\x00'
rsn_ie = Dot11EltRSN(b'0\x14\x01\x00\x00\x0f\xac\x04\x01\x00\x00\x0f\xac\x04\x01\x00\x00\x0f\xac\x01\x01\x00')
assert rsn_ie.group_cipher_suite.cipher == 0x04
assert rsn_ie.nb_pairwise_cipher_suites == 0x01
assert rsn_ie.pairwise_cipher_suites[0].cipher == 0x04
assert rsn_ie.nb_akm_suites == 0x01
assert rsn_ie.akm_suites[0].suite == 0x01
assert rsn_ie.mfp_capable
assert Dot11Elt in rsn_ie

= Dot11EltMicrosoftWPA
assert bytes(Dot11EltMicrosoftWPA()) == b'\xdd\x16\x00P\xf2\x01\x01\x00\x00\x0f\xac\x04\x01\x00\x00\x0f\xac\x04\x01\x00\x00\x0f\xac\x01'
ms_wpa_ie = Dot11EltMicrosoftWPA(b'\xdd\x1a\x00P\xf2\x01\x01\x00\x00P\xf2\x02\x02\x00\x00P\xf2\x04\x00P\xf2\x02\x01\x00\x00P\xf2\x01')
assert ms_wpa_ie[Dot11EltMicrosoftWPA].type == 0x01
assert ms_wpa_ie[Dot11EltMicrosoftWPA].version == 0x01
assert ms_wpa_ie[Dot11EltMicrosoftWPA].group_cipher_suite.cipher == 0x02
assert ms_wpa_ie[Dot11EltMicrosoftWPA].nb_pairwise_cipher_suites == 0x02
assert ms_wpa_ie[Dot11EltMicrosoftWPA].pairwise_cipher_suites[0].cipher == 0x04
assert ms_wpa_ie[Dot11EltMicrosoftWPA].pairwise_cipher_suites[1].cipher == 0x02
assert ms_wpa_ie[Dot11EltMicrosoftWPA].nb_akm_suites == 0x01
assert ms_wpa_ie[Dot11EltMicrosoftWPA].akm_suites[0].suite == 0x01
assert Dot11Elt in ms_wpa_ie

= Dot11EltVendorSpecific
assert bytes(Dot11EltVendorSpecific()) == b'\xdd\x03\x00\x00\x00'
vendor_specific_ie = Dot11EltVendorSpecific(b'\xdd\t\x00\x03\x7f\x01\x01\x00\x00\xff\x7f')
assert vendor_specific_ie.oui == 0x00037f
assert Dot11Elt in vendor_specific_ie

= Beacon with RSN IE
f = Dot11(b"\x80\x00\x00\x00\xff\xff\xff\xff\xff\xffLN5V\xee\x03LN5V\xee\x03\xf0\x8f\x80\x01\xdc7\x00\x00\x00\x00\x90\x011\x04\x00\x0cciscosb-wpa2\x01\x08\x82\x84\x8b\x96\x0c\x12\x18$\x03\x01\x06\x05\x04\x00\x01\x00\x00*\x01\x000\x14\x01\x00\x00\x0f\xac\x04\x01\x00\x00\x0f\xac\x04\x01\x00\x00\x0f\xac\x01\x01\x002\x040H`l\xdd\x18\x00P\xf2\x02\x01\x01\x84\x00\x03\xa4\x00\x00'\xa4\x00\x00BC^\x00b2/\x00\xdd\x1e\x00\x90L3L\x10\x1b\xff\xff\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00-\x1aL\x10\x1b\xff\xff\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xdd\x1a\x00\x90L4\x06\x08\x08\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00=\x16\x06\x08\x08\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00J\x0e\x14\x00\n\x00,\x01\xc8\x00\x14\x00\x05\x00\x19\x00\x7f\x01\x01\xdd\t\x00\x03\x7f\x01\x01\x00\x00\xff\x7f\xdd\n\x00\x03\x7f\x04\x01\x00\x06\x00@\x00")
assert Dot11EltRSN in f
assert f[Dot11EltRSN].len == 20
assert f[Dot11EltRSN].group_cipher_suite[0].cipher == 0x04
assert f[Dot11EltRSN].pairwise_cipher_suites[0].cipher == 0x04
assert f[Dot11EltRSN].akm_suites[0].suite == 0x01

= Beacon with Microsoft WPA IE
f = Dot11(b"\x80\x00\x00\x00\xff\xff\xff\xff\xff\xffNN5V\xee\x03NN5V\xee\x030\x8f\x80\x01\xdc7\x00\x00\x00\x00\x90\x011\x04\x00\x0bciscosb-wpa\x01\x08\x82\x84\x8b\x96\x0c\x12\x18$\x03\x01\x06\x05\x04\x00\x01\x00\x00*\x01\x00\xdd\x16\x00P\xf2\x01\x01\x00\x00P\xf2\x04\x01\x00\x00P\xf2\x04\x01\x00\x00P\xf2\x012\x040H`l\xdd\x18\x00P\xf2\x02\x01\x01\x85\x00\x03\xa4\x00\x00'\xa4\x00\x00BC^\x00b2/\x00\xdd\x1e\x00\x90L3L\x10\x1b\xff\xff\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00-\x1aL\x10\x1b\xff\xff\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xdd\x1a\x00\x90L4\x06\x08\x08\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00=\x16\x06\x08\x08\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00J\x0e\x14\x00\n\x00,\x01\xc8\x00\x14\x00\x05\x00\x19\x00\x7f\x01\x01\xdd\t\x00\x03\x7f\x01\x01\x00\x00\xff\x7f\xdd\n\x00\x03\x7f\x04\x01\x00\x06\x00@\x00")
assert Dot11EltMicrosoftWPA in f
assert f[Dot11EltMicrosoftWPA].type == 0x01
assert f[Dot11EltMicrosoftWPA].version == 0x01
assert f[Dot11EltMicrosoftWPA].group_cipher_suite.cipher == 0x04
assert f[Dot11EltMicrosoftWPA].nb_pairwise_cipher_suites == 0x01
assert f[Dot11EltMicrosoftWPA].pairwise_cipher_suites[0].cipher == 0x04
assert f[Dot11EltMicrosoftWPA].nb_akm_suites == 0x01
assert f[Dot11EltMicrosoftWPA].akm_suites[0].suite == 0x01

= Reassociation request
f = Dot11(b' \x00:\x01@\xe3\xd6\x7f*\x00\x00\x10\x18\xa9l.@\xe3\xd6\x7f*\x00 \t1\x04\n\x00@\xe3\xd6\x7f*\x00\x00\x064.2.12\x01\x08\x82\x84\x0b\x16$0Hl!\x02\x08\x1a$\x02\x01\x0b0&\x01\x00\x00\x0f\xac\x04\x01\x00\x00\x0f\xac\x04\x01\x00\x00\x0f\xac\x01\x00\x00\x01\x00LD\xfe\xf2l\xdcV\xce\x0b7\xab\xc62\x02O\x112\x04\x0c\x12\x18`\x7f\x08\x01\x00\x00\x00\x00\x00\x00@\xdd\t\x00\x10\x18\x02\x00\x00\x10\x00\x00')
assert Dot11EltRSN in f
assert f[Dot11EltRSN].pmkids.nb_pmkids == 1
assert len(f[Dot11EltRSN].pmkids.pmkid_list) == 1
assert f[Dot11EltRSN].pmkids.pmkid_list[0] == b'LD\xfe\xf2l\xdcV\xce\x0b7\xab\xc62\x02O\x11'


######################################
# More PPI tests in contrib/ppi_cace #
######################################

############
############
+ 802.3

= Test detection

assert isinstance(Dot3(raw(Ether())),Ether)
assert isinstance(Ether(raw(Dot3())),Dot3)

a = Ether(b'\xff\xff\xff\xff\xff\xff\x00\x00\x00\x00\x00\x00\x00\x00')
assert isinstance(a,Dot3)
assert a.dst == 'ff:ff:ff:ff:ff:ff'
assert a.src == '00:00:00:00:00:00'

a = Dot3(b'\xff\xff\xff\xff\xff\xff\x00\x00\x00\x00\x00\x00\x90\x00')
assert isinstance(a,Ether)
assert a.dst == 'ff:ff:ff:ff:ff:ff'
assert a.src == '00:00:00:00:00:00'


############
############
+ ASN.1

= MIB
~ mib

import tempfile
fd, fname = tempfile.mkstemp()
os.write(fd, b"-- MIB test\nscapy       OBJECT IDENTIFIER ::= {test 2807}\n")
os.close(fd)

load_mib(fname)
assert(len([k for k in conf.mib.__dict__.values() if "scapy" in k]) == 1)

assert(len([oid for oid in conf.mib]) > 100)

assert(conf.mib._my_find("MIB", "keyUsage"))

assert(len(conf.mib._find("MIB", "keyUsage")))

assert(len(conf.mib._recurs_find_all((), "MIB", "keyUsage")))

= MIB - graph
~ mib

import mock

@mock.patch("scapy.asn1.mib.do_graph")
def get_mib_graph(do_graph):
    def store_graph(graph, **kargs):
        assert graph.startswith("""digraph "mib" {""")
        assert """"test.2807" [ label="scapy"  ];""" in graph
    do_graph.side_effect = store_graph
    conf.mib._make_graph()

get_mib_graph()

= DADict tests

a = DADict("test")
a.test_value = "scapy"
with ContextManagerCaptureOutput() as cmco:
    a._show()
    assert(cmco.get_output() == "test_value = 'scapy'\n")

b = DADict("test2")
b.test_value_2 = "hello_world"

a._branch(b, 1)
try:
    a._branch(b, 1)
    assert False
except DADict_Exception:
    pass

assert(len(a._find("test2")))

assert(len(a._find(test_value_2="hello_world")))

assert(len(a._find_all("test2")))

assert(not a._recurs_find((a,)))

assert(not a._recurs_find_all((a,)))

= BER tests

BER_id_enc(42) == '*'
BER_id_enc(2807) == b'\xbfw'

b = BERcodec_IPADDRESS()
r1 = b.enc("8.8.8.8")
r1 == b'@\x04\x08\x08\x08\x08'

r2 = b.dec(r1)[0]
r2.val == '8.8.8.8'

a = b'\x1f\xfe\xfe\xfe\xfe\xfe\xfe\xfe\xfe\xfe\xfe\xfe\xfe\xfe\xfe\xfe\xfe\xfe\xfe\xfe\xfe\xfe\xfe\xfe\xfe\xfe\xfe\xfe\xfe\xfe\xfe\xfe\xfe\xfe\xfe\xfe\xfe\xfe\xfe\xfe\xfe\xfe\xfe\xfe\xfe\xfe\xfe\xfe\xfe\xfe\xfe\xfe\xfe\xfe\xfe\xfe\xfe\xfe\xfe\xfe\xfe\xfe\xfe\xfe\xfe\xfe\xfe\xfe\xfe\xfe\xfe\xfe\xfe\xfe\xfe\xfe\xfe\xfe\xfe\xfe\xfe\xfe\xfe\xfe\xfe\xfe\xfe\xfe\xfe\xfe\xfe\xfe\xfe\xfe\xfe\xfe\xfe\xfe\xfe\xfe\xfe\xfe\xfe\xfe\xfe\xfe\xfe\xfe\xfe\xfe\xfe\xfe\xfe\xfe\xfe\xfe\xfe\xfe\xfe\xfe\xfe\xfe\xfe\xfe\xfe\xfe\xfe\xfe\xfe\xfe\x01\x01\x00C\x02\x01U0\x0f0\r\x06\x08+\x06\x01\x02\x01\x02\x01\x00\x02\x01!'
ret = False
try:
    BERcodec_Object.check_type(a)
except BER_BadTag_Decoding_Error:
    ret = True
else:
    ret = False

assert(ret)

############
############
+ inet.py

= IPv4 - ICMPTimeStampField
test = ICMPTimeStampField("test", None)
value = test.any2i("", "07:28:28.07")
value == 26908070
test.i2repr("", value) == '7:28:28.70'

= IPv4 - UDP null checksum
IP(raw(IP()/UDP()/Raw(b"\xff\xff\x01\x6a")))[UDP].chksum == 0xFFFF

= IPv4 - (IP|UDP|TCP|ICMP)Error
query = IP(dst="192.168.0.1", src="192.168.0.254", ttl=1)/UDP()/DNS()
answer = IP(dst="192.168.0.254", src="192.168.0.2", ttl=1)/ICMP()/IPerror(dst="192.168.0.1", src="192.168.0.254", ttl=0)/UDPerror()/DNS()

query = IP(dst="192.168.0.1", src="192.168.0.254", ttl=1)/UDP()/DNS()
answer = IP(dst="192.168.0.254", src="192.168.0.2")/ICMP(type=11)/IPerror(dst="192.168.0.1", src="192.168.0.254", ttl=0)/UDPerror()/DNS()
assert(answer.answers(query) == True)

query = IP(dst="192.168.0.1", src="192.168.0.254", ttl=1)/TCP()
answer = IP(dst="192.168.0.254", src="192.168.0.2")/ICMP(type=11)/IPerror(dst="192.168.0.1", src="192.168.0.254", ttl=0)/TCPerror()

assert(answer.answers(query) == True)

query = IP(dst="192.168.0.1", src="192.168.0.254", ttl=1)/ICMP()/"scapy"
answer = IP(dst="192.168.0.254", src="192.168.0.2")/ICMP(type=11)/IPerror(dst="192.168.0.1", src="192.168.0.254", ttl=0)/ICMPerror()/"scapy"
assert(answer.answers(query) == True)

= IPv4 - mDNS
a = IP(dst="224.0.0.251")
assert a.hashret() == b"\x00"

# TODO add real case here

= IPv4 - utilities
l = overlap_frag(IP(dst="1.2.3.4")/ICMP()/("AB"*8), ICMP()/("CD"*8))
assert(len(l) == 6)
assert([len(raw(p[IP].payload)) for p in l] == [8, 8, 8, 8, 8, 8])
assert([(p.frag, p.flags.MF) for p in [IP(raw(p)) for p in l]] == [(0, True), (1, True), (2, True), (0, True), (1, True), (2, False)])

= IPv4 - traceroute utilities
ip_ttl = [("192.168.0.%d" % i, i) for i in six.moves.range(1, 10)]

tr_packets = [ (IP(dst="192.168.0.1", src="192.168.0.254", ttl=ttl)/TCP(options=[("Timestamp", "00:00:%.2d.00" % ttl)])/"scapy",
                IP(dst="192.168.0.254", src=ip)/ICMP(type=11)/IPerror(dst="192.168.0.1", src="192.168.0.254", ttl=0)/TCPerror()/"scapy")
               for (ip, ttl) in ip_ttl ]

tr = TracerouteResult(tr_packets)
assert(tr.get_trace() == {'192.168.0.1': {1: ('192.168.0.1', False), 2: ('192.168.0.2', False), 3: ('192.168.0.3', False), 4: ('192.168.0.4', False), 5: ('192.168.0.5', False), 6: ('192.168.0.6', False), 7: ('192.168.0.7', False), 8: ('192.168.0.8', False), 9: ('192.168.0.9', False)}})

def test_show():
    with ContextManagerCaptureOutput() as cmco:
        tr = TracerouteResult(tr_packets)
        tr.show()
        result_show = cmco.get_output()
    expected = "  192.168.0.1:tcp80  \n"
    expected += "1 192.168.0.1     11 \n"
    expected += "2 192.168.0.2     11 \n"
    expected += "3 192.168.0.3     11 \n"
    expected += "4 192.168.0.4     11 \n"
    expected += "5 192.168.0.5     11 \n"
    expected += "6 192.168.0.6     11 \n"
    expected += "7 192.168.0.7     11 \n"
    expected += "8 192.168.0.8     11 \n"
    expected += "9 192.168.0.9     11 \n"
    index_result = result_show.index("\n1")
    index_expected = expected.index("\n1")
    assert(result_show[index_result:] == expected[index_expected:])

test_show()

def test_summary():
    with ContextManagerCaptureOutput() as cmco:
        tr = TracerouteResult(tr_packets)
        tr.summary()
        result_summary = cmco.get_output()
    assert(len(result_summary.split('\n')) == 10)
    assert(any(
        "IP / TCP 192.168.0.254:%s > 192.168.0.1:%s S / Raw ==> "
        "IP / ICMP 192.168.0.9 > 192.168.0.254 time-exceeded "
        "ttl-zero-during-transit / IPerror / TCPerror / "
        "Raw" % (ftp_data, http) in result_summary
        for ftp_data in ['21', 'ftp_data']
        for http in ['80', 'http', 'www_http', 'www']
    ))

test_summary()

@mock.patch("scapy.layers.inet.plt")
def test_timeskew_graph(mock_plt):
    def fake_plot(data, **kwargs):
        return data
    mock_plt.plot = fake_plot
    srl = SndRcvList([(a, a) for a in [IP(raw(p[0])) for p in tr_packets]])
    ret = srl.timeskew_graph("192.168.0.254")
    assert(len(ret) == 9)
    assert(ret[0][1] == 0.0)

test_timeskew_graph()

tr = TracerouteResult(tr_packets)
saved_AS_resolver = conf.AS_resolver
conf.AS_resolver = None
tr.make_graph()
assert(len(tr.graphdef) == 491)
tr.graphdef.startswith("digraph trace {") == True
assert(('"192.168.0.9" ->' in tr.graphdef) == True)
conf.AS_resolver = conf.AS_resolver

pl = PacketList(list([Ether()/x for x in itertools.chain(*tr_packets)]))
srl, ul = pl.sr()
assert(len(srl) == 9 and len(ul) == 0)

conf_color_theme = conf.color_theme
conf.color_theme = BlackAndWhite()
assert(len(pl.sessions().keys()) == 10)
conf.color_theme = conf_color_theme

new_pl = pl.replace(IP.src, "192.168.0.254", "192.168.0.42")
assert("192.168.0.254" not in [p[IP].src for p in new_pl])

= IPv4 - reporting

@mock.patch("scapy.layers.inet.sr")
def test_report_ports(mock_sr):
    def sr(*args, **kargs):
        return [(IP()/TCP(dport=65081, flags="S"), IP()/TCP(sport=65081, flags="SA")),
                (IP()/TCP(dport=65082, flags="S"), IP()/ICMP(type=3, code=1)),
                (IP()/TCP(dport=65083, flags="S"), IP()/TCP(sport=65083, flags="R"))], [IP()/TCP(dport=65084, flags="S")]
    mock_sr.side_effect = sr
    report = "\\begin{tabular}{|r|l|l|}\n\\hline\n65081 & open & SA \\\\\n\\hline\n?? & closed & ICMP type dest-unreach/host-unreachable from 127.0.0.1 \\\\\n65083 & closed & TCP R \\\\\n\\hline\n65084 & ? & unanswered \\\\\n\\hline\n\\end{tabular}\n"
    assert(report_ports("www.secdev.org", [65081,65082,65083,65084]) == report)

test_report_ports()

def test_IPID_count():
    with ContextManagerCaptureOutput() as cmco:
        random.seed(0x2807)
        IPID_count([(IP()/UDP(), IP(id=random.randint(0, 65535))/UDP()) for i in range(3)])
        result_IPID_count = cmco.get_output()
    lines = result_IPID_count.split("\n")
    assert(len(lines) == 5)
    assert(lines[0] in ["Probably 3 classes: [4613, 53881, 58437]",
                        "Probably 3 classes: [9103, 9227, 46399]"])

test_IPID_count()


############
############
+ ARP

= ARP for IPv4

p = raw(ARP())
assert p == raw(ARP(ptype=0x0800))
p = ARP(p)
assert p.ptype == 0x0800
assert valid_ip(p.pdst)
assert valid_ip(p.psrc)
assert isinstance(p.payload, NoPayload)

= ARP for IPv6

p = ARP(raw(ARP(ptype=0x86dd)))
assert p.ptype == 0x86dd
assert valid_ip6(p.pdst)
assert valid_ip6(p.psrc)
assert isinstance(p.payload, NoPayload)

= Dummy ARP

p = ARP(raw(ARP(plen=2, hwlen=1, hwdst="x", hwsrc="y", pdst="aa", psrc="bb")))
assert p.hwdst == b"x"
assert p.hwsrc == b"y"
assert p.pdst == b"aa"
assert p.psrc == b"bb"
assert isinstance(p.payload, NoPayload)

p = ARP(raw(ARP(plen=1, hwlen=1)))
assert p.hwdst == p.hwsrc == p.pdst == p.psrc == b"\x00"
assert isinstance(p.payload, NoPayload)


############
############
+ Fields

= FieldLenField with BitField
class Test(Packet):
    name = "Test"
    fields_desc = [
        FieldLenField("BitCount", None, fmt="H", count_of="Values"),
        FieldLenField("ByteCount", None, fmt="B", length_of="Values"),
        FieldListField("Values", [], BitField("data", 0x0, size=1),
                       count_from=lambda pkt: pkt.BitCount),
    ]

pkt = Test(raw(Test(Values=[0, 0, 0, 0, 1, 1, 1, 1])))
assert(pkt.BitCount == 8)
assert(pkt.ByteCount == 1)

= PacketListField

class TestPacket(Packet):
  name = 'TestPacket'
  fields_desc = [ PacketListField('list', [], 0) ]

a = TestPacket()
a.list.append(1)
assert(len(a.list) == 1)

b = TestPacket()
assert(len(b.list) == 0)

= PacketField

class InnerPacket(Packet):
    fields_desc = [ StrField("f_name", "test") ]

class TestPacket(Packet):
    fields_desc = [ PacketField("inner", InnerPacket(), InnerPacket) ]

p = TestPacket()
print(p.inner.f_name)
assert p.inner.f_name == b"test"

p = TestPacket()
p.inner.f_name = b"scapy"
assert p.inner.f_name == b"scapy"

p = TestPacket()
assert p.inner.f_name == b"test"

############
############
+ MPLS tests

= MPLS - build/dissection
from scapy.contrib.mpls import EoMCW, MPLS
p1 = MPLS()/IP()/UDP()
assert(p1[MPLS].s == 1)
p2 = MPLS()/MPLS()/IP()/UDP()
assert(p2[MPLS].s == 0)

p1[MPLS]
p1[IP]
p2[MPLS]
p2[MPLS:1]
p2[IP]

= MPLS encapsulated Ethernet with CW - build/dissection
p = Ether(dst="11:11:11:11:11:11", src="22:22:22:22:22:22")
p /= MPLS(label=1)/EoMCW(seq=1234)
p /= Ether(dst="33:33:33:33:33:33", src="44:44:44:44:44:44")/IP()
p = Ether(raw(p))
assert(p[EoMCW].zero == 0)
assert(p[EoMCW].reserved == 0)
assert(p[EoMCW].seq == 1234)

=  MPLS encapsulated Ethernet without CW - build/dissection
p = Ether(dst="11:11:11:11:11:11", src="22:22:22:22:22:22")
p /= MPLS(label=2)/MPLS(label=1)
p /= Ether(dst="33:33:33:33:33:33", src="44:44:44:44:44:44")/IP()
p = Ether(raw(p))
assert(p[Ether:2].type == 0x0800)

try:
    p[EoMCW]
except IndexError:
    ret = True
else:
    ret = False

assert(ret)
assert(p[Ether:2].type == 0x0800)

= MPLS encapsulated IP - build/dissection
p = Ether(dst="11:11:11:11:11:11", src="22:22:22:22:22:22")
p /= MPLS(label=1)/IP()
p = Ether(raw(p))

try:
    p[EoMCW]
except IndexError:
    ret = True
else:
    ret = False

assert(ret)

try:
    p[Ether:2]
except IndexError:
    ret = True
else:
    ret = False

assert(ret)

p[IP]


############
############
+ PacketList methods

= plot()

import mock
@mock.patch("scapy.plist.plt")
def test_plot(mock_plt):
    def fake_plot(data, **kwargs):
        return data
    mock_plt.plot = fake_plot
    plist = PacketList([IP(id=i)/TCP() for i in range(10)])
    lines = plist.plot(lambda p: (p.time, p.id))
    assert(len(lines) == 10)

test_plot()

= diffplot()

import mock
@mock.patch("scapy.plist.plt")
def test_diffplot(mock_plt):
    def fake_plot(data, **kwargs):
        return data
    mock_plt.plot = fake_plot
    plist = PacketList([IP(id=i)/TCP() for i in range(10)])
    lines = plist.diffplot(lambda x,y: (x.time, y.id-x.id))
    assert(len(lines) == 9)

test_diffplot()

= multiplot()

import mock
@mock.patch("scapy.plist.plt")
def test_multiplot(mock_plt):
    def fake_plot(data, **kwargs):
        return data
    mock_plt.plot = fake_plot
    tmp = [IP(id=i)/TCP() for i in range(10)]
    plist = PacketList([tuple(tmp[i-2:i]) for i in range(2, 10, 2)])
    lines = plist.multiplot(lambda x: (x[1][IP].src, (x[1].time, x[1][IP].id)))
    assert(len(lines) == 1)
    assert(len(lines[0]) == 4)

test_multiplot()

= rawhexdump()

def test_rawhexdump():
    with ContextManagerCaptureOutput() as cmco:
        p = PacketList([IP()/TCP() for i in range(2)])
        p.rawhexdump()
        result_pl_rawhexdump = cmco.get_output()
    assert(len(result_pl_rawhexdump.split('\n')) == 7)
    assert(result_pl_rawhexdump.startswith("0000  45 00 00 28"))

test_rawhexdump()

= hexraw()

def test_hexraw():
    with ContextManagerCaptureOutput() as cmco:
        p = PacketList([IP()/Raw(str(i)) for i in range(2)])
        p.hexraw()
        result_pl_hexraw = cmco.get_output()
    assert(len(result_pl_hexraw.split('\n')) == 5)
    assert("0000  30" in result_pl_hexraw)

test_hexraw()

= hexdump()

def test_hexdump():
    with ContextManagerCaptureOutput() as cmco:
        p = PacketList([IP()/Raw(str(i)) for i in range(2)])
        p.hexdump()
        result_pl_hexdump = cmco.get_output()
    assert(len(result_pl_hexdump.split('\n')) == 7)
    assert("0010  7F 00 00 01 31" in result_pl_hexdump)

test_hexdump()

= import_hexcap()

@mock.patch("%s.input" % six.moves.builtins.__name__)
def test_import_hexcap(mock_input):
    data = """
0000  FF FF FF FF FF FF AA AA AA AA AA AA 08 00 45 00  ..............E.
0010  00 1C 00 01 00 00 40 01 7C DE 7F 00 00 01 7F 00  ......@.|.......
0020  00 01 08 00 F7 FF 00 00 00 00                    ..........
"""[1:].split("\n")
    lines = iter(data)
    mock_input.side_effect = lambda: next(lines)
    return import_hexcap()

pkt = test_import_hexcap()
pkt = Ether(pkt)
assert pkt[Ether].dst == "ff:ff:ff:ff:ff:ff"
assert pkt[IP].dst == "127.0.0.1"
assert ICMP in pkt

= padding()

def test_padding():
    with ContextManagerCaptureOutput() as cmco:
        p = PacketList([IP()/conf.padding_layer(str(i)) for i in range(2)])
        p.padding()
        result_pl_padding = cmco.get_output()
    assert(len(result_pl_padding.split('\n')) == 5)
    assert("0000  30" in result_pl_padding)

test_padding()

= nzpadding()

def test_nzpadding():
    with ContextManagerCaptureOutput() as cmco:
        p = PacketList([IP()/conf.padding_layer("A%s" % i) for i in range(2)])
        p.nzpadding()
        result_pl_nzpadding = cmco.get_output()
    assert(len(result_pl_nzpadding.split('\n')) == 5)
    assert("0000  41 30" in result_pl_nzpadding)

test_nzpadding()

= conversations()

import mock
@mock.patch("scapy.plist.do_graph")
def test_conversations(mock_do_graph):
    def fake_do_graph(graph, **kwargs):
        return graph
    mock_do_graph.side_effect = fake_do_graph
    plist = PacketList([IP(dst="127.0.0.2")/TCP(dport=i) for i in range(2)])
    plist.extend([IP(src="127.0.0.2")/TCP(sport=i) for i in range(2)])
    plist.extend([IPv6(dst="::2", src="::1")/TCP(sport=i) for i in range(2)])
    plist.extend([IPv6(src="::2", dst="::1")/TCP(sport=i) for i in range(2)])
    plist.extend([Ether()/ARP(pdst="127.0.0.1")])
    result_conversations = plist.conversations()
    assert(len(result_conversations.split('\n')) == 8)
    assert(result_conversations.startswith('digraph "conv" {'))
    assert("127.0.0.1" in result_conversations)
    assert("::1" in result_conversations)

test_conversations()

= sessions()

pl = PacketList([Ether()/IPv6()/ICMPv6EchoRequest(), Ether()/IPv6()/IPv6()])
pl.extend([Ether()/IP()/IP(), Ether()/ARP()])
pl.extend([Ether()/Ether()/IP()])
assert(len(pl.sessions().keys()) == 5)

= afterglow()

import mock
@mock.patch("scapy.plist.do_graph")
def test_afterglow(mock_do_graph):
    def fake_do_graph(graph, **kwargs):
        return graph
    mock_do_graph.side_effect = fake_do_graph
    plist = PacketList([IP(dst="127.0.0.2")/TCP(dport=i) for i in range(2)])
    plist.extend([IP(src="127.0.0.2")/TCP(sport=i) for i in range(2)])
    result_afterglow = plist.afterglow()
    assert(len(result_afterglow.split('\n')) == 19)
    assert(result_afterglow.startswith('digraph "afterglow" {'))

test_afterglow()

= psdump()

print("PYX: %d" % PYX)
if PYX:
    import tempfile
    import os
    filename = tempfile.mktemp(suffix=".ps")
    plist = PacketList([IP()/TCP()])
    plist.psdump(filename)
    assert(os.path.exists(filename))
    os.unlink(filename)

= pdfdump()

print("PYX: %d" % PYX)
if PYX:
    import tempfile
    import os
    filename = tempfile.mktemp(suffix=".pdf")
    plist = PacketList([IP()/TCP()])
    plist.pdfdump(filename)
    assert(os.path.exists(filename))
    os.unlink(filename)

= svgdump()

print("PYX: %d" % PYX)
if PYX and not six.PY2:
    import tempfile
    import os
    filename = tempfile.mktemp(suffix=".svg")
    plist = PacketList([IP()/TCP()])
    plist.svgdump(filename)
    assert(os.path.exists(filename))
    os.unlink(filename)

= __getstate__ / __setstate__ (used by pickle)

import pickle

frm = Ether(src='00:11:22:33:44:55', dst='00:22:33:44:55:66')/Raw()
pl = PacketList(res=[frm, frm], name='WhatAGreatName')
pickled = pickle.dumps(pl)
pl = pickle.loads(pickled)
assert(pl.listname == "WhatAGreatName")
assert(len(pl) == 2)
assert(pl[0][Ether].src == '00:11:22:33:44:55')
assert(pl[1][Ether].dst == '00:22:33:44:55:66')


############
############
+ Scapy version

= _version()

import os
version_filename = os.path.join(scapy._SCAPY_PKG_DIR, "VERSION")

version = scapy._version()
assert(os.path.exists(version_filename))

import mock
with mock.patch("scapy._version_from_git_describe") as version_mocked:
  version_mocked.side_effect = Exception()
  assert(scapy._version() == version)
  os.unlink(version_filename)
  assert(scapy._version() == "git-archive.dev$Format:%h")


############
# RTP
############

+ RTP tests

= test rtp with extension header
~ rtp

data = b'\x90o\x14~YY\xf5h\xcc#\xd7\xcfUH\x00\x03\x167116621 \x000\x00'
pkt = RTP(data)
assert "RTP" in pkt
parsed = pkt["RTP"]
assert parsed.version == 2
assert parsed.extension
assert parsed.numsync == 0
assert not parsed.marker
assert parsed.payload_type == 111
assert parsed.sequence == 5246
assert parsed.timestamp == 1499067752
assert parsed.sourcesync == 0xcc23d7cf
assert "RTPExtension" in parsed, parsed.show()
assert parsed["RTPExtension"].header_id == 0x5548
assert parsed["RTPExtension"].header == [0x16373131,0x36363231,0x20003000]

= test layer creation

created = RTP(extension=True, payload_type="PCMA", sequence=0x1234, timestamp=12345678, sourcesync=0xabcdef01)
created /= RTPExtension(header_id=0x4321, header=[0x11223344])
assert raw(created) == b'\x90\x08\x124\x00\xbcaN\xab\xcd\xef\x01C!\x00\x01\x11"3D'
parsed = RTP(raw(created))
assert parsed.payload_type == 8
assert "RTPExtension" in parsed, parsed.show()
assert parsed["RTPExtension"].header == [0x11223344]

= test RTP without extension

created = RTP(extension=False, payload_type="DVI4", sequence=0x1234, timestamp=12345678, sourcesync=0xabcdef01)
assert raw(created) == b'\x80\x11\x124\x00\xbcaN\xab\xcd\xef\x01'
parsed = RTP(raw(created))
assert parsed.sourcesync == 0xabcdef01
assert "RTPExtension" not in parsed

#= Test snmpwalk()
#
#~ netaccess
#def test_snmpwalk(dst):
#    with ContextManagerCaptureOutput() as cmco:
#        snmpwalk(dst=dst)
#        output = cmco.get_output()
#    expected = "No answers\n"
#    assert(output == expected)
#
#test_snmpwalk("secdev.org")
